rtnetlink.c (54156da8937c9f5f84b4215e239a61ecc7c29275) rtnetlink.c (b2d3bcfa26a7a8de41f358a6cae8b848673b3c6e)
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 struct module *owner;
65 unsigned int flags;
66 unsigned int flags;
67 struct rcu_head rcu;
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
68};
69
70static DEFINE_MUTEX(rtnl_mutex);
71
72void rtnl_lock(void)
73{
74 mutex_lock(&rtnl_mutex);
75}

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

124#ifdef CONFIG_PROVE_LOCKING
125bool lockdep_rtnl_is_held(void)
126{
127 return lockdep_is_held(&rtnl_mutex);
128}
129EXPORT_SYMBOL(lockdep_rtnl_is_held);
130#endif /* #ifdef CONFIG_PROVE_LOCKING */
131
130static struct rtnl_link __rcu *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1];
131static refcount_t rtnl_msg_handlers_ref[RTNL_FAMILY_MAX + 1];
132static struct rtnl_link *__rcu *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1];
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
133
134static inline int rtm_msgindex(int msgtype)
135{
136 int msgindex = msgtype - RTM_BASE;
137
138 /*
139 * msgindex < 0 implies someone tried to register a netlink
140 * control code. msgindex >= RTM_NR_MSGTYPES may indicate that
141 * the message type has not been added to linux/rtnetlink.h
142 */
143 BUG_ON(msgindex < 0 || msgindex >= RTM_NR_MSGTYPES);
144
145 return msgindex;
146}
147
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
153 * @flags: rtnl_link_flags to modifiy behaviour of doit/dumpit functions
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,
167 unsigned int flags)
148static struct rtnl_link *rtnl_get_link(int protocol, int msgtype)
168{
149{
169 struct rtnl_link *tab;
150 struct rtnl_link **tab;
151
152 if (protocol >= ARRAY_SIZE(rtnl_msg_handlers))
153 protocol = PF_UNSPEC;
154
155 tab = rcu_dereference_rtnl(rtnl_msg_handlers[protocol]);
156 if (!tab)
157 tab = rcu_dereference_rtnl(rtnl_msg_handlers[PF_UNSPEC]);
158
159 return tab[msgtype];
160}
161
162static int rtnl_register_internal(struct module *owner,
163 int protocol, int msgtype,
164 rtnl_doit_func doit, rtnl_dumpit_func dumpit,
165 unsigned int flags)
166{
167 struct rtnl_link *link, *old;
168 struct rtnl_link __rcu **tab;
170 int msgindex;
169 int msgindex;
170 int ret = -ENOBUFS;
171
172 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
173 msgindex = rtm_msgindex(msgtype);
174
171
172 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
173 msgindex = rtm_msgindex(msgtype);
174
175 tab = rcu_dereference_raw(rtnl_msg_handlers[protocol]);
175 rtnl_lock();
176 tab = rtnl_msg_handlers[protocol];
176 if (tab == NULL) {
177 if (tab == NULL) {
177 tab = kcalloc(RTM_NR_MSGTYPES, sizeof(*tab), GFP_KERNEL);
178 if (tab == NULL)
179 return -ENOBUFS;
178 tab = kcalloc(RTM_NR_MSGTYPES, sizeof(void *), GFP_KERNEL);
179 if (!tab)
180 goto unlock;
180
181
182 /* ensures we see the 0 stores */
181 rcu_assign_pointer(rtnl_msg_handlers[protocol], tab);
182 }
183
183 rcu_assign_pointer(rtnl_msg_handlers[protocol], tab);
184 }
185
186 old = rtnl_dereference(tab[msgindex]);
187 if (old) {
188 link = kmemdup(old, sizeof(*old), GFP_KERNEL);
189 if (!link)
190 goto unlock;
191 } else {
192 link = kzalloc(sizeof(*link), GFP_KERNEL);
193 if (!link)
194 goto unlock;
195 }
196
197 WARN_ON(link->owner && link->owner != owner);
198 link->owner = owner;
199
200 WARN_ON(doit && link->doit && link->doit != doit);
184 if (doit)
201 if (doit)
185 tab[msgindex].doit = doit;
202 link->doit = doit;
203 WARN_ON(dumpit && link->dumpit && link->dumpit != dumpit);
186 if (dumpit)
204 if (dumpit)
187 tab[msgindex].dumpit = dumpit;
188 tab[msgindex].flags |= flags;
205 link->dumpit = dumpit;
189
206
190 return 0;
207 link->flags |= flags;
208
209 /* publish protocol:msgtype */
210 rcu_assign_pointer(tab[msgindex], link);
211 ret = 0;
212 if (old)
213 kfree_rcu(old, rcu);
214unlock:
215 rtnl_unlock();
216 return ret;
191}
217}
192EXPORT_SYMBOL_GPL(__rtnl_register);
193
194/**
218
219/**
220 * rtnl_register_module - Register a rtnetlink message type
221 *
222 * @owner: module registering the hook (THIS_MODULE)
223 * @protocol: Protocol family or PF_UNSPEC
224 * @msgtype: rtnetlink message type
225 * @doit: Function pointer called for each request message
226 * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message
227 * @flags: rtnl_link_flags to modifiy behaviour of doit/dumpit functions
228 *
229 * Like rtnl_register, but for use by removable modules.
230 */
231int rtnl_register_module(struct module *owner,
232 int protocol, int msgtype,
233 rtnl_doit_func doit, rtnl_dumpit_func dumpit,
234 unsigned int flags)
235{
236 return rtnl_register_internal(owner, protocol, msgtype,
237 doit, dumpit, flags);
238}
239EXPORT_SYMBOL_GPL(rtnl_register_module);
240
241/**
195 * rtnl_register - Register a rtnetlink message type
242 * rtnl_register - Register a rtnetlink message type
243 * @protocol: Protocol family or PF_UNSPEC
244 * @msgtype: rtnetlink message type
245 * @doit: Function pointer called for each request message
246 * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message
247 * @flags: rtnl_link_flags to modifiy behaviour of doit/dumpit functions
196 *
248 *
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.
249 * Registers the specified function pointers (at least one of them has
250 * to be non-NULL) to be called whenever a request message for the
251 * specified protocol family and message type is received.
252 *
253 * The special protocol family PF_UNSPEC may be used to define fallback
254 * function pointers for the case when no entry for the specific protocol
255 * family exists.
202 */
203void rtnl_register(int protocol, int msgtype,
204 rtnl_doit_func doit, rtnl_dumpit_func dumpit,
205 unsigned int flags)
206{
256 */
257void rtnl_register(int protocol, int msgtype,
258 rtnl_doit_func doit, rtnl_dumpit_func dumpit,
259 unsigned int flags)
260{
207 if (__rtnl_register(protocol, msgtype, doit, dumpit, flags) < 0)
208 panic("Unable to register rtnetlink message handler, "
209 "protocol = %d, message type = %d\n",
210 protocol, msgtype);
261 int err;
262
263 err = rtnl_register_internal(NULL, protocol, msgtype, doit, dumpit,
264 flags);
265 if (err)
266 pr_err("Unable to register rtnetlink message handler, "
267 "protocol = %d, message type = %d\n", protocol, msgtype);
211}
268}
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{
269
270/**
271 * rtnl_unregister - Unregister a rtnetlink message type
272 * @protocol: Protocol family or PF_UNSPEC
273 * @msgtype: rtnetlink message type
274 *
275 * Returns 0 on success or a negative error code.
276 */
277int rtnl_unregister(int protocol, int msgtype)
278{
223 struct rtnl_link *handlers;
279 struct rtnl_link **tab, *link;
224 int msgindex;
225
226 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
227 msgindex = rtm_msgindex(msgtype);
228
229 rtnl_lock();
280 int msgindex;
281
282 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
283 msgindex = rtm_msgindex(msgtype);
284
285 rtnl_lock();
230 handlers = rtnl_dereference(rtnl_msg_handlers[protocol]);
231 if (!handlers) {
286 tab = rtnl_dereference(rtnl_msg_handlers[protocol]);
287 if (!tab) {
232 rtnl_unlock();
233 return -ENOENT;
234 }
235
288 rtnl_unlock();
289 return -ENOENT;
290 }
291
236 handlers[msgindex].doit = NULL;
237 handlers[msgindex].dumpit = NULL;
238 handlers[msgindex].flags = 0;
292 link = tab[msgindex];
293 rcu_assign_pointer(tab[msgindex], NULL);
239 rtnl_unlock();
240
294 rtnl_unlock();
295
296 kfree_rcu(link, rcu);
297
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{
298 return 0;
299}
300EXPORT_SYMBOL_GPL(rtnl_unregister);
301
302/**
303 * rtnl_unregister_all - Unregister all rtnetlink message type of a protocol
304 * @protocol : Protocol family or PF_UNSPEC
305 *
306 * Identical to calling rtnl_unregster() for all registered message types
307 * of a certain protocol family.
308 */
309void rtnl_unregister_all(int protocol)
310{
254 struct rtnl_link *handlers;
311 struct rtnl_link **tab, *link;
312 int msgindex;
255
256 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
257
258 rtnl_lock();
313
314 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
315
316 rtnl_lock();
259 handlers = rtnl_dereference(rtnl_msg_handlers[protocol]);
317 tab = rtnl_msg_handlers[protocol];
260 RCU_INIT_POINTER(rtnl_msg_handlers[protocol], NULL);
318 RCU_INIT_POINTER(rtnl_msg_handlers[protocol], NULL);
319 for (msgindex = 0; msgindex < RTM_NR_MSGTYPES; msgindex++) {
320 link = tab[msgindex];
321 if (!link)
322 continue;
323
324 rcu_assign_pointer(tab[msgindex], NULL);
325 kfree_rcu(link, rcu);
326 }
261 rtnl_unlock();
262
263 synchronize_net();
264
327 rtnl_unlock();
328
329 synchronize_net();
330
265 while (refcount_read(&rtnl_msg_handlers_ref[protocol]) > 1)
266 schedule();
267 kfree(handlers);
331 kfree(tab);
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;

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

835 /* IFLA_VF_STATS_RX_BYTES */
836 nla_total_size_64bit(sizeof(__u64)) +
837 /* IFLA_VF_STATS_TX_BYTES */
838 nla_total_size_64bit(sizeof(__u64)) +
839 /* IFLA_VF_STATS_BROADCAST */
840 nla_total_size_64bit(sizeof(__u64)) +
841 /* IFLA_VF_STATS_MULTICAST */
842 nla_total_size_64bit(sizeof(__u64)) +
332}
333EXPORT_SYMBOL_GPL(rtnl_unregister_all);
334
335static LIST_HEAD(link_ops);
336
337static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind)
338{
339 const struct rtnl_link_ops *ops;

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

899 /* IFLA_VF_STATS_RX_BYTES */
900 nla_total_size_64bit(sizeof(__u64)) +
901 /* IFLA_VF_STATS_TX_BYTES */
902 nla_total_size_64bit(sizeof(__u64)) +
903 /* IFLA_VF_STATS_BROADCAST */
904 nla_total_size_64bit(sizeof(__u64)) +
905 /* IFLA_VF_STATS_MULTICAST */
906 nla_total_size_64bit(sizeof(__u64)) +
907 /* IFLA_VF_STATS_RX_DROPPED */
908 nla_total_size_64bit(sizeof(__u64)) +
909 /* IFLA_VF_STATS_TX_DROPPED */
910 nla_total_size_64bit(sizeof(__u64)) +
843 nla_total_size(sizeof(struct ifla_vf_trust)));
844 return size;
845 } else
846 return 0;
847}
848
849static size_t rtnl_port_size(const struct net_device *dev,
850 u32 ext_filter_mask)

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

