/*
  *      IPVS Connection Flags
+ *      Only flags 0..15 are sent to backup server
  */
 #define IP_VS_CONN_F_FWD_MASK  0x0007          /* mask for the fwd methods */
 #define IP_VS_CONN_F_MASQ      0x0000          /* masquerading/NAT */
 #define IP_VS_CONN_F_TEMPLATE  0x1000          /* template, not connection */
 #define IP_VS_CONN_F_ONE_PACKET        0x2000          /* forward only one packet */
 
+/* Flags that are not sent to backup server start from bit 16 */
+
+/* Connection flags from destination that can be changed by user space */
+#define IP_VS_CONN_F_DEST_MASK (IP_VS_CONN_F_FWD_MASK | \
+                               IP_VS_CONN_F_ONE_PACKET | \
+                               0)
+
 #define IP_VS_SCHEDNAME_MAXLEN 16
 #define IP_VS_IFNAME_MAXLEN    16
 
 
        union nf_inet_addr       caddr;          /* client address */
        union nf_inet_addr       vaddr;          /* virtual address */
        union nf_inet_addr       daddr;          /* destination address */
+       volatile __u32           flags;          /* status flags */
        __be16                   cport;
        __be16                   vport;
        __be16                   dport;
 
        /* Flags and state transition */
        spinlock_t              lock;           /* lock for state transition */
-       volatile __u16          flags;          /* status flags */
        volatile __u16          state;          /* state info */
        volatile __u16          old_state;      /* old state, to be used for
                                                 * state transition triggerd
 
 static inline void
 ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
 {
+       unsigned int conn_flags;
+
        /* if dest is NULL, then return directly */
        if (!dest)
                return;
        /* Increase the refcnt counter of the dest */
        atomic_inc(&dest->refcnt);
 
+       conn_flags = atomic_read(&dest->conn_flags);
+       if (cp->protocol != IPPROTO_UDP)
+               conn_flags &= ~IP_VS_CONN_F_ONE_PACKET;
        /* Bind with the destination and its corresponding transmitter */
-       if ((cp->flags & IP_VS_CONN_F_SYNC) &&
-           (!(cp->flags & IP_VS_CONN_F_TEMPLATE)))
+       if (cp->flags & IP_VS_CONN_F_SYNC) {
                /* if the connection is not template and is created
                 * by sync, preserve the activity flag.
                 */
-               cp->flags |= atomic_read(&dest->conn_flags) &
-                            (~IP_VS_CONN_F_INACTIVE);
-       else
-               cp->flags |= atomic_read(&dest->conn_flags);
+               if (!(cp->flags & IP_VS_CONN_F_TEMPLATE))
+                       conn_flags &= ~IP_VS_CONN_F_INACTIVE;
+       }
+       cp->flags |= conn_flags;
        cp->dest = dest;
 
        IP_VS_DBG_BUF(7, "Bind-dest %s c:%s:%d v:%s:%d "
 
        struct ip_vs_dest *dest;
        struct ip_vs_conn *ct;
        __be16  dport;                  /* destination port to forward */
-       __be16  flags;
+       unsigned int flags;
        union nf_inet_addr snet;        /* source network of the client,
                                           after masking */
 
        struct ip_vs_conn *cp = NULL;
        struct ip_vs_iphdr iph;
        struct ip_vs_dest *dest;
-       __be16 _ports[2], *pptr, flags;
+       __be16 _ports[2], *pptr;
+       unsigned int flags;
 
        ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
        pptr = skb_header_pointer(skb, iph.len, sizeof(_ports), _ports);
        if (sysctl_ip_vs_cache_bypass && svc->fwmark && unicast) {
                int ret, cs;
                struct ip_vs_conn *cp;
-               __u16 flags = (svc->flags & IP_VS_SVC_F_ONEPACKET &&
-                               iph.protocol == IPPROTO_UDP)?
-                               IP_VS_CONN_F_ONE_PACKET : 0;
+               unsigned int flags = (svc->flags & IP_VS_SVC_F_ONEPACKET &&
+                                     iph.protocol == IPPROTO_UDP)?
+                                     IP_VS_CONN_F_ONE_PACKET : 0;
                union nf_inet_addr daddr =  { .all = { 0, 0, 0, 0 } };
 
                ip_vs_service_put(svc);
 
 
        /* set the weight and the flags */
        atomic_set(&dest->weight, udest->weight);
-       conn_flags = udest->conn_flags | IP_VS_CONN_F_INACTIVE;
+       conn_flags = udest->conn_flags & IP_VS_CONN_F_DEST_MASK;
+       conn_flags |= IP_VS_CONN_F_INACTIVE;
 
        /* check if local node and update the flags */
 #ifdef CONFIG_IP_VS_IPV6
                }
 
        /* set the IP_VS_CONN_F_NOOUTPUT flag if not masquerading/NAT */
-       if ((conn_flags & IP_VS_CONN_F_FWD_MASK) != 0) {
+       if ((conn_flags & IP_VS_CONN_F_FWD_MASK) != IP_VS_CONN_F_MASQ) {
                conn_flags |= IP_VS_CONN_F_NOOUTPUT;
        } else {
                /*