@@ -943,28 +943,33 @@ static bool vxlan_snoop(struct net_device *dev,
943
943
static bool vxlan_group_used (struct vxlan_net * vn , struct vxlan_dev * dev )
944
944
{
945
945
struct vxlan_dev * vxlan ;
946
+ struct vxlan_sock * sock4 ;
947
+ struct vxlan_sock * sock6 = NULL ;
946
948
unsigned short family = dev -> default_dst .remote_ip .sa .sa_family ;
947
949
950
+ sock4 = rtnl_dereference (dev -> vn4_sock );
951
+
948
952
/* The vxlan_sock is only used by dev, leaving group has
949
953
* no effect on other vxlan devices.
950
954
*/
951
- if (family == AF_INET && dev -> vn4_sock &&
952
- atomic_read (& dev -> vn4_sock -> refcnt ) == 1 )
955
+ if (family == AF_INET && sock4 && atomic_read (& sock4 -> refcnt ) == 1 )
953
956
return false;
954
957
#if IS_ENABLED (CONFIG_IPV6 )
955
- if ( family == AF_INET6 && dev -> vn6_sock &&
956
- atomic_read (& dev -> vn6_sock -> refcnt ) == 1 )
958
+ sock6 = rtnl_dereference ( dev -> vn6_sock );
959
+ if ( family == AF_INET6 && sock6 && atomic_read (& sock6 -> refcnt ) == 1 )
957
960
return false;
958
961
#endif
959
962
960
963
list_for_each_entry (vxlan , & vn -> vxlan_list , next ) {
961
964
if (!netif_running (vxlan -> dev ) || vxlan == dev )
962
965
continue ;
963
966
964
- if (family == AF_INET && vxlan -> vn4_sock != dev -> vn4_sock )
967
+ if (family == AF_INET &&
968
+ rtnl_dereference (vxlan -> vn4_sock ) != sock4 )
965
969
continue ;
966
970
#if IS_ENABLED (CONFIG_IPV6 )
967
- if (family == AF_INET6 && vxlan -> vn6_sock != dev -> vn6_sock )
971
+ if (family == AF_INET6 &&
972
+ rtnl_dereference (vxlan -> vn6_sock ) != sock6 )
968
973
continue ;
969
974
#endif
970
975
@@ -1005,22 +1010,25 @@ static bool __vxlan_sock_release_prep(struct vxlan_sock *vs)
1005
1010
1006
1011
static void vxlan_sock_release (struct vxlan_dev * vxlan )
1007
1012
{
1008
- bool ipv4 = __vxlan_sock_release_prep (vxlan -> vn4_sock );
1013
+ struct vxlan_sock * sock4 = rtnl_dereference (vxlan -> vn4_sock );
1009
1014
#if IS_ENABLED (CONFIG_IPV6 )
1010
- bool ipv6 = __vxlan_sock_release_prep (vxlan -> vn6_sock );
1015
+ struct vxlan_sock * sock6 = rtnl_dereference (vxlan -> vn6_sock );
1016
+
1017
+ rcu_assign_pointer (vxlan -> vn6_sock , NULL );
1011
1018
#endif
1012
1019
1020
+ rcu_assign_pointer (vxlan -> vn4_sock , NULL );
1013
1021
synchronize_net ();
1014
1022
1015
- if (ipv4 ) {
1016
- udp_tunnel_sock_release (vxlan -> vn4_sock -> sock );
1017
- kfree (vxlan -> vn4_sock );
1023
+ if (__vxlan_sock_release_prep ( sock4 ) ) {
1024
+ udp_tunnel_sock_release (sock4 -> sock );
1025
+ kfree (sock4 );
1018
1026
}
1019
1027
1020
1028
#if IS_ENABLED (CONFIG_IPV6 )
1021
- if (ipv6 ) {
1022
- udp_tunnel_sock_release (vxlan -> vn6_sock -> sock );
1023
- kfree (vxlan -> vn6_sock );
1029
+ if (__vxlan_sock_release_prep ( sock6 ) ) {
1030
+ udp_tunnel_sock_release (sock6 -> sock );
1031
+ kfree (sock6 );
1024
1032
}
1025
1033
#endif
1026
1034
}
@@ -1036,18 +1044,21 @@ static int vxlan_igmp_join(struct vxlan_dev *vxlan)
1036
1044
int ret = - EINVAL ;
1037
1045
1038
1046
if (ip -> sa .sa_family == AF_INET ) {
1047
+ struct vxlan_sock * sock4 = rtnl_dereference (vxlan -> vn4_sock );
1039
1048
struct ip_mreqn mreq = {
1040
1049
.imr_multiaddr .s_addr = ip -> sin .sin_addr .s_addr ,
1041
1050
.imr_ifindex = ifindex ,
1042
1051
};
1043
1052
1044
- sk = vxlan -> vn4_sock -> sock -> sk ;
1053
+ sk = sock4 -> sock -> sk ;
1045
1054
lock_sock (sk );
1046
1055
ret = ip_mc_join_group (sk , & mreq );
1047
1056
release_sock (sk );
1048
1057
#if IS_ENABLED (CONFIG_IPV6 )
1049
1058
} else {
1050
- sk = vxlan -> vn6_sock -> sock -> sk ;
1059
+ struct vxlan_sock * sock6 = rtnl_dereference (vxlan -> vn6_sock );
1060
+
1061
+ sk = sock6 -> sock -> sk ;
1051
1062
lock_sock (sk );
1052
1063
ret = ipv6_stub -> ipv6_sock_mc_join (sk , ifindex ,
1053
1064
& ip -> sin6 .sin6_addr );
@@ -1067,18 +1078,21 @@ static int vxlan_igmp_leave(struct vxlan_dev *vxlan)
1067
1078
int ret = - EINVAL ;
1068
1079
1069
1080
if (ip -> sa .sa_family == AF_INET ) {
1081
+ struct vxlan_sock * sock4 = rtnl_dereference (vxlan -> vn4_sock );
1070
1082
struct ip_mreqn mreq = {
1071
1083
.imr_multiaddr .s_addr = ip -> sin .sin_addr .s_addr ,
1072
1084
.imr_ifindex = ifindex ,
1073
1085
};
1074
1086
1075
- sk = vxlan -> vn4_sock -> sock -> sk ;
1087
+ sk = sock4 -> sock -> sk ;
1076
1088
lock_sock (sk );
1077
1089
ret = ip_mc_leave_group (sk , & mreq );
1078
1090
release_sock (sk );
1079
1091
#if IS_ENABLED (CONFIG_IPV6 )
1080
1092
} else {
1081
- sk = vxlan -> vn6_sock -> sock -> sk ;
1093
+ struct vxlan_sock * sock6 = rtnl_dereference (vxlan -> vn6_sock );
1094
+
1095
+ sk = sock6 -> sock -> sk ;
1082
1096
lock_sock (sk );
1083
1097
ret = ipv6_stub -> ipv6_sock_mc_drop (sk , ifindex ,
1084
1098
& ip -> sin6 .sin6_addr );
@@ -1828,11 +1842,15 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
1828
1842
struct dst_cache * dst_cache ,
1829
1843
const struct ip_tunnel_info * info )
1830
1844
{
1845
+ struct vxlan_sock * sock6 = rcu_dereference (vxlan -> vn6_sock );
1831
1846
bool use_cache = ip_tunnel_dst_cache_usable (skb , info );
1832
1847
struct dst_entry * ndst ;
1833
1848
struct flowi6 fl6 ;
1834
1849
int err ;
1835
1850
1851
+ if (!sock6 )
1852
+ return ERR_PTR (- EIO );
1853
+
1836
1854
if (tos && !info )
1837
1855
use_cache = false;
1838
1856
if (use_cache ) {
@@ -1850,7 +1868,7 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
1850
1868
fl6 .flowi6_proto = IPPROTO_UDP ;
1851
1869
1852
1870
err = ipv6_stub -> ipv6_dst_lookup (vxlan -> net ,
1853
- vxlan -> vn6_sock -> sock -> sk ,
1871
+ sock6 -> sock -> sk ,
1854
1872
& ndst , & fl6 );
1855
1873
if (err < 0 )
1856
1874
return ERR_PTR (err );
@@ -1995,9 +2013,11 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
1995
2013
}
1996
2014
1997
2015
if (dst -> sa .sa_family == AF_INET ) {
1998
- if (!vxlan -> vn4_sock )
2016
+ struct vxlan_sock * sock4 = rcu_dereference (vxlan -> vn4_sock );
2017
+
2018
+ if (!sock4 )
1999
2019
goto drop ;
2000
- sk = vxlan -> vn4_sock -> sock -> sk ;
2020
+ sk = sock4 -> sock -> sk ;
2001
2021
2002
2022
rt = vxlan_get_route (vxlan , skb ,
2003
2023
rdst ? rdst -> remote_ifindex : 0 , tos ,
@@ -2050,12 +2070,13 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
2050
2070
src_port , dst_port , xnet , !udp_sum );
2051
2071
#if IS_ENABLED (CONFIG_IPV6 )
2052
2072
} else {
2073
+ struct vxlan_sock * sock6 = rcu_dereference (vxlan -> vn6_sock );
2053
2074
struct dst_entry * ndst ;
2054
2075
u32 rt6i_flags ;
2055
2076
2056
- if (!vxlan -> vn6_sock )
2077
+ if (!sock6 )
2057
2078
goto drop ;
2058
- sk = vxlan -> vn6_sock -> sock -> sk ;
2079
+ sk = sock6 -> sock -> sk ;
2059
2080
2060
2081
ndst = vxlan6_get_route (vxlan , skb ,
2061
2082
rdst ? rdst -> remote_ifindex : 0 , tos ,
@@ -2415,9 +2436,10 @@ static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
2415
2436
dport = info -> key .tp_dst ? : vxlan -> cfg .dst_port ;
2416
2437
2417
2438
if (ip_tunnel_info_af (info ) == AF_INET ) {
2439
+ struct vxlan_sock * sock4 = rcu_dereference (vxlan -> vn4_sock );
2418
2440
struct rtable * rt ;
2419
2441
2420
- if (!vxlan -> vn4_sock )
2442
+ if (!sock4 )
2421
2443
return - EINVAL ;
2422
2444
rt = vxlan_get_route (vxlan , skb , 0 , info -> key .tos ,
2423
2445
info -> key .u .ipv4 .dst ,
@@ -2429,8 +2451,6 @@ static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
2429
2451
#if IS_ENABLED (CONFIG_IPV6 )
2430
2452
struct dst_entry * ndst ;
2431
2453
2432
- if (!vxlan -> vn6_sock )
2433
- return - EINVAL ;
2434
2454
ndst = vxlan6_get_route (vxlan , skb , 0 , info -> key .tos ,
2435
2455
info -> key .label , & info -> key .u .ipv6 .dst ,
2436
2456
& info -> key .u .ipv6 .src , NULL , info );
@@ -2740,10 +2760,10 @@ static int __vxlan_sock_add(struct vxlan_dev *vxlan, bool ipv6)
2740
2760
return PTR_ERR (vs );
2741
2761
#if IS_ENABLED (CONFIG_IPV6 )
2742
2762
if (ipv6 )
2743
- vxlan -> vn6_sock = vs ;
2763
+ rcu_assign_pointer ( vxlan -> vn6_sock , vs ) ;
2744
2764
else
2745
2765
#endif
2746
- vxlan -> vn4_sock = vs ;
2766
+ rcu_assign_pointer ( vxlan -> vn4_sock , vs ) ;
2747
2767
vxlan_vs_add_dev (vs , vxlan );
2748
2768
return 0 ;
2749
2769
}
@@ -2754,9 +2774,9 @@ static int vxlan_sock_add(struct vxlan_dev *vxlan)
2754
2774
bool metadata = vxlan -> flags & VXLAN_F_COLLECT_METADATA ;
2755
2775
int ret = 0 ;
2756
2776
2757
- vxlan -> vn4_sock = NULL ;
2777
+ RCU_INIT_POINTER ( vxlan -> vn4_sock , NULL ) ;
2758
2778
#if IS_ENABLED (CONFIG_IPV6 )
2759
- vxlan -> vn6_sock = NULL ;
2779
+ RCU_INIT_POINTER ( vxlan -> vn6_sock , NULL ) ;
2760
2780
if (ipv6 || metadata )
2761
2781
ret = __vxlan_sock_add (vxlan , true);
2762
2782
#endif
0 commit comments