917 + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */
918 + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_SWITCH_ID */
919 + nla_total_size(IFNAMSIZ) /* IFLA_PHYS_PORT_NAME */
920 + rtnl_xdp_size() /* IFLA_XDP */
921 + nla_total_size(4) /* IFLA_EVENT */
922 + nla_total_size(4) /* IFLA_NEW_NETNSID */
923 + nla_total_size(1) /* IFLA_PROTO_DOWN */
924 + nla_total_size(4) /* IFLA_IF_NETNSID */
911 nla_total_size(sizeof(struct ifla_vf_trust)));
912 return size;
913 } else
914 return 0;
915}
916
917static size_t rtnl_port_size(const struct net_device *dev,
918 u32 ext_filter_mask)

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

985 + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */
986 + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_SWITCH_ID */
987 + nla_total_size(IFNAMSIZ) /* IFLA_PHYS_PORT_NAME */
988 + rtnl_xdp_size() /* IFLA_XDP */
989 + nla_total_size(4) /* IFLA_EVENT */
990 + nla_total_size(4) /* IFLA_NEW_NETNSID */
991 + nla_total_size(1) /* IFLA_PROTO_DOWN */
992 + nla_total_size(4) /* IFLA_IF_NETNSID */
993 + nla_total_size(4) /* IFLA_CARRIER_UP_COUNT */
994 + nla_total_size(4) /* IFLA_CARRIER_DOWN_COUNT */
925 + 0;
926}
927
928static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev)
929{
930 struct nlattr *vf_ports;
931 struct nlattr *vf_port;
932 int vf;

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

1189 vf_stats.tx_packets, IFLA_VF_STATS_PAD) ||
1190 nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES,
1191 vf_stats.rx_bytes, IFLA_VF_STATS_PAD) ||
1192 nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES,
1193 vf_stats.tx_bytes, IFLA_VF_STATS_PAD) ||
1194 nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST,
1195 vf_stats.broadcast, IFLA_VF_STATS_PAD) ||
1196 nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST,
995 + 0;
996}
997
998static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev)
999{
1000 struct nlattr *vf_ports;
1001 struct nlattr *vf_port;
1002 int vf;

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

1259 vf_stats.tx_packets, IFLA_VF_STATS_PAD) ||
1260 nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES,
1261 vf_stats.rx_bytes, IFLA_VF_STATS_PAD) ||
1262 nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES,
1263 vf_stats.tx_bytes, IFLA_VF_STATS_PAD) ||
1264 nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST,
1265 vf_stats.broadcast, IFLA_VF_STATS_PAD) ||
1266 nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST,
1197 vf_stats.multicast, IFLA_VF_STATS_PAD)) {
1267 vf_stats.multicast, IFLA_VF_STATS_PAD) ||
1268 nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED,
1269 vf_stats.rx_dropped, IFLA_VF_STATS_PAD) ||
1270 nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED,
1271 vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) {
1198 nla_nest_cancel(skb, vfstats);
1199 goto nla_put_vf_failure;
1200 }
1201 nla_nest_end(skb, vfstats);
1202 nla_nest_end(skb, vf);
1203 return 0;
1204
1205nla_put_vf_failure:

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

