rtnetlink.c (2f7043a37708110aa98262b91702da6bc32e17b6) rtnetlink.c (d0225784be6c9bdfb05149ebc30bf9fc1fdbce3a)
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]) > 1)
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;

--- 121 unchanged lines hidden (view full) ---

428 mutex_unlock(&net_mutex);
429}
430EXPORT_SYMBOL_GPL(rtnl_link_unregister);
431
432static size_t rtnl_link_get_slave_info_data_size(const struct net_device *dev)
433{
434 struct net_device *master_dev;
435 const struct rtnl_link_ops *ops;
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;

--- 121 unchanged lines hidden (view full) ---

397 mutex_unlock(&net_mutex);
398}
399EXPORT_SYMBOL_GPL(rtnl_link_unregister);
400
401static size_t rtnl_link_get_slave_info_data_size(const struct net_device *dev)
402{
403 struct net_device *master_dev;
404 const struct rtnl_link_ops *ops;
405 size_t size = 0;
436
406
437 master_dev = netdev_master_upper_dev_get((struct net_device *) dev);
407 rcu_read_lock();
408
409 master_dev = netdev_master_upper_dev_get_rcu((struct net_device *)dev);
438 if (!master_dev)
410 if (!master_dev)
439 return 0;
411 goto out;
412
440 ops = master_dev->rtnl_link_ops;
441 if (!ops || !ops->get_slave_size)
413 ops = master_dev->rtnl_link_ops;
414 if (!ops || !ops->get_slave_size)
442 return 0;
415 goto out;
443 /* IFLA_INFO_SLAVE_DATA + nested data */
416 /* IFLA_INFO_SLAVE_DATA + nested data */
444 return nla_total_size(sizeof(struct nlattr)) +
417 size = nla_total_size(sizeof(struct nlattr)) +
445 ops->get_slave_size(master_dev, dev);
418 ops->get_slave_size(master_dev, dev);
419
420out:
421 rcu_read_unlock();
422 return size;
446}
447
448static size_t rtnl_link_get_size(const struct net_device *dev)
449{
450 const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
451 size_t size;
452
453 if (!ops)

--- 1185 unchanged lines hidden (view full) ---

1639 unsigned int flags = NLM_F_MULTI;
1640 int master_idx = 0;
1641 int err;
1642 int hdrlen;
1643
1644 s_h = cb->args[0];
1645 s_idx = cb->args[1];
1646
423}
424
425static size_t rtnl_link_get_size(const struct net_device *dev)
426{
427 const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
428 size_t size;
429
430 if (!ops)

--- 1185 unchanged lines hidden (view full) ---

1616 unsigned int flags = NLM_F_MULTI;
1617 int master_idx = 0;
1618 int err;
1619 int hdrlen;
1620
1621 s_h = cb->args[0];
1622 s_idx = cb->args[1];
1623
1647 cb->seq = net->dev_base_seq;
1648
1649 /* A hack to preserve kernel<->userspace interface.
1650 * The correct header is ifinfomsg. It is consistent with rtnl_getlink.
1651 * However, before Linux v3.9 the code here assumed rtgenmsg and that's
1652 * what iproute2 < v3.9.0 used.
1653 * We can detect the old iproute2. Even including the IFLA_EXT_MASK
1654 * attribute, its netlink message is shorter than struct ifinfomsg.
1655 */
1656 hdrlen = nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg) ?

--- 29 unchanged lines hidden (view full) ---

1686 ext_filter_mask, 0);
1687
1688 if (err < 0) {
1689 if (likely(skb->len))
1690 goto out;
1691
1692 goto out_err;
1693 }
1624 /* A hack to preserve kernel<->userspace interface.
1625 * The correct header is ifinfomsg. It is consistent with rtnl_getlink.
1626 * However, before Linux v3.9 the code here assumed rtgenmsg and that's
1627 * what iproute2 < v3.9.0 used.
1628 * We can detect the old iproute2. Even including the IFLA_EXT_MASK
1629 * attribute, its netlink message is shorter than struct ifinfomsg.
1630 */
1631 hdrlen = nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg) ?

--- 29 unchanged lines hidden (view full) ---

