Commit 95ab09917a8187a02b518e22587c7f035edc7465
Committed by
David S. Miller
1 parent
79d4a94fab
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
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
drivers/net/vxlan.c
... | ... | @@ -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); |