1256
1257 return 0;
1258}
1259
1260static u8 rtnl_xdp_attached_mode(struct net_device *dev, u32 *prog_id)
1261{
1262 const struct net_device_ops *ops = dev->netdev_ops;
1263 const struct bpf_prog *generic_xdp_prog;
1272 nla_nest_cancel(skb, vfstats);
1273 goto nla_put_vf_failure;
1274 }
1275 nla_nest_end(skb, vfstats);
1276 nla_nest_end(skb, vf);
1277 return 0;
1278
1279nla_put_vf_failure:

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

1330
1331 return 0;
1332}
1333
1334static u8 rtnl_xdp_attached_mode(struct net_device *dev, u32 *prog_id)
1335{
1336 const struct net_device_ops *ops = dev->netdev_ops;
1337 const struct bpf_prog *generic_xdp_prog;
1338 struct netdev_bpf xdp;
1264
1265 ASSERT_RTNL();
1266
1267 *prog_id = 0;
1268 generic_xdp_prog = rtnl_dereference(dev->xdp_prog);
1269 if (generic_xdp_prog) {
1270 *prog_id = generic_xdp_prog->aux->id;
1271 return XDP_ATTACHED_SKB;
1272 }
1273 if (!ops->ndo_bpf)
1274 return XDP_ATTACHED_NONE;
1275
1339
1340 ASSERT_RTNL();
1341
1342 *prog_id = 0;
1343 generic_xdp_prog = rtnl_dereference(dev->xdp_prog);
1344 if (generic_xdp_prog) {
1345 *prog_id = generic_xdp_prog->aux->id;
1346 return XDP_ATTACHED_SKB;
1347 }
1348 if (!ops->ndo_bpf)
1349 return XDP_ATTACHED_NONE;
1350
1276 return __dev_xdp_attached(dev, ops->ndo_bpf, prog_id);
1351 __dev_xdp_query(dev, ops->ndo_bpf, &xdp);
1352 *prog_id = xdp.prog_id;
1353
1354 return xdp.prog_attached;
1277}
1278
1279static int rtnl_xdp_fill(struct sk_buff *skb, struct net_device *dev)
1280{
1281 struct nlattr *xdp;
1282 u32 prog_id;
1283 int err;
1284

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

1470#endif
1471 nla_put_iflink(skb, dev) ||
1472 put_master_ifindex(skb, dev) ||
1473 nla_put_u8(skb, IFLA_CARRIER, netif_carrier_ok(dev)) ||
1474 (dev->qdisc &&
1475 nla_put_string(skb, IFLA_QDISC, dev->qdisc->ops->id)) ||
1476 nla_put_ifalias(skb, dev) ||
1477 nla_put_u32(skb, IFLA_CARRIER_CHANGES,
1355}
1356
1357static int rtnl_xdp_fill(struct sk_buff *skb, struct net_device *dev)
1358{
1359 struct nlattr *xdp;
1360 u32 prog_id;
1361 int err;
1362

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

1548#endif
1549 nla_put_iflink(skb, dev) ||
1550 put_master_ifindex(skb, dev) ||
1551 nla_put_u8(skb, IFLA_CARRIER, netif_carrier_ok(dev)) ||
1552 (dev->qdisc &&
1553 nla_put_string(skb, IFLA_QDISC, dev->qdisc->ops->id)) ||
1554 nla_put_ifalias(skb, dev) ||
1555 nla_put_u32(skb, IFLA_CARRIER_CHANGES,
1478 atomic_read(&dev->carrier_changes)) ||
1479 nla_put_u8(skb, IFLA_PROTO_DOWN, dev->proto_down))
1556 atomic_read(&dev->carrier_up_count) +
1557 atomic_read(&dev->carrier_down_count)) ||
1558 nla_put_u8(skb, IFLA_PROTO_DOWN, dev->proto_down) ||
1559 nla_put_u32(skb, IFLA_CARRIER_UP_COUNT,
1560 atomic_read(&dev->carrier_up_count)) ||
1561 nla_put_u32(skb, IFLA_CARRIER_DOWN_COUNT,
1562 atomic_read(&dev->carrier_down_count)))
1480 goto nla_put_failure;
1481
1482 if (event != IFLA_EVENT_NONE) {
1483 if (nla_put_u32(skb, IFLA_EVENT, event))
1484 goto nla_put_failure;
1485 }
1486
1487 if (rtnl_fill_link_ifmap(skb, dev))

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

