rtnetlink.c (c002c27874faaa170b535d03d7efee89ecdd9be4) | rtnetlink.c (377cb248840907adc407324b4d23f97b3ee70c98) |
---|---|
1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * Routing netlink socket interface: protocol independent part. 7 * 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> --- 48 unchanged lines hidden (view full) --- 57#include <net/pkt_sched.h> 58#include <net/fib_rules.h> 59#include <net/rtnetlink.h> 60#include <net/net_namespace.h> 61 62struct rtnl_link { 63 rtnl_doit_func doit; 64 rtnl_dumpit_func dumpit; | 1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * Routing netlink socket interface: protocol independent part. 7 * 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> --- 48 unchanged lines hidden (view full) --- 57#include <net/pkt_sched.h> 58#include <net/fib_rules.h> 59#include <net/rtnetlink.h> 60#include <net/net_namespace.h> 61 62struct rtnl_link { 63 rtnl_doit_func doit; 64 rtnl_dumpit_func dumpit; |
65 rtnl_calcit_func calcit; | 65 unsigned int flags; |
66}; 67 68static DEFINE_MUTEX(rtnl_mutex); 69 70void rtnl_lock(void) 71{ 72 mutex_lock(&rtnl_mutex); 73} --- 48 unchanged lines hidden (view full) --- 122#ifdef CONFIG_PROVE_LOCKING 123bool lockdep_rtnl_is_held(void) 124{ 125 return lockdep_is_held(&rtnl_mutex); 126} 127EXPORT_SYMBOL(lockdep_rtnl_is_held); 128#endif /* #ifdef CONFIG_PROVE_LOCKING */ 129 | 66}; 67 68static DEFINE_MUTEX(rtnl_mutex); 69 70void rtnl_lock(void) 71{ 72 mutex_lock(&rtnl_mutex); 73} --- 48 unchanged lines hidden (view full) --- 122#ifdef CONFIG_PROVE_LOCKING 123bool lockdep_rtnl_is_held(void) 124{ 125 return lockdep_is_held(&rtnl_mutex); 126} 127EXPORT_SYMBOL(lockdep_rtnl_is_held); 128#endif /* #ifdef CONFIG_PROVE_LOCKING */ 129 |
130static struct rtnl_link *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1]; | 130static struct rtnl_link __rcu *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1]; 131static refcount_t rtnl_msg_handlers_ref[RTNL_FAMILY_MAX + 1]; |
131 132static inline int rtm_msgindex(int msgtype) 133{ 134 int msgindex = msgtype - RTM_BASE; 135 136 /* 137 * msgindex < 0 implies someone tried to register a netlink 138 * control code. msgindex >= RTM_NR_MSGTYPES may indicate that 139 * the message type has not been added to linux/rtnetlink.h 140 */ 141 BUG_ON(msgindex < 0 || msgindex >= RTM_NR_MSGTYPES); 142 143 return msgindex; 144} 145 | 132 133static inline int rtm_msgindex(int msgtype) 134{ 135 int msgindex = msgtype - RTM_BASE; 136 137 /* 138 * msgindex < 0 implies someone tried to register a netlink 139 * control code. msgindex >= RTM_NR_MSGTYPES may indicate that 140 * the message type has not been added to linux/rtnetlink.h 141 */ 142 BUG_ON(msgindex < 0 || msgindex >= RTM_NR_MSGTYPES); 143 144 return msgindex; 145} 146 |
146static rtnl_doit_func rtnl_get_doit(int protocol, int msgindex) 147{ 148 struct rtnl_link *tab; 149 150 if (protocol <= RTNL_FAMILY_MAX) 151 tab = rtnl_msg_handlers[protocol]; 152 else 153 tab = NULL; 154 155 if (tab == NULL || tab[msgindex].doit == NULL) 156 tab = rtnl_msg_handlers[PF_UNSPEC]; 157 158 return tab[msgindex].doit; 159} 160 161static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex) 162{ 163 struct rtnl_link *tab; 164 165 if (protocol <= RTNL_FAMILY_MAX) 166 tab = rtnl_msg_handlers[protocol]; 167 else 168 tab = NULL; 169 170 if (tab == NULL || tab[msgindex].dumpit == NULL) 171 tab = rtnl_msg_handlers[PF_UNSPEC]; 172 173 return tab[msgindex].dumpit; 174} 175 176static rtnl_calcit_func rtnl_get_calcit(int protocol, int msgindex) 177{ 178 struct rtnl_link *tab; 179 180 if (protocol <= RTNL_FAMILY_MAX) 181 tab = rtnl_msg_handlers[protocol]; 182 else 183 tab = NULL; 184 185 if (tab == NULL || tab[msgindex].calcit == NULL) 186 tab = rtnl_msg_handlers[PF_UNSPEC]; 187 188 return tab[msgindex].calcit; 189} 190 | |
191/** 192 * __rtnl_register - Register a rtnetlink message type 193 * @protocol: Protocol family or PF_UNSPEC 194 * @msgtype: rtnetlink message type 195 * @doit: Function pointer called for each request message 196 * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message | 147/** 148 * __rtnl_register - Register a rtnetlink message type 149 * @protocol: Protocol family or PF_UNSPEC 150 * @msgtype: rtnetlink message type 151 * @doit: Function pointer called for each request message 152 * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message |
197 * @calcit: Function pointer to calc size of dump message | 153 * @flags: rtnl_link_flags to modifiy behaviour of doit/dumpit functions |
198 * 199 * Registers the specified function pointers (at least one of them has 200 * to be non-NULL) to be called whenever a request message for the 201 * specified protocol family and message type is received. 202 * 203 * The special protocol family PF_UNSPEC may be used to define fallback 204 * function pointers for the case when no entry for the specific protocol 205 * family exists. 206 * 207 * Returns 0 on success or a negative error code. 208 */ 209int __rtnl_register(int protocol, int msgtype, 210 rtnl_doit_func doit, rtnl_dumpit_func dumpit, | 154 * 155 * Registers the specified function pointers (at least one of them has 156 * to be non-NULL) to be called whenever a request message for the 157 * specified protocol family and message type is received. 158 * 159 * The special protocol family PF_UNSPEC may be used to define fallback 160 * function pointers for the case when no entry for the specific protocol 161 * family exists. 162 * 163 * Returns 0 on success or a negative error code. 164 */ 165int __rtnl_register(int protocol, int msgtype, 166 rtnl_doit_func doit, rtnl_dumpit_func dumpit, |
211 rtnl_calcit_func calcit) | 167 unsigned int flags) |
212{ 213 struct rtnl_link *tab; 214 int msgindex; 215 216 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); 217 msgindex = rtm_msgindex(msgtype); 218 | 168{ 169 struct rtnl_link *tab; 170 int msgindex; 171 172 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); 173 msgindex = rtm_msgindex(msgtype); 174 |
219 tab = rtnl_msg_handlers[protocol]; | 175 tab = rcu_dereference_raw(rtnl_msg_handlers[protocol]); |
220 if (tab == NULL) { 221 tab = kcalloc(RTM_NR_MSGTYPES, sizeof(*tab), GFP_KERNEL); 222 if (tab == NULL) 223 return -ENOBUFS; 224 | 176 if (tab == NULL) { 177 tab = kcalloc(RTM_NR_MSGTYPES, sizeof(*tab), GFP_KERNEL); 178 if (tab == NULL) 179 return -ENOBUFS; 180 |
225 rtnl_msg_handlers[protocol] = tab; | 181 rcu_assign_pointer(rtnl_msg_handlers[protocol], tab); |
226 } 227 228 if (doit) 229 tab[msgindex].doit = doit; | 182 } 183 184 if (doit) 185 tab[msgindex].doit = doit; |
230 | |
231 if (dumpit) 232 tab[msgindex].dumpit = dumpit; | 186 if (dumpit) 187 tab[msgindex].dumpit = dumpit; |
188 tab[msgindex].flags |= flags; |
|
233 | 189 |
234 if (calcit) 235 tab[msgindex].calcit = calcit; 236 | |
237 return 0; 238} 239EXPORT_SYMBOL_GPL(__rtnl_register); 240 241/** 242 * rtnl_register - Register a rtnetlink message type 243 * 244 * Identical to __rtnl_register() but panics on failure. This is useful 245 * as failure of this function is very unlikely, it can only happen due 246 * to lack of memory when allocating the chain to store all message 247 * handlers for a protocol. Meant for use in init functions where lack 248 * of memory implies no sense in continuing. 249 */ 250void rtnl_register(int protocol, int msgtype, 251 rtnl_doit_func doit, rtnl_dumpit_func dumpit, | 190 return 0; 191} 192EXPORT_SYMBOL_GPL(__rtnl_register); 193 194/** 195 * rtnl_register - Register a rtnetlink message type 196 * 197 * Identical to __rtnl_register() but panics on failure. This is useful 198 * as failure of this function is very unlikely, it can only happen due 199 * to lack of memory when allocating the chain to store all message 200 * handlers for a protocol. Meant for use in init functions where lack 201 * of memory implies no sense in continuing. 202 */ 203void rtnl_register(int protocol, int msgtype, 204 rtnl_doit_func doit, rtnl_dumpit_func dumpit, |
252 rtnl_calcit_func calcit) | 205 unsigned int flags) |
253{ | 206{ |
254 if (__rtnl_register(protocol, msgtype, doit, dumpit, calcit) < 0) | 207 if (__rtnl_register(protocol, msgtype, doit, dumpit, flags) < 0) |
255 panic("Unable to register rtnetlink message handler, " 256 "protocol = %d, message type = %d\n", 257 protocol, msgtype); 258} 259EXPORT_SYMBOL_GPL(rtnl_register); 260 261/** 262 * rtnl_unregister - Unregister a rtnetlink message type 263 * @protocol: Protocol family or PF_UNSPEC 264 * @msgtype: rtnetlink message type 265 * 266 * Returns 0 on success or a negative error code. 267 */ 268int rtnl_unregister(int protocol, int msgtype) 269{ | 208 panic("Unable to register rtnetlink message handler, " 209 "protocol = %d, message type = %d\n", 210 protocol, msgtype); 211} 212EXPORT_SYMBOL_GPL(rtnl_register); 213 214/** 215 * rtnl_unregister - Unregister a rtnetlink message type 216 * @protocol: Protocol family or PF_UNSPEC 217 * @msgtype: rtnetlink message type 218 * 219 * Returns 0 on success or a negative error code. 220 */ 221int rtnl_unregister(int protocol, int msgtype) 222{ |
223 struct rtnl_link *handlers; |
|
270 int msgindex; 271 272 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); 273 msgindex = rtm_msgindex(msgtype); 274 | 224 int msgindex; 225 226 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); 227 msgindex = rtm_msgindex(msgtype); 228 |
275 if (rtnl_msg_handlers[protocol] == NULL) | 229 rtnl_lock(); 230 handlers = rtnl_dereference(rtnl_msg_handlers[protocol]); 231 if (!handlers) { 232 rtnl_unlock(); |
276 return -ENOENT; | 233 return -ENOENT; |
234 } |
|
277 | 235 |
278 rtnl_msg_handlers[protocol][msgindex].doit = NULL; 279 rtnl_msg_handlers[protocol][msgindex].dumpit = NULL; 280 rtnl_msg_handlers[protocol][msgindex].calcit = NULL; | 236 handlers[msgindex].doit = NULL; 237 handlers[msgindex].dumpit = NULL; 238 handlers[msgindex].flags = 0; 239 rtnl_unlock(); |
281 282 return 0; 283} 284EXPORT_SYMBOL_GPL(rtnl_unregister); 285 286/** 287 * rtnl_unregister_all - Unregister all rtnetlink message type of a protocol 288 * @protocol : Protocol family or PF_UNSPEC 289 * 290 * Identical to calling rtnl_unregster() for all registered message types 291 * of a certain protocol family. 292 */ 293void rtnl_unregister_all(int protocol) 294{ | 240 241 return 0; 242} 243EXPORT_SYMBOL_GPL(rtnl_unregister); 244 245/** 246 * rtnl_unregister_all - Unregister all rtnetlink message type of a protocol 247 * @protocol : Protocol family or PF_UNSPEC 248 * 249 * Identical to calling rtnl_unregster() for all registered message types 250 * of a certain protocol family. 251 */ 252void rtnl_unregister_all(int protocol) 253{ |
254 struct rtnl_link *handlers; 255 |
|
295 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); 296 | 256 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); 257 |
297 kfree(rtnl_msg_handlers[protocol]); 298 rtnl_msg_handlers[protocol] = NULL; | 258 rtnl_lock(); 259 handlers = rtnl_dereference(rtnl_msg_handlers[protocol]); 260 RCU_INIT_POINTER(rtnl_msg_handlers[protocol], NULL); 261 rtnl_unlock(); 262 263 synchronize_net(); 264 265 while (refcount_read(&rtnl_msg_handlers_ref[protocol]) > 0) 266 schedule(); 267 kfree(handlers); |
299} 300EXPORT_SYMBOL_GPL(rtnl_unregister_all); 301 302static LIST_HEAD(link_ops); 303 304static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind) 305{ 306 const struct rtnl_link_ops *ops; --- 1719 unchanged lines hidden (view full) --- 2026 2027 status |= DO_SETLINK_NOTIFY; 2028 } 2029 2030 if (tb[IFLA_ADDRESS]) { 2031 struct sockaddr *sa; 2032 int len; 2033 | 268} 269EXPORT_SYMBOL_GPL(rtnl_unregister_all); 270 271static LIST_HEAD(link_ops); 272 273static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind) 274{ 275 const struct rtnl_link_ops *ops; --- 1719 unchanged lines hidden (view full) --- 1995 1996 status |= DO_SETLINK_NOTIFY; 1997 } 1998 1999 if (tb[IFLA_ADDRESS]) { 2000 struct sockaddr *sa; 2001 int len; 2002 |
2034 len = sizeof(sa_family_t) + dev->addr_len; | 2003 len = sizeof(sa_family_t) + max_t(size_t, dev->addr_len, 2004 sizeof(*sa)); |
2035 sa = kmalloc(len, GFP_KERNEL); 2036 if (!sa) { 2037 err = -ENOMEM; 2038 goto errout; 2039 } 2040 sa->sa_family = dev->type; 2041 memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]), 2042 dev->addr_len); --- 782 unchanged lines hidden (view full) --- 2825 } 2826 2827 if (!ext_filter_mask) 2828 return NLMSG_GOODSIZE; 2829 /* 2830 * traverse the list of net devices and compute the minimum 2831 * buffer size based upon the filter mask. 2832 */ | 2005 sa = kmalloc(len, GFP_KERNEL); 2006 if (!sa) { 2007 err = -ENOMEM; 2008 goto errout; 2009 } 2010 sa->sa_family = dev->type; 2011 memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]), 2012 dev->addr_len); --- 782 unchanged lines hidden (view full) --- 2795 } 2796 2797 if (!ext_filter_mask) 2798 return NLMSG_GOODSIZE; 2799 /* 2800 * traverse the list of net devices and compute the minimum 2801 * buffer size based upon the filter mask. 2802 */ |
2833 list_for_each_entry(dev, &net->dev_base_head, dev_list) { | 2803 rcu_read_lock(); 2804 for_each_netdev_rcu(net, dev) { |
2834 min_ifinfo_dump_size = max_t(u16, min_ifinfo_dump_size, 2835 if_nlmsg_size(dev, 2836 ext_filter_mask)); 2837 } | 2805 min_ifinfo_dump_size = max_t(u16, min_ifinfo_dump_size, 2806 if_nlmsg_size(dev, 2807 ext_filter_mask)); 2808 } |
2809 rcu_read_unlock(); |
|
2838 2839 return nlmsg_total_size(min_ifinfo_dump_size); 2840} 2841 2842static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) 2843{ 2844 int idx; 2845 int s_idx = cb->family; 2846 2847 if (s_idx == 0) 2848 s_idx = 1; | 2810 2811 return nlmsg_total_size(min_ifinfo_dump_size); 2812} 2813 2814static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) 2815{ 2816 int idx; 2817 int s_idx = cb->family; 2818 2819 if (s_idx == 0) 2820 s_idx = 1; |
2821 |
|
2849 for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) { 2850 int type = cb->nlh->nlmsg_type-RTM_BASE; | 2822 for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) { 2823 int type = cb->nlh->nlmsg_type-RTM_BASE; |
2824 struct rtnl_link *handlers; 2825 rtnl_dumpit_func dumpit; 2826 |
|
2851 if (idx < s_idx || idx == PF_PACKET) 2852 continue; | 2827 if (idx < s_idx || idx == PF_PACKET) 2828 continue; |
2853 if (rtnl_msg_handlers[idx] == NULL || 2854 rtnl_msg_handlers[idx][type].dumpit == NULL) | 2829 2830 handlers = rtnl_dereference(rtnl_msg_handlers[idx]); 2831 if (!handlers) |
2855 continue; | 2832 continue; |
2833 2834 dumpit = READ_ONCE(handlers[type].dumpit); 2835 if (!dumpit) 2836 continue; 2837 |
|
2856 if (idx > s_idx) { 2857 memset(&cb->args[0], 0, sizeof(cb->args)); 2858 cb->prev_seq = 0; 2859 cb->seq = 0; 2860 } | 2838 if (idx > s_idx) { 2839 memset(&cb->args[0], 0, sizeof(cb->args)); 2840 cb->prev_seq = 0; 2841 cb->seq = 0; 2842 } |
2861 if (rtnl_msg_handlers[idx][type].dumpit(skb, cb)) | 2843 if (dumpit(skb, cb)) |
2862 break; 2863 } 2864 cb->family = idx; 2865 2866 return skb->len; 2867} 2868 2869struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev, --- 1286 unchanged lines hidden (view full) --- 4156} 4157 4158/* Process one rtnetlink message. */ 4159 4160static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, 4161 struct netlink_ext_ack *extack) 4162{ 4163 struct net *net = sock_net(skb->sk); | 2844 break; 2845 } 2846 cb->family = idx; 2847 2848 return skb->len; 2849} 2850 2851struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev, --- 1286 unchanged lines hidden (view full) --- 4138} 4139 4140/* Process one rtnetlink message. */ 4141 4142static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, 4143 struct netlink_ext_ack *extack) 4144{ 4145 struct net *net = sock_net(skb->sk); |
4146 struct rtnl_link *handlers; 4147 int err = -EOPNOTSUPP; |
|
4164 rtnl_doit_func doit; | 4148 rtnl_doit_func doit; |
4149 unsigned int flags; |
|
4165 int kind; 4166 int family; 4167 int type; | 4150 int kind; 4151 int family; 4152 int type; |
4168 int err; | |
4169 4170 type = nlh->nlmsg_type; 4171 if (type > RTM_MAX) 4172 return -EOPNOTSUPP; 4173 4174 type -= RTM_BASE; 4175 4176 /* All the messages must have at least 1 byte length */ 4177 if (nlmsg_len(nlh) < sizeof(struct rtgenmsg)) 4178 return 0; 4179 4180 family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family; 4181 kind = type&3; 4182 4183 if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN)) 4184 return -EPERM; 4185 | 4153 4154 type = nlh->nlmsg_type; 4155 if (type > RTM_MAX) 4156 return -EOPNOTSUPP; 4157 4158 type -= RTM_BASE; 4159 4160 /* All the messages must have at least 1 byte length */ 4161 if (nlmsg_len(nlh) < sizeof(struct rtgenmsg)) 4162 return 0; 4163 4164 family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family; 4165 kind = type&3; 4166 4167 if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN)) 4168 return -EPERM; 4169 |
4170 if (family > ARRAY_SIZE(rtnl_msg_handlers)) 4171 family = PF_UNSPEC; 4172 4173 rcu_read_lock(); 4174 handlers = rcu_dereference(rtnl_msg_handlers[family]); 4175 if (!handlers) { 4176 family = PF_UNSPEC; 4177 handlers = rcu_dereference(rtnl_msg_handlers[family]); 4178 } 4179 |
|
4186 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { 4187 struct sock *rtnl; 4188 rtnl_dumpit_func dumpit; | 4180 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { 4181 struct sock *rtnl; 4182 rtnl_dumpit_func dumpit; |
4189 rtnl_calcit_func calcit; | |
4190 u16 min_dump_alloc = 0; 4191 | 4183 u16 min_dump_alloc = 0; 4184 |
4192 dumpit = rtnl_get_dumpit(family, type); 4193 if (dumpit == NULL) 4194 return -EOPNOTSUPP; 4195 calcit = rtnl_get_calcit(family, type); 4196 if (calcit) 4197 min_dump_alloc = calcit(skb, nlh); | 4185 dumpit = READ_ONCE(handlers[type].dumpit); 4186 if (!dumpit) { 4187 family = PF_UNSPEC; 4188 handlers = rcu_dereference(rtnl_msg_handlers[PF_UNSPEC]); 4189 if (!handlers) 4190 goto err_unlock; |
4198 | 4191 |
4199 __rtnl_unlock(); | 4192 dumpit = READ_ONCE(handlers[type].dumpit); 4193 if (!dumpit) 4194 goto err_unlock; 4195 } 4196 4197 refcount_inc(&rtnl_msg_handlers_ref[family]); 4198 4199 if (type == RTM_GETLINK) 4200 min_dump_alloc = rtnl_calcit(skb, nlh); 4201 4202 rcu_read_unlock(); 4203 |
4200 rtnl = net->rtnl; 4201 { 4202 struct netlink_dump_control c = { 4203 .dump = dumpit, 4204 .min_dump_alloc = min_dump_alloc, 4205 }; 4206 err = netlink_dump_start(rtnl, skb, nlh, &c); 4207 } | 4204 rtnl = net->rtnl; 4205 { 4206 struct netlink_dump_control c = { 4207 .dump = dumpit, 4208 .min_dump_alloc = min_dump_alloc, 4209 }; 4210 err = netlink_dump_start(rtnl, skb, nlh, &c); 4211 } |
4208 rtnl_lock(); | 4212 refcount_dec(&rtnl_msg_handlers_ref[family]); |
4209 return err; 4210 } 4211 | 4213 return err; 4214 } 4215 |
4212 doit = rtnl_get_doit(family, type); 4213 if (doit == NULL) 4214 return -EOPNOTSUPP; | 4216 flags = READ_ONCE(handlers[type].flags); 4217 if (flags & RTNL_FLAG_DOIT_UNLOCKED) { 4218 refcount_inc(&rtnl_msg_handlers_ref[family]); 4219 doit = READ_ONCE(handlers[type].doit); 4220 rcu_read_unlock(); 4221 if (doit) 4222 err = doit(skb, nlh, extack); 4223 refcount_dec(&rtnl_msg_handlers_ref[family]); 4224 return err; 4225 } |
4215 | 4226 |
4216 return doit(skb, nlh, extack); | 4227 rcu_read_unlock(); 4228 4229 rtnl_lock(); 4230 handlers = rtnl_dereference(rtnl_msg_handlers[family]); 4231 if (handlers) { 4232 doit = READ_ONCE(handlers[type].doit); 4233 if (doit) 4234 err = doit(skb, nlh, extack); 4235 } 4236 rtnl_unlock(); 4237 return err; 4238 4239err_unlock: 4240 rcu_read_unlock(); 4241 return -EOPNOTSUPP; |
4217} 4218 4219static void rtnetlink_rcv(struct sk_buff *skb) 4220{ | 4242} 4243 4244static void rtnetlink_rcv(struct sk_buff *skb) 4245{ |
4221 rtnl_lock(); | |
4222 netlink_rcv_skb(skb, &rtnetlink_rcv_msg); | 4246 netlink_rcv_skb(skb, &rtnetlink_rcv_msg); |
4223 rtnl_unlock(); | |
4224} 4225 4226static int rtnetlink_bind(struct net *net, int group) 4227{ 4228 switch (group) { 4229 case RTNLGRP_IPV4_MROUTE_R: 4230 case RTNLGRP_IPV6_MROUTE_R: 4231 if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) --- 4 unchanged lines hidden (view full) --- 4236} 4237 4238static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr) 4239{ 4240 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 4241 4242 switch (event) { 4243 case NETDEV_REBOOT: | 4247} 4248 4249static int rtnetlink_bind(struct net *net, int group) 4250{ 4251 switch (group) { 4252 case RTNLGRP_IPV4_MROUTE_R: 4253 case RTNLGRP_IPV6_MROUTE_R: 4254 if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) --- 4 unchanged lines hidden (view full) --- 4259} 4260 4261static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr) 4262{ 4263 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 4264 4265 switch (event) { 4266 case NETDEV_REBOOT: |
4267 case NETDEV_CHANGEADDR: |
|
4244 case NETDEV_CHANGENAME: 4245 case NETDEV_FEAT_CHANGE: 4246 case NETDEV_BONDING_FAILOVER: 4247 case NETDEV_NOTIFY_PEERS: 4248 case NETDEV_RESEND_IGMP: 4249 case NETDEV_CHANGEINFODATA: 4250 rtmsg_ifinfo_event(RTM_NEWLINK, dev, 0, rtnl_get_event(event), 4251 GFP_KERNEL); --- 41 unchanged lines hidden (view full) --- 4293void __init rtnetlink_init(void) 4294{ 4295 if (register_pernet_subsys(&rtnetlink_net_ops)) 4296 panic("rtnetlink_init: cannot initialize rtnetlink\n"); 4297 4298 register_netdevice_notifier(&rtnetlink_dev_notifier); 4299 4300 rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, | 4268 case NETDEV_CHANGENAME: 4269 case NETDEV_FEAT_CHANGE: 4270 case NETDEV_BONDING_FAILOVER: 4271 case NETDEV_NOTIFY_PEERS: 4272 case NETDEV_RESEND_IGMP: 4273 case NETDEV_CHANGEINFODATA: 4274 rtmsg_ifinfo_event(RTM_NEWLINK, dev, 0, rtnl_get_event(event), 4275 GFP_KERNEL); --- 41 unchanged lines hidden (view full) --- 4317void __init rtnetlink_init(void) 4318{ 4319 if (register_pernet_subsys(&rtnetlink_net_ops)) 4320 panic("rtnetlink_init: cannot initialize rtnetlink\n"); 4321 4322 register_netdevice_notifier(&rtnetlink_dev_notifier); 4323 4324 rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, |
4301 rtnl_dump_ifinfo, rtnl_calcit); 4302 rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL, NULL); 4303 rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL, NULL); 4304 rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL, NULL); | 4325 rtnl_dump_ifinfo, 0); 4326 rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL, 0); 4327 rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL, 0); 4328 rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL, 0); |
4305 | 4329 |
4306 rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, NULL); 4307 rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, NULL); 4308 rtnl_register(PF_UNSPEC, RTM_GETNETCONF, NULL, rtnl_dump_all, NULL); | 4330 rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, 0); 4331 rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, 0); 4332 rtnl_register(PF_UNSPEC, RTM_GETNETCONF, NULL, rtnl_dump_all, 0); |
4309 | 4333 |
4310 rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, NULL); 4311 rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, NULL); 4312 rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, NULL); | 4334 rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, 0); 4335 rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, 0); 4336 rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, 0); |
4313 | 4337 |
4314 rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, NULL); 4315 rtnl_register(PF_BRIDGE, RTM_DELLINK, rtnl_bridge_dellink, NULL, NULL); 4316 rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, NULL); | 4338 rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, 0); 4339 rtnl_register(PF_BRIDGE, RTM_DELLINK, rtnl_bridge_dellink, NULL, 0); 4340 rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, 0); |
4317 4318 rtnl_register(PF_UNSPEC, RTM_GETSTATS, rtnl_stats_get, rtnl_stats_dump, | 4341 4342 rtnl_register(PF_UNSPEC, RTM_GETSTATS, rtnl_stats_get, rtnl_stats_dump, |
4319 NULL); | 4343 0); |
4320} | 4344} |