aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-07-10 05:51:34 -0400
committerDavid S. Miller <davem@davemloft.net>2009-07-12 17:03:27 -0400
commit134e63756d5f3d0f7604dfcca847b09d1b14fd66 (patch)
treed2b5eab085d90cde0a4c0136a118800ca72b76ad /include
parent11a28d373ed2539a110d56419457e2e7db221ac7 (diff)
genetlink: make netns aware
This makes generic netlink network namespace aware. No generic netlink families except for the controller family are made namespace aware, they need to be checked one by one and then set the family->netnsok member to true. A new function genlmsg_multicast_netns() is introduced to allow sending a multicast message in a given namespace, for example when it applies to an object that lives in that namespace, a new function genlmsg_multicast_allns() to send a message to all network namespaces (for objects that do not have an associated netns). The function genlmsg_multicast() is changed to multicast the message in just init_net, which is currently correct for all generic netlink families since they only work in init_net right now. Some will later want to work in all net namespaces because they do not care about the netns at all -- those will have to be converted to use one of the new functions genlmsg_multicast_allns() or genlmsg_multicast_netns() whenever they are made netns aware in some way. After this patch families can easily decide whether or not they should be available in all net namespaces. Many genl families us it for objects not related to networking and should therefore be available in all namespaces, but that will have to be done on a per family basis. Note that this doesn't touch on the checkpoint/restart problem where network namespaces could be used, genl families and multicast groups are numbered globally and I see no easy way of changing that, especially since it must be possible to multicast to all network namespaces for those families that do not care about netns. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/net/genetlink.h66
-rw-r--r--include/net/net_namespace.h2
2 files changed, 61 insertions, 7 deletions
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 1b0e3ee4ddd8..2a1c06874c42 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -3,6 +3,7 @@
3 3
4#include <linux/genetlink.h> 4#include <linux/genetlink.h>
5#include <net/netlink.h> 5#include <net/netlink.h>
6#include <net/net_namespace.h>
6 7
7/** 8/**
8 * struct genl_multicast_group - generic netlink multicast group 9 * struct genl_multicast_group - generic netlink multicast group
@@ -27,6 +28,8 @@ struct genl_multicast_group
27 * @name: name of family 28 * @name: name of family
28 * @version: protocol version 29 * @version: protocol version
29 * @maxattr: maximum number of attributes supported 30 * @maxattr: maximum number of attributes supported
31 * @netnsok: set to true if the family can handle network
32 * namespaces and should be presented in all of them
30 * @attrbuf: buffer to store parsed attributes 33 * @attrbuf: buffer to store parsed attributes
31 * @ops_list: list of all assigned operations 34 * @ops_list: list of all assigned operations
32 * @family_list: family list 35 * @family_list: family list
@@ -39,6 +42,7 @@ struct genl_family
39 char name[GENL_NAMSIZ]; 42 char name[GENL_NAMSIZ];
40 unsigned int version; 43 unsigned int version;
41 unsigned int maxattr; 44 unsigned int maxattr;
45 bool netnsok;
42 struct nlattr ** attrbuf; /* private */ 46 struct nlattr ** attrbuf; /* private */
43 struct list_head ops_list; /* private */ 47 struct list_head ops_list; /* private */
44 struct list_head family_list; /* private */ 48 struct list_head family_list; /* private */
@@ -62,8 +66,32 @@ struct genl_info
62 struct genlmsghdr * genlhdr; 66 struct genlmsghdr * genlhdr;
63 void * userhdr; 67 void * userhdr;
64 struct nlattr ** attrs; 68 struct nlattr ** attrs;
69#ifdef CONFIG_NET_NS
70 struct net * _net;
71#endif
65}; 72};
66 73
74#ifdef CONFIG_NET_NS
75static inline struct net *genl_info_net(struct genl_info *info)
76{
77 return info->_net;
78}
79
80static inline void genl_info_net_set(struct genl_info *info, struct net *net)
81{
82 info->_net = net;
83}
84#else
85static inline struct net *genl_info_net(struct genl_info *info)
86{
87 return &init_net;
88}
89
90static inline void genl_info_net_set(struct genl_info *info, struct net *net)
91{
92}
93#endif
94
67/** 95/**
68 * struct genl_ops - generic netlink operations 96 * struct genl_ops - generic netlink operations
69 * @cmd: command identifier 97 * @cmd: command identifier
@@ -98,8 +126,6 @@ extern int genl_register_mc_group(struct genl_family *family,
98extern void genl_unregister_mc_group(struct genl_family *family, 126extern void genl_unregister_mc_group(struct genl_family *family,
99 struct genl_multicast_group *grp); 127 struct genl_multicast_group *grp);
100 128
101extern struct sock *genl_sock;
102
103/** 129/**
104 * genlmsg_put - Add generic netlink header to netlink message 130 * genlmsg_put - Add generic netlink header to netlink message
105 * @skb: socket buffer holding the message 131 * @skb: socket buffer holding the message
@@ -170,7 +196,21 @@ static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
170} 196}
171 197
172/** 198/**
173 * genlmsg_multicast - multicast a netlink message 199 * genlmsg_multicast_netns - multicast a netlink message to a specific netns
200 * @net: the net namespace
201 * @skb: netlink message as socket buffer
202 * @pid: own netlink pid to avoid sending to yourself
203 * @group: multicast group id
204 * @flags: allocation flags
205 */
206static inline int genlmsg_multicast_netns(struct net *net, struct sk_buff *skb,
207 u32 pid, unsigned int group, gfp_t flags)
208{
209 return nlmsg_multicast(net->genl_sock, skb, pid, group, flags);
210}
211
212/**
213 * genlmsg_multicast - multicast a netlink message to the default netns
174 * @skb: netlink message as socket buffer 214 * @skb: netlink message as socket buffer
175 * @pid: own netlink pid to avoid sending to yourself 215 * @pid: own netlink pid to avoid sending to yourself
176 * @group: multicast group id 216 * @group: multicast group id
@@ -179,17 +219,29 @@ static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
179static inline int genlmsg_multicast(struct sk_buff *skb, u32 pid, 219static inline int genlmsg_multicast(struct sk_buff *skb, u32 pid,
180 unsigned int group, gfp_t flags) 220 unsigned int group, gfp_t flags)
181{ 221{
182 return nlmsg_multicast(genl_sock, skb, pid, group, flags); 222 return genlmsg_multicast_netns(&init_net, skb, pid, group, flags);
183} 223}
184 224
185/** 225/**
226 * genlmsg_multicast_allns - multicast a netlink message to all net namespaces
227 * @skb: netlink message as socket buffer
228 * @pid: own netlink pid to avoid sending to yourself
229 * @group: multicast group id
230 * @flags: allocation flags
231 *
232 * This function must hold the RTNL or rcu_read_lock().
233 */
234int genlmsg_multicast_allns(struct sk_buff *skb, u32 pid,
235 unsigned int group, gfp_t flags);
236
237/**
186 * genlmsg_unicast - unicast a netlink message 238 * genlmsg_unicast - unicast a netlink message
187 * @skb: netlink message as socket buffer 239 * @skb: netlink message as socket buffer
188 * @pid: netlink pid of the destination socket 240 * @pid: netlink pid of the destination socket
189 */ 241 */
190static inline int genlmsg_unicast(struct sk_buff *skb, u32 pid) 242static inline int genlmsg_unicast(struct net *net, struct sk_buff *skb, u32 pid)
191{ 243{
192 return nlmsg_unicast(genl_sock, skb, pid); 244 return nlmsg_unicast(net->genl_sock, skb, pid);
193} 245}
194 246
195/** 247/**
@@ -199,7 +251,7 @@ static inline int genlmsg_unicast(struct sk_buff *skb, u32 pid)
199 */ 251 */
200static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info) 252static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info)
201{ 253{
202 return genlmsg_unicast(skb, info->snd_pid); 254 return genlmsg_unicast(genl_info_net(info), skb, info->snd_pid);
203} 255}
204 256
205/** 257/**
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index b34a6ee73754..3173d12d946b 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -26,6 +26,7 @@ struct net_device;
26struct sock; 26struct sock;
27struct ctl_table_header; 27struct ctl_table_header;
28struct net_generic; 28struct net_generic;
29struct sock;
29 30
30struct net { 31struct net {
31 atomic_t count; /* To decided when the network 32 atomic_t count; /* To decided when the network
@@ -57,6 +58,7 @@ struct net {
57 spinlock_t rules_mod_lock; 58 spinlock_t rules_mod_lock;
58 59
59 struct sock *rtnl; /* rtnetlink socket */ 60 struct sock *rtnl; /* rtnetlink socket */
61 struct sock *genl_sock;
60 62
61 struct netns_core core; 63 struct netns_core core;
62 struct netns_mib mib; 64 struct netns_mib mib;