ipv4, ipv6: kill ip_mc_{join, leave}_group and ipv6_sock_mc_{join, drop}
[cascardo/linux.git] / net / netfilter / ipvs / ip_vs_sync.c
index c47ffd7..19b9cce 100644 (file)
@@ -845,10 +845,27 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
        struct ip_vs_conn *cp;
        struct netns_ipvs *ipvs = net_ipvs(net);
 
-       if (!(flags & IP_VS_CONN_F_TEMPLATE))
+       if (!(flags & IP_VS_CONN_F_TEMPLATE)) {
                cp = ip_vs_conn_in_get(param);
-       else
+               if (cp && ((cp->dport != dport) ||
+                          !ip_vs_addr_equal(cp->daf, &cp->daddr, daddr))) {
+                       if (!(flags & IP_VS_CONN_F_INACTIVE)) {
+                               ip_vs_conn_expire_now(cp);
+                               __ip_vs_conn_put(cp);
+                               cp = NULL;
+                       } else {
+                               /* This is the expiration message for the
+                                * connection that was already replaced, so we
+                                * just ignore it.
+                                */
+                               __ip_vs_conn_put(cp);
+                               kfree(param->pe_data);
+                               return;
+                       }
+               }
+       } else {
                cp = ip_vs_ct_in_get(param);
+       }
 
        if (cp) {
                /* Free pe_data */
@@ -896,6 +913,8 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
                        IP_VS_DBG(2, "BACKUP, add new conn. failed\n");
                        return;
                }
+               if (!(flags & IP_VS_CONN_F_TEMPLATE))
+                       kfree(param->pe_data);
        }
 
        if (opt)
@@ -1169,6 +1188,7 @@ static inline int ip_vs_proc_sync_conn(struct net *net, __u8 *p, __u8 *msg_end)
                                (opt_flags & IPVS_OPT_F_SEQ_DATA ? &opt : NULL)
                                );
 #endif
+       ip_vs_pe_put(param.pe);
        return 0;
        /* Error exit */
 out:
@@ -1385,9 +1405,11 @@ join_mcast_group(struct sock *sk, struct in_addr *addr, char *ifname)
 
        mreq.imr_ifindex = dev->ifindex;
 
+       rtnl_lock();
        lock_sock(sk);
        ret = ip_mc_join_group(sk, &mreq);
        release_sock(sk);
+       rtnl_unlock();
 
        return ret;
 }