always be the same as the original route so it is an optimisation
        to disable snat_reroute and avoid the recalculation.
 
+sync_persist_mode - INTEGER
+       default 0
+
+       Controls the synchronisation of connections when using persistence
+
+       0: All types of connections are synchronised
+       1: Attempt to reduce the synchronisation traffic depending on
+       the connection type. For persistent services avoid synchronisation
+       for normal connections, do it only for persistence templates.
+       In such case, for TCP and SCTP it may need enabling sloppy_tcp and
+       sloppy_sctp flags on backup servers. For non-persistent services
+       such optimization is not applied, mode 0 is assumed.
+
 sync_version - INTEGER
        default 1
 
 
        int                     sysctl_snat_reroute;
        int                     sysctl_sync_ver;
        int                     sysctl_sync_ports;
+       int                     sysctl_sync_persist_mode;
        unsigned long           sysctl_sync_qlen_max;
        int                     sysctl_sync_sock_size;
        int                     sysctl_cache_bypass;
        return ACCESS_ONCE(ipvs->sysctl_sync_ports);
 }
 
+static inline int sysctl_sync_persist_mode(struct netns_ipvs *ipvs)
+{
+       return ipvs->sysctl_sync_persist_mode;
+}
+
 static inline unsigned long sysctl_sync_qlen_max(struct netns_ipvs *ipvs)
 {
        return ipvs->sysctl_sync_qlen_max;
        return 1;
 }
 
+static inline int sysctl_sync_persist_mode(struct netns_ipvs *ipvs)
+{
+       return 0;
+}
+
 static inline unsigned long sysctl_sync_qlen_max(struct netns_ipvs *ipvs)
 {
        return IPVS_SYNC_QLEN_MAX;
 
                .mode           = 0644,
                .proc_handler   = &proc_do_sync_ports,
        },
+       {
+               .procname       = "sync_persist_mode",
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec,
+       },
        {
                .procname       = "sync_qlen_max",
                .maxlen         = sizeof(unsigned long),
        tbl[idx++].data = &ipvs->sysctl_sync_ver;
        ipvs->sysctl_sync_ports = 1;
        tbl[idx++].data = &ipvs->sysctl_sync_ports;
+       tbl[idx++].data = &ipvs->sysctl_sync_persist_mode;
        ipvs->sysctl_sync_qlen_max = nr_free_buffer_pages() / 32;
        tbl[idx++].data = &ipvs->sysctl_sync_qlen_max;
        ipvs->sysctl_sync_sock_size = 0;
 
        return sb;
 }
 
+/* Check if connection is controlled by persistence */
+static inline bool in_persistence(struct ip_vs_conn *cp)
+{
+       for (cp = cp->control; cp; cp = cp->control) {
+               if (cp->flags & IP_VS_CONN_F_TEMPLATE)
+                       return true;
+       }
+       return false;
+}
+
 /* Check if conn should be synced.
  * pkts: conn packets, use sysctl_sync_threshold to avoid packet check
  * - (1) sync_refresh_period: reduce sync rate. Additionally, retry
        /* Check if we sync in current state */
        if (unlikely(cp->flags & IP_VS_CONN_F_TEMPLATE))
                force = 0;
+       else if (unlikely(sysctl_sync_persist_mode(ipvs) && in_persistence(cp)))
+               return 0;
        else if (likely(cp->protocol == IPPROTO_TCP)) {
                if (!((1 << cp->state) &
                      ((1 << IP_VS_TCP_S_ESTABLISHED) |