rtnetlink.c (942baad211336efefb93a8369478888ab845c450) rtnetlink.c (d467d0bc7ab8062197158658c456e1f2f6c3fcf1)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * INET An implementation of the TCP/IP protocol suite for the LINUX
4 * operating system. INET is implemented using the BSD Socket
5 * interface as the means of communication with the user level.
6 *
7 * Routing netlink socket interface: protocol independent part.
8 *
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10 *
11 * Fixes:
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * INET An implementation of the TCP/IP protocol suite for the LINUX
4 * operating system. INET is implemented using the BSD Socket
5 * interface as the means of communication with the user level.
6 *
7 * Routing netlink socket interface: protocol independent part.
8 *
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10 *
11 * Fixes:
12 * Vitaly E. Lavrov RTA_OK arithmetics was wrong.
12 * Vitaly E. Lavrov RTA_OK arithmetic was wrong.
13 */
14
15#include <linux/bitops.h>
16#include <linux/errno.h>
17#include <linux/module.h>
18#include <linux/types.h>
19#include <linux/socket.h>
20#include <linux/kernel.h>

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

229/**
230 * rtnl_register_module - Register a rtnetlink message type
231 *
232 * @owner: module registering the hook (THIS_MODULE)
233 * @protocol: Protocol family or PF_UNSPEC
234 * @msgtype: rtnetlink message type
235 * @doit: Function pointer called for each request message
236 * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message
13 */
14
15#include <linux/bitops.h>
16#include <linux/errno.h>
17#include <linux/module.h>
18#include <linux/types.h>
19#include <linux/socket.h>
20#include <linux/kernel.h>

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

229/**
230 * rtnl_register_module - Register a rtnetlink message type
231 *
232 * @owner: module registering the hook (THIS_MODULE)
233 * @protocol: Protocol family or PF_UNSPEC
234 * @msgtype: rtnetlink message type
235 * @doit: Function pointer called for each request message
236 * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message
237 * @flags: rtnl_link_flags to modifiy behaviour of doit/dumpit functions
237 * @flags: rtnl_link_flags to modify behaviour of doit/dumpit functions
238 *
239 * Like rtnl_register, but for use by removable modules.
240 */
241int rtnl_register_module(struct module *owner,
242 int protocol, int msgtype,
243 rtnl_doit_func doit, rtnl_dumpit_func dumpit,
244 unsigned int flags)
245{
246 return rtnl_register_internal(owner, protocol, msgtype,
247 doit, dumpit, flags);
248}
249EXPORT_SYMBOL_GPL(rtnl_register_module);
250
251/**
252 * rtnl_register - Register a rtnetlink message type
253 * @protocol: Protocol family or PF_UNSPEC
254 * @msgtype: rtnetlink message type
255 * @doit: Function pointer called for each request message
256 * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message
238 *
239 * Like rtnl_register, but for use by removable modules.
240 */
241int rtnl_register_module(struct module *owner,
242 int protocol, int msgtype,
243 rtnl_doit_func doit, rtnl_dumpit_func dumpit,
244 unsigned int flags)
245{
246 return rtnl_register_internal(owner, protocol, msgtype,
247 doit, dumpit, flags);
248}
249EXPORT_SYMBOL_GPL(rtnl_register_module);
250
251/**
252 * rtnl_register - Register a rtnetlink message type
253 * @protocol: Protocol family or PF_UNSPEC
254 * @msgtype: rtnetlink message type
255 * @doit: Function pointer called for each request message
256 * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message
257 * @flags: rtnl_link_flags to modifiy behaviour of doit/dumpit functions
257 * @flags: rtnl_link_flags to modify behaviour of doit/dumpit functions
258 *
259 * Registers the specified function pointers (at least one of them has
260 * to be non-NULL) to be called whenever a request message for the
261 * specified protocol family and message type is received.
262 *
263 * The special protocol family PF_UNSPEC may be used to define fallback
264 * function pointers for the case when no entry for the specific protocol
265 * family exists.

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

538}
539
540static LIST_HEAD(rtnl_af_ops);
541
542static const struct rtnl_af_ops *rtnl_af_lookup(const int family)
543{
544 const struct rtnl_af_ops *ops;
545
258 *
259 * Registers the specified function pointers (at least one of them has
260 * to be non-NULL) to be called whenever a request message for the
261 * specified protocol family and message type is received.
262 *
263 * The special protocol family PF_UNSPEC may be used to define fallback
264 * function pointers for the case when no entry for the specific protocol
265 * family exists.

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

538}
539
540static LIST_HEAD(rtnl_af_ops);
541
542static const struct rtnl_af_ops *rtnl_af_lookup(const int family)
543{
544 const struct rtnl_af_ops *ops;
545
546 list_for_each_entry_rcu(ops, &rtnl_af_ops, list) {
546 ASSERT_RTNL();
547
548 list_for_each_entry(ops, &rtnl_af_ops, list) {
547 if (ops->family == family)
548 return ops;
549 }
550
551 return NULL;
552}
553
554/**

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

2269
2270 if (tb[IFLA_AF_SPEC]) {
2271 struct nlattr *af;
2272 int rem, err;
2273
2274 nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) {
2275 const struct rtnl_af_ops *af_ops;
2276
549 if (ops->family == family)
550 return ops;
551 }
552
553 return NULL;
554}
555
556/**

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

2271
2272 if (tb[IFLA_AF_SPEC]) {
2273 struct nlattr *af;
2274 int rem, err;
2275
2276 nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) {
2277 const struct rtnl_af_ops *af_ops;
2278
2277 rcu_read_lock();
2278 af_ops = rtnl_af_lookup(nla_type(af));
2279 af_ops = rtnl_af_lookup(nla_type(af));
2279 if (!af_ops) {
2280 rcu_read_unlock();
2280 if (!af_ops)
2281 return -EAFNOSUPPORT;
2281 return -EAFNOSUPPORT;
2282 }
2283
2282
2284 if (!af_ops->set_link_af) {
2285 rcu_read_unlock();
2283 if (!af_ops->set_link_af)
2286 return -EOPNOTSUPP;
2284 return -EOPNOTSUPP;
2287 }
2288
2289 if (af_ops->validate_link_af) {
2290 err = af_ops->validate_link_af(dev, af);
2285
2286 if (af_ops->validate_link_af) {
2287 err = af_ops->validate_link_af(dev, af);
2291 if (err < 0) {
2292 rcu_read_unlock();
2288 if (err < 0)
2293 return err;
2289 return err;
2294 }
2295 }
2290 }
2296
2297 rcu_read_unlock();
2298 }
2299 }
2300
2301 return 0;
2302}
2303
2304static int handle_infiniband_guid(struct net_device *dev, struct ifla_vf_guid *ivt,
2305 int guid_type)

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

2569 mask = nla_get_u32(pdreason[IFLA_PROTO_DOWN_REASON_MASK]);
2570
2571 dev_change_proto_down_reason(dev, mask, value);
2572 }
2573
2574 if (nl_proto_down) {
2575 proto_down = nla_get_u8(nl_proto_down);
2576
2291 }
2292 }
2293
2294 return 0;
2295}
2296
2297static int handle_infiniband_guid(struct net_device *dev, struct ifla_vf_guid *ivt,
2298 int guid_type)

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

2562 mask = nla_get_u32(pdreason[IFLA_PROTO_DOWN_REASON_MASK]);
2563
2564 dev_change_proto_down_reason(dev, mask, value);
2565 }
2566
2567 if (nl_proto_down) {
2568 proto_down = nla_get_u8(nl_proto_down);
2569
2577 /* Dont turn off protodown if there are active reasons */
2570 /* Don't turn off protodown if there are active reasons */
2578 if (!proto_down && dev->proto_down_reason) {
2579 NL_SET_ERR_MSG(extack, "Cannot clear protodown, active reasons");
2580 return -EBUSY;
2581 }
2582 err = dev_change_proto_down(dev,
2583 proto_down);
2584 if (err)
2585 return err;

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

