Commit 95ab09917a8187a02b518e22587c7f035edc7465

Authored by Gao feng
Committed by David S. Miller
1 parent 79d4a94fab

vxlan: leave multicast group when vxlan device down

vxlan_group_used only allows device to leave multicast group
when the remote_ip of this vxlan device is difference from
other vxlan devices' remote_ip. this will cause device not
leave multicast group untile the vn_sock of this vxlan deivce
being released.

The check in vxlan_group_used is not quite precise. since even
the remote_ip is same, but these vxlan devices may use different
lower devices, and they may use different vn_socks.

Only when some vxlan devices use the same vn_sock,same lower
device and same remote_ip, the mc_list of the vn_sock should
not be changed.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 21 additions and 6 deletions Side-by-side Diff

... ... @@ -916,17 +916,32 @@
916 916 }
917 917  
918 918 /* See if multicast group is already in use by other ID */
919   -static bool vxlan_group_used(struct vxlan_net *vn, union vxlan_addr *remote_ip)
  919 +static bool vxlan_group_used(struct vxlan_net *vn, struct vxlan_dev *dev)
920 920 {
921 921 struct vxlan_dev *vxlan;
922 922  
  923 + /* The vxlan_sock is only used by dev, leaving group has
  924 + * no effect on other vxlan devices.
  925 + */
  926 + if (atomic_read(&dev->vn_sock->refcnt) == 1)
  927 + return false;
  928 +
923 929 list_for_each_entry(vxlan, &vn->vxlan_list, next) {
924   - if (!netif_running(vxlan->dev))
  930 + if (!netif_running(vxlan->dev) || vxlan == dev)
925 931 continue;
926 932  
927   - if (vxlan_addr_equal(&vxlan->default_dst.remote_ip,
928   - remote_ip))
929   - return true;
  933 + if (vxlan->vn_sock != dev->vn_sock)
  934 + continue;
  935 +
  936 + if (!vxlan_addr_equal(&vxlan->default_dst.remote_ip,
  937 + &dev->default_dst.remote_ip))
  938 + continue;
  939 +
  940 + if (vxlan->default_dst.remote_ifindex !=
  941 + dev->default_dst.remote_ifindex)
  942 + continue;
  943 +
  944 + return true;
930 945 }
931 946  
932 947 return false;
... ... @@ -1981,7 +1996,7 @@
1981 1996 struct vxlan_sock *vs = vxlan->vn_sock;
1982 1997  
1983 1998 if (vs && vxlan_addr_multicast(&vxlan->default_dst.remote_ip) &&
1984   - ! vxlan_group_used(vn, &vxlan->default_dst.remote_ip)) {
  1999 + !vxlan_group_used(vn, vxlan)) {
1985 2000 vxlan_sock_hold(vs);
1986 2001 dev_hold(dev);
1987 2002 queue_work(vxlan_wq, &vxlan->igmp_leave);