1564 [IFLA_VFINFO_LIST] = {. type = NLA_NESTED },
1565 [IFLA_VF_PORTS] = { .type = NLA_NESTED },
1566 [IFLA_PORT_SELF] = { .type = NLA_NESTED },
1567 [IFLA_AF_SPEC] = { .type = NLA_NESTED },
1568 [IFLA_EXT_MASK] = { .type = NLA_U32 },
1569 [IFLA_PROMISCUITY] = { .type = NLA_U32 },
1570 [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 },
1571 [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
1563 goto nla_put_failure;
1564
1565 if (event != IFLA_EVENT_NONE) {
1566 if (nla_put_u32(skb, IFLA_EVENT, event))
1567 goto nla_put_failure;
1568 }
1569
1570 if (rtnl_fill_link_ifmap(skb, dev))

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

1647 [IFLA_VFINFO_LIST] = {. type = NLA_NESTED },
1648 [IFLA_VF_PORTS] = { .type = NLA_NESTED },
1649 [IFLA_PORT_SELF] = { .type = NLA_NESTED },
1650 [IFLA_AF_SPEC] = { .type = NLA_NESTED },
1651 [IFLA_EXT_MASK] = { .type = NLA_U32 },
1652 [IFLA_PROMISCUITY] = { .type = NLA_U32 },
1653 [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 },
1654 [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
1655 [IFLA_GSO_MAX_SEGS] = { .type = NLA_U32 },
1656 [IFLA_GSO_MAX_SIZE] = { .type = NLA_U32 },
1572 [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
1573 [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, /* ignored */
1574 [IFLA_PHYS_SWITCH_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
1575 [IFLA_LINK_NETNSID] = { .type = NLA_S32 },
1576 [IFLA_PROTO_DOWN] = { .type = NLA_U8 },
1577 [IFLA_XDP] = { .type = NLA_NESTED },
1578 [IFLA_EVENT] = { .type = NLA_U32 },
1579 [IFLA_GROUP] = { .type = NLA_U32 },
1580 [IFLA_IF_NETNSID] = { .type = NLA_S32 },
1657 [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
1658 [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, /* ignored */
1659 [IFLA_PHYS_SWITCH_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
1660 [IFLA_LINK_NETNSID] = { .type = NLA_S32 },
1661 [IFLA_PROTO_DOWN] = { .type = NLA_U8 },
1662 [IFLA_XDP] = { .type = NLA_NESTED },
1663 [IFLA_EVENT] = { .type = NLA_U32 },
1664 [IFLA_GROUP] = { .type = NLA_U32 },
1665 [IFLA_IF_NETNSID] = { .type = NLA_S32 },
1666 [IFLA_CARRIER_UP_COUNT] = { .type = NLA_U32 },
1667 [IFLA_CARRIER_DOWN_COUNT] = { .type = NLA_U32 },
1581};
1582
1583static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
1584 [IFLA_INFO_KIND] = { .type = NLA_STRING },
1585 [IFLA_INFO_DATA] = { .type = NLA_NESTED },
1586 [IFLA_INFO_SLAVE_KIND] = { .type = NLA_STRING },
1587 [IFLA_INFO_SLAVE_DATA] = { .type = NLA_NESTED },
1588};

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

2214 if (err) {
2215 dev->tx_queue_len = orig_len;
2216 goto errout;
2217 }
2218 status |= DO_SETLINK_MODIFIED;
2219 }
2220 }
2221
1668};
1669
1670static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
1671 [IFLA_INFO_KIND] = { .type = NLA_STRING },
1672 [IFLA_INFO_DATA] = { .type = NLA_NESTED },
1673 [IFLA_INFO_SLAVE_KIND] = { .type = NLA_STRING },
1674 [IFLA_INFO_SLAVE_DATA] = { .type = NLA_NESTED },
1675};

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

2301 if (err) {
2302 dev->tx_queue_len = orig_len;
2303 goto errout;
2304 }
2305 status |= DO_SETLINK_MODIFIED;
2306 }
2307 }
2308
2309 if (tb[IFLA_GSO_MAX_SIZE]) {
2310 u32 max_size = nla_get_u32(tb[IFLA_GSO_MAX_SIZE]);
2311
2312 if (max_size > GSO_MAX_SIZE) {
2313 err = -EINVAL;
2314 goto errout;
2315 }
2316
2317 if (dev->gso_max_size ^ max_size) {
2318 netif_set_gso_max_size(dev, max_size);
2319 status |= DO_SETLINK_MODIFIED;
2320 }
2321 }
2322
2323 if (tb[IFLA_GSO_MAX_SEGS]) {
2324 u32 max_segs = nla_get_u32(tb[IFLA_GSO_MAX_SEGS]);
2325
2326 if (max_segs > GSO_MAX_SEGS) {
2327 err = -EINVAL;
2328 goto errout;
2329 }
2330
2331 if (dev->gso_max_segs ^ max_segs) {
2332 dev->gso_max_segs = max_segs;
2333 status |= DO_SETLINK_MODIFIED;
2334 }
2335 }
2336
2222 if (tb[IFLA_OPERSTATE])
2223 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
2224
2225 if (tb[IFLA_LINKMODE]) {
2226 unsigned char value = nla_get_u8(tb[IFLA_LINKMODE]);
2227
2228 write_lock_bh(&dev_base_lock);
2229 if (dev->link_mode ^ value)

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

2578 if (tb[IFLA_TXQLEN])
2579 dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
2580 if (tb[IFLA_OPERSTATE])
2581 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
2582 if (tb[IFLA_LINKMODE])
2583 dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
2584 if (tb[IFLA_GROUP])
2585 dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP]));
2337 if (tb[IFLA_OPERSTATE])
2338 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
2339
2340 if (tb[IFLA_LINKMODE]) {
2341 unsigned char value = nla_get_u8(tb[IFLA_LINKMODE]);
2342
2343 write_lock_bh(&dev_base_lock);
2344 if (dev->link_mode ^ value)

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

2693 if (tb[IFLA_TXQLEN])
2694 dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
2695 if (tb[IFLA_OPERSTATE])
2696 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
2697 if (tb[IFLA_LINKMODE])
2698 dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
2699 if (tb[IFLA_GROUP])
2700 dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP]));
2701 if (tb[IFLA_GSO_MAX_SIZE])
2702 netif_set_gso_max_size(dev, nla_get_u32(tb[IFLA_GSO_MAX_SIZE]));
2703 if (tb[IFLA_GSO_MAX_SEGS])
2704 dev->gso_max_segs = nla_get_u32(tb[IFLA_GSO_MAX_SEGS]);
2586
2587 return dev;
2588}
2589EXPORT_SYMBOL(rtnl_create_link);
2590
2591static int rtnl_group_changelink(const struct sk_buff *skb,
2592 struct net *net, int group,
2593 struct ifinfomsg *ifm,

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

2968{
2969 int idx;
2970 int s_idx = cb->family;
2971
2972 if (s_idx == 0)
2973 s_idx = 1;
2974
2975 for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) {
2705
2706 return dev;
2707}
2708EXPORT_SYMBOL(rtnl_create_link);
2709
2710static int rtnl_group_changelink(const struct sk_buff *skb,
2711 struct net *net, int group,
2712 struct ifinfomsg *ifm,

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

3087{
3088 int idx;
3089 int s_idx = cb->family;
3090
3091 if (s_idx == 0)
3092 s_idx = 1;
3093
3094 for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) {
3095 struct rtnl_link **tab;
2976 int type = cb->nlh->nlmsg_type-RTM_BASE;
3096 int type = cb->nlh->nlmsg_type-RTM_BASE;
2977 struct rtnl_link *handlers;
3097 struct rtnl_link *link;
2978 rtnl_dumpit_func dumpit;
2979
2980 if (idx < s_idx || idx == PF_PACKET)
2981 continue;
2982
3098 rtnl_dumpit_func dumpit;
3099
3100 if (idx < s_idx || idx == PF_PACKET)
3101 continue;
3102
2983 handlers = rtnl_dereference(rtnl_msg_handlers[idx]);
2984 if (!handlers)
3103 if (type < 0 || type >= RTM_NR_MSGTYPES)
2985 continue;
2986
3104 continue;
3105
2987 dumpit = READ_ONCE(handlers[type].dumpit);
3106 tab = rcu_dereference_rtnl(rtnl_msg_handlers[idx]);
3107 if (!tab)
3108 continue;
3109
3110 link = tab[type];
3111 if (!link)
3112 continue;
3113
3114 dumpit = link->dumpit;
2988 if (!dumpit)
2989 continue;
2990
2991 if (idx > s_idx) {
2992 memset(&cb->args[0], 0, sizeof(cb->args));
2993 cb->prev_seq = 0;
2994 cb->seq = 0;
2995 }

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

4309}
4310
4311/* Process one rtnetlink message. */
4312
4313static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
4314 struct netlink_ext_ack *extack)
4315{
4316 struct net *net = sock_net(skb->sk);
3115 if (!dumpit)
3116 continue;
3117
3118 if (idx > s_idx) {
3119 memset(&cb->args[0], 0, sizeof(cb->args));
3120 cb->prev_seq = 0;
3121 cb->seq = 0;
3122 }

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

4436}
4437
4438/* Process one rtnetlink message. */
4439
4440static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
4441 struct netlink_ext_ack *extack)
4442{
4443 struct net *net = sock_net(skb->sk);
4317 struct rtnl_link *handlers;
4444 struct rtnl_link *link;
4445 struct module *owner;
4318 int err = -EOPNOTSUPP;
4319 rtnl_doit_func doit;
4320 unsigned int flags;
4321 int kind;
4322 int family;
4323 int type;
4324
4325 type = nlh->nlmsg_type;

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

4333 return 0;
4334
4335 family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family;
4336 kind = type&3;
4337
4338 if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN))
4339 return -EPERM;
4340
4446 int err = -EOPNOTSUPP;
4447 rtnl_doit_func doit;
4448 unsigned int flags;
4449 int kind;
4450 int family;
4451 int type;
4452
4453 type = nlh->nlmsg_type;

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