2863
2864 if (tb[IFLA_AF_SPEC]) {
2865 struct nlattr *af;
2866 int rem;
2867
2868 nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) {
2869 const struct rtnl_af_ops *af_ops;
2870
2571 if (!proto_down && dev->proto_down_reason) {
2572 NL_SET_ERR_MSG(extack, "Cannot clear protodown, active reasons");
2573 return -EBUSY;
2574 }
2575 err = dev_change_proto_down(dev,
2576 proto_down);
2577 if (err)
2578 return err;

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

2856
2857 if (tb[IFLA_AF_SPEC]) {
2858 struct nlattr *af;
2859 int rem;
2860
2861 nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) {
2862 const struct rtnl_af_ops *af_ops;
2863
2871 rcu_read_lock();
2872
2873 BUG_ON(!(af_ops = rtnl_af_lookup(nla_type(af))));
2874
2875 err = af_ops->set_link_af(dev, af, extack);
2864 BUG_ON(!(af_ops = rtnl_af_lookup(nla_type(af))));
2865
2866 err = af_ops->set_link_af(dev, af, extack);
2876 if (err < 0) {
2877 rcu_read_unlock();
2867 if (err < 0)
2878 goto errout;
2868 goto errout;
2879 }
2880
2869
2881 rcu_read_unlock();
2882 status |= DO_SETLINK_NOTIFY;
2883 }
2884 }
2885 err = 0;
2886
2887 if (tb[IFLA_PROTO_DOWN] || tb[IFLA_PROTO_DOWN_REASON]) {
2888 err = do_set_proto_down(dev, tb[IFLA_PROTO_DOWN],
2889 tb[IFLA_PROTO_DOWN_REASON], extack);

--- 2797 unchanged lines hidden ---
2870 status |= DO_SETLINK_NOTIFY;
2871 }
2872 }
2873 err = 0;
2874
2875 if (tb[IFLA_PROTO_DOWN] || tb[IFLA_PROTO_DOWN_REASON]) {
2876 err = do_set_proto_down(dev, tb[IFLA_PROTO_DOWN],
2877 tb[IFLA_PROTO_DOWN_REASON], extack);

--- 2797 unchanged lines hidden ---