1 /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ 2 3 #include <net/sock.h> 4 #include <net/netns/generic.h> 5 #include <net/net_namespace.h> 6 #include <linux/module.h> 7 #include <linux/skbuff.h> 8 #include <linux/pid_namespace.h> 9 #include <net/udp_tunnel.h> 10 11 #include "rxe_ns.h" 12 13 /* 14 * Per network namespace data 15 */ 16 struct rxe_ns_sock { 17 struct sock __rcu *rxe_sk4; 18 struct sock __rcu *rxe_sk6; 19 }; 20 21 /* 22 * Index to store custom data for each network namespace. 23 */ 24 static unsigned int rxe_pernet_id; 25 26 /* 27 * Called for every existing and added network namespaces 28 */ 29 static int rxe_ns_init(struct net *net) 30 { 31 /* defer socket create in the namespace to the first 32 * device create. 33 */ 34 35 return 0; 36 } 37 38 static void rxe_ns_exit(struct net *net) 39 { 40 /* called when the network namespace is removed 41 */ 42 struct rxe_ns_sock *ns_sk = net_generic(net, rxe_pernet_id); 43 struct sock *sk; 44 45 rcu_read_lock(); 46 sk = rcu_dereference(ns_sk->rxe_sk4); 47 rcu_read_unlock(); 48 if (sk) { 49 rcu_assign_pointer(ns_sk->rxe_sk4, NULL); 50 udp_tunnel_sock_release(sk->sk_socket); 51 } 52 53 #if IS_ENABLED(CONFIG_IPV6) 54 rcu_read_lock(); 55 sk = rcu_dereference(ns_sk->rxe_sk6); 56 rcu_read_unlock(); 57 if (sk) { 58 rcu_assign_pointer(ns_sk->rxe_sk6, NULL); 59 udp_tunnel_sock_release(sk->sk_socket); 60 } 61 #endif 62 } 63 64 /* 65 * callback to make the module network namespace aware 66 */ 67 static struct pernet_operations rxe_net_ops = { 68 .init = rxe_ns_init, 69 .exit = rxe_ns_exit, 70 .id = &rxe_pernet_id, 71 .size = sizeof(struct rxe_ns_sock), 72 }; 73 74 struct sock *rxe_ns_pernet_sk4(struct net *net) 75 { 76 struct rxe_ns_sock *ns_sk = net_generic(net, rxe_pernet_id); 77 struct sock *sk; 78 79 rcu_read_lock(); 80 sk = rcu_dereference(ns_sk->rxe_sk4); 81 rcu_read_unlock(); 82 83 return sk; 84 } 85 86 void rxe_ns_pernet_set_sk4(struct net *net, struct sock *sk) 87 { 88 struct rxe_ns_sock *ns_sk = net_generic(net, rxe_pernet_id); 89 90 rcu_assign_pointer(ns_sk->rxe_sk4, sk); 91 synchronize_rcu(); 92 } 93 94 #if IS_ENABLED(CONFIG_IPV6) 95 struct sock *rxe_ns_pernet_sk6(struct net *net) 96 { 97 struct rxe_ns_sock *ns_sk = net_generic(net, rxe_pernet_id); 98 struct sock *sk; 99 100 rcu_read_lock(); 101 sk = rcu_dereference(ns_sk->rxe_sk6); 102 rcu_read_unlock(); 103 104 return sk; 105 } 106 107 void rxe_ns_pernet_set_sk6(struct net *net, struct sock *sk) 108 { 109 struct rxe_ns_sock *ns_sk = net_generic(net, rxe_pernet_id); 110 111 rcu_assign_pointer(ns_sk->rxe_sk6, sk); 112 synchronize_rcu(); 113 } 114 #endif /* IPV6 */ 115 116 int rxe_namespace_init(void) 117 { 118 return register_pernet_subsys(&rxe_net_ops); 119 } 120 121 void rxe_namespace_exit(void) 122 { 123 unregister_pernet_subsys(&rxe_net_ops); 124 } 125