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