@@ -76,9 +76,9 @@ struct geneve_dev {
7676 struct hlist_node hlist ; /* vni hash table */
7777 struct net * net ; /* netns for packet i/o */
7878 struct net_device * dev ; /* netdev for geneve tunnel */
79- struct geneve_sock * sock4 ; /* IPv4 socket used for geneve tunnel */
79+ struct geneve_sock __rcu * sock4 ; /* IPv4 socket used for geneve tunnel */
8080#if IS_ENABLED (CONFIG_IPV6 )
81- struct geneve_sock * sock6 ; /* IPv6 socket used for geneve tunnel */
81+ struct geneve_sock __rcu * sock6 ; /* IPv6 socket used for geneve tunnel */
8282#endif
8383 u8 vni [3 ]; /* virtual network ID for tunnel */
8484 u8 ttl ; /* TTL override */
@@ -629,9 +629,19 @@ static void __geneve_sock_release(struct geneve_sock *gs)
629629
630630static void geneve_sock_release (struct geneve_dev * geneve )
631631{
632- __geneve_sock_release (geneve -> sock4 );
632+ struct geneve_sock * gs4 = rtnl_dereference (geneve -> sock4 );
633633#if IS_ENABLED (CONFIG_IPV6 )
634- __geneve_sock_release (geneve -> sock6 );
634+ struct geneve_sock * gs6 = rtnl_dereference (geneve -> sock6 );
635+
636+ rcu_assign_pointer (geneve -> sock6 , NULL );
637+ #endif
638+
639+ rcu_assign_pointer (geneve -> sock4 , NULL );
640+ synchronize_net ();
641+
642+ __geneve_sock_release (gs4 );
643+ #if IS_ENABLED (CONFIG_IPV6 )
644+ __geneve_sock_release (gs6 );
635645#endif
636646}
637647
@@ -672,10 +682,10 @@ static int geneve_sock_add(struct geneve_dev *geneve, bool ipv6)
672682 gs -> flags = geneve -> flags ;
673683#if IS_ENABLED (CONFIG_IPV6 )
674684 if (ipv6 )
675- geneve -> sock6 = gs ;
685+ rcu_assign_pointer ( geneve -> sock6 , gs ) ;
676686 else
677687#endif
678- geneve -> sock4 = gs ;
688+ rcu_assign_pointer ( geneve -> sock4 , gs ) ;
679689
680690 hash = geneve_net_vni_hash (geneve -> vni );
681691 hlist_add_head_rcu (& geneve -> hlist , & gs -> vni_list [hash ]);
@@ -689,9 +699,7 @@ static int geneve_open(struct net_device *dev)
689699 bool metadata = geneve -> collect_md ;
690700 int ret = 0 ;
691701
692- geneve -> sock4 = NULL ;
693702#if IS_ENABLED (CONFIG_IPV6 )
694- geneve -> sock6 = NULL ;
695703 if (ipv6 || metadata )
696704 ret = geneve_sock_add (geneve , true);
697705#endif
@@ -807,6 +815,9 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
807815 struct rtable * rt = NULL ;
808816 __u8 tos ;
809817
818+ if (!rcu_dereference (geneve -> sock4 ))
819+ return ERR_PTR (- EIO );
820+
810821 memset (fl4 , 0 , sizeof (* fl4 ));
811822 fl4 -> flowi4_mark = skb -> mark ;
812823 fl4 -> flowi4_proto = IPPROTO_UDP ;
@@ -859,11 +870,15 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
859870{
860871 bool use_cache = ip_tunnel_dst_cache_usable (skb , info );
861872 struct geneve_dev * geneve = netdev_priv (dev );
862- struct geneve_sock * gs6 = geneve -> sock6 ;
863873 struct dst_entry * dst = NULL ;
864874 struct dst_cache * dst_cache ;
875+ struct geneve_sock * gs6 ;
865876 __u8 prio ;
866877
878+ gs6 = rcu_dereference (geneve -> sock6 );
879+ if (!gs6 )
880+ return ERR_PTR (- EIO );
881+
867882 memset (fl6 , 0 , sizeof (* fl6 ));
868883 fl6 -> flowi6_mark = skb -> mark ;
869884 fl6 -> flowi6_proto = IPPROTO_UDP ;
@@ -937,7 +952,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
937952 struct ip_tunnel_info * info )
938953{
939954 struct geneve_dev * geneve = netdev_priv (dev );
940- struct geneve_sock * gs4 = geneve -> sock4 ;
955+ struct geneve_sock * gs4 ;
941956 struct rtable * rt = NULL ;
942957 const struct iphdr * iip ; /* interior IP header */
943958 int err = - EINVAL ;
@@ -948,6 +963,10 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
948963 bool xnet = !net_eq (geneve -> net , dev_net (geneve -> dev ));
949964 u32 flags = geneve -> flags ;
950965
966+ gs4 = rcu_dereference (geneve -> sock4 );
967+ if (!gs4 )
968+ goto tx_error ;
969+
951970 if (geneve -> collect_md ) {
952971 if (unlikely (!info || !(info -> mode & IP_TUNNEL_INFO_TX ))) {
953972 netdev_dbg (dev , "no tunnel metadata\n" );
@@ -1027,9 +1046,9 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
10271046 struct ip_tunnel_info * info )
10281047{
10291048 struct geneve_dev * geneve = netdev_priv (dev );
1030- struct geneve_sock * gs6 = geneve -> sock6 ;
10311049 struct dst_entry * dst = NULL ;
10321050 const struct iphdr * iip ; /* interior IP header */
1051+ struct geneve_sock * gs6 ;
10331052 int err = - EINVAL ;
10341053 struct flowi6 fl6 ;
10351054 __u8 prio , ttl ;
@@ -1038,6 +1057,10 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
10381057 bool xnet = !net_eq (geneve -> net , dev_net (geneve -> dev ));
10391058 u32 flags = geneve -> flags ;
10401059
1060+ gs6 = rcu_dereference (geneve -> sock6 );
1061+ if (!gs6 )
1062+ goto tx_error ;
1063+
10411064 if (geneve -> collect_md ) {
10421065 if (unlikely (!info || !(info -> mode & IP_TUNNEL_INFO_TX ))) {
10431066 netdev_dbg (dev , "no tunnel metadata\n" );
0 commit comments