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