libnl: /data/src/libnl3/lib/route/link.c Source File

libnl 3.10.0

link.c
1/* SPDX-License-Identifier: LGPL-2.1-only */
2/*
3 * Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
4 */
5
6/**
7 * @ingroup rtnl
8 * @defgroup link Links (Interfaces)
9 *
10 * @details
11 * @route_doc{route_link, Link Documentation}
12 * @{
13 */
14
15#include "nl-default.h"
16
17#include <linux/if_arp.h>
18
19#include <netlink/netlink.h>
20#include <netlink/attr.h>
21#include <netlink/utils.h>
22#include <netlink/object.h>
23#include <netlink/hashtable.h>
24#include <netlink/data.h>
25#include <netlink/route/rtnl.h>
26#include <netlink/route/link.h>
27
28#include "nl-aux-route/nl-route.h"
29#include "nl-priv-dynamic-core/nl-core.h"
30#include "nl-priv-dynamic-core/cache-api.h"
31#include "nl-route.h"
32#include "link-sriov.h"
33#include "link/link-api.h"
34
35/** @cond SKIP */
36#define LINK_ATTR_MTU (1 << 0)
37#define LINK_ATTR_LINK (1 << 1)
38#define LINK_ATTR_TXQLEN (1 << 2)
39#define LINK_ATTR_WEIGHT (1 << 3)
40#define LINK_ATTR_MASTER (1 << 4)
41#define LINK_ATTR_QDISC (1 << 5)
42#define LINK_ATTR_MAP (1 << 6)
43#define LINK_ATTR_ADDR (1 << 7)
44#define LINK_ATTR_BRD (1 << 8)
45#define LINK_ATTR_FLAGS (1 << 9)
46#define LINK_ATTR_IFNAME (1 << 10)
47#define LINK_ATTR_IFINDEX (1 << 11)
48#define LINK_ATTR_FAMILY (1 << 12)
49#define LINK_ATTR_ARPTYPE (1 << 13)
50#define LINK_ATTR_STATS (1 << 14)
51#define LINK_ATTR_CHANGE (1 << 15)
52#define LINK_ATTR_OPERSTATE (1 << 16)
53#define LINK_ATTR_LINKMODE (1 << 17)
54#define LINK_ATTR_LINKINFO (1 << 18)
55#define LINK_ATTR_IFALIAS (1 << 19)
56#define LINK_ATTR_NUM_VF (1 << 20)
57#define LINK_ATTR_PROMISCUITY (1 << 21)
58#define LINK_ATTR_NUM_TX_QUEUES (1 << 22)
59#define LINK_ATTR_NUM_RX_QUEUES (1 << 23)
60#define LINK_ATTR_GROUP (1 << 24)
61#define LINK_ATTR_CARRIER (1 << 25)
62#define LINK_ATTR_PROTINFO (1 << 26)
63#define LINK_ATTR_AF_SPEC (1 << 27)
64#define LINK_ATTR_PHYS_PORT_ID (1 << 28)
65#define LINK_ATTR_NS_FD (1 << 29)
66#define LINK_ATTR_NS_PID (1 << 30)
67/* 31 used by 32-bit api */
68#define LINK_ATTR_LINK_NETNSID ((uint64_t) 1 << 32)
69#define LINK_ATTR_VF_LIST ((uint64_t) 1 << 33)
70#define LINK_ATTR_CARRIER_CHANGES ((uint64_t) 1 << 34)
71#define LINK_ATTR_PHYS_PORT_NAME ((uint64_t) 1 << 35)
72#define LINK_ATTR_PHYS_SWITCH_ID ((uint64_t) 1 << 36)
73#define LINK_ATTR_GSO_MAX_SEGS ((uint64_t) 1 << 37)
74#define LINK_ATTR_GSO_MAX_SIZE ((uint64_t) 1 << 38)
75#define LINK_ATTR_LINKINFO_SLAVE_KIND ((uint64_t) 1 << 39)
76
77static struct nl_cache_ops rtnl_link_ops;
78static struct nl_object_ops link_obj_ops;
79/** @endcond */
80
81struct rtnl_link *link_lookup(struct nl_cache *cache, int ifindex)
82{
83 if (!cache) {
84 cache = __nl_cache_mngt_require("route/link");
85 if (!cache)
86 return NULL;
87 }
88
89 return rtnl_link_get(cache, ifindex);
90}
91
92static struct rtnl_link_af_ops *af_lookup_and_alloc(struct rtnl_link *link,
93 int family)
94{
95 struct rtnl_link_af_ops *af_ops;
96
97 af_ops = rtnl_link_af_ops_lookup(family);
98 if (!af_ops)
99 return NULL;
100
101 if (!rtnl_link_af_alloc(link, af_ops)) {
102 rtnl_link_af_ops_put(af_ops);
103 return NULL;
104 }
105
106 return af_ops;
107}
108
109static int af_free(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
110 void *data, void *arg)
111{
112 if (ops->ao_free)
113 ops->ao_free(link, data);
114
115 rtnl_link_af_ops_put(ops);
116
117 return 0;
118}
119
120static int af_request_type(int af_type, struct rtnl_link *changes)
121{
122 struct rtnl_link_af_ops *ops;
123
124 ops = rtnl_link_af_ops_lookup(af_type);
125 if (ops && ops->ao_override_rtm && ops->ao_override_rtm(changes))
126 return RTM_SETLINK;
127
128 return RTM_NEWLINK;
129}
130
131static int af_clone(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
132 void *data, void *arg)
133{
134 struct rtnl_link *dst = arg;
135
136 if (ops->ao_clone &&
137 !(dst->l_af_data[ops->ao_family] = ops->ao_clone(dst, data)))
138 return -NLE_NOMEM;
139
140 return 0;
141}
142
143static int af_fill(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
144 void *data, void *arg)
145{
146 struct nl_msg *msg = arg;
147 struct nlattr *af_attr = NULL;
148 int err;
149
150 if (!ops->ao_fill_af)
151 return 0;
152
153 if (!ops->ao_fill_af_no_nest)
154 if (!(af_attr = nla_nest_start(msg, ops->ao_family)))
155 return -NLE_MSGSIZE;
156
157 if ((err = ops->ao_fill_af(link, arg, data)) < 0)
158 return err;
159
160 if (!ops->ao_fill_af_no_nest)
161 nla_nest_end(msg, af_attr);
162
163 return 0;
164}
165
166static int af_fill_pi(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
167 void *data, void *arg)
168{
169 struct nl_msg *msg = arg;
170 struct nlattr *pi_attr;
171 int err, pi_type = IFLA_PROTINFO;
172
173 if (!ops->ao_fill_pi)
174 return 0;
175
176 if (ops->ao_fill_pi_flags > 0)
177 pi_type |= ops->ao_fill_pi_flags;
178
179 if (!(pi_attr = nla_nest_start(msg, pi_type)))
180 return -NLE_MSGSIZE;
181
182 if ((err = ops->ao_fill_pi(link, arg, data)) < 0)
183 return err;
184
185 nla_nest_end(msg, pi_attr);
186
187 return 0;
188}
189
190static int af_dump_line(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
191 void *data, void *arg)
192{
193 struct nl_dump_params *p = arg;
194
195 if (ops->ao_dump[NL_DUMP_LINE])
196 ops->ao_dump[NL_DUMP_LINE](link, p, data);
197
198 return 0;
199}
200
201static int af_dump_details(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
202 void *data, void *arg)
203{
204 struct nl_dump_params *p = arg;
205
206 if (ops->ao_dump[NL_DUMP_DETAILS])
207 ops->ao_dump[NL_DUMP_DETAILS](link, p, data);
208
209 return 0;
210}
211
212static int af_dump_stats(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
213 void *data, void *arg)
214{
215 struct nl_dump_params *p = arg;
216
217 if (ops->ao_dump[NL_DUMP_STATS])
218 ops->ao_dump[NL_DUMP_STATS](link, p, data);
219
220 return 0;
221}
222
223static int do_foreach_af(struct rtnl_link *link,
224 int (*cb)(struct rtnl_link *,
225 struct rtnl_link_af_ops *, void *, void *),
226 void *arg)
227{
228 int i, err;
229
230 for (i = 0; i < AF_MAX; i++) {
231 if (link->l_af_data[i]) {
232 _nl_auto_rtnl_link_af_ops struct rtnl_link_af_ops *ops = NULL;
233
234 if (!(ops = rtnl_link_af_ops_lookup(i)))
235 BUG();
236
237 err = cb(link, ops, link->l_af_data[i], arg);
238 if (err < 0)
239 return err;
240 }
241 }
242
243 return 0;
244}
245
246static void release_link_info(struct rtnl_link *link)
247{
248 struct rtnl_link_info_ops *io = link->l_info_ops;
249
250 if (io != NULL) {
251 if (io->io_free)
252 io->io_free(link);
253 else {
254 /* Catch missing io_free() implementations */
255 BUG_ON(link->l_info);
256 }
257 rtnl_link_info_ops_put(io);
258 link->l_info_ops = NULL;
259 }
260}
261
262static void link_free_data(struct nl_object *c)
263{
264 struct rtnl_link *link = nl_object_priv(c);
265
266 if (link) {
267 release_link_info(link);
268
269 /* proto info af reference */
270 rtnl_link_af_ops_put(link->l_af_ops);
271
272 nl_addr_put(link->l_addr);
273 nl_addr_put(link->l_bcast);
274
275 free(link->l_ifalias);
276 free(link->l_info_kind);
277 free(link->l_info_slave_kind);
278
279 do_foreach_af(link, af_free, NULL);
280
281 nl_data_free(link->l_phys_port_id);
282 nl_data_free(link->l_phys_switch_id);
283
284 if (link->ce_mask & LINK_ATTR_VF_LIST)
285 rtnl_link_sriov_free_data(link);
286 }
287}
288
289static int link_clone(struct nl_object *_dst, struct nl_object *_src)
290{
291 struct rtnl_link *dst = nl_object_priv(_dst);
292 struct rtnl_link *src = nl_object_priv(_src);
293 int err;
294
295 dst->l_addr = NULL;
296 dst->l_bcast = NULL;
297 dst->l_info_kind = NULL;
298 dst->l_info_slave_kind = NULL;
299 dst->l_info_ops = NULL;
300 memset(dst->l_af_data, 0, sizeof (dst->l_af_data));
301 dst->l_info = NULL;
302 dst->l_ifalias = NULL;
303 dst->l_af_ops = NULL;
304 dst->l_phys_port_id = NULL;
305 dst->l_phys_switch_id = NULL;
306 dst->l_vf_list = NULL;
307
308 if (src->l_addr)
309 if (!(dst->l_addr = nl_addr_clone(src->l_addr)))
310 return -NLE_NOMEM;
311
312 if (src->l_bcast)
313 if (!(dst->l_bcast = nl_addr_clone(src->l_bcast)))
314 return -NLE_NOMEM;
315
316 if (src->l_ifalias)
317 if (!(dst->l_ifalias = strdup(src->l_ifalias)))
318 return -NLE_NOMEM;
319
320 if (src->l_info_kind)
321 if (!(dst->l_info_kind = strdup(src->l_info_kind)))
322 return -NLE_NOMEM;
323
324 if (src->l_info_slave_kind)
325 if (!(dst->l_info_slave_kind = strdup(src->l_info_slave_kind)))
326 return -NLE_NOMEM;
327
328 if (src->l_info_ops) {
329
330 rtnl_link_info_ops_get(src->l_info_ops);
331 dst->l_info_ops = src->l_info_ops;
332
333 if (src->l_info_ops->io_clone) {
334 err = src->l_info_ops->io_clone(dst, src);
335 if (err < 0)
336 return err;
337 }
338 }
339
340 if ((err = do_foreach_af(src, af_clone, dst)) < 0)
341 return err;
342
343 if (src->l_af_ops)
344 dst->l_af_ops = af_lookup_and_alloc(dst, src->l_af_ops->ao_family);
345
346 if (src->l_phys_port_id)
347 if (!(dst->l_phys_port_id = nl_data_clone(src->l_phys_port_id)))
348 return -NLE_NOMEM;
349
350 if (src->l_phys_switch_id)
351 if (!(dst->l_phys_switch_id = nl_data_clone(src->l_phys_switch_id)))
352 return -NLE_NOMEM;
353
354 if (src->ce_mask & LINK_ATTR_VF_LIST)
355 if ((err = rtnl_link_sriov_clone(dst, src)) < 0)
356 return err;
357
358 return 0;
359}
360
361struct nla_policy rtln_link_policy[IFLA_MAX+1] = {
362 [IFLA_IFNAME] = { .type = NLA_STRING,
363 .maxlen = IFNAMSIZ },
364 [IFLA_MTU] = { .type = NLA_U32 },
365 [IFLA_TXQLEN] = { .type = NLA_U32 },
366 [IFLA_LINK] = { .type = NLA_U32 },
367 [IFLA_WEIGHT] = { .type = NLA_U32 },
368 [IFLA_MASTER] = { .type = NLA_U32 },
369 [IFLA_OPERSTATE] = { .type = NLA_U8 },
370 [IFLA_LINKMODE] = { .type = NLA_U8 },
371 [IFLA_LINKINFO] = { .type = NLA_NESTED },
372 [IFLA_QDISC] = { .type = NLA_STRING,
373 .maxlen = IFQDISCSIZ },
374 [IFLA_STATS] = { .minlen = _nl_offsetofend (struct rtnl_link_stats, tx_compressed) },
375 [IFLA_STATS64] = { .minlen = _nl_offsetofend (struct rtnl_link_stats64, tx_compressed) },
376 [IFLA_MAP] = { .minlen = sizeof(struct rtnl_link_ifmap) },
377 [IFLA_IFALIAS] = { .type = NLA_STRING, .maxlen = IFALIASZ },
378 [IFLA_NUM_VF] = { .type = NLA_U32 },
379 [IFLA_VFINFO_LIST] = { .type = NLA_NESTED },
380 [IFLA_AF_SPEC] = { .type = NLA_NESTED },
381 [IFLA_PROMISCUITY] = { .type = NLA_U32 },
382 [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 },
383 [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
384 [IFLA_GSO_MAX_SEGS] = { .type = NLA_U32 },
385 [IFLA_GSO_MAX_SIZE] = { .type = NLA_U32 },
386 [IFLA_GROUP] = { .type = NLA_U32 },
387 [IFLA_CARRIER] = { .type = NLA_U8 },
388 [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 },
389 [IFLA_PHYS_PORT_ID] = { .type = NLA_UNSPEC },
390 [IFLA_PHYS_PORT_NAME] = { .type = NLA_STRING, .maxlen = IFNAMSIZ },
391 [IFLA_PHYS_SWITCH_ID] = { .type = NLA_UNSPEC },
392 [IFLA_NET_NS_PID] = { .type = NLA_U32 },
393 [IFLA_NET_NS_FD] = { .type = NLA_U32 },
394};
395
396static struct nla_policy link_info_policy[IFLA_INFO_MAX+1] = {
397 [IFLA_INFO_KIND] = { .type = NLA_STRING },
398 [IFLA_INFO_DATA] = { .type = NLA_NESTED },
399 [IFLA_INFO_XSTATS] = { .type = NLA_NESTED },
400};
401
402int rtnl_link_info_parse(struct rtnl_link *link, struct nlattr **tb)
403{
404 if (tb[IFLA_IFNAME] == NULL)
405 return -NLE_MISSING_ATTR;
406
407 nla_strlcpy(link->l_name, tb[IFLA_IFNAME], IFNAMSIZ);
408 link->ce_mask |= LINK_ATTR_IFNAME;
409
410 if (tb[IFLA_STATS]) {
411 struct rtnl_link_stats *st = nla_data(tb[IFLA_STATS]);
412
413 link->l_stats[RTNL_LINK_RX_PACKETS] = st->rx_packets;
414 link->l_stats[RTNL_LINK_TX_PACKETS] = st->tx_packets;
415 link->l_stats[RTNL_LINK_RX_BYTES] = st->rx_bytes;
416 link->l_stats[RTNL_LINK_TX_BYTES] = st->tx_bytes;
417 link->l_stats[RTNL_LINK_RX_ERRORS] = st->rx_errors;
418 link->l_stats[RTNL_LINK_TX_ERRORS] = st->tx_errors;
419 link->l_stats[RTNL_LINK_RX_DROPPED] = st->rx_dropped;
420 link->l_stats[RTNL_LINK_TX_DROPPED] = st->tx_dropped;
421 link->l_stats[RTNL_LINK_MULTICAST] = st->multicast;
422 link->l_stats[RTNL_LINK_COLLISIONS] = st->collisions;
423
424 link->l_stats[RTNL_LINK_RX_LEN_ERR] = st->rx_length_errors;
425 link->l_stats[RTNL_LINK_RX_OVER_ERR] = st->rx_over_errors;
426 link->l_stats[RTNL_LINK_RX_CRC_ERR] = st->rx_crc_errors;
427 link->l_stats[RTNL_LINK_RX_FRAME_ERR] = st->rx_frame_errors;
428 link->l_stats[RTNL_LINK_RX_FIFO_ERR] = st->rx_fifo_errors;
429 link->l_stats[RTNL_LINK_RX_MISSED_ERR] = st->rx_missed_errors;
430
431 link->l_stats[RTNL_LINK_TX_ABORT_ERR] = st->tx_aborted_errors;
432 link->l_stats[RTNL_LINK_TX_CARRIER_ERR] = st->tx_carrier_errors;
433 link->l_stats[RTNL_LINK_TX_FIFO_ERR] = st->tx_fifo_errors;
434 link->l_stats[RTNL_LINK_TX_HBEAT_ERR] = st->tx_heartbeat_errors;
435 link->l_stats[RTNL_LINK_TX_WIN_ERR] = st->tx_window_errors;
436
437 link->l_stats[RTNL_LINK_RX_COMPRESSED] = st->rx_compressed;
438 link->l_stats[RTNL_LINK_TX_COMPRESSED] = st->tx_compressed;
439
440 /* beware: @st might not be the full struct, only fields up to
441 * tx_compressed are present. See _nl_offsetofend() above. */
442
443 if (_nla_len(tb[IFLA_STATS]) >= _nl_offsetofend (struct rtnl_link_stats, rx_nohandler))
444 link->l_stats[RTNL_LINK_RX_NOHANDLER] = st->rx_nohandler;
445 else
446 link->l_stats[RTNL_LINK_RX_NOHANDLER] = 0;
447
448 link->ce_mask |= LINK_ATTR_STATS;
449 }
450
451 if (tb[IFLA_STATS64]) {
452 /*
453 * This structure contains 64bit parameters, and per the
454 * documentation in lib/attr.c, must not be accessed
455 * directly (because of alignment to 4 instead of 8).
456 * Therefore, copy the data to the stack and access it from
457 * there, where it will be aligned to 8.
458 */
459 struct rtnl_link_stats64 st = { 0 };
460
461 nla_memcpy(&st, tb[IFLA_STATS64], sizeof (st));
462
463 link->l_stats[RTNL_LINK_RX_PACKETS] = st.rx_packets;
464 link->l_stats[RTNL_LINK_TX_PACKETS] = st.tx_packets;
465 link->l_stats[RTNL_LINK_RX_BYTES] = st.rx_bytes;
466 link->l_stats[RTNL_LINK_TX_BYTES] = st.tx_bytes;
467 link->l_stats[RTNL_LINK_RX_ERRORS] = st.rx_errors;
468 link->l_stats[RTNL_LINK_TX_ERRORS] = st.tx_errors;
469 link->l_stats[RTNL_LINK_RX_DROPPED] = st.rx_dropped;
470 link->l_stats[RTNL_LINK_TX_DROPPED] = st.tx_dropped;
471 link->l_stats[RTNL_LINK_MULTICAST] = st.multicast;
472 link->l_stats[RTNL_LINK_COLLISIONS] = st.collisions;
473
474 link->l_stats[RTNL_LINK_RX_LEN_ERR] = st.rx_length_errors;
475 link->l_stats[RTNL_LINK_RX_OVER_ERR] = st.rx_over_errors;
476 link->l_stats[RTNL_LINK_RX_CRC_ERR] = st.rx_crc_errors;
477 link->l_stats[RTNL_LINK_RX_FRAME_ERR] = st.rx_frame_errors;
478 link->l_stats[RTNL_LINK_RX_FIFO_ERR] = st.rx_fifo_errors;
479 link->l_stats[RTNL_LINK_RX_MISSED_ERR] = st.rx_missed_errors;
480
481 link->l_stats[RTNL_LINK_TX_ABORT_ERR] = st.tx_aborted_errors;
482 link->l_stats[RTNL_LINK_TX_CARRIER_ERR] = st.tx_carrier_errors;
483 link->l_stats[RTNL_LINK_TX_FIFO_ERR] = st.tx_fifo_errors;
484 link->l_stats[RTNL_LINK_TX_HBEAT_ERR] = st.tx_heartbeat_errors;
485 link->l_stats[RTNL_LINK_TX_WIN_ERR] = st.tx_window_errors;
486
487 link->l_stats[RTNL_LINK_RX_COMPRESSED] = st.rx_compressed;
488 link->l_stats[RTNL_LINK_TX_COMPRESSED] = st.tx_compressed;
489
490 /* beware: @st might not be the full struct, only fields up to
491 * tx_compressed are present. See _nl_offsetofend() above. */
492
493 link->l_stats[RTNL_LINK_RX_NOHANDLER] = st.rx_nohandler;
494
495 link->ce_mask |= LINK_ATTR_STATS;
496 }
497
498 if (tb[IFLA_TXQLEN]) {
499 link->l_txqlen = nla_get_u32(tb[IFLA_TXQLEN]);
500 link->ce_mask |= LINK_ATTR_TXQLEN;
501 }
502
503 if (tb[IFLA_MTU]) {
504 link->l_mtu = nla_get_u32(tb[IFLA_MTU]);
505 link->ce_mask |= LINK_ATTR_MTU;
506 }
507
508 if (tb[IFLA_ADDRESS]) {
509 link->l_addr = nl_addr_alloc_attr(tb[IFLA_ADDRESS], AF_UNSPEC);
510 if (link->l_addr == NULL)
511 return -NLE_NOMEM;
512 nl_addr_set_family(link->l_addr,
513 nl_addr_guess_family(link->l_addr));
514 link->ce_mask |= LINK_ATTR_ADDR;
515 }
516
517 if (tb[IFLA_BROADCAST]) {
518 link->l_bcast = nl_addr_alloc_attr(tb[IFLA_BROADCAST],
519 AF_UNSPEC);
520 if (link->l_bcast == NULL)
521 return -NLE_NOMEM;
522 nl_addr_set_family(link->l_bcast,
523 nl_addr_guess_family(link->l_bcast));
524 link->ce_mask |= LINK_ATTR_BRD;
525 }
526
527 if (tb[IFLA_LINK]) {
528 link->l_link = nla_get_u32(tb[IFLA_LINK]);
529 link->ce_mask |= LINK_ATTR_LINK;
530 }
531
532 if (tb[IFLA_LINK_NETNSID]) {
533 link->l_link_netnsid = nla_get_s32(tb[IFLA_LINK_NETNSID]);
534 link->ce_mask |= LINK_ATTR_LINK_NETNSID;
535 }
536
537 if (tb[IFLA_WEIGHT]) {
538 link->l_weight = nla_get_u32(tb[IFLA_WEIGHT]);
539 link->ce_mask |= LINK_ATTR_WEIGHT;
540 }
541
542 if (tb[IFLA_QDISC]) {
543 nla_strlcpy(link->l_qdisc, tb[IFLA_QDISC], IFQDISCSIZ);
544 link->ce_mask |= LINK_ATTR_QDISC;
545 }
546
547 if (tb[IFLA_MAP]) {
548 nla_memcpy(&link->l_map, tb[IFLA_MAP],
549 sizeof(struct rtnl_link_ifmap));
550 link->ce_mask |= LINK_ATTR_MAP;
551 }
552
553 if (tb[IFLA_MASTER]) {
554 link->l_master = nla_get_u32(tb[IFLA_MASTER]);
555 link->ce_mask |= LINK_ATTR_MASTER;
556 }
557
558 if (tb[IFLA_CARRIER]) {
559 link->l_carrier = nla_get_u8(tb[IFLA_CARRIER]);
560 link->ce_mask |= LINK_ATTR_CARRIER;
561 }
562
563 if (tb[IFLA_CARRIER_CHANGES]) {
564 link->l_carrier_changes = nla_get_u32(tb[IFLA_CARRIER_CHANGES]);
565 link->ce_mask |= LINK_ATTR_CARRIER_CHANGES;
566 }
567
568 if (tb[IFLA_OPERSTATE]) {
569 link->l_operstate = nla_get_u8(tb[IFLA_OPERSTATE]);
570 link->ce_mask |= LINK_ATTR_OPERSTATE;
571 }
572
573 if (tb[IFLA_LINKMODE]) {
574 link->l_linkmode = nla_get_u8(tb[IFLA_LINKMODE]);
575 link->ce_mask |= LINK_ATTR_LINKMODE;
576 }
577
578 if (tb[IFLA_IFALIAS]) {
579 link->l_ifalias = nla_strdup(tb[IFLA_IFALIAS]);
580 if (link->l_ifalias == NULL)
581 return -NLE_NOMEM;
582 link->ce_mask |= LINK_ATTR_IFALIAS;
583 }
584
585 if (tb[IFLA_NET_NS_FD]) {
586 link->l_ns_fd = nla_get_u32(tb[IFLA_NET_NS_FD]);
587 link->ce_mask |= LINK_ATTR_NS_FD;
588 }
589
590 if (tb[IFLA_NET_NS_PID]) {
591 link->l_ns_pid = nla_get_u32(tb[IFLA_NET_NS_PID]);
592 link->ce_mask |= LINK_ATTR_NS_PID;
593 }
594
595 return 0;
596}
597
598static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
599 struct nlmsghdr *n, struct nl_parser_param *pp)
600{
601 _nl_auto_rtnl_link struct rtnl_link *link = NULL;
602 struct nla_policy real_link_policy[ARRAY_SIZE(rtln_link_policy)];
603 struct nla_policy *link_policy = rtln_link_policy;
604 struct rtnl_link_af_ops *af_ops_family;
605 struct ifinfomsg *ifi;
606 struct nlattr *tb[IFLA_MAX+1];
607 int err, family;
608
609 link = rtnl_link_alloc();
610 if (link == NULL)
611 return -NLE_NOMEM;
612
613 link->ce_msgtype = n->nlmsg_type;
614
615 if (!nlmsg_valid_hdr(n, sizeof(*ifi)))
616 return -NLE_MSG_TOOSHORT;
617
618 ifi = nlmsg_data(n);
619 link->l_family = family = ifi->ifi_family;
620 link->l_arptype = ifi->ifi_type;
621 link->l_index = ifi->ifi_index;
622 link->l_flags = ifi->ifi_flags;
623 link->l_change = ifi->ifi_change;
624 link->ce_mask = (LINK_ATTR_FAMILY |
625 LINK_ATTR_ARPTYPE| LINK_ATTR_IFINDEX |
626 LINK_ATTR_FLAGS | LINK_ATTR_CHANGE);
627
628 if ((link->l_af_ops = af_lookup_and_alloc(link, family))) {
629 if (link->l_af_ops->ao_protinfo_policy) {
630 _NL_STATIC_ASSERT (sizeof(rtln_link_policy) == sizeof(real_link_policy));
631 memcpy(&real_link_policy, rtln_link_policy, sizeof(rtln_link_policy));
632 memcpy(&real_link_policy[IFLA_PROTINFO],
633 link->l_af_ops->ao_protinfo_policy,
634 sizeof(struct nla_policy));
635 link_policy = real_link_policy;
636 }
637 }
638
639 af_ops_family = link->l_af_ops;
640
641 err = nlmsg_parse(n, sizeof(*ifi), tb, IFLA_MAX, link_policy);
642 if (err < 0)
643 return err;
644
645 err = rtnl_link_info_parse(link, tb);
646 if (err < 0)
647 return err;
648
649 if (tb[IFLA_NUM_VF]) {
650 link->l_num_vf = nla_get_u32(tb[IFLA_NUM_VF]);
651 link->ce_mask |= LINK_ATTR_NUM_VF;
652 if (link->l_num_vf && tb[IFLA_VFINFO_LIST]) {
653 if ((err = rtnl_link_sriov_parse_vflist(link, tb)) < 0)
654 return err;
655 link->ce_mask |= LINK_ATTR_VF_LIST;
656 }
657 }
658
659 if (tb[IFLA_LINKINFO]) {
660 struct nlattr *li[IFLA_INFO_MAX+1];
661
662 err = nla_parse_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO],
663 link_info_policy);
664 if (err < 0)
665 return err;
666
667 if (li[IFLA_INFO_KIND]) {
668 struct rtnl_link_info_ops *ops;
669 const char *kind = nla_get_string(li[IFLA_INFO_KIND]);
670 int af;
671
672 err = rtnl_link_set_type(link, kind);
673 if (err < 0)
674 return err;
675
676 if ( (af = nl_str2af(kind)) >= 0
677 && !link->l_af_ops
678 && (link->l_af_ops = af_lookup_and_alloc(link, af))) {
679 link->l_family = af;
680 if (link->l_af_ops->ao_protinfo_policy)
681 tb[IFLA_PROTINFO] = (struct nlattr *)link->l_af_ops->ao_protinfo_policy;
682 }
683
684 if (link->l_info_ops)
685 release_link_info(link);
686
687 ops = rtnl_link_info_ops_lookup(kind);
688 link->l_info_ops = ops;
689
690 if (ops) {
691 if (ops->io_parse &&
692 (li[IFLA_INFO_DATA] || li[IFLA_INFO_XSTATS])) {
693 err = ops->io_parse(link, li[IFLA_INFO_DATA],
694 li[IFLA_INFO_XSTATS]);
695 if (err < 0)
696 return err;
697 } else {
698 /* XXX: Warn about unparsed info? */
699 }
700 }
701
702 link->ce_mask |= LINK_ATTR_LINKINFO;
703 }
704
705 if (li[IFLA_INFO_SLAVE_KIND]) {
706 const char *kind = nla_get_string(li[IFLA_INFO_SLAVE_KIND]);
707
708 err = rtnl_link_set_slave_type(link, kind);
709 if (err < 0)
710 return err;
711
712 link->ce_mask |= LINK_ATTR_LINKINFO_SLAVE_KIND;
713 }
714 }
715
716 if ( tb[IFLA_PROTINFO]
717 && link->l_af_ops
718 && link->l_af_ops->ao_parse_protinfo) {
719 err = link->l_af_ops->ao_parse_protinfo(link, tb[IFLA_PROTINFO],
720 link->l_af_data[link->l_family]);
721 if (err < 0)
722 return err;
723 link->ce_mask |= LINK_ATTR_PROTINFO;
724 }
725
726 if (tb[IFLA_AF_SPEC]) {
727 /* parsing of IFLA_AF_SPEC is dependent on the family used
728 * in the request message.
729 */
730 if ( af_ops_family
731 && af_ops_family->ao_parse_af_full) {
732 err = af_ops_family->ao_parse_af_full(link,
733 tb[IFLA_AF_SPEC],
734 link->l_af_data[af_ops_family->ao_family]);
735 if (err < 0)
736 return err;
737 link->ce_mask |= LINK_ATTR_AF_SPEC;
738 } else if (family == AF_UNSPEC) {
739 struct nlattr *af_attr;
740 int remaining;
741
742 nla_for_each_nested(af_attr, tb[IFLA_AF_SPEC], remaining) {
743 _nl_auto_rtnl_link_af_ops struct rtnl_link_af_ops *af_ops = NULL;
744
745 af_ops = af_lookup_and_alloc(link, nla_type(af_attr));
746 if (af_ops && af_ops->ao_parse_af) {
747 char *af_data = link->l_af_data[nla_type(af_attr)];
748
749 err = af_ops->ao_parse_af(link, af_attr, af_data);
750 if (err < 0)
751 return err;
752 }
753 }
754 link->ce_mask |= LINK_ATTR_AF_SPEC;
755 } else {
756 NL_DBG(3, "IFLA_AF_SPEC parsing not implemented for family %d\n",
757 family);
758 }
759 }
760
761 if (tb[IFLA_PROMISCUITY]) {
762 link->l_promiscuity = nla_get_u32(tb[IFLA_PROMISCUITY]);
763 link->ce_mask |= LINK_ATTR_PROMISCUITY;
764 }
765
766 if (tb[IFLA_NUM_TX_QUEUES]) {
767 link->l_num_tx_queues = nla_get_u32(tb[IFLA_NUM_TX_QUEUES]);
768 link->ce_mask |= LINK_ATTR_NUM_TX_QUEUES;
769 }
770
771 if (tb[IFLA_NUM_RX_QUEUES]) {
772 link->l_num_rx_queues = nla_get_u32(tb[IFLA_NUM_RX_QUEUES]);
773 link->ce_mask |= LINK_ATTR_NUM_RX_QUEUES;
774 }
775
776 if (tb[IFLA_GSO_MAX_SEGS]) {
777 link->l_gso_max_segs = nla_get_u32(tb[IFLA_GSO_MAX_SEGS]);
778 link->ce_mask |= LINK_ATTR_GSO_MAX_SEGS;
779 }
780
781 if (tb[IFLA_GSO_MAX_SIZE]) {
782 link->l_gso_max_size = nla_get_u32(tb[IFLA_GSO_MAX_SIZE]);
783 link->ce_mask |= LINK_ATTR_GSO_MAX_SIZE;
784 }
785
786 if (tb[IFLA_GROUP]) {
787 link->l_group = nla_get_u32(tb[IFLA_GROUP]);
788 link->ce_mask |= LINK_ATTR_GROUP;
789 }
790
791 if (tb[IFLA_PHYS_PORT_ID]) {
792 link->l_phys_port_id = nl_data_alloc_attr(tb[IFLA_PHYS_PORT_ID]);
793 if (link->l_phys_port_id == NULL)
794 return -NLE_NOMEM;
795 link->ce_mask |= LINK_ATTR_PHYS_PORT_ID;
796 }
797
798 if (tb[IFLA_PHYS_PORT_NAME]) {
799 nla_strlcpy(link->l_phys_port_name, tb[IFLA_PHYS_PORT_NAME], IFNAMSIZ);
800 link->ce_mask |= LINK_ATTR_PHYS_PORT_NAME;
801 }
802
803 if (tb[IFLA_PHYS_SWITCH_ID]) {
804 link->l_phys_switch_id = nl_data_alloc_attr(tb[IFLA_PHYS_SWITCH_ID]);
805 if (link->l_phys_switch_id == NULL)
806 return -NLE_NOMEM;
807 link->ce_mask |= LINK_ATTR_PHYS_SWITCH_ID;
808 }
809
810 return pp->pp_cb((struct nl_object *) link, pp);
811}
812
813static int link_request_update(struct nl_cache *cache, struct nl_sock *sk)
814{
815 _nl_auto_nl_msg struct nl_msg *msg = NULL;
816 int family = cache->c_iarg1;
817 struct ifinfomsg hdr = { .ifi_family = family };
818 struct rtnl_link_af_ops *ops;
819 int err;
820 __u32 ext_filter_mask = RTEXT_FILTER_VF;
821
822 msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_DUMP);
823 if (!msg)
824 return -NLE_NOMEM;
825
826 if (nlmsg_append(msg, &hdr, sizeof(hdr), NLMSG_ALIGNTO) < 0)
827 return -NLE_MSGSIZE;
828
829 ops = rtnl_link_af_ops_lookup(family);
830 if (ops && ops->ao_get_af) {
831 err = ops->ao_get_af(msg, &ext_filter_mask);
832 if (err < 0)
833 return err;
834 }
835
836 if (ext_filter_mask) {
837 err = nla_put(msg, IFLA_EXT_MASK, sizeof(ext_filter_mask), &ext_filter_mask);
838 if (err < 0)
839 return err;
840 }
841
842 err = nl_send_auto(sk, msg);
843 if (err < 0)
844 return 0;
845
846 return 0;
847}
848
849static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p)
850{
851 char buf[128];
852 struct nl_cache *cache = obj->ce_cache;
853 struct rtnl_link *link = (struct rtnl_link *) obj;
854 int fetched_cache = 0;
855
856 if (!cache) {
857 cache = nl_cache_mngt_require_safe("route/link");
858 fetched_cache = 1;
859 }
860
861 if (link->l_family != AF_UNSPEC)
862 nl_dump_line(p, "%s ", nl_af2str(link->l_family, buf, sizeof(buf)));
863
864 nl_dump_line(p, "%s %s ", link->l_name,
865 nl_llproto2str(link->l_arptype, buf, sizeof(buf)));
866
867 if (link->l_addr && !nl_addr_iszero(link->l_addr))
868 nl_dump(p, "%s ", nl_addr2str(link->l_addr, buf, sizeof(buf)));
869
870 if (link->ce_mask & LINK_ATTR_MASTER) {
871 if (cache) {
872 _nl_auto_rtnl_link struct rtnl_link *master = rtnl_link_get(cache, link->l_master);
873
874 nl_dump(p, "master %s ", master ? master->l_name : "inv");
875 } else
876 nl_dump(p, "master %d ", link->l_master);
877 }
878
879 rtnl_link_flags2str(link->l_flags, buf, sizeof(buf));
880 if (buf[0])
881 nl_dump(p, "<%s> ", buf);
882
883 if (link->ce_mask & LINK_ATTR_LINK) {
884 if ( cache
885 && !(link->ce_mask & LINK_ATTR_LINK_NETNSID)) {
886 _nl_auto_rtnl_link struct rtnl_link *ll = rtnl_link_get(cache, link->l_link);
887
888 nl_dump(p, "slave-of %s ", ll ? ll->l_name : "NONE");
889 } else
890 nl_dump(p, "slave-of %d ", link->l_link);
891 }
892 if (link->ce_mask & LINK_ATTR_LINK_NETNSID)
893 nl_dump(p, "link-netnsid %d ", link->l_link_netnsid);
894
895 if (link->ce_mask & LINK_ATTR_GROUP)
896 nl_dump(p, "group %u ", link->l_group);
897
898 if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_LINE])
899 link->l_info_ops->io_dump[NL_DUMP_LINE](link, p);
900
901 do_foreach_af(link, af_dump_line, p);
902
903 nl_dump(p, "\n");
904
905 if (fetched_cache)
906 nl_cache_put(cache);
907}
908
909static void link_dump_details(struct nl_object *obj, struct nl_dump_params *p)
910{
911 struct rtnl_link *link = (struct rtnl_link *) obj;
912 char buf[64];
913
914 link_dump_line(obj, p);
915
916 nl_dump_line(p, " mtu %u ", link->l_mtu);
917 nl_dump(p, "txqlen %u weight %u ", link->l_txqlen, link->l_weight);
918
919 if (link->ce_mask & LINK_ATTR_QDISC)
920 nl_dump(p, "qdisc %s ", link->l_qdisc);
921
922 if (link->ce_mask & LINK_ATTR_MAP && link->l_map.lm_irq)
923 nl_dump(p, "irq %u ", link->l_map.lm_irq);
924
925 if (link->ce_mask & LINK_ATTR_IFINDEX)
926 nl_dump(p, "index %u ", link->l_index);
927
928 if (link->ce_mask & LINK_ATTR_PROMISCUITY && link->l_promiscuity > 0)
929 nl_dump(p, "promisc-mode (%u users) ", link->l_promiscuity);
930
931 nl_dump(p, "\n");
932
933 if (link->ce_mask & LINK_ATTR_IFALIAS)
934 nl_dump_line(p, " alias %s\n", link->l_ifalias);
935
936 nl_dump_line(p, " ");
937
938 if (link->ce_mask & LINK_ATTR_NUM_TX_QUEUES)
939 nl_dump(p, "txq %u ", link->l_num_tx_queues);
940
941 if (link->ce_mask & LINK_ATTR_NUM_RX_QUEUES)
942 nl_dump(p, "rxq %u ", link->l_num_rx_queues);
943
944 if (link->ce_mask & LINK_ATTR_BRD)
945 nl_dump(p, "brd %s ", nl_addr2str(link->l_bcast, buf,
946 sizeof(buf)));
947
948 if ((link->ce_mask & LINK_ATTR_OPERSTATE) &&
949 link->l_operstate != IF_OPER_UNKNOWN) {
950 rtnl_link_operstate2str(link->l_operstate, buf, sizeof(buf));
951 nl_dump(p, "state %s ", buf);
952 }
953
954 if (link->ce_mask & LINK_ATTR_NUM_VF)
955 nl_dump(p, "num-vf %u ", link->l_num_vf);
956
957 nl_dump(p, "mode %s ",
958 rtnl_link_mode2str(link->l_linkmode, buf, sizeof(buf)));
959
960 nl_dump(p, "carrier %s",
961 rtnl_link_carrier2str(link->l_carrier, buf, sizeof(buf)));
962
963 if (link->ce_mask & LINK_ATTR_CARRIER_CHANGES)
964 nl_dump(p, " carrier-changes %u", link->l_carrier_changes);
965
966 nl_dump(p, "\n");
967
968 if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_DETAILS])
969 link->l_info_ops->io_dump[NL_DUMP_DETAILS](link, p);
970
971 do_foreach_af(link, af_dump_details, p);
972
973 if (link->ce_mask & LINK_ATTR_VF_LIST)
974 rtnl_link_sriov_dump_details(link, p);
975}
976
977static void link_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
978{
979 struct rtnl_link *link = (struct rtnl_link *) obj;
980 char *unit, fmt[64];
981 float res;
982
983 link_dump_details(obj, p);
984
985 nl_dump_line(p, " Stats: bytes packets errors "
986 " dropped fifo-err compressed\n");
987
988 res = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_RX_BYTES], &unit);
989
990 strcpy(fmt, " RX %X.2f %s %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 "\n");
991 fmt[9] = *unit == 'B' ? '9' : '7';
992
993 nl_dump_line(p, fmt, res, unit,
994 link->l_stats[RTNL_LINK_RX_PACKETS],
995 link->l_stats[RTNL_LINK_RX_ERRORS],
996 link->l_stats[RTNL_LINK_RX_DROPPED],
997 link->l_stats[RTNL_LINK_RX_FIFO_ERR],
998 link->l_stats[RTNL_LINK_RX_COMPRESSED]);
999
1000 res = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_TX_BYTES], &unit);
1001
1002 strcpy(fmt, " TX %X.2f %s %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 "\n");
1003 fmt[9] = *unit == 'B' ? '9' : '7';
1004
1005 nl_dump_line(p, fmt, res, unit,
1006 link->l_stats[RTNL_LINK_TX_PACKETS],
1007 link->l_stats[RTNL_LINK_TX_ERRORS],
1008 link->l_stats[RTNL_LINK_TX_DROPPED],
1009 link->l_stats[RTNL_LINK_TX_FIFO_ERR],
1010 link->l_stats[RTNL_LINK_TX_COMPRESSED]);
1011
1012 nl_dump_line(p, " Errors: length over crc "
1013 " frame missed multicast\n");
1014
1015 nl_dump_line(p, " RX %10" PRIu64 " %10" PRIu64 " %10"
1016 PRIu64 " %10" PRIu64 " %10" PRIu64 " %10"
1017 PRIu64 "\n",
1018 link->l_stats[RTNL_LINK_RX_LEN_ERR],
1019 link->l_stats[RTNL_LINK_RX_OVER_ERR],
1020 link->l_stats[RTNL_LINK_RX_CRC_ERR],
1021 link->l_stats[RTNL_LINK_RX_FRAME_ERR],
1022 link->l_stats[RTNL_LINK_RX_MISSED_ERR],
1023 link->l_stats[RTNL_LINK_MULTICAST]);
1024
1025 nl_dump_line(p, " aborted carrier heartbeat "
1026 " window collision\n");
1027
1028 nl_dump_line(p, " TX %10" PRIu64 " %10" PRIu64 " %10"
1029 PRIu64 " %10" PRIu64 " %10" PRIu64 "\n",
1030 link->l_stats[RTNL_LINK_TX_ABORT_ERR],
1031 link->l_stats[RTNL_LINK_TX_CARRIER_ERR],
1032 link->l_stats[RTNL_LINK_TX_HBEAT_ERR],
1033 link->l_stats[RTNL_LINK_TX_WIN_ERR],
1034 link->l_stats[RTNL_LINK_COLLISIONS]);
1035
1036 if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_STATS])
1037 link->l_info_ops->io_dump[NL_DUMP_STATS](link, p);
1038
1039 do_foreach_af(link, af_dump_stats, p);
1040
1041 if (link->ce_mask & LINK_ATTR_VF_LIST)
1042 rtnl_link_sriov_dump_stats(link, p);
1043}
1044
1045#if 0
1046static int link_handle_event(struct nl_object *a, struct rtnl_link_event_cb *cb)
1047{
1048 struct rtnl_link *l = (struct rtnl_link *) a;
1049 struct nl_cache *c = dp_cache(a);
1050 int nevents = 0;
1051
1052 if (l->l_change == ~0U) {
1053 if (l->ce_msgtype == RTM_NEWLINK)
1054 cb->le_register(l);
1055 else
1056 cb->le_unregister(l);
1057
1058 return 1;
1059 }
1060
1061 if (l->l_change & IFF_SLAVE) {
1062 if (l->l_flags & IFF_SLAVE) {
1063 struct rtnl_link *m = rtnl_link_get(c, l->l_master);
1064 cb->le_new_bonding(l, m);
1065 if (m)
1066 rtnl_link_put(m);
1067 } else
1068 cb->le_cancel_bonding(l);
1069 }
1070
1071#if 0
1072 if (l->l_change & IFF_UP && l->l_change & IFF_RUNNING)
1073 dp_dump_line(p, line++, "link %s changed state to %s.\n",
1074 l->l_name, l->l_flags & IFF_UP ? "up" : "down");
1075
1076 if (l->l_change & IFF_PROMISC) {
1077 dp_new_line(p, line++);
1078 dp_dump(p, "link %s %s promiscuous mode.\n",
1079 l->l_name, l->l_flags & IFF_PROMISC ? "entered" : "left");
1080 }
1081
1082 if (line == 0)
1083 dp_dump_line(p, line++, "link %s sent unknown event.\n",
1084 l->l_name);
1085#endif
1086
1087 return nevents;
1088}
1089#endif
1090
1091
1092static void link_keygen(struct nl_object *obj, uint32_t *hashkey,
1093 uint32_t table_sz)
1094{
1095 struct rtnl_link *link = (struct rtnl_link *) obj;
1096 unsigned int lkey_sz;
1097 struct link_hash_key {
1098 uint32_t l_index;
1099 uint32_t l_family;
1100 } _nl_packed lkey;
1101
1102 lkey_sz = sizeof(lkey);
1103 lkey.l_index = link->l_index;
1104 lkey.l_family = link->l_family;
1105
1106 *hashkey = nl_hash(&lkey, lkey_sz, 0) % table_sz;
1107
1108 NL_DBG(5, "link %p key (dev %d fam %d) keysz %d, hash 0x%x\n",
1109 link, lkey.l_index, lkey.l_family, lkey_sz, *hashkey);
1110
1111 return;
1112}
1113
1114static uint64_t link_compare(struct nl_object *_a, struct nl_object *_b,
1115 uint64_t attrs, int flags)
1116{
1117 struct rtnl_link *a = (struct rtnl_link *) _a;
1118 struct rtnl_link *b = (struct rtnl_link *) _b;
1119 uint64_t diff = 0;
1120
1121#define _DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ATTR, a, b, EXPR)
1122 diff |= _DIFF(LINK_ATTR_IFINDEX, a->l_index != b->l_index);
1123 diff |= _DIFF(LINK_ATTR_MTU, a->l_mtu != b->l_mtu);
1124 diff |= _DIFF(LINK_ATTR_LINK, a->l_link != b->l_link);
1125 diff |= _DIFF(LINK_ATTR_LINK_NETNSID,
1126 a->l_link_netnsid != b->l_link_netnsid);
1127 diff |= _DIFF(LINK_ATTR_TXQLEN, a->l_txqlen != b->l_txqlen);
1128 diff |= _DIFF(LINK_ATTR_WEIGHT, a->l_weight != b->l_weight);
1129 diff |= _DIFF(LINK_ATTR_MASTER, a->l_master != b->l_master);
1130 diff |= _DIFF(LINK_ATTR_FAMILY, a->l_family != b->l_family);
1131 diff |= _DIFF(LINK_ATTR_OPERSTATE, a->l_operstate != b->l_operstate);
1132 diff |= _DIFF(LINK_ATTR_LINKMODE, a->l_linkmode != b->l_linkmode);
1133 diff |= _DIFF(LINK_ATTR_QDISC, strcmp(a->l_qdisc, b->l_qdisc));
1134 diff |= _DIFF(LINK_ATTR_IFNAME, strcmp(a->l_name, b->l_name));
1135 diff |= _DIFF(LINK_ATTR_ADDR, nl_addr_cmp(a->l_addr, b->l_addr));
1136 diff |= _DIFF(LINK_ATTR_BRD, nl_addr_cmp(a->l_bcast, b->l_bcast));
1137 diff |= _DIFF(LINK_ATTR_IFALIAS, strcmp(a->l_ifalias, b->l_ifalias));
1138 diff |= _DIFF(LINK_ATTR_NUM_VF, a->l_num_vf != b->l_num_vf);
1139 diff |= _DIFF(LINK_ATTR_PROMISCUITY,
1140 a->l_promiscuity != b->l_promiscuity);
1141 diff |= _DIFF(LINK_ATTR_NUM_TX_QUEUES,
1142 a->l_num_tx_queues != b->l_num_tx_queues);
1143 diff |= _DIFF(LINK_ATTR_NUM_RX_QUEUES,
1144 a->l_num_rx_queues != b->l_num_rx_queues);
1145 diff |= _DIFF(LINK_ATTR_GROUP, a->l_group != b->l_group);
1146
1147 if (flags & LOOSE_COMPARISON)
1148 diff |= _DIFF(LINK_ATTR_FLAGS,
1149 (a->l_flags ^ b->l_flags) & b->l_flag_mask);
1150 else
1151 diff |= _DIFF(LINK_ATTR_FLAGS, a->l_flags != b->l_flags);
1152
1153 /*
1154 * Compare LINK_ATTR_PROTINFO af_data
1155 */
1156 if (a->l_family == b->l_family) {
1157 if (rtnl_link_af_data_compare(a, b, a->l_family) != 0)
1158 goto protinfo_mismatch;
1159 }
1160
1161 diff |= _DIFF(LINK_ATTR_LINKINFO, rtnl_link_info_data_compare(a, b, flags) != 0);
1162out:
1163 return diff;
1164
1165protinfo_mismatch:
1166 diff |= _DIFF(LINK_ATTR_PROTINFO, 1);
1167 goto out;
1168
1169#undef _DIFF
1170}
1171
1172static const struct trans_tbl link_attrs[] = {
1173 __ADD(LINK_ATTR_MTU, mtu),
1174 __ADD(LINK_ATTR_LINK, link),
1175 __ADD(LINK_ATTR_TXQLEN, txqlen),
1176 __ADD(LINK_ATTR_WEIGHT, weight),
1177 __ADD(LINK_ATTR_MASTER, master),
1178 __ADD(LINK_ATTR_QDISC, qdisc),
1179 __ADD(LINK_ATTR_MAP, map),
1180 __ADD(LINK_ATTR_ADDR, address),
1181 __ADD(LINK_ATTR_BRD, broadcast),
1182 __ADD(LINK_ATTR_FLAGS, flags),
1183 __ADD(LINK_ATTR_IFNAME, name),
1184 __ADD(LINK_ATTR_IFINDEX, ifindex),
1185 __ADD(LINK_ATTR_FAMILY, family),
1186 __ADD(LINK_ATTR_ARPTYPE, arptype),
1187 __ADD(LINK_ATTR_STATS, stats),
1188 __ADD(LINK_ATTR_CHANGE, change),
1189 __ADD(LINK_ATTR_OPERSTATE, operstate),
1190 __ADD(LINK_ATTR_LINKMODE, linkmode),
1191 __ADD(LINK_ATTR_IFALIAS, ifalias),
1192 __ADD(LINK_ATTR_NUM_VF, num_vf),
1193 __ADD(LINK_ATTR_PROMISCUITY, promiscuity),
1194 __ADD(LINK_ATTR_NUM_TX_QUEUES, num_tx_queues),
1195 __ADD(LINK_ATTR_NUM_RX_QUEUES, num_rx_queues),
1196 __ADD(LINK_ATTR_GSO_MAX_SEGS, gso_max_segs),
1197 __ADD(LINK_ATTR_GSO_MAX_SIZE, gso_max_size),
1198 __ADD(LINK_ATTR_GROUP, group),
1199 __ADD(LINK_ATTR_CARRIER, carrier),
1200 __ADD(LINK_ATTR_CARRIER_CHANGES, carrier_changes),
1201 __ADD(LINK_ATTR_PHYS_PORT_ID, phys_port_id),
1202 __ADD(LINK_ATTR_PHYS_PORT_NAME, phys_port_name),
1203 __ADD(LINK_ATTR_PHYS_SWITCH_ID, phys_switch_id),
1204 __ADD(LINK_ATTR_NS_FD, ns_fd),
1205 __ADD(LINK_ATTR_NS_PID, ns_pid),
1206 __ADD(LINK_ATTR_LINK_NETNSID, link_netnsid),
1207};
1208
1209static char *link_attrs2str(int attrs, char *buf, size_t len)
1210{
1211 return __flags2str(attrs, buf, len, link_attrs,
1212 ARRAY_SIZE(link_attrs));
1213}
1214
1215/**
1216 * @name Get / List
1217 * @{
1218 */
1219
1220
1221/**
1222 * Allocate link cache and fill in all configured links.
1223 * @arg sk Netlink socket.
1224 * @arg family Link address family or AF_UNSPEC
1225 * @arg result Pointer to store resulting cache.
1226 * @arg flags Flags to set in link cache before filling
1227 *
1228 * Allocates and initializes a new link cache. If \c sk is valid, a netlink
1229 * message is sent to the kernel requesting a full dump of all configured
1230 * links. The returned messages are parsed and filled into the cache. If
1231 * the operation succeeds, the resulting cache will contain a link object for
1232 * each link configured in the kernel. If \c sk is NULL, returns 0 but the
1233 * cache is still empty.
1234 *
1235 * If \c family is set to an address family other than \c AF_UNSPEC the
1236 * contents of the cache can be limited to a specific address family.
1237 * Currently the following address families are supported:
1238 * - AF_BRIDGE
1239 * - AF_INET6
1240 *
1241 * @route_doc{link_list, Get List of Links}
1242 * @see rtnl_link_get()
1243 * @see rtnl_link_get_by_name()
1244 * @return 0 on success or a negative error code.
1245 */
1246 int rtnl_link_alloc_cache_flags(struct nl_sock *sk, int family,
1247 struct nl_cache **result, unsigned int flags)
1248{
1249 struct nl_cache * cache;
1250 int err;
1251
1252 cache = nl_cache_alloc(&rtnl_link_ops);
1253 if (!cache)
1254 return -NLE_NOMEM;
1255
1256 cache->c_iarg1 = family;
1257
1258 if (flags)
1259 nl_cache_set_flags(cache, flags);
1260
1261 if (sk && (err = nl_cache_refill(sk, cache)) < 0) {
1262 nl_cache_free(cache);
1263 return err;
1264 }
1265
1266 *result = cache;
1267 return 0;
1268}
1269
1270/**
1271 * Allocate link cache and fill in all configured links.
1272 * @arg sk Netlink socket.
1273 * @arg family Link address family or AF_UNSPEC
1274 * @arg result Pointer to store resulting cache.
1275 *
1276 * Allocates and initializes a new link cache. If \c sk is valid, a netlink
1277 * message is sent to the kernel requesting a full dump of all configured
1278 * links. The returned messages are parsed and filled into the cache. If
1279 * the operation succeeds, the resulting cache will contain a link object for
1280 * each link configured in the kernel. If \c sk is NULL, returns 0 but the
1281 * cache is still empty.
1282 *
1283 * If \c family is set to an address family other than \c AF_UNSPEC the
1284 * contents of the cache can be limited to a specific address family.
1285 * Currently the following address families are supported:
1286 * - AF_BRIDGE
1287 * - AF_INET6
1288 *
1289 * @route_doc{link_list, Get List of Links}
1290 * @see rtnl_link_get()
1291 * @see rtnl_link_get_by_name()
1292 * @return 0 on success or a negative error code.
1293 */
1294 int rtnl_link_alloc_cache(struct nl_sock *sk, int family, struct nl_cache **result)
1295{
1296 return rtnl_link_alloc_cache_flags(sk, family, result, 0);
1297}
1298
1299
1300/**
1301 * Lookup link in cache by interface index
1302 * @arg cache Link cache
1303 * @arg ifindex Interface index
1304 *
1305 * Searches through the provided cache looking for a link with matching
1306 * interface index.
1307 *
1308 * @attention The reference counter of the returned link object will be
1309 * incremented. Use rtnl_link_put() to release the reference.
1310 *
1311 * @route_doc{link_list, Get List of Links}
1312 * @see rtnl_link_get_by_name()
1313 * @return Link object or NULL if no match was found.
1314 */
1315 struct rtnl_link *rtnl_link_get(struct nl_cache *cache, int ifindex)
1316{
1317 struct rtnl_link *link;
1318
1319 if (cache->c_ops != &rtnl_link_ops)
1320 return NULL;
1321
1322 nl_list_for_each_entry(link, &cache->c_items, ce_list) {
1323 if (link->l_index == ((unsigned)ifindex)) {
1324 nl_object_get((struct nl_object *) link);
1325 return link;
1326 }
1327 }
1328
1329 return NULL;
1330}
1331
1332/**
1333 * Lookup link in cache by link name
1334 * @arg cache Link cache
1335 * @arg name Name of link
1336 *
1337 * Searches through the provided cache looking for a link with matching
1338 * link name
1339 *
1340 * @attention The reference counter of the returned link object will be
1341 * incremented. Use rtnl_link_put() to release the reference.
1342 *
1343 * @route_doc{link_list, Get List of Links}
1344 * @see rtnl_link_get()
1345 * @return Link object or NULL if no match was found.
1346 */
1347 struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *cache,
1348 const char *name)
1349{
1350 struct rtnl_link *link;
1351
1352 if (cache->c_ops != &rtnl_link_ops)
1353 return NULL;
1354
1355 nl_list_for_each_entry(link, &cache->c_items, ce_list) {
1356 if (!strcmp(name, link->l_name)) {
1357 nl_object_get((struct nl_object *) link);
1358 return link;
1359 }
1360 }
1361
1362 return NULL;
1363}
1364
1365/**
1366 * Construct RTM_GETLINK netlink message
1367 * @arg ifindex Interface index
1368 * @arg name Name of link
1369 * @arg result Pointer to store resulting netlink message
1370 *
1371 * The behaviour of this function is identical to rtnl_link_get_kernel()
1372 * with the exception that it will not send the message but return it in
1373 * the provided return pointer instead.
1374 *
1375 * @see rtnl_link_get_kernel()
1376 *
1377 * @return 0 on success or a negative error code.
1378 */
1379 int rtnl_link_build_get_request(int ifindex, const char *name,
1380 struct nl_msg **result)
1381{
1382 _nl_auto_nl_msg struct nl_msg *msg = NULL;
1383 struct ifinfomsg ifi;
1384 __u32 vf_mask = RTEXT_FILTER_VF;
1385
1386 if (ifindex <= 0 && !name) {
1387 APPBUG("ifindex or name must be specified");
1388 return -NLE_MISSING_ATTR;
1389 }
1390
1391 memset(&ifi, 0, sizeof(ifi));
1392
1393 if (!(msg = nlmsg_alloc_simple(RTM_GETLINK, 0)))
1394 return -NLE_NOMEM;
1395
1396 if (ifindex > 0)
1397 ifi.ifi_index = ifindex;
1398
1399 _NL_RETURN_ON_PUT_ERR(nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO));
1400
1401 if (name)
1402 _NL_RETURN_ON_PUT_ERR(nla_put_string(msg, IFLA_IFNAME, name));
1403
1404 _NL_RETURN_ON_PUT_ERR(nla_put(msg, IFLA_EXT_MASK, sizeof(vf_mask), &vf_mask));
1405
1406 *result = _nl_steal_pointer(&msg);
1407 return 0;
1408}
1409
1410/**
1411 * Get a link object directly from kernel
1412 * @arg sk Netlink socket
1413 * @arg ifindex Interface index
1414 * @arg name Name of link
1415 * @arg result Pointer to store resulting link object
1416 *
1417 * This function builds a \c RTM_GETLINK netlink message to request
1418 * a specific link directly from the kernel. The returned answer is
1419 * parsed into a struct rtnl_link object and returned via the result
1420 * pointer or -NLE_OBJ_NOTFOUND is returned if no matching link was
1421 * found.
1422 *
1423 * Older kernels do not support lookup by name. In that case, libnl
1424 * will fail with -NLE_OPNOTSUPP. Note that previous version of libnl
1425 * failed in this case with -NLE_INVAL. You can check libnl behavior
1426 * using NL_CAPABILITY_ROUTE_LINK_GET_KERNEL_FAIL_OPNOTSUPP capability.
1427 *
1428 * @route_doc{link_direct_lookup, Lookup Single Link (Direct Lookup)}
1429 * @return 0 on success or a negative error code.
1430 */
1431 int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name,
1432 struct rtnl_link **result)
1433{
1434 _nl_auto_rtnl_link struct rtnl_link *link = NULL;
1435 _nl_auto_nl_msg struct nl_msg *msg = NULL;
1436 int err;
1437 int syserr;
1438
1439 if ((err = rtnl_link_build_get_request(ifindex, name, &msg)) < 0)
1440 return err;
1441
1442 err = nl_send_auto(sk, msg);
1443 if (err < 0)
1444 return err;
1445
1446 err = nl_pickup_keep_syserr(sk, link_msg_parser, (struct nl_object **) &link, &syserr);
1447 if (err < 0) {
1448 if ( syserr == -EINVAL
1449 && ifindex <= 0
1450 && name
1451 && *name) {
1452 /* Older kernels do not support lookup by ifname. This was added
1453 * by commit kernel a3d1289126e7b14307074b76bf1677015ea5036f .
1454 * Detect this error case and return NLE_OPNOTSUPP instead of
1455 * NLE_INVAL. */
1456 return -NLE_OPNOTSUPP;
1457 }
1458 return err;
1459 }
1460
1461 /* If an object has been returned, we also need to wait for the ACK */
1462 if (err == 0 && link)
1463 wait_for_ack(sk);
1464
1465 *result = _nl_steal_pointer(&link);
1466 return 0;
1467}
1468
1469/**
1470 * Translate interface index to corresponding link name
1471 * @arg cache Link cache
1472 * @arg ifindex Interface index
1473 * @arg dst String to store name
1474 * @arg len Length of destination string
1475 *
1476 * Translates the specified interface index to the corresponding
1477 * link name and stores the name in the destination string.
1478 *
1479 * @route_doc{link_translate_ifindex, Translating interface index to link name}
1480 * @see rtnl_link_name2i()
1481 * @return Name of link or NULL if no match was found.
1482 */
1483 char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst,
1484 size_t len)
1485{
1486 _nl_auto_rtnl_link struct rtnl_link *link = NULL;
1487
1488 link = rtnl_link_get(cache, ifindex);
1489 if (link) {
1490 _nl_strncpy_trunc(dst, link->l_name, len);
1491 return dst;
1492 }
1493
1494 return NULL;
1495}
1496
1497/**
1498 * Translate link name to corresponding interface index
1499 * @arg cache Link cache
1500 * @arg name Name of link
1501 *
1502 * @route_doc{link_translate_ifindex, Translating interface index to link name}
1503 * @see rtnl_link_i2name()
1504 * @return Interface index or 0 if no match was found.
1505 */
1506 int rtnl_link_name2i(struct nl_cache *cache, const char *name)
1507{
1508 _nl_auto_rtnl_link struct rtnl_link *link = NULL;
1509
1510 link = rtnl_link_get_by_name(cache, name);
1511 if (link)
1512 return link->l_index;
1513
1514 return 0;
1515}
1516
1517/** @} */
1518
1519int rtnl_link_fill_info(struct nl_msg *msg, struct rtnl_link *link)
1520{
1521 if (link->ce_mask & LINK_ATTR_ADDR)
1522 NLA_PUT_ADDR(msg, IFLA_ADDRESS, link->l_addr);
1523
1524 if (link->ce_mask & LINK_ATTR_BRD)
1525 NLA_PUT_ADDR(msg, IFLA_BROADCAST, link->l_bcast);
1526
1527 if (link->ce_mask & LINK_ATTR_MTU)
1528 NLA_PUT_U32(msg, IFLA_MTU, link->l_mtu);
1529
1530 if (link->ce_mask & LINK_ATTR_TXQLEN)
1531 NLA_PUT_U32(msg, IFLA_TXQLEN, link->l_txqlen);
1532
1533 if (link->ce_mask & LINK_ATTR_WEIGHT)
1534 NLA_PUT_U32(msg, IFLA_WEIGHT, link->l_weight);
1535
1536 if (link->ce_mask & LINK_ATTR_IFNAME)
1537 NLA_PUT_STRING(msg, IFLA_IFNAME, link->l_name);
1538
1539 if (link->ce_mask & LINK_ATTR_OPERSTATE)
1540 NLA_PUT_U8(msg, IFLA_OPERSTATE, link->l_operstate);
1541
1542 if (link->ce_mask & LINK_ATTR_CARRIER)
1543 NLA_PUT_U8(msg, IFLA_CARRIER, link->l_carrier);
1544
1545 if (link->ce_mask & LINK_ATTR_LINKMODE)
1546 NLA_PUT_U8(msg, IFLA_LINKMODE, link->l_linkmode);
1547
1548 if (link->ce_mask & LINK_ATTR_IFALIAS)
1549 NLA_PUT_STRING(msg, IFLA_IFALIAS, link->l_ifalias);
1550
1551 if (link->ce_mask & LINK_ATTR_LINK)
1552 NLA_PUT_U32(msg, IFLA_LINK, link->l_link);
1553
1554 if (link->ce_mask & LINK_ATTR_LINK_NETNSID)
1555 NLA_PUT_S32(msg, IFLA_LINK_NETNSID, link->l_link_netnsid);
1556
1557 if (link->ce_mask & LINK_ATTR_MASTER)
1558 NLA_PUT_U32(msg, IFLA_MASTER, link->l_master);
1559
1560 if (link->ce_mask & LINK_ATTR_NUM_TX_QUEUES)
1561 NLA_PUT_U32(msg, IFLA_NUM_TX_QUEUES, link->l_num_tx_queues);
1562
1563 if (link->ce_mask & LINK_ATTR_NUM_RX_QUEUES)
1564 NLA_PUT_U32(msg, IFLA_NUM_RX_QUEUES, link->l_num_rx_queues);
1565
1566 if (link->ce_mask & LINK_ATTR_NS_FD)
1567 NLA_PUT_U32(msg, IFLA_NET_NS_FD, link->l_ns_fd);
1568
1569 if (link->ce_mask & LINK_ATTR_NS_PID)
1570 NLA_PUT_U32(msg, IFLA_NET_NS_PID, link->l_ns_pid);
1571
1572 return 0;
1573
1574nla_put_failure:
1575 return -NLE_MSGSIZE;
1576}
1577
1578static int build_link_msg(int cmd, struct ifinfomsg *hdr,
1579 struct rtnl_link *link, int flags, struct nl_msg **result)
1580{
1581 _nl_auto_nl_msg struct nl_msg *msg = NULL;
1582 struct nlattr *af_spec;
1583
1584 msg = nlmsg_alloc_simple(cmd, flags);
1585 if (!msg)
1586 return -NLE_NOMEM;
1587
1588 if (nlmsg_append(msg, hdr, sizeof(*hdr), NLMSG_ALIGNTO) < 0)
1589 goto nla_put_failure;
1590
1591 if (rtnl_link_fill_info(msg, link))
1592 goto nla_put_failure;
1593
1594 if (link->ce_mask & LINK_ATTR_GROUP)
1595 NLA_PUT_U32(msg, IFLA_GROUP, link->l_group);
1596
1597 if (link->ce_mask & (LINK_ATTR_LINKINFO|LINK_ATTR_LINKINFO_SLAVE_KIND)) {
1598 struct nlattr *info;
1599
1600 if (!(info = nla_nest_start(msg, IFLA_LINKINFO)))
1601 goto nla_put_failure;
1602
1603 if (link->ce_mask & LINK_ATTR_LINKINFO) {
1604 NLA_PUT_STRING(msg, IFLA_INFO_KIND, link->l_info_kind);
1605
1606 if (link->l_info_ops) {
1607 if (link->l_info_ops->io_put_attrs &&
1608 link->l_info_ops->io_put_attrs(msg, link) < 0)
1609 goto nla_put_failure;
1610 }
1611 }
1612
1613 if (link->ce_mask & LINK_ATTR_LINKINFO_SLAVE_KIND) {
1614 NLA_PUT_STRING(msg, IFLA_INFO_SLAVE_KIND, link->l_info_slave_kind);
1615 }
1616
1617 nla_nest_end(msg, info);
1618 }
1619
1620 if (link->ce_mask & LINK_ATTR_VF_LIST) {
1621 if (rtnl_link_sriov_fill_vflist(msg, link) < 0)
1622 goto nla_put_failure;
1623 }
1624
1625 if (do_foreach_af(link, af_fill_pi, msg) < 0)
1626 goto nla_put_failure;
1627
1628 if (!(af_spec = nla_nest_start(msg, IFLA_AF_SPEC)))
1629 goto nla_put_failure;
1630
1631 if (do_foreach_af(link, af_fill, msg) < 0)
1632 goto nla_put_failure;
1633
1634 nla_nest_end(msg, af_spec);
1635
1636 *result = _nl_steal_pointer(&msg);
1637 return 0;
1638
1639nla_put_failure:
1640 return -NLE_MSGSIZE;
1641}
1642
1643/**
1644 * @name Add / Modify
1645 * @{
1646 */
1647
1648/**
1649 * Build a netlink message requesting the addition of new virtual link
1650 * @arg link new link to add
1651 * @arg flags additional netlink message flags
1652 * @arg result pointer to store resulting netlink message
1653 *
1654 * The behaviour of this function is identical to rtnl_link_add() with
1655 * the exception that it will not send the message but return it in the
1656 * provided return pointer instead.
1657 *
1658 * @see rtnl_link_add()
1659 *
1660 * @note This operation is not supported on all kernel versions.
1661 *
1662 * @return 0 on success or a negative error code.
1663 */
1664 int rtnl_link_build_add_request(struct rtnl_link *link, int flags,
1665 struct nl_msg **result)
1666{
1667 struct ifinfomsg ifi = {
1668 .ifi_family = link->l_family,
1669 .ifi_index = link->l_index,
1670 .ifi_flags = link->l_flags,
1671 .ifi_change = link->l_flag_mask,
1672 };
1673
1674 return build_link_msg(RTM_NEWLINK, &ifi, link, flags, result);
1675}
1676
1677/**
1678 * Add virtual link
1679 * @arg sk netlink socket.
1680 * @arg link new link to add
1681 * @arg flags additional netlink message flags
1682 *
1683 * Builds a \c RTM_NEWLINK netlink message requesting the addition of
1684 * a new virtual link.
1685 *
1686 * After sending, the function will wait for the ACK or an eventual
1687 * error message to be received and will therefore block until the
1688 * operation has been completed.
1689 *
1690 * @copydoc auto_ack_warning
1691 *
1692 * @return 0 on success or a negative error code.
1693 */
1694 int rtnl_link_add(struct nl_sock *sk, struct rtnl_link *link, int flags)
1695{
1696 struct nl_msg *msg;
1697 int err;
1698
1699 err = rtnl_link_build_add_request(link, flags, &msg);
1700 if (err < 0)
1701 return err;
1702
1703 return nl_send_sync(sk, msg);
1704}
1705
1706/**
1707 * Build a netlink message requesting the modification of link
1708 * @arg orig original link to change
1709 * @arg changes link containing the changes to be made
1710 * @arg flags additional netlink message flags
1711 * @arg result pointer to store resulting netlink message
1712 *
1713 * The behaviour of this function is identical to rtnl_link_change() with
1714 * the exception that it will not send the message but return it in the
1715 * provided return pointer instead.
1716 *
1717 * @see rtnl_link_change()
1718 *
1719 * @note The resulting message will have message type set to RTM_NEWLINK
1720 * which may not work with older kernels. You may have to modify it
1721 * to RTM_SETLINK (does not allow changing link info attributes) to
1722 * have the change request work with older kernels.
1723 *
1724 * @return 0 on success or a negative error code.
1725 */
1726 int rtnl_link_build_change_request(struct rtnl_link *orig,
1727 struct rtnl_link *changes, int flags,
1728 struct nl_msg **result)
1729{
1730 struct ifinfomsg ifi = {
1731 .ifi_family = orig->l_family,
1732 .ifi_index = orig->l_index,
1733 };
1734 int err, rt;
1735
1736 if (changes->ce_mask & LINK_ATTR_FLAGS) {
1737 ifi.ifi_flags = orig->l_flags & ~changes->l_flag_mask;
1738 ifi.ifi_flags |= changes->l_flags;
1739 ifi.ifi_change = changes->l_flag_mask;
1740 }
1741
1742 if (changes->l_family && changes->l_family != orig->l_family) {
1743 APPBUG("link change: family is immutable");
1744 return -NLE_IMMUTABLE;
1745 }
1746
1747 /* Avoid unnecessary name change requests */
1748 if (orig->ce_mask & LINK_ATTR_IFINDEX &&
1749 orig->ce_mask & LINK_ATTR_IFNAME &&
1750 changes->ce_mask & LINK_ATTR_IFNAME &&
1751 !strcmp(orig->l_name, changes->l_name))
1752 changes->ce_mask &= ~LINK_ATTR_IFNAME;
1753
1754 rt = af_request_type(orig->l_family, changes);
1755
1756 if ((err = build_link_msg(rt, &ifi, changes, flags, result)) < 0)
1757 return err;
1758
1759 return 0;
1760}
1761
1762/**
1763 * Change link
1764 * @arg sk netlink socket.
1765 * @arg orig original link to be changed
1766 * @arg changes link containing the changes to be made
1767 * @arg flags additional netlink message flags
1768 *
1769 * Builds a \c RTM_NEWLINK netlink message requesting the change of
1770 * a network link. If -EOPNOTSUPP is returned by the kernel, the
1771 * message type will be changed to \c RTM_SETLINK and the message is
1772 * resent to work around older kernel versions.
1773 *
1774 * The link to be changed is looked up based on the interface index
1775 * supplied in the \p orig link. Optionaly the link name is used but
1776 * only if no interface index is provided, otherwise providing an
1777 * link name will result in the link name being changed.
1778 *
1779 * If no matching link exists, the function will return
1780 * -NLE_OBJ_NOTFOUND.
1781 *
1782 * After sending, the function will wait for the ACK or an eventual
1783 * error message to be received and will therefore block until the
1784 * operation has been completed.
1785 *
1786 * @copydoc auto_ack_warning
1787 *
1788 * @note The link name can only be changed if the link has been put
1789 * in opertional down state. (~IF_UP)
1790 *
1791 * @note On versions up to 3.4.0, \c NLE_SEQ_MISMATCH would be returned if the
1792 * kernel does not supports \c RTM_NEWLINK. It is advised to ignore the
1793 * error code if you cannot upgrade the library.
1794 *
1795 * @return 0 on success or a negative error code.
1796 */
1797 int rtnl_link_change(struct nl_sock *sk, struct rtnl_link *orig,
1798 struct rtnl_link *changes, int flags)
1799{
1800 _nl_auto_nl_msg struct nl_msg *msg = NULL;
1801 int err;
1802
1803 err = rtnl_link_build_change_request(orig, changes, flags, &msg);
1804 if (err < 0)
1805 return err;
1806
1807 BUG_ON(msg->nm_nlh->nlmsg_seq != NL_AUTO_SEQ);
1808retry:
1809 err = nl_send_auto_complete(sk, msg);
1810 if (err < 0)
1811 return err;
1812
1813 err = wait_for_ack(sk);
1814 if ( err == -NLE_OPNOTSUPP
1815 && msg->nm_nlh->nlmsg_type == RTM_NEWLINK) {
1816 msg->nm_nlh->nlmsg_type = RTM_SETLINK;
1817 msg->nm_nlh->nlmsg_seq = NL_AUTO_SEQ;
1818 goto retry;
1819 }
1820
1821 if (err < 0)
1822 return err;
1823
1824 return 0;
1825}
1826
1827/** @} */
1828
1829/**
1830 * @name Delete
1831 * @{
1832 */
1833
1834/**
1835 * Build a netlink message requesting the deletion of a link
1836 * @arg link Link to delete
1837 * @arg result Pointer to store resulting netlink message
1838 *
1839 * The behaviour of this function is identical to rtnl_link_delete() with
1840 * the exception that it will not send the message but return it in the
1841 * provided return pointer instead.
1842 *
1843 * @see rtnl_link_delete()
1844 *
1845 * @return 0 on success or a negative error code.
1846 */
1847 int rtnl_link_build_delete_request(const struct rtnl_link *link,
1848 struct nl_msg **result)
1849{
1850 _nl_auto_nl_msg struct nl_msg *msg = NULL;
1851 struct ifinfomsg ifi = {
1852 .ifi_index = link->l_index,
1853 };
1854
1855 if (!(link->ce_mask & (LINK_ATTR_IFINDEX | LINK_ATTR_IFNAME))) {
1856 APPBUG("ifindex or name must be specified");
1857 return -NLE_MISSING_ATTR;
1858 }
1859
1860 if (!(msg = nlmsg_alloc_simple(RTM_DELLINK, 0)))
1861 return -NLE_NOMEM;
1862
1863 _NL_RETURN_ON_PUT_ERR(nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO));
1864
1865 if (link->ce_mask & LINK_ATTR_IFNAME)
1866 _NL_RETURN_ON_PUT_ERR(nla_put_string(msg, IFLA_IFNAME, link->l_name));
1867
1868 *result = _nl_steal_pointer(&msg);
1869 return 0;
1870}
1871
1872/**
1873 * Delete link
1874 * @arg sk Netlink socket
1875 * @arg link Link to delete
1876 *
1877 * Builds a \c RTM_DELLINK netlink message requesting the deletion of
1878 * a network link which has been previously added to the kernel and
1879 * sends the message to the kernel.
1880 *
1881 * If no matching link exists, the function will return
1882 * -NLE_OBJ_NOTFOUND.
1883 *
1884 * After sending, the function will wait for the ACK or an eventual
1885 * error message to be received and will therefore block until the
1886 * operation has been completed.
1887 *
1888 * @copydoc auto_ack_warning
1889 *
1890 * @note Only virtual links such as dummy interface or vlan interfaces
1891 * can be deleted. It is not possible to delete physical interfaces
1892 * such as ethernet interfaces or the loopback device.
1893 *
1894 * @return 0 on success or a negative error code.
1895 */
1896 int rtnl_link_delete(struct nl_sock *sk, const struct rtnl_link *link)
1897{
1898 struct nl_msg *msg;
1899 int err;
1900
1901 if ((err = rtnl_link_build_delete_request(link, &msg)) < 0)
1902 return err;
1903
1904 return nl_send_sync(sk, msg);
1905}
1906
1907/** @} */
1908
1909/**
1910 * @name Link Object
1911 * @{
1912 */
1913
1914/**
1915 * Allocate link object
1916 *
1917 * @see rtnl_link_put()
1918 * @return New link object or NULL if allocation failed
1919 */
1920 struct rtnl_link *rtnl_link_alloc(void)
1921{
1922 return (struct rtnl_link *) nl_object_alloc(&link_obj_ops);
1923}
1924
1925/**
1926 * Release a link object reference
1927 * @arg link Link object
1928 */
1929 void rtnl_link_put(struct rtnl_link *link)
1930{
1931 nl_object_put((struct nl_object *) link);
1932}
1933
1934/**
1935 * Set name of link object
1936 * @arg link Link object
1937 * @arg name New name
1938 *
1939 * @note To change the name of a link in the kernel, set the interface
1940 * index to the link you wish to change, modify the link name using
1941 * this function and pass the link object to rtnl_link_change() or
1942 * rtnl_link_add().
1943 *
1944 * @route_doc{link_attr_name, Link Name}
1945 * @see rtnl_link_get_name()
1946 * @see rtnl_link_set_ifindex()
1947 */
1948 void rtnl_link_set_name(struct rtnl_link *link, const char *name)
1949{
1950 _nl_strncpy_trunc(link->l_name, name, sizeof(link->l_name));
1951 link->ce_mask |= LINK_ATTR_IFNAME;
1952}
1953
1954/**
1955 * Return name of link object
1956 * @arg link Link object
1957 *
1958 * @route_doc{link_attr_name, Link Name}
1959 * @see rtnl_link_set_name()
1960 * @return Link name or NULL if name is not specified
1961 */
1962 char *rtnl_link_get_name(struct rtnl_link *link)
1963{
1964 return link->ce_mask & LINK_ATTR_IFNAME ? link->l_name : NULL;
1965}
1966
1967/**
1968 * Set the group identifier of a link object
1969 * @arg link Link object
1970 * @arg group Group identifier
1971 */
1972 void rtnl_link_set_group(struct rtnl_link *link, uint32_t group)
1973{
1974 link->l_group = group;
1975 link->ce_mask |= LINK_ATTR_GROUP;
1976}
1977
1978/**
1979 * Return the group identifier of link object
1980 * @arg link Link object
1981 *
1982 * @return Group identifier or 0 if not set.
1983 */
1984uint32_t rtnl_link_get_group(struct rtnl_link *link)
1985{
1986 return link->l_group;
1987}
1988
1989static inline void __assign_addr(struct rtnl_link *link, struct nl_addr **pos,
1990 struct nl_addr *new, int flag)
1991{
1992 if (*pos)
1993 nl_addr_put(*pos);
1994
1995 nl_addr_get(new);
1996 *pos = new;
1997
1998 link->ce_mask |= flag;
1999}
2000
2001/**
2002 * Set link layer address of link object
2003 * @arg link Link object
2004 * @arg addr New link layer address
2005 *
2006 * The function increments the reference counter of the address object
2007 * and overwrites any existing link layer address previously assigned.
2008 *
2009 * @route_doc{link_attr_address, Link layer address}
2010 * @see rtnl_link_get_addr()
2011 */
2012 void rtnl_link_set_addr(struct rtnl_link *link, struct nl_addr *addr)
2013{
2014 __assign_addr(link, &link->l_addr, addr, LINK_ATTR_ADDR);
2015}
2016
2017/**
2018 * Return link layer address of link object
2019 * @arg link Link object
2020 *
2021 * @copydoc pointer_lifetime_warning
2022 * @route_doc{link_attr_address, Link Layer Address}
2023 * @see rtnl_link_set_addr()
2024 * @return Link layer address or NULL if not set.
2025 */
2026 struct nl_addr *rtnl_link_get_addr(struct rtnl_link *link)
2027{
2028 return link->ce_mask & LINK_ATTR_ADDR ? link->l_addr : NULL;
2029}
2030
2031/**
2032 * Set link layer broadcast address of link object
2033 * @arg link Link object
2034 * @arg addr New broadcast address
2035 *
2036 * The function increments the reference counter of the address object
2037 * and overwrites any existing link layer broadcast address previously
2038 * assigned.
2039 *
2040 * @route_doc{link_attr_broadcast, Link Layer Broadcast Address}
2041 * @see rtnl_link_get_broadcast()
2042 */
2043 void rtnl_link_set_broadcast(struct rtnl_link *link, struct nl_addr *addr)
2044{
2045 __assign_addr(link, &link->l_bcast, addr, LINK_ATTR_BRD);
2046}
2047
2048/**
2049 * Return link layer broadcast address of link object
2050 * @arg link Link object
2051 *
2052 * @copydoc pointer_lifetime_warning
2053 * @route_doc{link_attr_address, Link Layer Address}
2054 * @see rtnl_link_set_broadcast()
2055 * @return Link layer address or NULL if not set.
2056 */
2057 struct nl_addr *rtnl_link_get_broadcast(struct rtnl_link *link)
2058{
2059 return link->ce_mask & LINK_ATTR_BRD ? link->l_bcast : NULL;
2060}
2061
2062/**
2063 * Set flags of link object
2064 * @arg link Link object
2065 * @arg flags Flags
2066 *
2067 * @see rtnl_link_get_flags()
2068 * @see rtnl_link_unset_flags()
2069 */
2070 void rtnl_link_set_flags(struct rtnl_link *link, unsigned int flags)
2071{
2072 link->l_flag_mask |= flags;
2073 link->l_flags |= flags;
2074 link->ce_mask |= LINK_ATTR_FLAGS;
2075}
2076
2077/**
2078 * Unset flags of link object
2079 * @arg link Link object
2080 * @arg flags Flags
2081 *
2082 * @see rtnl_link_set_flags()
2083 * @see rtnl_link_get_flags()
2084 */
2085 void rtnl_link_unset_flags(struct rtnl_link *link, unsigned int flags)
2086{
2087 link->l_flag_mask |= flags;
2088 link->l_flags &= ~flags;
2089 link->ce_mask |= LINK_ATTR_FLAGS;
2090}
2091
2092/**
2093 * Return flags of link object
2094 * @arg link Link object
2095 *
2096 * @route_doc{link_attr_flags, Link Flags}
2097 * @see rtnl_link_set_flags()
2098 * @see rtnl_link_unset_flags()
2099 * @return Link flags or 0 if none have been set.
2100 */
2101 unsigned int rtnl_link_get_flags(struct rtnl_link *link)
2102{
2103 return link->l_flags;
2104}
2105
2106/**
2107 * Set address family of link object
2108 *
2109 * @see rtnl_link_get_family()
2110 */
2111 void rtnl_link_set_family(struct rtnl_link *link, int family)
2112{
2113 link->l_family = family;
2114 link->ce_mask |= LINK_ATTR_FAMILY;
2115
2116 if (link->l_af_ops) {
2117 int ao_family = link->l_af_ops->ao_family;
2118
2119 af_free(link, link->l_af_ops, link->l_af_data[ao_family], NULL);
2120 link->l_af_data[ao_family] = NULL;
2121 }
2122
2123 link->l_af_ops = af_lookup_and_alloc(link, family);
2124}
2125
2126/**
2127 * Return address family of link object
2128 * @arg link Link object
2129 *
2130 * @see rtnl_link_set_family()
2131 * @return Address family or \c AF_UNSPEC if not specified.
2132 */
2133 int rtnl_link_get_family(struct rtnl_link *link)
2134{
2135 return link->ce_mask & LINK_ATTR_FAMILY ? link->l_family : AF_UNSPEC;
2136}
2137
2138/**
2139 * Set hardware type of link object
2140 * @arg link Link object
2141 * @arg arptype New hardware type \c (ARPHRD_*)
2142 *
2143 * @route_doc{link_attr_arptype, Hardware Type}
2144 * @copydoc read_only_attribute
2145 * @see rtnl_link_get_arptype()
2146 */
2147 void rtnl_link_set_arptype(struct rtnl_link *link, unsigned int arptype)
2148{
2149 link->l_arptype = arptype;
2150 link->ce_mask |= LINK_ATTR_ARPTYPE;
2151}
2152
2153/**
2154 * Get hardware type of link object
2155 * @arg link Link object
2156 *
2157 * @route_doc{link_attr_arptype, Hardware Type}
2158 * @see rtnl_link_set_arptype()
2159 * @return Hardware type \c (ARPHRD_ETHER *) or \c ARPHRD_VOID
2160 */
2161 unsigned int rtnl_link_get_arptype(struct rtnl_link *link)
2162{
2163 if (link->ce_mask & LINK_ATTR_ARPTYPE)
2164 return link->l_arptype;
2165 else
2166 return ARPHRD_VOID;
2167}
2168
2169/**
2170 * Set interface index of link object
2171 * @arg link Link object
2172 * @arg ifindex Interface index
2173 *
2174 * @route_doc{link_attr_ifindex, Interface Index}
2175 * @see rtnl_link_get_ifindex()
2176 */
2177 void rtnl_link_set_ifindex(struct rtnl_link *link, int ifindex)
2178{
2179 link->l_index = ifindex;
2180 link->ce_mask |= LINK_ATTR_IFINDEX;
2181}
2182
2183
2184/**
2185 * Return interface index of link object
2186 * @arg link Link object
2187 *
2188 * @route_doc{link_attr_ifindex, Interface Index}
2189 * @see rtnl_link_set_ifindex()
2190 * @return Interface index or 0 if not set.
2191 */
2192 int rtnl_link_get_ifindex(struct rtnl_link *link)
2193{
2194 return link->l_index;
2195}
2196
2197/**
2198 * Set Maximum Transmission Unit of link object
2199 * @arg link Link object
2200 * @arg mtu New MTU value in number of bytes
2201 *
2202 * @route_doc{link_attr_mtu, Maximum Transmission Unit}
2203 * @see rtnl_link_get_mtu()
2204 */
2205 void rtnl_link_set_mtu(struct rtnl_link *link, unsigned int mtu)
2206{
2207 link->l_mtu = mtu;
2208 link->ce_mask |= LINK_ATTR_MTU;
2209}
2210
2211/**
2212 * Return maximum transmission unit of link object
2213 * @arg link Link object
2214 *
2215 * @route_doc{link_attr_mtu, Maximum Transmission Unit}
2216 * @see rtnl_link_set_mtu()
2217 * @return MTU in bytes or 0 if not set
2218 */
2219 unsigned int rtnl_link_get_mtu(struct rtnl_link *link)
2220{
2221 return link->l_mtu;
2222}
2223
2224/**
2225 * Set transmission queue length
2226 * @arg link Link object
2227 * @arg txqlen New queue length
2228 *
2229 * The unit is dependant on the link type. The most common units is number
2230 * of packets.
2231 *
2232 * @route_doc{link_attr_txqlen, Transmission Queue Length}
2233 */
2234 void rtnl_link_set_txqlen(struct rtnl_link *link, unsigned int txqlen)
2235{
2236 link->l_txqlen = txqlen;
2237 link->ce_mask |= LINK_ATTR_TXQLEN;
2238}
2239
2240/**
2241 * Return transmission queue length
2242 * @arg link Link object
2243 *
2244 * The unit is dependant on the link type. The most common units is number
2245 * of packets.
2246 *
2247 * @route_doc{link_attr_txqlen, Transmission Queue Length}
2248 * @return queue length or 0 if not specified.
2249 */
2250 unsigned int rtnl_link_get_txqlen(struct rtnl_link *link)
2251{
2252 return link->ce_mask & LINK_ATTR_TXQLEN ? link->l_txqlen : 0;
2253}
2254
2255void rtnl_link_set_link(struct rtnl_link *link, int ifindex)
2256{
2257 link->l_link = ifindex;
2258 link->ce_mask |= LINK_ATTR_LINK;
2259}
2260
2261int rtnl_link_get_link(struct rtnl_link *link)
2262{
2263 return link->l_link;
2264}
2265
2266/**
2267 * Set the netnsid of the link
2268 * @arg link Link object
2269 * @link_netnsid the netnsid to set
2270 *
2271 * Sets the IFLA_LINK_NETNSID attribute of the link
2272 * @returns 0 on success
2273 */
2274 int rtnl_link_set_link_netnsid(struct rtnl_link *link, int32_t link_netnsid)
2275{
2276 link->l_link_netnsid = link_netnsid;
2277 link->ce_mask |= LINK_ATTR_LINK_NETNSID;
2278 return 0;
2279}
2280
2281/**
2282 * Get the netnsid of the link
2283 * @arg link Link object
2284 * @out_link_netnsid the netnsid
2285 *
2286 * Gets the IFLA_LINK_NETNSID attribute of the link
2287 * or returns an error if the value is unset.
2288 *
2289 * @returns 0 on success
2290 */
2291 int rtnl_link_get_link_netnsid(const struct rtnl_link *link, int32_t *out_link_netnsid)
2292{
2293 if (!(link->ce_mask & LINK_ATTR_LINK_NETNSID))
2294 return -NLE_INVAL;
2295
2296 *out_link_netnsid = link->l_link_netnsid;
2297 return 0;
2298}
2299
2300/**
2301 * Set master link of link object
2302 * @arg link Link object
2303 * @arg ifindex Interface index of master link
2304 *
2305 * @see rtnl_link_get_master()
2306 */
2307 void rtnl_link_set_master(struct rtnl_link *link, int ifindex)
2308{
2309 link->l_master = ifindex;
2310 link->ce_mask |= LINK_ATTR_MASTER;
2311}
2312
2313/**
2314 * Return master link of link object
2315 * @arg link Link object
2316 *
2317 * @see rtnl_link_set_master()
2318 * @return Interface index of master link or 0 if not specified
2319 */
2320 int rtnl_link_get_master(struct rtnl_link *link)
2321{
2322 return link->l_master;
2323}
2324
2325/**
2326 * Set carrier of link object
2327 * @arg link Link object
2328 * @arg status New carrier status
2329 *
2330 * @see rtnl_link_get_carrier()
2331 */
2332 void rtnl_link_set_carrier(struct rtnl_link *link, uint8_t status)
2333{
2334 link->l_carrier = status;
2335 link->ce_mask |= LINK_ATTR_CARRIER;
2336}
2337
2338/**
2339 * Return carrier status of link object
2340 * @arg link Link object
2341 *
2342 * @see rtnl_link_set_master()
2343 * @return Carrier state.
2344 */
2345uint8_t rtnl_link_get_carrier(struct rtnl_link *link)
2346{
2347 return link->l_carrier;
2348}
2349
2350/**
2351 * Return carrier on/off changes of link object
2352 * @arg link Link object
2353 * @arg carrier_changes Pointer to store number of carrier changes
2354 *
2355 * @return 0 on success, negative error number otherwise
2356 */
2357 int rtnl_link_get_carrier_changes(struct rtnl_link *link, uint32_t *carrier_changes)
2358{
2359 if (!(link->ce_mask & LINK_ATTR_CARRIER_CHANGES))
2360 return -NLE_NOATTR;
2361
2362 if (carrier_changes)
2363 *carrier_changes = link->l_carrier_changes;
2364
2365 return 0;
2366}
2367
2368/**
2369 * Set operational status of link object
2370 * @arg link Link object
2371 * @arg status New opertional status
2372 *
2373 * @route_doc{link_attr_operstate, Operational Status}}
2374 * @see rtnl_link_get_operstate()
2375 */
2376 void rtnl_link_set_operstate(struct rtnl_link *link, uint8_t status)
2377{
2378 link->l_operstate = status;
2379 link->ce_mask |= LINK_ATTR_OPERSTATE;
2380}
2381
2382/**
2383 * Return operational status of link object
2384 * @arg link Link object
2385 *
2386 * @route_doc{link_attr_operstate, Operational Status}
2387 * @see rtnl_link_set_operstate()
2388 * @return Opertional state or \c IF_OPER_UNKNOWN
2389 */
2390uint8_t rtnl_link_get_operstate(struct rtnl_link *link)
2391{
2392 return link->l_operstate;
2393}
2394
2395/**
2396 * Set link mode of link object
2397 * @arg link Link object
2398 * @arg mode New link mode
2399 *
2400 * @route_doc{link_attr_mode, Mode}
2401 * @see rtnl_link_get_linkmode()
2402 */
2403 void rtnl_link_set_linkmode(struct rtnl_link *link, uint8_t mode)
2404{
2405 link->l_linkmode = mode;
2406 link->ce_mask |= LINK_ATTR_LINKMODE;
2407}
2408
2409/**
2410 * Return link mode of link object
2411 * @arg link Link object
2412 *
2413 * @route_doc{link_attr_mode, Mode}
2414 * @see rtnl_link_get_linkmode()
2415 * @return Link mode or \c IF_LINK_MODE_DEFAULT
2416 */
2417uint8_t rtnl_link_get_linkmode(struct rtnl_link *link)
2418{
2419 return link->l_linkmode;
2420}
2421
2422/**
2423 * Return alias name of link object (SNMP IfAlias)
2424 * @arg link Link object
2425 *
2426 * @route_doc{link_attr_alias, Alias}
2427 * @see rtnl_link_set_ifalias()
2428 * @return Alias name or NULL if not set.
2429 */
2430 const char *rtnl_link_get_ifalias(struct rtnl_link *link)
2431{
2432 return link->l_ifalias;
2433}
2434
2435/**
2436 * Set alias name of link object (SNMP IfAlias)
2437 * @arg link Link object
2438 * @arg alias Alias name or NULL to unset
2439 *
2440 * Sets the alias name of the link to the specified name. The alias
2441 * name can be unset by specyfing NULL as the alias. The name will
2442 * be strdup()ed, so no need to provide a persistent character string.
2443 *
2444 * @route_doc{link_attr_alias, Alias}
2445 * @see rtnl_link_get_ifalias()
2446 */
2447 void rtnl_link_set_ifalias(struct rtnl_link *link, const char *alias)
2448{
2449 free(link->l_ifalias);
2450
2451 if (alias) {
2452 link->l_ifalias = strdup(alias);
2453 link->ce_mask |= LINK_ATTR_IFALIAS;
2454 } else {
2455 link->l_ifalias = NULL;
2456 link->ce_mask &= ~LINK_ATTR_IFALIAS;
2457 }
2458}
2459
2460/**
2461 * Set queueing discipline name of link object
2462 * @arg link Link object
2463 * @arg name Name of queueing discipline
2464 *
2465 * @copydoc read_only_attribute
2466 *
2467 * For more information on how to modify the qdisc of a link, see section
2468 * @ref_route{route_tc, Traffic Control}.
2469 *
2470 * @route_doc{link_attr_qdisc, Queueing Discipline Name}
2471 * @see rtnl_link_get_qdisc()
2472 */
2473 void rtnl_link_set_qdisc(struct rtnl_link *link, const char *name)
2474{
2475 _nl_strncpy_trunc(link->l_qdisc, name, sizeof(link->l_qdisc));
2476 link->ce_mask |= LINK_ATTR_QDISC;
2477}
2478
2479/**
2480 * Return name of queueing discipline of link object
2481 * @arg link Link object
2482 *
2483 * @route_doc{link_attr_qdisc, Queueing Discipline Name}
2484 * @see rtnl_link_set_qdisc()
2485 * @return Name of qdisc or NULL if not specified.
2486 */
2487 char *rtnl_link_get_qdisc(struct rtnl_link *link)
2488{
2489 return link->ce_mask & LINK_ATTR_QDISC ? link->l_qdisc : NULL;
2490}
2491
2492
2493/**
2494 * Return number of PCI virtual functions of link object
2495 * @arg link Link object
2496 * @arg num_vf Pointer to store number of VFs
2497 *
2498 * @return 0 on success or -NLE_OPNOTSUPP if not available
2499 */
2500 int rtnl_link_get_num_vf(struct rtnl_link *link, uint32_t *num_vf)
2501{
2502 if (link->ce_mask & LINK_ATTR_NUM_VF) {
2503 *num_vf = link->l_num_vf;
2504 return 0;
2505 } else
2506 return -NLE_OPNOTSUPP;
2507}
2508
2509/**
2510 * Return value of link statistics counter
2511 * @arg link Link object
2512 * @arg id Identifier of statistical counter
2513 *
2514 * @return Value of counter or 0 if not specified.
2515 */
2516uint64_t rtnl_link_get_stat(struct rtnl_link *link, rtnl_link_stat_id_t id)
2517{
2518 if (id > RTNL_LINK_STATS_MAX)
2519 return 0;
2520
2521 return link->l_stats[id];
2522}
2523
2524/**
2525 * Set value of link statistics counter
2526 * @arg link Link object
2527 * @arg id Identifier of statistical counter
2528 * @arg value New value
2529 *
2530 * \note Changing the value of a statistical counter will not change the
2531 * value in the kernel.
2532 *
2533 * @return 0 on success or a negative error code
2534 */
2535 int rtnl_link_set_stat(struct rtnl_link *link, rtnl_link_stat_id_t id,
2536 const uint64_t value)
2537{
2538 if (id > RTNL_LINK_STATS_MAX)
2539 return -NLE_INVAL;
2540
2541 link->l_stats[id] = value;
2542
2543 return 0;
2544}
2545
2546/**
2547 * Set type of link object
2548 * @arg link Link object
2549 * @arg type Name of link type
2550 *
2551 * Looks up the link type module and prepares the link to store type
2552 * specific attributes. If a type has been assigned already it will
2553 * be released with all link type specific attributes lost.
2554 *
2555 * @route_doc{link_modules, Link Modules}
2556 * @return 0 on success or a negative error code.
2557 */
2558 int rtnl_link_set_type(struct rtnl_link *link, const char *type)
2559{
2560 struct rtnl_link_info_ops *io;
2561 _nl_auto_free char *kind = NULL;
2562 int err;
2563
2564 free(link->l_info_kind);
2565 link->ce_mask &= ~LINK_ATTR_LINKINFO;
2566 release_link_info(link);
2567
2568 if (!type)
2569 return 0;
2570
2571 kind = strdup(type);
2572 if (!kind)
2573 return -NLE_NOMEM;
2574
2575 io = rtnl_link_info_ops_lookup(type);
2576 if (io) {
2577 if (io->io_alloc && (err = io->io_alloc(link)) < 0) {
2578 _nl_clear_free(&kind);
2579 return err;
2580 }
2581
2582 link->l_info_ops = io;
2583 }
2584
2585 link->l_info_kind = _nl_steal_pointer(&kind);
2586 link->ce_mask |= LINK_ATTR_LINKINFO;
2587
2588 return 0;
2589}
2590
2591/**
2592 * Return type of link
2593 * @arg link Link object
2594 *
2595 * @route_doc{link_modules, Link Modules}
2596 * @return Name of link type or NULL if not specified.
2597 */
2598 char *rtnl_link_get_type(struct rtnl_link *link)
2599{
2600 return link->l_info_kind;
2601}
2602
2603/**
2604 * Set type of slave link object
2605 * @arg link Link object (slave)
2606 * @arg type Name of link type
2607 *
2608 * If a slave type has been assigned already it will be released.
2609 *
2610 * @route_doc{link_modules, Link Modules}
2611 * @return 0 on success or a negative error code.
2612 */
2613 int rtnl_link_set_slave_type(struct rtnl_link *link, const char *type)
2614{
2615 char *kind = NULL;
2616
2617 if (type) {
2618 kind = strdup(type);
2619 if (!kind)
2620 return -NLE_NOMEM;
2621 }
2622
2623 free(link->l_info_slave_kind);
2624 link->l_info_slave_kind = kind;
2625
2626 if (kind)
2627 link->ce_mask |= LINK_ATTR_LINKINFO_SLAVE_KIND;
2628 else
2629 link->ce_mask &= ~LINK_ATTR_LINKINFO_SLAVE_KIND;
2630 return 0;
2631}
2632
2633/**
2634 * Return type of enslaved link
2635 * @arg link Link object
2636 *
2637 * @route_doc{link_modules, Link Modules}
2638 * @return Name of enslaved link type or NULL if not specified.
2639 */
2640 const char *rtnl_link_get_slave_type(const struct rtnl_link *link)
2641{
2642 return link->l_info_slave_kind;
2643}
2644
2645
2646/**
2647 * Set link promiscuity count
2648 * @arg link Link object
2649 * @arg count New promiscuity count
2650 *
2651 * @copydoc read_only_attribute
2652 *
2653 * @see rtnl_link_get_promiscuity()
2654 */
2655 void rtnl_link_set_promiscuity(struct rtnl_link *link, uint32_t count)
2656{
2657 link->l_promiscuity = count;
2658 link->ce_mask |= LINK_ATTR_PROMISCUITY;
2659}
2660
2661/**
2662 * Return link promiscuity count
2663 * @arg link Link object
2664 *
2665 * @see rtnl_link_set_promiscuity()
2666 * @return Link promiscuity count or 0
2667 */
2668uint32_t rtnl_link_get_promiscuity(struct rtnl_link *link)
2669{
2670 return link->l_promiscuity;
2671}
2672
2673/**
2674 * Set number of TX queues
2675 * @arg link Link object
2676 * @arg nqueues Number of queues
2677 *
2678 * Sets the number of TX queues of the link object. The value is considered
2679 * by the kernel when creating network devices that can be created via
2680 * netlink. The value will be passed on to alloc_netdev_mqs()
2681 *
2682 * Therefore use of rtnl_link_set_num_tx_queues() only makes sense in
2683 * combination with rtnl_link_add() or if the link object is used as a filter.
2684 *
2685 * @see rtnl_link_get_num_tx_queues()
2686 */
2687 void rtnl_link_set_num_tx_queues(struct rtnl_link *link, uint32_t nqueues)
2688{
2689 link->l_num_tx_queues = nqueues;
2690 link->ce_mask |= LINK_ATTR_NUM_TX_QUEUES;
2691}
2692
2693/**
2694 * Return number of TX queues
2695 * @arg link Link object
2696 *
2697 * @return Number of TX queues or 0
2698 */
2699uint32_t rtnl_link_get_num_tx_queues(struct rtnl_link *link)
2700{
2701 return link->l_num_tx_queues;
2702}
2703
2704/**
2705 * Set number of RX queues
2706 * @arg link Link object
2707 * @arg nqueues Number of queues
2708 *
2709 * Sets the number of RX queues of the link object. The value is considered
2710 * by the kernel when creating network devices that can be created via
2711 * netlink. The value will be passed on to alloc_netdev_mqs()
2712 *
2713 * Therefore use of rtnl_link_set_num_rx_queues() only makes sense in
2714 * combination with rtnl_link_add() or if the link object is used as a filter.
2715 *
2716 * @see rtnl_link_get_num_rx_queues()
2717 */
2718 void rtnl_link_set_num_rx_queues(struct rtnl_link *link, uint32_t nqueues)
2719{
2720 link->l_num_rx_queues = nqueues;
2721 link->ce_mask |= LINK_ATTR_NUM_RX_QUEUES;
2722}
2723
2724/**
2725 * Return number of RX queues
2726 * @arg link Link object
2727 *
2728 * @return Number of RX queues or 0
2729 */
2730uint32_t rtnl_link_get_num_rx_queues(struct rtnl_link *link)
2731{
2732 return link->l_num_rx_queues;
2733}
2734
2735/**
2736 * Return maximum number of segments for generic segmentation offload
2737 * @arg link Link object
2738 * @arg gso_max_segs Pointer to store maximum number GSO segments
2739 *
2740 * @return 0 on success, negative error number otherwise
2741 */
2742 int rtnl_link_get_gso_max_segs(struct rtnl_link *link, uint32_t *gso_max_segs)
2743{
2744 if (!(link->ce_mask & LINK_ATTR_GSO_MAX_SEGS))
2745 return -NLE_NOATTR;
2746
2747 if (gso_max_segs)
2748 *gso_max_segs = link->l_gso_max_segs;
2749
2750 return 0;
2751}
2752
2753/**
2754 * Return maximum size for generic segmentation offload
2755 * @arg link Link object
2756 * @arg gso_max_segs Pointer to store maximum GSO size
2757 *
2758 * @return 0 on success, negative error number otherwise
2759 */
2760 int rtnl_link_get_gso_max_size(struct rtnl_link *link, uint32_t *gso_max_size)
2761{
2762 if (!(link->ce_mask & LINK_ATTR_GSO_MAX_SIZE))
2763 return -NLE_NOATTR;
2764
2765 if (gso_max_size)
2766 *gso_max_size = link->l_gso_max_size;
2767
2768 return 0;
2769}
2770
2771/**
2772 * Return physical port id of link object
2773 * @arg link Link object
2774 *
2775 * @return Physical port id or NULL if not set.
2776 */
2777 struct nl_data *rtnl_link_get_phys_port_id(struct rtnl_link *link)
2778{
2779 return link->l_phys_port_id;
2780}
2781
2782/**
2783 * Return physical port name of link object
2784 * @arg link Link object
2785 *
2786 * @return Physical port name or NULL if not set.
2787 */
2788 char *rtnl_link_get_phys_port_name(struct rtnl_link *link)
2789{
2790 return link->l_phys_port_name;
2791}
2792
2793/*
2794 * Return physical switch id of link object
2795 * @arg link Link object
2796 *
2797 * @return Physical switch id or NULL if not set.
2798 */
2799struct nl_data *rtnl_link_get_phys_switch_id(struct rtnl_link *link)
2800{
2801 return link->l_phys_switch_id;
2802}
2803
2804void rtnl_link_set_ns_fd(struct rtnl_link *link, int fd)
2805{
2806 link->l_ns_fd = fd;
2807 link->ce_mask |= LINK_ATTR_NS_FD;
2808}
2809
2810int rtnl_link_get_ns_fd(struct rtnl_link *link)
2811{
2812 return link->l_ns_fd;
2813}
2814
2815void rtnl_link_set_ns_pid(struct rtnl_link *link, pid_t pid)
2816{
2817 link->l_ns_pid = pid;
2818 link->ce_mask |= LINK_ATTR_NS_PID;
2819}
2820
2821pid_t rtnl_link_get_ns_pid(struct rtnl_link *link)
2822{
2823 return link->l_ns_pid;
2824}
2825
2826/** @} */
2827
2828/**
2829 * @name Master/Slave
2830 * @{
2831 */
2832
2833/**
2834 * Enslave slave link to master link
2835 * @arg sock netlink socket
2836 * @arg master ifindex of master link
2837 * @arg slave ifindex of slave link
2838 *
2839 * This function is identical to rtnl_link_enslave() except that
2840 * it takes interface indices instead of rtnl_link objects.
2841 *
2842 * @see rtnl_link_enslave()
2843 *
2844 * @return 0 on success or a negative error code.
2845 */
2846 int rtnl_link_enslave_ifindex(struct nl_sock *sock, int master, int slave)
2847{
2848 _nl_auto_rtnl_link struct rtnl_link *link = NULL;
2849 int err;
2850
2851 if (!(link = rtnl_link_alloc()))
2852 return -NLE_NOMEM;
2853
2854 rtnl_link_set_ifindex(link, slave);
2855 rtnl_link_set_master(link, master);
2856
2857 if ((err = rtnl_link_change(sock, link, link, 0)) < 0)
2858 return err;
2859
2860 _nl_clear_pointer(&link, rtnl_link_put);
2861
2862 /*
2863 * Due to the kernel not signaling whether this operation is
2864 * supported or not, we will retrieve the attribute to see if the
2865 * request was successful. If the master assigned remains unchanged
2866 * we will return NLE_OPNOTSUPP to allow performing backwards
2867 * compatibility of some sort.
2868 */
2869 if ((err = rtnl_link_get_kernel(sock, slave, NULL, &link)) < 0)
2870 return err;
2871
2872 if (rtnl_link_get_master(link) != master)
2873 return -NLE_OPNOTSUPP;
2874
2875 return 0;
2876}
2877
2878/**
2879 * Enslave slave link to master link
2880 * @arg sock netlink socket
2881 * @arg master master link
2882 * @arg slave slave link
2883 *
2884 * Constructs a RTM_NEWLINK or RTM_SETLINK message adding the slave to
2885 * the master and sends the request via the specified netlink socket.
2886 *
2887 * @note The feature of enslaving/releasing via netlink has only been added
2888 * recently to the kernel (Feb 2011). Also, the kernel does not signal
2889 * if the operation is not supported. Therefore this function will
2890 * verify if the master assignment has changed and will return
2891 * -NLE_OPNOTSUPP if it did not.
2892 *
2893 * @see rtnl_link_enslave_ifindex()
2894 * @see rtnl_link_release()
2895 *
2896 * @return 0 on success or a negative error code.
2897 */
2898 int rtnl_link_enslave(struct nl_sock *sock, struct rtnl_link *master,
2899 struct rtnl_link *slave)
2900{
2901 return rtnl_link_enslave_ifindex(sock, rtnl_link_get_ifindex(master),
2902 rtnl_link_get_ifindex(slave));
2903}
2904
2905/**
2906 * Release slave link from its master
2907 * @arg sock netlink socket
2908 * @arg slave slave link
2909 *
2910 * This function is identical to rtnl_link_release() except that
2911 * it takes an interface index instead of a rtnl_link object.
2912 *
2913 * @see rtnl_link_release()
2914 *
2915 * @return 0 on success or a negative error code.
2916 */
2917 int rtnl_link_release_ifindex(struct nl_sock *sock, int slave)
2918{
2919 return rtnl_link_enslave_ifindex(sock, 0, slave);
2920}
2921
2922/**
2923 * Release slave link from its master
2924 * @arg sock netlink socket
2925 * @arg slave slave link
2926 *
2927 * Constructs a RTM_NEWLINK or RTM_SETLINK message releasing the slave from
2928 * its master and sends the request via the specified netlink socket.
2929 *
2930 * @note The feature of enslaving/releasing via netlink has only been added
2931 * recently to the kernel (Feb 2011). Also, the kernel does not signal
2932 * if the operation is not supported. Therefore this function will
2933 * verify if the master assignment has changed and will return
2934 * -NLE_OPNOTSUPP if it did not.
2935 *
2936 * @see rtnl_link_release_ifindex()
2937 * @see rtnl_link_enslave()
2938 *
2939 * @return 0 on success or a negative error code.
2940 */
2941 int rtnl_link_release(struct nl_sock *sock, struct rtnl_link *slave)
2942{
2943 return rtnl_link_release_ifindex(sock, rtnl_link_get_ifindex(slave));
2944}
2945
2946/** @} */
2947
2948/**
2949 * @name Utilities
2950 * @{
2951 */
2952
2953static const struct trans_tbl link_flags[] = {
2954 __ADD(IFF_LOOPBACK, loopback),
2955 __ADD(IFF_BROADCAST, broadcast),
2956 __ADD(IFF_POINTOPOINT, pointopoint),
2957 __ADD(IFF_MULTICAST, multicast),
2958 __ADD(IFF_NOARP, noarp),
2959 __ADD(IFF_ALLMULTI, allmulti),
2960 __ADD(IFF_PROMISC, promisc),
2961 __ADD(IFF_MASTER, master),
2962 __ADD(IFF_SLAVE, slave),
2963 __ADD(IFF_DEBUG, debug),
2964 __ADD(IFF_DYNAMIC, dynamic),
2965 __ADD(IFF_AUTOMEDIA, automedia),
2966 __ADD(IFF_PORTSEL, portsel),
2967 __ADD(IFF_NOTRAILERS, notrailers),
2968 __ADD(IFF_UP, up),
2969 __ADD(IFF_RUNNING, running),
2970 __ADD(IFF_LOWER_UP, lowerup),
2971 __ADD(IFF_DORMANT, dormant),
2972 __ADD(IFF_ECHO, echo),
2973};
2974
2975char *rtnl_link_flags2str(int flags, char *buf, size_t len)
2976{
2977 return __flags2str(flags, buf, len, link_flags,
2978 ARRAY_SIZE(link_flags));
2979}
2980
2981int rtnl_link_str2flags(const char *name)
2982{
2983 return __str2flags(name, link_flags, ARRAY_SIZE(link_flags));
2984}
2985
2986static const struct trans_tbl link_stats[] = {
2987 __ADD(RTNL_LINK_RX_PACKETS, rx_packets),
2988 __ADD(RTNL_LINK_TX_PACKETS, tx_packets),
2989 __ADD(RTNL_LINK_RX_BYTES, rx_bytes),
2990 __ADD(RTNL_LINK_TX_BYTES, tx_bytes),
2991 __ADD(RTNL_LINK_RX_ERRORS, rx_errors),
2992 __ADD(RTNL_LINK_TX_ERRORS, tx_errors),
2993 __ADD(RTNL_LINK_RX_DROPPED, rx_dropped),
2994 __ADD(RTNL_LINK_TX_DROPPED, tx_dropped),
2995 __ADD(RTNL_LINK_RX_COMPRESSED, rx_compressed),
2996 __ADD(RTNL_LINK_TX_COMPRESSED, tx_compressed),
2997 __ADD(RTNL_LINK_RX_FIFO_ERR, rx_fifo_err),
2998 __ADD(RTNL_LINK_TX_FIFO_ERR, tx_fifo_err),
2999 __ADD(RTNL_LINK_RX_LEN_ERR, rx_len_err),
3000 __ADD(RTNL_LINK_RX_OVER_ERR, rx_over_err),
3001 __ADD(RTNL_LINK_RX_CRC_ERR, rx_crc_err),
3002 __ADD(RTNL_LINK_RX_FRAME_ERR, rx_frame_err),
3003 __ADD(RTNL_LINK_RX_MISSED_ERR, rx_missed_err),
3004 __ADD(RTNL_LINK_TX_ABORT_ERR, tx_abort_err),
3005 __ADD(RTNL_LINK_TX_CARRIER_ERR, tx_carrier_err),
3006 __ADD(RTNL_LINK_TX_HBEAT_ERR, tx_hbeat_err),
3007 __ADD(RTNL_LINK_TX_WIN_ERR, tx_win_err),
3008 __ADD(RTNL_LINK_COLLISIONS, collisions),
3009 __ADD(RTNL_LINK_MULTICAST, multicast),
3010 __ADD(RTNL_LINK_IP6_INPKTS, Ip6InReceives),
3011 __ADD(RTNL_LINK_IP6_INHDRERRORS, Ip6InHdrErrors),
3012 __ADD(RTNL_LINK_IP6_INTOOBIGERRORS, Ip6InTooBigErrors),
3013 __ADD(RTNL_LINK_IP6_INNOROUTES, Ip6InNoRoutes),
3014 __ADD(RTNL_LINK_IP6_INADDRERRORS, Ip6InAddrErrors),
3015 __ADD(RTNL_LINK_IP6_INUNKNOWNPROTOS, Ip6InUnknownProtos),
3016 __ADD(RTNL_LINK_IP6_INTRUNCATEDPKTS, Ip6InTruncatedPkts),
3017 __ADD(RTNL_LINK_IP6_INDISCARDS, Ip6InDiscards),
3018 __ADD(RTNL_LINK_IP6_INDELIVERS, Ip6InDelivers),
3019 __ADD(RTNL_LINK_IP6_OUTFORWDATAGRAMS, Ip6OutForwDatagrams),
3020 __ADD(RTNL_LINK_IP6_OUTPKTS, Ip6OutRequests),
3021 __ADD(RTNL_LINK_IP6_OUTDISCARDS, Ip6OutDiscards),
3022 __ADD(RTNL_LINK_IP6_OUTNOROUTES, Ip6OutNoRoutes),
3023 __ADD(RTNL_LINK_IP6_REASMTIMEOUT, Ip6ReasmTimeout),
3024 __ADD(RTNL_LINK_IP6_REASMREQDS, Ip6ReasmReqds),
3025 __ADD(RTNL_LINK_IP6_REASMOKS, Ip6ReasmOKs),
3026 __ADD(RTNL_LINK_IP6_REASMFAILS, Ip6ReasmFails),
3027 __ADD(RTNL_LINK_IP6_FRAGOKS, Ip6FragOKs),
3028 __ADD(RTNL_LINK_IP6_FRAGFAILS, Ip6FragFails),
3029 __ADD(RTNL_LINK_IP6_FRAGCREATES, Ip6FragCreates),
3030 __ADD(RTNL_LINK_IP6_INMCASTPKTS, Ip6InMcastPkts),
3031 __ADD(RTNL_LINK_IP6_OUTMCASTPKTS, Ip6OutMcastPkts),
3032 __ADD(RTNL_LINK_IP6_INBCASTPKTS, Ip6InBcastPkts),
3033 __ADD(RTNL_LINK_IP6_OUTBCASTPKTS, Ip6OutBcastPkts),
3034 __ADD(RTNL_LINK_IP6_INOCTETS, Ip6InOctets),
3035 __ADD(RTNL_LINK_IP6_OUTOCTETS, Ip6OutOctets),
3036 __ADD(RTNL_LINK_IP6_INMCASTOCTETS, Ip6InMcastOctets),
3037 __ADD(RTNL_LINK_IP6_OUTMCASTOCTETS, Ip6OutMcastOctets),
3038 __ADD(RTNL_LINK_IP6_INBCASTOCTETS, Ip6InBcastOctets),
3039 __ADD(RTNL_LINK_IP6_OUTBCASTOCTETS, Ip6OutBcastOctets),
3040 __ADD(RTNL_LINK_ICMP6_INMSGS, ICMP6_InMsgs),
3041 __ADD(RTNL_LINK_ICMP6_INERRORS, ICMP6_InErrors),
3042 __ADD(RTNL_LINK_ICMP6_OUTMSGS, ICMP6_OutMsgs),
3043 __ADD(RTNL_LINK_ICMP6_OUTERRORS, ICMP6_OutErrors),
3044 __ADD(RTNL_LINK_ICMP6_CSUMERRORS, ICMP6_InCsumErrors),
3045 __ADD(RTNL_LINK_IP6_CSUMERRORS, Ip6_InCsumErrors),
3046 __ADD(RTNL_LINK_IP6_NOECTPKTS, Ip6_InNoECTPkts),
3047 __ADD(RTNL_LINK_IP6_ECT1PKTS, Ip6_InECT1Pkts),
3048 __ADD(RTNL_LINK_IP6_ECT0PKTS, Ip6_InECT0Pkts),
3049 __ADD(RTNL_LINK_IP6_CEPKTS, Ip6_InCEPkts),
3050 __ADD(RTNL_LINK_RX_NOHANDLER, rx_nohandler),
3051 __ADD(RTNL_LINK_REASM_OVERLAPS, ReasmOverlaps),
3052};
3053
3054char *rtnl_link_stat2str(int st, char *buf, size_t len)
3055{
3056 return __type2str(st, buf, len, link_stats, ARRAY_SIZE(link_stats));
3057}
3058
3059int rtnl_link_str2stat(const char *name)
3060{
3061 return __str2type(name, link_stats, ARRAY_SIZE(link_stats));
3062}
3063
3064static const struct trans_tbl link_operstates[] = {
3065 __ADD(IF_OPER_UNKNOWN, unknown),
3066 __ADD(IF_OPER_NOTPRESENT, notpresent),
3067 __ADD(IF_OPER_DOWN, down),
3068 __ADD(IF_OPER_LOWERLAYERDOWN, lowerlayerdown),
3069 __ADD(IF_OPER_TESTING, testing),
3070 __ADD(IF_OPER_DORMANT, dormant),
3071 __ADD(IF_OPER_UP, up),
3072};
3073
3074char *rtnl_link_operstate2str(uint8_t st, char *buf, size_t len)
3075{
3076 return __type2str(st, buf, len, link_operstates,
3077 ARRAY_SIZE(link_operstates));
3078}
3079
3080int rtnl_link_str2operstate(const char *name)
3081{
3082 return __str2type(name, link_operstates,
3083 ARRAY_SIZE(link_operstates));
3084}
3085
3086static const struct trans_tbl link_modes[] = {
3087 __ADD(IF_LINK_MODE_DEFAULT, default),
3088 __ADD(IF_LINK_MODE_DORMANT, dormant),
3089};
3090
3091static const struct trans_tbl carrier_states[] = {
3092 __ADD(0, down),
3093 __ADD(1, up),
3094};
3095
3096char *rtnl_link_mode2str(uint8_t st, char *buf, size_t len)
3097{
3098 return __type2str(st, buf, len, link_modes, ARRAY_SIZE(link_modes));
3099}
3100
3101int rtnl_link_str2mode(const char *name)
3102{
3103 return __str2type(name, link_modes, ARRAY_SIZE(link_modes));
3104}
3105
3106char *rtnl_link_carrier2str(uint8_t st, char *buf, size_t len)
3107{
3108 return __type2str(st, buf, len, carrier_states,
3109 ARRAY_SIZE(carrier_states));
3110}
3111
3112int rtnl_link_str2carrier(const char *name)
3113{
3114 return __str2type(name, carrier_states, ARRAY_SIZE(carrier_states));
3115}
3116
3117int rtnl_link_has_vf_list(struct rtnl_link *link) {
3118 if (link->ce_mask & LINK_ATTR_VF_LIST)
3119 return 1;
3120 else
3121 return 0;
3122}
3123
3124void rtnl_link_set_vf_list(struct rtnl_link *link)
3125{
3126 if (!rtnl_link_has_vf_list(link))
3127 link->ce_mask |= LINK_ATTR_VF_LIST;
3128}
3129
3130void rtnl_link_unset_vf_list(struct rtnl_link *link)
3131{
3132 if (rtnl_link_has_vf_list(link))
3133 link->ce_mask &= ~LINK_ATTR_VF_LIST;
3134}
3135
3136/** @} */
3137
3138/**
3139 * @name Deprecated Functions
3140 */
3141
3142/**
3143 * @deprecated Use of this function is deprecated, use rtnl_link_set_type()
3144 */
3145 int rtnl_link_set_info_type(struct rtnl_link *link, const char *type)
3146{
3147 return rtnl_link_set_type(link, type);
3148}
3149
3150/**
3151 * @deprecated Use of this function is deprecated, use rtnl_link_get_type()
3152 */
3153 char *rtnl_link_get_info_type(struct rtnl_link *link)
3154{
3155 return rtnl_link_get_type(link);
3156}
3157
3158/**
3159 * @deprecated The weight attribute is unused and obsoleted in all recent kernels
3160 */
3161 void rtnl_link_set_weight(struct rtnl_link *link, unsigned int weight)
3162{
3163 link->l_weight = weight;
3164 link->ce_mask |= LINK_ATTR_WEIGHT;
3165}
3166
3167/**
3168 * @deprecated The weight attribute is unused and obsoleted in all recent kernels
3169 */
3170 unsigned int rtnl_link_get_weight(struct rtnl_link *link)
3171{
3172 return link->l_weight;
3173}
3174
3175/** @} */
3176
3177static struct nl_object_ops link_obj_ops = {
3178 .oo_name = "route/link",
3179 .oo_size = sizeof(struct rtnl_link),
3180 .oo_free_data = link_free_data,
3181 .oo_clone = link_clone,
3182 .oo_dump = {
3183 [NL_DUMP_LINE] = link_dump_line,
3184 [NL_DUMP_DETAILS] = link_dump_details,
3185 [NL_DUMP_STATS] = link_dump_stats,
3186 },
3187 .oo_compare = link_compare,
3188 .oo_keygen = link_keygen,
3189 .oo_attrs2str = link_attrs2str,
3190 .oo_id_attrs = LINK_ATTR_IFINDEX | LINK_ATTR_FAMILY,
3191};
3192
3193static struct nl_af_group link_groups[] = {
3194 { AF_UNSPEC, RTNLGRP_LINK },
3195 { AF_BRIDGE, RTNLGRP_LINK },
3196 { AF_INET6, RTNLGRP_IPV6_IFINFO },
3197 { END_OF_GROUP_LIST },
3198};
3199
3200static struct nl_cache_ops rtnl_link_ops = {
3201 .co_name = "route/link",
3202 .co_hdrsize = sizeof(struct ifinfomsg),
3203 .co_msgtypes = {
3204 { RTM_NEWLINK, NL_ACT_NEW, "new" },
3205 { RTM_DELLINK, NL_ACT_DEL, "del" },
3206 { RTM_GETLINK, NL_ACT_GET, "get" },
3207 { RTM_SETLINK, NL_ACT_CHANGE, "set" },
3208 END_OF_MSGTYPES_LIST,
3209 },
3210 .co_protocol = NETLINK_ROUTE,
3211 .co_groups = link_groups,
3212 .co_request_update = link_request_update,
3213 .co_msg_parser = link_msg_parser,
3214 .co_obj_ops = &link_obj_ops,
3215};
3216
3217static void _nl_init link_init(void)
3218{
3219 nl_cache_mngt_register(&rtnl_link_ops);
3220}
3221
3222static void _nl_exit link_exit(void)
3223{
3224 nl_cache_mngt_unregister(&rtnl_link_ops);
3225}
3226
3227/** @} */
nl_addr_iszero
int nl_addr_iszero(const struct nl_addr *addr)
Returns true if the address consists of all zeros.
Definition addr.c:652
nl_addr_get
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
Definition addr.c:525
nl_addr_alloc_attr
struct nl_addr * nl_addr_alloc_attr(const struct nlattr *nla, int family)
Allocate abstract address based on Netlink attribute.
Definition addr.c:261
nl_addr_cmp
int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
Compare abstract addresses.
Definition addr.c:587
nl_addr_clone
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
Definition addr.c:495
nl_addr2str
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
Definition addr.c:1001
nl_addr_put
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
Definition addr.c:541
nl_addr_set_family
void nl_addr_set_family(struct nl_addr *addr, int family)
Set address family.
Definition addr.c:882
nl_addr_guess_family
int nl_addr_guess_family(const struct nl_addr *addr)
Guess address family of abstract address based on address size.
Definition addr.c:711
nla_get_u32
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition attr.c:712
NLA_PUT_U8
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
Definition attr.h:194
NLA_PUT_S32
#define NLA_PUT_S32(msg, attrtype, value)
Add 32 bit signed integer attribute to netlink message.
Definition attr.h:221
nla_put_string
int nla_put_string(struct nl_msg *msg, int attrtype, const char *str)
Add string attribute to netlink message.
Definition attr.c:792
nla_type
int nla_type(const struct nlattr *nla)
Return type of the attribute.
Definition attr.c:108
NLA_PUT_ADDR
#define NLA_PUT_ADDR(msg, attrtype, addr)
Add address attribute to netlink message.
Definition attr.h:283
nla_data
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
Definition attr.c:119
NLA_PUT_U32
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
Definition attr.h:230
nla_get_u8
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
Definition attr.c:612
nla_memcpy
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
Definition attr.c:353
nla_nest_start
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
Definition attr.c:908
nla_strlcpy
size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
Copy string attribute payload to a buffer.
Definition attr.c:381
nla_parse_nested
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, const struct nla_policy *policy)
Create attribute index based on nested attribute.
Definition attr.c:1035
nla_get_string
char * nla_get_string(const struct nlattr *nla)
Return payload of string attribute.
Definition attr.c:803
nla_get_s32
int32_t nla_get_s32(const struct nlattr *nla)
Return payload of 32 bit signed integer attribute.
Definition attr.c:687
nla_for_each_nested
#define nla_for_each_nested(pos, nla, rem)
Iterate over a stream of nested attributes.
Definition attr.h:324
NLA_PUT_STRING
#define NLA_PUT_STRING(msg, attrtype, value)
Add string attribute to netlink message.
Definition attr.h:257
nla_nest_end
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
Definition attr.c:971
nla_put
int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data)
Add a unspecific attribute to netlink message.
Definition attr.c:503
NLA_STRING
@ NLA_STRING
NUL terminated character string.
Definition attr.h:39
NLA_UNSPEC
@ NLA_UNSPEC
Unspecified type, binary data chunk.
Definition attr.h:34
NLA_U8
@ NLA_U8
8 bit integer
Definition attr.h:35
NLA_NESTED
@ NLA_NESTED
Nested attributes.
Definition attr.h:42
NLA_U32
@ NLA_U32
32 bit integer
Definition attr.h:37
nl_cache_mngt_unregister
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
Definition cache_mngt.c:287
nl_cache_mngt_register
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
Definition cache_mngt.c:252
nl_cache_mngt_require_safe
struct nl_cache * nl_cache_mngt_require_safe(const char *name)
Return cache previously provided via nl_cache_mngt_provide()
Definition cache_mngt.c:430
nl_cache_refill
int nl_cache_refill(struct nl_sock *sk, struct nl_cache *cache)
(Re)fill a cache with the contents in the kernel.
Definition cache.c:1041
nl_cache_set_flags
void nl_cache_set_flags(struct nl_cache *cache, unsigned int flags)
Set cache flags.
Definition cache.c:614
nl_cache_free
void nl_cache_free(struct nl_cache *cache)
Free a cache.
Definition cache.c:409
nl_cache_alloc
struct nl_cache * nl_cache_alloc(struct nl_cache_ops *ops)
Allocate new cache.
Definition cache.c:184
nl_data_clone
struct nl_data * nl_data_clone(const struct nl_data *src)
Clone an abstract data object.
Definition data.c:95
nl_data_free
void nl_data_free(struct nl_data *data)
Free an abstract data object.
Definition data.c:134
nl_data_alloc_attr
struct nl_data * nl_data_alloc_attr(const struct nlattr *nla)
Allocate abstract data object based on netlink attribute.
Definition data.c:84
rtnl_link_af_ops_put
void rtnl_link_af_ops_put(struct rtnl_link_af_ops *ops)
Give back reference to a set of operations.
Definition api.c:226
rtnl_link_af_alloc
void * rtnl_link_af_alloc(struct rtnl_link *link, const struct rtnl_link_af_ops *ops)
Allocate and return data buffer for link address family modules.
Definition api.c:249
rtnl_link_info_data_compare
int rtnl_link_info_data_compare(struct rtnl_link *a, struct rtnl_link *b, int flags)
Compare link info data.
Definition api.c:425
rtnl_link_info_ops_get
void rtnl_link_info_ops_get(struct rtnl_link_info_ops *ops)
Take reference to a set of operations.
Definition api.c:90
rtnl_link_info_ops_lookup
struct rtnl_link_info_ops * rtnl_link_info_ops_lookup(const char *name)
Return operations of a specific link info type.
Definition api.c:74
rtnl_link_af_data_compare
int rtnl_link_af_data_compare(struct rtnl_link *a, struct rtnl_link *b, int family)
Compare af data for a link address family.
Definition api.c:385
rtnl_link_info_ops_put
void rtnl_link_info_ops_put(struct rtnl_link_info_ops *ops)
Give back reference to a set of operations.
Definition api.c:104
rtnl_link_af_ops_lookup
struct rtnl_link_af_ops * rtnl_link_af_ops_lookup(const unsigned int family)
Return operations of a specific link address family.
Definition api.c:209
rtnl_link_release
int rtnl_link_release(struct nl_sock *sock, struct rtnl_link *slave)
Release slave link from its master.
Definition link.c:2941
rtnl_link_add
int rtnl_link_add(struct nl_sock *sk, struct rtnl_link *link, int flags)
Add virtual link.
Definition link.c:1694
rtnl_link_set_broadcast
void rtnl_link_set_broadcast(struct rtnl_link *link, struct nl_addr *addr)
Set link layer broadcast address of link object.
Definition link.c:2043
rtnl_link_set_carrier
void rtnl_link_set_carrier(struct rtnl_link *link, uint8_t status)
Set carrier of link object.
Definition link.c:2332
rtnl_link_get_linkmode
uint8_t rtnl_link_get_linkmode(struct rtnl_link *link)
Return link mode of link object.
Definition link.c:2417
rtnl_link_get_stat
uint64_t rtnl_link_get_stat(struct rtnl_link *link, rtnl_link_stat_id_t id)
Return value of link statistics counter.
Definition link.c:2516
rtnl_link_get_master
int rtnl_link_get_master(struct rtnl_link *link)
Return master link of link object.
Definition link.c:2320
rtnl_link_set_mtu
void rtnl_link_set_mtu(struct rtnl_link *link, unsigned int mtu)
Set Maximum Transmission Unit of link object.
Definition link.c:2205
rtnl_link_set_link_netnsid
int rtnl_link_set_link_netnsid(struct rtnl_link *link, int32_t link_netnsid)
Set the netnsid of the link.
Definition link.c:2274
rtnl_link_get_num_rx_queues
uint32_t rtnl_link_get_num_rx_queues(struct rtnl_link *link)
Return number of RX queues.
Definition link.c:2730
rtnl_link_get_weight
unsigned int rtnl_link_get_weight(struct rtnl_link *link)
Definition link.c:3170
rtnl_link_release_ifindex
int rtnl_link_release_ifindex(struct nl_sock *sock, int slave)
Release slave link from its master.
Definition link.c:2917
rtnl_link_alloc
struct rtnl_link * rtnl_link_alloc(void)
Allocate link object.
Definition link.c:1920
rtnl_link_set_addr
void rtnl_link_set_addr(struct rtnl_link *link, struct nl_addr *addr)
Set link layer address of link object.
Definition link.c:2012
rtnl_link_set_arptype
void rtnl_link_set_arptype(struct rtnl_link *link, unsigned int arptype)
Set hardware type of link object.
Definition link.c:2147
rtnl_link_unset_flags
void rtnl_link_unset_flags(struct rtnl_link *link, unsigned int flags)
Unset flags of link object.
Definition link.c:2085
rtnl_link_set_linkmode
void rtnl_link_set_linkmode(struct rtnl_link *link, uint8_t mode)
Set link mode of link object.
Definition link.c:2403
rtnl_link_get_num_tx_queues
uint32_t rtnl_link_get_num_tx_queues(struct rtnl_link *link)
Return number of TX queues.
Definition link.c:2699
rtnl_link_get_group
uint32_t rtnl_link_get_group(struct rtnl_link *link)
Return the group identifier of link object.
Definition link.c:1984
rtnl_link_get_phys_port_id
struct nl_data * rtnl_link_get_phys_port_id(struct rtnl_link *link)
Return physical port id of link object.
Definition link.c:2777
rtnl_link_get_slave_type
const char * rtnl_link_get_slave_type(const struct rtnl_link *link)
Return type of enslaved link.
Definition link.c:2640
rtnl_link_get_operstate
uint8_t rtnl_link_get_operstate(struct rtnl_link *link)
Return operational status of link object.
Definition link.c:2390
rtnl_link_delete
int rtnl_link_delete(struct nl_sock *sk, const struct rtnl_link *link)
Delete link.
Definition link.c:1896
rtnl_link_get_broadcast
struct nl_addr * rtnl_link_get_broadcast(struct rtnl_link *link)
Return link layer broadcast address of link object.
Definition link.c:2057
rtnl_link_get_num_vf
int rtnl_link_get_num_vf(struct rtnl_link *link, uint32_t *num_vf)
Return number of PCI virtual functions of link object.
Definition link.c:2500
rtnl_link_set_slave_type
int rtnl_link_set_slave_type(struct rtnl_link *link, const char *type)
Set type of slave link object.
Definition link.c:2613
rtnl_link_get_phys_port_name
char * rtnl_link_get_phys_port_name(struct rtnl_link *link)
Return physical port name of link object.
Definition link.c:2788
rtnl_link_build_change_request
int rtnl_link_build_change_request(struct rtnl_link *orig, struct rtnl_link *changes, int flags, struct nl_msg **result)
Build a netlink message requesting the modification of link.
Definition link.c:1726
rtnl_link_set_weight
void rtnl_link_set_weight(struct rtnl_link *link, unsigned int weight)
Definition link.c:3161
rtnl_link_set_ifalias
void rtnl_link_set_ifalias(struct rtnl_link *link, const char *alias)
Set alias name of link object (SNMP IfAlias)
Definition link.c:2447
rtnl_link_get_promiscuity
uint32_t rtnl_link_get_promiscuity(struct rtnl_link *link)
Return link promiscuity count.
Definition link.c:2668
rtnl_link_set_num_tx_queues
void rtnl_link_set_num_tx_queues(struct rtnl_link *link, uint32_t nqueues)
Set number of TX queues.
Definition link.c:2687
rtnl_link_build_add_request
int rtnl_link_build_add_request(struct rtnl_link *link, int flags, struct nl_msg **result)
Build a netlink message requesting the addition of new virtual link.
Definition link.c:1664
rtnl_link_set_name
void rtnl_link_set_name(struct rtnl_link *link, const char *name)
Set name of link object.
Definition link.c:1948
rtnl_link_get_type
char * rtnl_link_get_type(struct rtnl_link *link)
Return type of link.
Definition link.c:2598
rtnl_link_get_qdisc
char * rtnl_link_get_qdisc(struct rtnl_link *link)
Return name of queueing discipline of link object.
Definition link.c:2487
rtnl_link_set_num_rx_queues
void rtnl_link_set_num_rx_queues(struct rtnl_link *link, uint32_t nqueues)
Set number of RX queues.
Definition link.c:2718
rtnl_link_get_by_name
struct rtnl_link * rtnl_link_get_by_name(struct nl_cache *cache, const char *name)
Lookup link in cache by link name.
Definition link.c:1347
rtnl_link_name2i
int rtnl_link_name2i(struct nl_cache *cache, const char *name)
Translate link name to corresponding interface index.
Definition link.c:1506
rtnl_link_alloc_cache
int rtnl_link_alloc_cache(struct nl_sock *sk, int family, struct nl_cache **result)
Allocate link cache and fill in all configured links.
Definition link.c:1294
rtnl_link_get_arptype
unsigned int rtnl_link_get_arptype(struct rtnl_link *link)
Get hardware type of link object.
Definition link.c:2161
rtnl_link_set_group
void rtnl_link_set_group(struct rtnl_link *link, uint32_t group)
Set the group identifier of a link object.
Definition link.c:1972
rtnl_link_get_family
int rtnl_link_get_family(struct rtnl_link *link)
Return address family of link object.
Definition link.c:2133
rtnl_link_get_kernel
int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name, struct rtnl_link **result)
Get a link object directly from kernel.
Definition link.c:1431
rtnl_link_set_flags
void rtnl_link_set_flags(struct rtnl_link *link, unsigned int flags)
Set flags of link object.
Definition link.c:2070
rtnl_link_set_qdisc
void rtnl_link_set_qdisc(struct rtnl_link *link, const char *name)
Set queueing discipline name of link object.
Definition link.c:2473
rtnl_link_get
struct rtnl_link * rtnl_link_get(struct nl_cache *cache, int ifindex)
Lookup link in cache by interface index.
Definition link.c:1315
rtnl_link_get_txqlen
unsigned int rtnl_link_get_txqlen(struct rtnl_link *link)
Return transmission queue length.
Definition link.c:2250
rtnl_link_get_name
char * rtnl_link_get_name(struct rtnl_link *link)
Return name of link object.
Definition link.c:1962
rtnl_link_set_stat
int rtnl_link_set_stat(struct rtnl_link *link, rtnl_link_stat_id_t id, const uint64_t value)
Set value of link statistics counter.
Definition link.c:2535
rtnl_link_alloc_cache_flags
int rtnl_link_alloc_cache_flags(struct nl_sock *sk, int family, struct nl_cache **result, unsigned int flags)
Allocate link cache and fill in all configured links.
Definition link.c:1246
rtnl_link_get_info_type
char * rtnl_link_get_info_type(struct rtnl_link *link)
Definition link.c:3153
rtnl_link_enslave_ifindex
int rtnl_link_enslave_ifindex(struct nl_sock *sock, int master, int slave)
Enslave slave link to master link.
Definition link.c:2846
rtnl_link_build_delete_request
int rtnl_link_build_delete_request(const struct rtnl_link *link, struct nl_msg **result)
Build a netlink message requesting the deletion of a link.
Definition link.c:1847
rtnl_link_set_operstate
void rtnl_link_set_operstate(struct rtnl_link *link, uint8_t status)
Set operational status of link object.
Definition link.c:2376
rtnl_link_enslave
int rtnl_link_enslave(struct nl_sock *sock, struct rtnl_link *master, struct rtnl_link *slave)
Enslave slave link to master link.
Definition link.c:2898
rtnl_link_set_promiscuity
void rtnl_link_set_promiscuity(struct rtnl_link *link, uint32_t count)
Set link promiscuity count.
Definition link.c:2655
rtnl_link_stat_id_t
rtnl_link_stat_id_t
Definition link.h:31
rtnl_link_get_gso_max_segs
int rtnl_link_get_gso_max_segs(struct rtnl_link *link, uint32_t *gso_max_segs)
Return maximum number of segments for generic segmentation offload.
Definition link.c:2742
rtnl_link_i2name
char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst, size_t len)
Translate interface index to corresponding link name.
Definition link.c:1483
rtnl_link_set_family
void rtnl_link_set_family(struct rtnl_link *link, int family)
Set address family of link object.
Definition link.c:2111
rtnl_link_get_carrier
uint8_t rtnl_link_get_carrier(struct rtnl_link *link)
Return carrier status of link object.
Definition link.c:2345
rtnl_link_put
void rtnl_link_put(struct rtnl_link *link)
Release a link object reference.
Definition link.c:1929
rtnl_link_set_type
int rtnl_link_set_type(struct rtnl_link *link, const char *type)
Set type of link object.
Definition link.c:2558
rtnl_link_set_info_type
int rtnl_link_set_info_type(struct rtnl_link *link, const char *type)
Definition link.c:3145
rtnl_link_get_ifalias
const char * rtnl_link_get_ifalias(struct rtnl_link *link)
Return alias name of link object (SNMP IfAlias)
Definition link.c:2430
rtnl_link_get_gso_max_size
int rtnl_link_get_gso_max_size(struct rtnl_link *link, uint32_t *gso_max_size)
Return maximum size for generic segmentation offload.
Definition link.c:2760
rtnl_link_set_master
void rtnl_link_set_master(struct rtnl_link *link, int ifindex)
Set master link of link object.
Definition link.c:2307
rtnl_link_get_mtu
unsigned int rtnl_link_get_mtu(struct rtnl_link *link)
Return maximum transmission unit of link object.
Definition link.c:2219
rtnl_link_set_txqlen
void rtnl_link_set_txqlen(struct rtnl_link *link, unsigned int txqlen)
Set transmission queue length.
Definition link.c:2234
rtnl_link_build_get_request
int rtnl_link_build_get_request(int ifindex, const char *name, struct nl_msg **result)
Construct RTM_GETLINK netlink message.
Definition link.c:1379
rtnl_link_set_ifindex
void rtnl_link_set_ifindex(struct rtnl_link *link, int ifindex)
Set interface index of link object.
Definition link.c:2177
rtnl_link_get_addr
struct nl_addr * rtnl_link_get_addr(struct rtnl_link *link)
Return link layer address of link object.
Definition link.c:2026
rtnl_link_get_carrier_changes
int rtnl_link_get_carrier_changes(struct rtnl_link *link, uint32_t *carrier_changes)
Return carrier on/off changes of link object.
Definition link.c:2357
rtnl_link_get_link_netnsid
int rtnl_link_get_link_netnsid(const struct rtnl_link *link, int32_t *out_link_netnsid)
Get the netnsid of the link.
Definition link.c:2291
rtnl_link_get_flags
unsigned int rtnl_link_get_flags(struct rtnl_link *link)
Return flags of link object.
Definition link.c:2101
rtnl_link_get_ifindex
int rtnl_link_get_ifindex(struct rtnl_link *link)
Return interface index of link object.
Definition link.c:2192
rtnl_link_change
int rtnl_link_change(struct nl_sock *sk, struct rtnl_link *orig, struct rtnl_link *changes, int flags)
Change link.
Definition link.c:1797
RTNL_LINK_COLLISIONS
@ RTNL_LINK_COLLISIONS
Definition link.h:53
RTNL_LINK_IP6_INBCASTOCTETS
@ RTNL_LINK_IP6_INBCASTOCTETS
Definition link.h:83
RTNL_LINK_IP6_ECT0PKTS
@ RTNL_LINK_IP6_ECT0PKTS
Definition link.h:93
RTNL_LINK_RX_COMPRESSED
@ RTNL_LINK_RX_COMPRESSED
Definition link.h:40
RTNL_LINK_REASM_OVERLAPS
@ RTNL_LINK_REASM_OVERLAPS
Definition link.h:96
RTNL_LINK_IP6_INTRUNCATEDPKTS
@ RTNL_LINK_IP6_INTRUNCATEDPKTS
Definition link.h:61
RTNL_LINK_RX_LEN_ERR
@ RTNL_LINK_RX_LEN_ERR
Definition link.h:44
RTNL_LINK_ICMP6_INMSGS
@ RTNL_LINK_ICMP6_INMSGS
Definition link.h:85
RTNL_LINK_IP6_INNOROUTES
@ RTNL_LINK_IP6_INNOROUTES
Definition link.h:58
RTNL_LINK_IP6_OUTMCASTOCTETS
@ RTNL_LINK_IP6_OUTMCASTOCTETS
Definition link.h:82
RTNL_LINK_IP6_INMCASTPKTS
@ RTNL_LINK_IP6_INMCASTPKTS
Definition link.h:75
RTNL_LINK_IP6_REASMOKS
@ RTNL_LINK_IP6_REASMOKS
Definition link.h:70
RTNL_LINK_IP6_OUTBCASTOCTETS
@ RTNL_LINK_IP6_OUTBCASTOCTETS
Definition link.h:84
RTNL_LINK_IP6_INDELIVERS
@ RTNL_LINK_IP6_INDELIVERS
Definition link.h:63
RTNL_LINK_TX_DROPPED
@ RTNL_LINK_TX_DROPPED
Definition link.h:39
RTNL_LINK_IP6_REASMTIMEOUT
@ RTNL_LINK_IP6_REASMTIMEOUT
Definition link.h:68
RTNL_LINK_IP6_OUTPKTS
@ RTNL_LINK_IP6_OUTPKTS
Definition link.h:65
RTNL_LINK_IP6_OUTOCTETS
@ RTNL_LINK_IP6_OUTOCTETS
Definition link.h:80
RTNL_LINK_ICMP6_INERRORS
@ RTNL_LINK_ICMP6_INERRORS
Definition link.h:86
RTNL_LINK_IP6_FRAGFAILS
@ RTNL_LINK_IP6_FRAGFAILS
Definition link.h:73
RTNL_LINK_ICMP6_OUTMSGS
@ RTNL_LINK_ICMP6_OUTMSGS
Definition link.h:87
RTNL_LINK_IP6_CSUMERRORS
@ RTNL_LINK_IP6_CSUMERRORS
Definition link.h:90
RTNL_LINK_IP6_INUNKNOWNPROTOS
@ RTNL_LINK_IP6_INUNKNOWNPROTOS
Definition link.h:60
RTNL_LINK_ICMP6_CSUMERRORS
@ RTNL_LINK_ICMP6_CSUMERRORS
Definition link.h:89
RTNL_LINK_IP6_INPKTS
@ RTNL_LINK_IP6_INPKTS
Definition link.h:55
RTNL_LINK_RX_DROPPED
@ RTNL_LINK_RX_DROPPED
Definition link.h:38
RTNL_LINK_IP6_CEPKTS
@ RTNL_LINK_IP6_CEPKTS
Definition link.h:94
RTNL_LINK_IP6_INBCASTPKTS
@ RTNL_LINK_IP6_INBCASTPKTS
Definition link.h:77
RTNL_LINK_RX_FIFO_ERR
@ RTNL_LINK_RX_FIFO_ERR
Definition link.h:42
RTNL_LINK_TX_COMPRESSED
@ RTNL_LINK_TX_COMPRESSED
Definition link.h:41
RTNL_LINK_RX_ERRORS
@ RTNL_LINK_RX_ERRORS
Definition link.h:36
RTNL_LINK_RX_CRC_ERR
@ RTNL_LINK_RX_CRC_ERR
Definition link.h:46
RTNL_LINK_TX_HBEAT_ERR
@ RTNL_LINK_TX_HBEAT_ERR
Definition link.h:51
RTNL_LINK_IP6_INOCTETS
@ RTNL_LINK_IP6_INOCTETS
Definition link.h:79
RTNL_LINK_RX_NOHANDLER
@ RTNL_LINK_RX_NOHANDLER
Definition link.h:95
RTNL_LINK_RX_BYTES
@ RTNL_LINK_RX_BYTES
Definition link.h:34
RTNL_LINK_TX_BYTES
@ RTNL_LINK_TX_BYTES
Definition link.h:35
RTNL_LINK_IP6_INHDRERRORS
@ RTNL_LINK_IP6_INHDRERRORS
Definition link.h:56
RTNL_LINK_IP6_REASMREQDS
@ RTNL_LINK_IP6_REASMREQDS
Definition link.h:69
RTNL_LINK_TX_CARRIER_ERR
@ RTNL_LINK_TX_CARRIER_ERR
Definition link.h:50
RTNL_LINK_RX_MISSED_ERR
@ RTNL_LINK_RX_MISSED_ERR
Definition link.h:48
RTNL_LINK_IP6_OUTFORWDATAGRAMS
@ RTNL_LINK_IP6_OUTFORWDATAGRAMS
Definition link.h:64
RTNL_LINK_IP6_INDISCARDS
@ RTNL_LINK_IP6_INDISCARDS
Definition link.h:62
RTNL_LINK_IP6_NOECTPKTS
@ RTNL_LINK_IP6_NOECTPKTS
Definition link.h:91
RTNL_LINK_IP6_OUTNOROUTES
@ RTNL_LINK_IP6_OUTNOROUTES
Definition link.h:67
RTNL_LINK_IP6_OUTDISCARDS
@ RTNL_LINK_IP6_OUTDISCARDS
Definition link.h:66
RTNL_LINK_IP6_FRAGCREATES
@ RTNL_LINK_IP6_FRAGCREATES
Definition link.h:74
RTNL_LINK_ICMP6_OUTERRORS
@ RTNL_LINK_ICMP6_OUTERRORS
Definition link.h:88
RTNL_LINK_RX_OVER_ERR
@ RTNL_LINK_RX_OVER_ERR
Definition link.h:45
RTNL_LINK_IP6_INMCASTOCTETS
@ RTNL_LINK_IP6_INMCASTOCTETS
Definition link.h:81
RTNL_LINK_TX_ABORT_ERR
@ RTNL_LINK_TX_ABORT_ERR
Definition link.h:49
RTNL_LINK_IP6_INADDRERRORS
@ RTNL_LINK_IP6_INADDRERRORS
Definition link.h:59
RTNL_LINK_MULTICAST
@ RTNL_LINK_MULTICAST
Definition link.h:54
RTNL_LINK_IP6_ECT1PKTS
@ RTNL_LINK_IP6_ECT1PKTS
Definition link.h:92
RTNL_LINK_TX_FIFO_ERR
@ RTNL_LINK_TX_FIFO_ERR
Definition link.h:43
RTNL_LINK_TX_ERRORS
@ RTNL_LINK_TX_ERRORS
Definition link.h:37
RTNL_LINK_IP6_INTOOBIGERRORS
@ RTNL_LINK_IP6_INTOOBIGERRORS
Definition link.h:57
RTNL_LINK_RX_FRAME_ERR
@ RTNL_LINK_RX_FRAME_ERR
Definition link.h:47
RTNL_LINK_TX_WIN_ERR
@ RTNL_LINK_TX_WIN_ERR
Definition link.h:52
RTNL_LINK_RX_PACKETS
@ RTNL_LINK_RX_PACKETS
Definition link.h:32
RTNL_LINK_TX_PACKETS
@ RTNL_LINK_TX_PACKETS
Definition link.h:33
RTNL_LINK_IP6_OUTMCASTPKTS
@ RTNL_LINK_IP6_OUTMCASTPKTS
Definition link.h:76
RTNL_LINK_IP6_OUTBCASTPKTS
@ RTNL_LINK_IP6_OUTBCASTPKTS
Definition link.h:78
RTNL_LINK_IP6_FRAGOKS
@ RTNL_LINK_IP6_FRAGOKS
Definition link.h:72
RTNL_LINK_IP6_REASMFAILS
@ RTNL_LINK_IP6_REASMFAILS
Definition link.h:71
nlmsg_alloc_simple
struct nl_msg * nlmsg_alloc_simple(int nlmsgtype, int flags)
Allocate a new netlink message.
Definition msg.c:352
nlmsg_data
void * nlmsg_data(const struct nlmsghdr *nlh)
Return pointer to message payload.
Definition msg.c:108
nlmsg_parse
int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, const struct nla_policy *policy)
parse attributes of a netlink message
Definition msg.c:219
NL_AUTO_SEQ
#define NL_AUTO_SEQ
May be used to refer to a sequence number which should be automatically set just before sending the m...
Definition msg.h:40
nlmsg_append
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
Definition msg.c:456
nl_object_put
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
Definition object.c:221
nl_object_get
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
Definition object.c:210
nl_object_alloc
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
Definition object.c:55
nl_send_auto
int nl_send_auto(struct nl_sock *sk, struct nl_msg *msg)
Finalize and transmit Netlink message.
Definition nl.c:515
nl_send_sync
int nl_send_sync(struct nl_sock *sk, struct nl_msg *msg)
Finalize and transmit Netlink message and wait for ACK or error message.
Definition nl.c:547
nl_pickup_keep_syserr
int nl_pickup_keep_syserr(struct nl_sock *sk, int(*parser)(struct nl_cache_ops *, struct sockaddr_nl *, struct nlmsghdr *, struct nl_parser_param *), struct nl_object **result, int *syserror)
Pickup netlink answer, parse is and return object with preserving system error.
Definition nl.c:1195
nl_send_auto_complete
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
Definition nl.c:1247
nl_dump
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition utils.c:1015
nl_cancel_down_bytes
double nl_cancel_down_bytes(unsigned long long l, char **unit)
Cancel down a byte counter.
Definition utils.c:223
NL_DUMP_STATS
@ NL_DUMP_STATS
Dump all attributes including statistics.
Definition types.h:22
NL_DUMP_LINE
@ NL_DUMP_LINE
Dump object briefly on one line.
Definition types.h:20
NL_DUMP_DETAILS
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Definition types.h:21
nl_dump_params
Dumping parameters.
Definition types.h:32
nla_policy
Attribute validation policy.
Definition attr.h:63
nla_policy::type
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition attr.h:65
rtnl_link_af_ops
Available operations to modules implementing a link address family.
Definition link-api.h:76
rtnl_link_af_ops::ao_protinfo_policy
const struct nla_policy * ao_protinfo_policy
Validation policy for IFLA_PROTINFO attribute.
Definition link-api.h:87
rtnl_link_af_ops::ao_parse_protinfo
int(* ao_parse_protinfo)(struct rtnl_link *, struct nlattr *, void *)
Called if a IFLA_PROTINFO attribute needs to be parsed.
Definition link-api.h:103
rtnl_link_af_ops::ao_free
void(* ao_free)(struct rtnl_link *, void *)
Called when the link gets freed.
Definition link-api.h:99
rtnl_link_af_ops::ao_fill_pi
int(* ao_fill_pi)(struct rtnl_link *, struct nl_msg *msg, void *)
Called if a link message is sent to the kernel.
Definition link-api.h:154
rtnl_link_af_ops::ao_fill_af_no_nest
const int ao_fill_af_no_nest
IFLA_AF_SPEC nesting override.
Definition link-api.h:171
rtnl_link_af_ops::ao_family
const unsigned int ao_family
The address family this operations set implements.
Definition link-api.h:78
rtnl_link_af_ops::ao_dump
void(* ao_dump[NL_DUMP_MAX+1])(struct rtnl_link *, struct nl_dump_params *, void *)
Dump address family specific link attributes.
Definition link-api.h:127
rtnl_link_af_ops::ao_parse_af
int(* ao_parse_af)(struct rtnl_link *, struct nlattr *, void *)
Called if a IFLA_AF_SPEC attribute needs to be parsed.
Definition link-api.h:108
rtnl_link_af_ops::ao_parse_af_full
int(* ao_parse_af_full)(struct rtnl_link *, struct nlattr *, void *)
Called if the full IFLA_AF_SPEC data needs to be parsed.
Definition link-api.h:118
rtnl_link_af_ops::ao_get_af
int(* ao_get_af)(struct nl_msg *msg, uint32_t *ext_filter_mask)
Called for GETLINK message to the kernel.
Definition link-api.h:123
rtnl_link_af_ops::ao_fill_af
int(* ao_fill_af)(struct rtnl_link *, struct nl_msg *msg, void *)
Called if a link message is sent to the kernel.
Definition link-api.h:113
rtnl_link_af_ops::ao_fill_pi_flags
const int ao_fill_pi_flags
PROTINFO type.
Definition link-api.h:163
rtnl_link_af_ops::ao_clone
void *(* ao_clone)(struct rtnl_link *, void *)
Called when the link is cloned, must allocate a clone of the address family specific buffer and retur...
Definition link-api.h:96
rtnl_link_info_ops
Available operations to modules implementing a link info type.
Definition link-api.h:20
rtnl_link_info_ops::io_dump
void(* io_dump[NL_DUMP_MAX+1])(struct rtnl_link *, struct nl_dump_params *)
Called when the link object is dumped.
Definition link-api.h:41
rtnl_link_info_ops::io_free
void(* io_free)(struct rtnl_link *)
Called to release all resources previously allocated in either io_alloc() or io_parse().
Definition link-api.h:54
rtnl_link_info_ops::io_alloc
int(* io_alloc)(struct rtnl_link *)
Called to assign an info type to a link.
Definition link-api.h:30
rtnl_link_info_ops::io_parse
int(* io_parse)(struct rtnl_link *, struct nlattr *, struct nlattr *)
Called to parse the link info attribute.
Definition link-api.h:35
rtnl_link_info_ops::io_clone
int(* io_clone)(struct rtnl_link *, struct rtnl_link *)
Called when a link object is cloned.
Definition link-api.h:46
rtnl_link_info_ops::io_put_attrs
int(* io_put_attrs)(struct nl_msg *, struct rtnl_link *)
Called when construction a link netlink message.
Definition link-api.h:50
rtnl_link
Link object.
Definition nl-route.h:29