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