4461 return 0;
4462
4463 family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family;
4464 kind = type&3;
4465
4466 if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN))
4467 return -EPERM;
4468
4341 if (family >= ARRAY_SIZE(rtnl_msg_handlers))
4342 family = PF_UNSPEC;
4343
4344 rcu_read_lock();
4469 rcu_read_lock();
4345 handlers = rcu_dereference(rtnl_msg_handlers[family]);
4346 if (!handlers) {
4347 family = PF_UNSPEC;
4348 handlers = rcu_dereference(rtnl_msg_handlers[family]);
4349 }
4350
4351 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
4352 struct sock *rtnl;
4353 rtnl_dumpit_func dumpit;
4354 u16 min_dump_alloc = 0;
4355
4470 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
4471 struct sock *rtnl;
4472 rtnl_dumpit_func dumpit;
4473 u16 min_dump_alloc = 0;
4474
4356 dumpit = READ_ONCE(handlers[type].dumpit);
4357 if (!dumpit) {
4475 link = rtnl_get_link(family, type);
4476 if (!link || !link->dumpit) {
4358 family = PF_UNSPEC;
4477 family = PF_UNSPEC;
4359 handlers = rcu_dereference(rtnl_msg_handlers[PF_UNSPEC]);
4360 if (!handlers)
4478 link = rtnl_get_link(family, type);
4479 if (!link || !link->dumpit)
4361 goto err_unlock;
4480 goto err_unlock;
4362
4363 dumpit = READ_ONCE(handlers[type].dumpit);
4364 if (!dumpit)
4365 goto err_unlock;
4366 }
4481 }
4482 owner = link->owner;
4483 dumpit = link->dumpit;
4367
4484
4368 refcount_inc(&rtnl_msg_handlers_ref[family]);
4369
4370 if (type == RTM_GETLINK - RTM_BASE)
4371 min_dump_alloc = rtnl_calcit(skb, nlh);
4372
4485 if (type == RTM_GETLINK - RTM_BASE)
4486 min_dump_alloc = rtnl_calcit(skb, nlh);
4487
4488 err = 0;
4489 /* need to do this before rcu_read_unlock() */
4490 if (!try_module_get(owner))
4491 err = -EPROTONOSUPPORT;
4492
4373 rcu_read_unlock();
4374
4375 rtnl = net->rtnl;
4493 rcu_read_unlock();
4494
4495 rtnl = net->rtnl;
4376 {
4496 if (err == 0) {
4377 struct netlink_dump_control c = {
4378 .dump = dumpit,
4379 .min_dump_alloc = min_dump_alloc,
4497 struct netlink_dump_control c = {
4498 .dump = dumpit,
4499 .min_dump_alloc = min_dump_alloc,
4500 .module = owner,
4380 };
4381 err = netlink_dump_start(rtnl, skb, nlh, &c);
4501 };
4502 err = netlink_dump_start(rtnl, skb, nlh, &c);
4503 /* netlink_dump_start() will keep a reference on
4504 * module if dump is still in progress.
4505 */
4506 module_put(owner);
4382 }
4507 }
4383 refcount_dec(&rtnl_msg_handlers_ref[family]);
4384 return err;
4385 }
4386
4508 return err;
4509 }
4510
4387 doit = READ_ONCE(handlers[type].doit);
4388 if (!doit) {
4511 link = rtnl_get_link(family, type);
4512 if (!link || !link->doit) {
4389 family = PF_UNSPEC;
4513 family = PF_UNSPEC;
4390 handlers = rcu_dereference(rtnl_msg_handlers[family]);
4514 link = rtnl_get_link(PF_UNSPEC, type);
4515 if (!link || !link->doit)
4516 goto out_unlock;
4391 }
4392
4517 }
4518
4393 flags = READ_ONCE(handlers[type].flags);
4519 owner = link->owner;
4520 if (!try_module_get(owner)) {
4521 err = -EPROTONOSUPPORT;
4522 goto out_unlock;
4523 }
4524
4525 flags = link->flags;
4394 if (flags & RTNL_FLAG_DOIT_UNLOCKED) {
4526 if (flags & RTNL_FLAG_DOIT_UNLOCKED) {
4395 refcount_inc(&rtnl_msg_handlers_ref[family]);
4396 doit = READ_ONCE(handlers[type].doit);
4527 doit = link->doit;
4397 rcu_read_unlock();
4398 if (doit)
4399 err = doit(skb, nlh, extack);
4528 rcu_read_unlock();
4529 if (doit)
4530 err = doit(skb, nlh, extack);
4400 refcount_dec(&rtnl_msg_handlers_ref[family]);
4531 module_put(owner);
4401 return err;
4402 }
4532 return err;
4533 }
4403
4404 rcu_read_unlock();
4405
4406 rtnl_lock();
4534 rcu_read_unlock();
4535
4536 rtnl_lock();
4407 handlers = rtnl_dereference(rtnl_msg_handlers[family]);
4408 if (handlers) {
4409 doit = READ_ONCE(handlers[type].doit);
4410 if (doit)
4411 err = doit(skb, nlh, extack);
4412 }
4537 link = rtnl_get_link(family, type);
4538 if (link && link->doit)
4539 err = link->doit(skb, nlh, extack);
4413 rtnl_unlock();
4540 rtnl_unlock();
4541
4542 module_put(owner);
4543
4414 return err;
4415
4544 return err;
4545
4546out_unlock:
4547 rcu_read_unlock();
4548 return err;
4549
4416err_unlock:
4417 rcu_read_unlock();
4418 return -EOPNOTSUPP;
4419}
4420
4421static void rtnetlink_rcv(struct sk_buff *skb)
4422{
4423 netlink_rcv_skb(skb, &rtnetlink_rcv_msg);

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

4493
4494static struct pernet_operations rtnetlink_net_ops = {
4495 .init = rtnetlink_net_init,
4496 .exit = rtnetlink_net_exit,
4497};
4498
4499void __init rtnetlink_init(void)
4500{
4550err_unlock:
4551 rcu_read_unlock();
4552 return -EOPNOTSUPP;
4553}
4554
4555static void rtnetlink_rcv(struct sk_buff *skb)
4556{
4557 netlink_rcv_skb(skb, &rtnetlink_rcv_msg);

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

4627
4628static struct pernet_operations rtnetlink_net_ops = {
4629 .init = rtnetlink_net_init,
4630 .exit = rtnetlink_net_exit,
4631};
4632
4633void __init rtnetlink_init(void)
4634{
4501 int i;
4502
4503 for (i = 0; i < ARRAY_SIZE(rtnl_msg_handlers_ref); i++)
4504 refcount_set(&rtnl_msg_handlers_ref[i], 1);
4505
4506 if (register_pernet_subsys(&rtnetlink_net_ops))
4507 panic("rtnetlink_init: cannot initialize rtnetlink\n");
4508
4509 register_netdevice_notifier(&rtnetlink_dev_notifier);
4510
4511 rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink,
4512 rtnl_dump_ifinfo, 0);
4513 rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL, 0);

--- 18 unchanged lines hidden ---
4635 if (register_pernet_subsys(&rtnetlink_net_ops))
4636 panic("rtnetlink_init: cannot initialize rtnetlink\n");
4637
4638 register_netdevice_notifier(&rtnetlink_dev_notifier);
4639
4640 rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink,
4641 rtnl_dump_ifinfo, 0);
4642 rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL, 0);

--- 18 unchanged lines hidden ---