Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

RDMA/rxe: Add net namespace support for IPv4/IPv6 sockets

Add a net namespace implementation file to rxe to manage the
lifecycle of IPv4 and IPv6 sockets per network namespace.

This implementation handles the creation and destruction of the
sockets both for init_net and for dynamically created network
namespaces. The sockets are initialized when a namespace becomes
active and are properly released when the namespace is removed.

This change provides the infrastructure needed for rxe to operate
correctly in environments using multiple network namespaces.

Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: Zhu Yanjun <yanjun.zhu@linux.dev>
Link: https://patch.msgid.link/20260313023058.13020-3-yanjun.zhu@linux.dev
Signed-off-by: Leon Romanovsky <leon@kernel.org>

authored by

Zhu Yanjun and committed by
Leon Romanovsky
13f2a53c a60e3f3d

+152 -1
+2 -1
drivers/infiniband/sw/rxe/Makefile
··· 22 22 rxe_mcast.o \ 23 23 rxe_task.o \ 24 24 rxe_net.o \ 25 - rxe_hw_counters.o 25 + rxe_hw_counters.o \ 26 + rxe_ns.o 26 27 27 28 rdma_rxe-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += rxe_odp.o
+124
drivers/infiniband/sw/rxe/rxe_ns.c
··· 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 + }
+26
drivers/infiniband/sw/rxe/rxe_ns.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ 2 + 3 + #ifndef RXE_NS_H 4 + #define RXE_NS_H 5 + 6 + struct sock *rxe_ns_pernet_sk4(struct net *net); 7 + void rxe_ns_pernet_set_sk4(struct net *net, struct sock *sk); 8 + 9 + #if IS_ENABLED(CONFIG_IPV6) 10 + void rxe_ns_pernet_set_sk6(struct net *net, struct sock *sk); 11 + struct sock *rxe_ns_pernet_sk6(struct net *net); 12 + #else /* IPv6 */ 13 + static inline struct sock *rxe_ns_pernet_sk6(struct net *net) 14 + { 15 + return NULL; 16 + } 17 + 18 + static inline void rxe_ns_pernet_set_sk6(struct net *net, struct sock *sk) 19 + { 20 + } 21 + #endif /* IPv6 */ 22 + 23 + int rxe_namespace_init(void); 24 + void rxe_namespace_exit(void); 25 + 26 + #endif /* RXE_NS_H */