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