1661 ext_filter_mask, 0);
1662
1663 if (err < 0) {
1664 if (likely(skb->len))
1665 goto out;
1666
1667 goto out_err;
1668 }
1694
1695 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
1696cont:
1697 idx++;
1698 }
1699 }
1700out:
1701 err = skb->len;
1702out_err:
1703 cb->args[1] = idx;
1704 cb->args[0] = h;
1669cont:
1670 idx++;
1671 }
1672 }
1673out:
1674 err = skb->len;
1675out_err:
1676 cb->args[1] = idx;
1677 cb->args[0] = h;
1678 cb->seq = net->dev_base_seq;
1679 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
1705
1706 return err;
1707}
1708
1709int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len,
1710 struct netlink_ext_ack *exterr)
1711{
1712 return nla_parse(tb, IFLA_MAX, head, len, ifla_policy, exterr);

--- 1113 unchanged lines hidden (view full) ---

2826 }
2827
2828 if (!ext_filter_mask)
2829 return NLMSG_GOODSIZE;
2830 /*
2831 * traverse the list of net devices and compute the minimum
2832 * buffer size based upon the filter mask.
2833 */
1680
1681 return err;
1682}
1683
1684int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len,
1685 struct netlink_ext_ack *exterr)
1686{
1687 return nla_parse(tb, IFLA_MAX, head, len, ifla_policy, exterr);

--- 1113 unchanged lines hidden (view full) ---

2801 }
2802
2803 if (!ext_filter_mask)
2804 return NLMSG_GOODSIZE;
2805 /*
2806 * traverse the list of net devices and compute the minimum
2807 * buffer size based upon the filter mask.
2808 */
2834 list_for_each_entry(dev, &net->dev_base_head, dev_list) {
2809 rcu_read_lock();
2810 for_each_netdev_rcu(net, dev) {
2835 min_ifinfo_dump_size = max_t(u16, min_ifinfo_dump_size,
2836 if_nlmsg_size(dev,
2837 ext_filter_mask));
2838 }
2811 min_ifinfo_dump_size = max_t(u16, min_ifinfo_dump_size,
2812 if_nlmsg_size(dev,
2813 ext_filter_mask));
2814 }
2815 rcu_read_unlock();
2839
2840 return nlmsg_total_size(min_ifinfo_dump_size);
2841}
2842
2843static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
2844{
2845 int idx;
2846 int s_idx = cb->family;
2847
2848 if (s_idx == 0)
2849 s_idx = 1;
2816
2817 return nlmsg_total_size(min_ifinfo_dump_size);
2818}
2819
2820static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
2821{
2822 int idx;
2823 int s_idx = cb->family;
2824
2825 if (s_idx == 0)
2826 s_idx = 1;
2827
2850 for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) {
2851 int type = cb->nlh->nlmsg_type-RTM_BASE;
2828 for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) {
2829 int type = cb->nlh->nlmsg_type-RTM_BASE;
2830 struct rtnl_link *handlers;
2831 rtnl_dumpit_func dumpit;
2832
2852 if (idx < s_idx || idx == PF_PACKET)
2853 continue;
2833 if (idx < s_idx || idx == PF_PACKET)
2834 continue;
2854 if (rtnl_msg_handlers[idx] == NULL ||
2855 rtnl_msg_handlers[idx][type].dumpit == NULL)
2835
2836 handlers = rtnl_dereference(rtnl_msg_handlers[idx]);
2837 if (!handlers)
2856 continue;
2838 continue;
2839
2840 dumpit = READ_ONCE(handlers[type].dumpit);
2841 if (!dumpit)
2842 continue;
2843
2857 if (idx > s_idx) {
2858 memset(&cb->args[0], 0, sizeof(cb->args));
2859 cb->prev_seq = 0;
2860 cb->seq = 0;
2861 }
2844 if (idx > s_idx) {
2845 memset(&cb->args[0], 0, sizeof(cb->args));
2846 cb->prev_seq = 0;
2847 cb->seq = 0;
2848 }
2862 if (rtnl_msg_handlers[idx][type].dumpit(skb, cb))
2849 if (dumpit(skb, cb))
2863 break;
2864 }
2865 cb->family = idx;
2866
2867 return skb->len;
2868}
2869
2870struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev,

--- 1286 unchanged lines hidden (view full) ---

4157}
4158
4159/* Process one rtnetlink message. */
4160
4161static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
4162 struct netlink_ext_ack *extack)
4163{
4164 struct net *net = sock_net(skb->sk);
2850 break;
2851 }
2852 cb->family = idx;
2853
2854 return skb->len;
2855}
2856
2857struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev,

--- 1286 unchanged lines hidden (view full) ---

