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