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