4144}
4145
4146/* Process one rtnetlink message. */
4147
4148static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
4149 struct netlink_ext_ack *extack)
4150{
4151 struct net *net = sock_net(skb->sk);
4152 struct rtnl_link *handlers;
4153 int err = -EOPNOTSUPP;
4165 rtnl_doit_func doit;
4154 rtnl_doit_func doit;
4155 unsigned int flags;
4166 int kind;
4167 int family;
4168 int type;
4156 int kind;
4157 int family;
4158 int type;
4169 int err;
4170
4171 type = nlh->nlmsg_type;
4172 if (type > RTM_MAX)
4173 return -EOPNOTSUPP;
4174
4175 type -= RTM_BASE;
4176
4177 /* All the messages must have at least 1 byte length */
4178 if (nlmsg_len(nlh) < sizeof(struct rtgenmsg))
4179 return 0;
4180
4181 family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family;
4182 kind = type&3;
4183
4184 if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN))
4185 return -EPERM;
4186
4159
4160 type = nlh->nlmsg_type;
4161 if (type > RTM_MAX)
4162 return -EOPNOTSUPP;
4163
4164 type -= RTM_BASE;
4165
4166 /* All the messages must have at least 1 byte length */
4167 if (nlmsg_len(nlh) < sizeof(struct rtgenmsg))
4168 return 0;
4169
4170 family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family;
4171 kind = type&3;
4172
4173 if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN))
4174 return -EPERM;
4175
4176 if (family >= ARRAY_SIZE(rtnl_msg_handlers))
4177 family = PF_UNSPEC;
4178
4179 rcu_read_lock();
4180 handlers = rcu_dereference(rtnl_msg_handlers[family]);
4181 if (!handlers) {
4182 family = PF_UNSPEC;
4183 handlers = rcu_dereference(rtnl_msg_handlers[family]);
4184 }
4185
4187 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
4188 struct sock *rtnl;
4189 rtnl_dumpit_func dumpit;
4186 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
4187 struct sock *rtnl;
4188 rtnl_dumpit_func dumpit;
4190 rtnl_calcit_func calcit;
4191 u16 min_dump_alloc = 0;
4192
4189 u16 min_dump_alloc = 0;
4190
4193 dumpit = rtnl_get_dumpit(family, type);
4194 if (dumpit == NULL)
4195 return -EOPNOTSUPP;
4196 calcit = rtnl_get_calcit(family, type);
4197 if (calcit)
4198 min_dump_alloc = calcit(skb, nlh);
4191 dumpit = READ_ONCE(handlers[type].dumpit);
4192 if (!dumpit) {
4193 family = PF_UNSPEC;
4194 handlers = rcu_dereference(rtnl_msg_handlers[PF_UNSPEC]);
4195 if (!handlers)
4196 goto err_unlock;
4199
4197
4200 __rtnl_unlock();
4198 dumpit = READ_ONCE(handlers[type].dumpit);
4199 if (!dumpit)
4200 goto err_unlock;
4201 }
4202
4203 refcount_inc(&rtnl_msg_handlers_ref[family]);
4204
4205 if (type == RTM_GETLINK - RTM_BASE)
4206 min_dump_alloc = rtnl_calcit(skb, nlh);
4207
4208 rcu_read_unlock();
4209
4201 rtnl = net->rtnl;
4202 {
4203 struct netlink_dump_control c = {
4204 .dump = dumpit,
4205 .min_dump_alloc = min_dump_alloc,
4206 };
4207 err = netlink_dump_start(rtnl, skb, nlh, &c);
4208 }
4210 rtnl = net->rtnl;
4211 {
4212 struct netlink_dump_control c = {
4213 .dump = dumpit,
4214 .min_dump_alloc = min_dump_alloc,
4215 };
4216 err = netlink_dump_start(rtnl, skb, nlh, &c);
4217 }
4209 rtnl_lock();
4218 refcount_dec(&rtnl_msg_handlers_ref[family]);
4210 return err;
4211 }
4212
4219 return err;
4220 }
4221
4213 doit = rtnl_get_doit(family, type);
4214 if (doit == NULL)
4215 return -EOPNOTSUPP;
4222 doit = READ_ONCE(handlers[type].doit);
4223 if (!doit) {
4224 family = PF_UNSPEC;
4225 handlers = rcu_dereference(rtnl_msg_handlers[family]);
4226 }
4216
4227
4217 return doit(skb, nlh, extack);
4228 flags = READ_ONCE(handlers[type].flags);
4229 if (flags & RTNL_FLAG_DOIT_UNLOCKED) {
4230 refcount_inc(&rtnl_msg_handlers_ref[family]);
4231 doit = READ_ONCE(handlers[type].doit);
4232 rcu_read_unlock();
4233 if (doit)
4234 err = doit(skb, nlh, extack);
4235 refcount_dec(&rtnl_msg_handlers_ref[family]);
4236 return err;
4237 }
4238
4239 rcu_read_unlock();
4240
4241 rtnl_lock();
4242 handlers = rtnl_dereference(rtnl_msg_handlers[family]);
4243 if (handlers) {
4244 doit = READ_ONCE(handlers[type].doit);
4245 if (doit)
4246 err = doit(skb, nlh, extack);
4247 }
4248 rtnl_unlock();
4249 return err;
4250
4251err_unlock:
4252 rcu_read_unlock();
4253 return -EOPNOTSUPP;
4218}
4219
4220static void rtnetlink_rcv(struct sk_buff *skb)
4221{
4254}
4255
4256static void rtnetlink_rcv(struct sk_buff *skb)
4257{
4222 rtnl_lock();
4223 netlink_rcv_skb(skb, &rtnetlink_rcv_msg);
4258 netlink_rcv_skb(skb, &rtnetlink_rcv_msg);
4224 rtnl_unlock();
4225}
4226
4227static int rtnetlink_bind(struct net *net, int group)
4228{
4229 switch (group) {
4230 case RTNLGRP_IPV4_MROUTE_R:
4231 case RTNLGRP_IPV6_MROUTE_R:
4232 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))

--- 56 unchanged lines hidden (view full) ---

4289
4290static struct pernet_operations rtnetlink_net_ops = {
4291 .init = rtnetlink_net_init,
4292 .exit = rtnetlink_net_exit,
4293};
4294
4295void __init rtnetlink_init(void)
4296{
4259}
4260
4261static int rtnetlink_bind(struct net *net, int group)
4262{
4263 switch (group) {
4264 case RTNLGRP_IPV4_MROUTE_R:
4265 case RTNLGRP_IPV6_MROUTE_R:
4266 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))

--- 56 unchanged lines hidden (view full) ---

4323
4324static struct pernet_operations rtnetlink_net_ops = {
4325 .init = rtnetlink_net_init,
4326 .exit = rtnetlink_net_exit,
4327};
4328
4329void __init rtnetlink_init(void)
4330{
4331 int i;
4332
4333 for (i = 0; i < ARRAY_SIZE(rtnl_msg_handlers_ref); i++)
4334 refcount_set(&rtnl_msg_handlers_ref[i], 1);
4335
4297 if (register_pernet_subsys(&rtnetlink_net_ops))
4298 panic("rtnetlink_init: cannot initialize rtnetlink\n");
4299
4300 register_netdevice_notifier(&rtnetlink_dev_notifier);
4301
4302 rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink,
4336 if (register_pernet_subsys(&rtnetlink_net_ops))
4337 panic("rtnetlink_init: cannot initialize rtnetlink\n");
4338
4339 register_netdevice_notifier(&rtnetlink_dev_notifier);
4340
4341 rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink,
4303 rtnl_dump_ifinfo, rtnl_calcit);
4304 rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL, NULL);
4305 rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL, NULL);
4306 rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL, NULL);
4342 rtnl_dump_ifinfo, 0);
4343 rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL, 0);
4344 rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL, 0);
4345 rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL, 0);
4307
4346
4308 rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, NULL);
4309 rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, NULL);
4310 rtnl_register(PF_UNSPEC, RTM_GETNETCONF, NULL, rtnl_dump_all, NULL);
4347 rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, 0);
4348 rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, 0);
4349 rtnl_register(PF_UNSPEC, RTM_GETNETCONF, NULL, rtnl_dump_all, 0);
4311
4350
4312 rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, NULL);
4313 rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, NULL);
4314 rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, NULL);
4351 rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, 0);
4352 rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, 0);
4353 rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, 0);
4315
4354
4316 rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, NULL);
4317 rtnl_register(PF_BRIDGE, RTM_DELLINK, rtnl_bridge_dellink, NULL, NULL);
4318 rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, NULL);
4355 rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, 0);
4356 rtnl_register(PF_BRIDGE, RTM_DELLINK, rtnl_bridge_dellink, NULL, 0);
4357 rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, 0);
4319
4320 rtnl_register(PF_UNSPEC, RTM_GETSTATS, rtnl_stats_get, rtnl_stats_dump,
4358
4359 rtnl_register(PF_UNSPEC, RTM_GETSTATS, rtnl_stats_get, rtnl_stats_dump,
4321 NULL);
4360 0);
4322}
4361}