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>
33 #define LINK_ATTR_MTU (1 << 0)
34 #define LINK_ATTR_LINK (1 << 1)
35 #define LINK_ATTR_TXQLEN (1 << 2)
36 #define LINK_ATTR_WEIGHT (1 << 3)
37 #define LINK_ATTR_MASTER (1 << 4)
38 #define LINK_ATTR_QDISC (1 << 5)
39 #define LINK_ATTR_MAP (1 << 6)
40 #define LINK_ATTR_ADDR (1 << 7)
41 #define LINK_ATTR_BRD (1 << 8)
42 #define LINK_ATTR_FLAGS (1 << 9)
43 #define LINK_ATTR_IFNAME (1 << 10)
44 #define LINK_ATTR_IFINDEX (1 << 11)
45 #define LINK_ATTR_FAMILY (1 << 12)
46 #define LINK_ATTR_ARPTYPE (1 << 13)
47 #define LINK_ATTR_STATS (1 << 14)
48 #define LINK_ATTR_CHANGE (1 << 15)
49 #define LINK_ATTR_OPERSTATE (1 << 16)
50 #define LINK_ATTR_LINKMODE (1 << 17)
51 #define LINK_ATTR_LINKINFO (1 << 18)
52 #define LINK_ATTR_IFALIAS (1 << 19)
53 #define LINK_ATTR_NUM_VF (1 << 20)
54 #define LINK_ATTR_PROMISCUITY (1 << 21)
55 #define LINK_ATTR_NUM_TX_QUEUES (1 << 22)
56 #define LINK_ATTR_NUM_RX_QUEUES (1 << 23)
57 #define LINK_ATTR_GROUP (1 << 24)
58 #define LINK_ATTR_CARRIER (1 << 25)
59 #define LINK_ATTR_PROTINFO (1 << 26)
60 #define LINK_ATTR_AF_SPEC (1 << 27)
61 #define LINK_ATTR_PHYS_PORT_ID (1 << 28)
62 #define LINK_ATTR_NS_FD (1 << 29)
63 #define LINK_ATTR_NS_PID (1 << 30)
64 #define LINK_ATTR_LINK_NETNSID (1 << 31)
66 static struct nl_cache_ops rtnl_link_ops;
67 static struct nl_object_ops link_obj_ops;
70 static struct rtnl_link_af_ops *af_lookup_and_alloc(
struct rtnl_link *link,
73 struct rtnl_link_af_ops *af_ops;
88 static int af_free(
struct rtnl_link *link,
struct rtnl_link_af_ops *ops,
89 void *data,
void *arg)
92 ops->ao_free(link, data);
99 static int af_clone(
struct rtnl_link *link,
struct rtnl_link_af_ops *ops,
100 void *data,
void *arg)
105 !(dst->l_af_data[ops->ao_family] = ops->ao_clone(dst, data)))
111 static int af_fill(
struct rtnl_link *link,
struct rtnl_link_af_ops *ops,
112 void *data,
void *arg)
114 struct nl_msg *msg = arg;
115 struct nlattr *af_attr;
118 if (!ops->ao_fill_af)
124 if ((err = ops->ao_fill_af(link, arg, data)) < 0)
132 static int af_dump_line(
struct rtnl_link *link,
struct rtnl_link_af_ops *ops,
133 void *data,
void *arg)
143 static int af_dump_details(
struct rtnl_link *link,
struct rtnl_link_af_ops *ops,
144 void *data,
void *arg)
154 static int af_dump_stats(
struct rtnl_link *link,
struct rtnl_link_af_ops *ops,
155 void *data,
void *arg)
165 static int do_foreach_af(
struct rtnl_link *link,
167 struct rtnl_link_af_ops *,
void *,
void *),
172 for (i = 0; i < AF_MAX; i++) {
173 if (link->l_af_data[i]) {
174 struct rtnl_link_af_ops *ops;
179 err = cb(link, ops, link->l_af_data[i], arg);
191 static void release_link_info(
struct rtnl_link *link)
193 struct rtnl_link_info_ops *io = link->l_info_ops;
200 BUG_ON(link->l_info);
203 link->l_info_ops = NULL;
207 static void link_free_data(
struct nl_object *c)
209 struct rtnl_link *link = nl_object_priv(c);
212 release_link_info(link);
220 free(link->l_ifalias);
221 free(link->l_info_kind);
223 do_foreach_af(link, af_free, NULL);
229 static int link_clone(
struct nl_object *_dst,
struct nl_object *_src)
231 struct rtnl_link *dst = nl_object_priv(_dst);
232 struct rtnl_link *src = nl_object_priv(_src);
244 if (!(dst->l_ifalias = strdup(src->l_ifalias)))
247 if (src->l_info_kind)
248 if (!(dst->l_info_kind = strdup(src->l_info_kind)))
251 if (src->l_info_ops && src->l_info_ops->io_clone) {
252 err = src->l_info_ops->io_clone(dst, src);
257 if ((err = do_foreach_af(src, af_clone, dst)) < 0)
260 if (src->l_phys_port_id)
261 if (!(dst->l_phys_port_id =
nl_data_clone(src->l_phys_port_id)))
267 struct nla_policy rtln_link_policy[IFLA_MAX+1] = {
269 .maxlen = IFNAMSIZ },
270 [IFLA_MTU] = { .type =
NLA_U32 },
271 [IFLA_TXQLEN] = { .type =
NLA_U32 },
272 [IFLA_LINK] = { .type =
NLA_U32 },
273 [IFLA_WEIGHT] = { .type =
NLA_U32 },
274 [IFLA_MASTER] = { .type =
NLA_U32 },
275 [IFLA_OPERSTATE] = { .type =
NLA_U8 },
276 [IFLA_LINKMODE] = { .type =
NLA_U8 },
279 .maxlen = IFQDISCSIZ },
280 [IFLA_STATS] = { .minlen =
sizeof(
struct rtnl_link_stats) },
281 [IFLA_STATS64] = { .minlen =
sizeof(
struct rtnl_link_stats64)},
282 [IFLA_MAP] = { .minlen =
sizeof(
struct rtnl_link_ifmap) },
283 [IFLA_IFALIAS] = { .type =
NLA_STRING, .maxlen = IFALIASZ },
284 [IFLA_NUM_VF] = { .type =
NLA_U32 },
286 [IFLA_PROMISCUITY] = { .type =
NLA_U32 },
287 [IFLA_NUM_TX_QUEUES] = { .type =
NLA_U32 },
288 [IFLA_NUM_RX_QUEUES] = { .type =
NLA_U32 },
289 [IFLA_GROUP] = { .type =
NLA_U32 },
290 [IFLA_CARRIER] = { .type =
NLA_U8 },
292 [IFLA_NET_NS_PID] = { .type =
NLA_U32 },
293 [IFLA_NET_NS_FD] = { .type =
NLA_U32 },
296 static struct nla_policy link_info_policy[IFLA_INFO_MAX+1] = {
302 int rtnl_link_info_parse(
struct rtnl_link *link,
struct nlattr **tb)
304 if (tb[IFLA_IFNAME] == NULL)
305 return -NLE_MISSING_ATTR;
307 nla_strlcpy(link->l_name, tb[IFLA_IFNAME], IFNAMSIZ);
310 if (tb[IFLA_STATS]) {
311 struct rtnl_link_stats *st =
nla_data(tb[IFLA_STATS]);
340 link->ce_mask |= LINK_ATTR_STATS;
343 if (tb[IFLA_STATS64]) {
351 struct rtnl_link_stats64 st;
354 sizeof(
struct rtnl_link_stats64));
383 link->ce_mask |= LINK_ATTR_STATS;
386 if (tb[IFLA_TXQLEN]) {
388 link->ce_mask |= LINK_ATTR_TXQLEN;
393 link->ce_mask |= LINK_ATTR_MTU;
396 if (tb[IFLA_ADDRESS]) {
398 if (link->l_addr == NULL)
402 link->ce_mask |= LINK_ATTR_ADDR;
405 if (tb[IFLA_BROADCAST]) {
408 if (link->l_bcast == NULL)
412 link->ce_mask |= LINK_ATTR_BRD;
417 link->ce_mask |= LINK_ATTR_LINK;
420 if (tb[IFLA_LINK_NETNSID]) {
421 link->l_link_netnsid =
nla_get_s32(tb[IFLA_LINK_NETNSID]);
422 link->ce_mask |= LINK_ATTR_LINK_NETNSID;
425 if (tb[IFLA_WEIGHT]) {
427 link->ce_mask |= LINK_ATTR_WEIGHT;
430 if (tb[IFLA_QDISC]) {
431 nla_strlcpy(link->l_qdisc, tb[IFLA_QDISC], IFQDISCSIZ);
432 link->ce_mask |= LINK_ATTR_QDISC;
437 sizeof(
struct rtnl_link_ifmap));
438 link->ce_mask |= LINK_ATTR_MAP;
441 if (tb[IFLA_MASTER]) {
443 link->ce_mask |= LINK_ATTR_MASTER;
446 if (tb[IFLA_CARRIER]) {
447 link->l_carrier =
nla_get_u8(tb[IFLA_CARRIER]);
448 link->ce_mask |= LINK_ATTR_CARRIER;
451 if (tb[IFLA_OPERSTATE]) {
452 link->l_operstate =
nla_get_u8(tb[IFLA_OPERSTATE]);
453 link->ce_mask |= LINK_ATTR_OPERSTATE;
456 if (tb[IFLA_LINKMODE]) {
457 link->l_linkmode =
nla_get_u8(tb[IFLA_LINKMODE]);
458 link->ce_mask |= LINK_ATTR_LINKMODE;
461 if (tb[IFLA_IFALIAS]) {
462 link->l_ifalias = nla_strdup(tb[IFLA_IFALIAS]);
463 if (link->l_ifalias == NULL)
465 link->ce_mask |= LINK_ATTR_IFALIAS;
468 if (tb[IFLA_NET_NS_FD]) {
470 link->ce_mask |= LINK_ATTR_NS_FD;
473 if (tb[IFLA_NET_NS_PID]) {
475 link->ce_mask |= LINK_ATTR_NS_PID;
481 static int link_msg_parser(
struct nl_cache_ops *ops,
struct sockaddr_nl *who,
482 struct nlmsghdr *n,
struct nl_parser_param *pp)
485 struct ifinfomsg *ifi;
486 struct nlattr *tb[IFLA_MAX+1];
487 struct rtnl_link_af_ops *af_ops = NULL;
489 struct nla_policy real_link_policy[IFLA_MAX+1];
491 memcpy(&real_link_policy, rtln_link_policy,
sizeof(rtln_link_policy));
499 link->ce_msgtype = n->nlmsg_type;
501 if (!nlmsg_valid_hdr(n,
sizeof(*ifi))) {
502 err = -NLE_MSG_TOOSHORT;
507 link->l_family = family = ifi->ifi_family;
508 link->l_arptype = ifi->ifi_type;
509 link->l_index = ifi->ifi_index;
510 link->l_flags = ifi->ifi_flags;
511 link->l_change = ifi->ifi_change;
512 link->ce_mask = (LINK_ATTR_IFNAME | LINK_ATTR_FAMILY |
513 LINK_ATTR_ARPTYPE| LINK_ATTR_IFINDEX |
514 LINK_ATTR_FLAGS | LINK_ATTR_CHANGE);
516 if ((af_ops = af_lookup_and_alloc(link, family))) {
517 if (af_ops->ao_protinfo_policy) {
518 memcpy(&real_link_policy[IFLA_PROTINFO],
519 af_ops->ao_protinfo_policy,
523 link->l_af_ops = af_ops;
526 err =
nlmsg_parse(n,
sizeof(*ifi), tb, IFLA_MAX, real_link_policy);
530 err = rtnl_link_info_parse(link, tb);
534 if (tb[IFLA_NUM_VF]) {
536 link->ce_mask |= LINK_ATTR_NUM_VF;
539 if (tb[IFLA_LINKINFO]) {
540 struct nlattr *li[IFLA_INFO_MAX+1];
547 if (li[IFLA_INFO_KIND]) {
548 struct rtnl_link_info_ops *ops;
556 if ((af = nl_str2af(kind)) >= 0 &&
557 !af_ops && (af_ops = af_lookup_and_alloc(link, af))) {
559 if (af_ops->ao_protinfo_policy) {
560 tb[IFLA_PROTINFO] = (
struct nlattr *)af_ops->ao_protinfo_policy;
562 link->l_family = family = af;
563 link->l_af_ops = af_ops;
567 link->l_info_ops = ops;
571 (li[IFLA_INFO_DATA] || li[IFLA_INFO_XSTATS])) {
572 err = ops->io_parse(link, li[IFLA_INFO_DATA],
573 li[IFLA_INFO_XSTATS]);
581 link->ce_mask |= LINK_ATTR_LINKINFO;
584 if (tb[IFLA_PROTINFO] && af_ops && af_ops->ao_parse_protinfo) {
585 err = af_ops->ao_parse_protinfo(link, tb[IFLA_PROTINFO],
586 link->l_af_data[link->l_family]);
589 link->ce_mask |= LINK_ATTR_PROTINFO;
592 if (tb[IFLA_AF_SPEC]) {
593 struct nlattr *af_attr;
597 af_ops = af_lookup_and_alloc(link,
nla_type(af_attr));
598 if (af_ops && af_ops->ao_parse_af) {
599 char *af_data = link->l_af_data[
nla_type(af_attr)];
601 err = af_ops->ao_parse_af(link, af_attr, af_data);
607 link->ce_mask |= LINK_ATTR_AF_SPEC;
610 if (tb[IFLA_PROMISCUITY]) {
611 link->l_promiscuity =
nla_get_u32(tb[IFLA_PROMISCUITY]);
612 link->ce_mask |= LINK_ATTR_PROMISCUITY;
615 if (tb[IFLA_NUM_TX_QUEUES]) {
616 link->l_num_tx_queues =
nla_get_u32(tb[IFLA_NUM_TX_QUEUES]);
617 link->ce_mask |= LINK_ATTR_NUM_TX_QUEUES;
620 if (tb[IFLA_NUM_RX_QUEUES]) {
621 link->l_num_rx_queues =
nla_get_u32(tb[IFLA_NUM_RX_QUEUES]);
622 link->ce_mask |= LINK_ATTR_NUM_RX_QUEUES;
625 if (tb[IFLA_GROUP]) {
627 link->ce_mask |= LINK_ATTR_GROUP;
630 if (tb[IFLA_PHYS_PORT_ID]) {
632 if (link->l_phys_port_id == NULL) {
636 link->ce_mask |= LINK_ATTR_PHYS_PORT_ID;
639 err = pp->pp_cb((
struct nl_object *) link, pp);
646 static int link_request_update(
struct nl_cache *cache,
struct nl_sock *sk)
648 int family = cache->c_iarg1;
653 static void link_dump_line(
struct nl_object *obj,
struct nl_dump_params *p)
656 struct nl_cache *cache = obj->ce_cache;
658 int fetched_cache = 0;
665 nl_dump_line(p,
"%s %s ", link->l_name,
666 nl_llproto2str(link->l_arptype, buf,
sizeof(buf)));
671 if (link->ce_mask & LINK_ATTR_MASTER) {
674 nl_dump(p,
"master %s ", master ? master->l_name :
"inv");
678 nl_dump(p,
"master %d ", link->l_master);
681 rtnl_link_flags2str(link->l_flags, buf,
sizeof(buf));
685 if (link->ce_mask & LINK_ATTR_LINK) {
687 && !(link->ce_mask & LINK_ATTR_LINK_NETNSID)) {
689 nl_dump(p,
"slave-of %s ", ll ? ll->l_name :
"NONE");
693 nl_dump(p,
"slave-of %d ", link->l_link);
695 if (link->ce_mask & LINK_ATTR_LINK_NETNSID)
696 nl_dump(p,
"link-netnsid %d ", link->l_link_netnsid);
698 if (link->ce_mask & LINK_ATTR_GROUP)
699 nl_dump(p,
"group %u ", link->l_group);
701 if (link->l_info_ops && link->l_info_ops->io_dump[
NL_DUMP_LINE])
704 do_foreach_af(link, af_dump_line, p);
712 static void link_dump_details(
struct nl_object *obj,
struct nl_dump_params *p)
717 link_dump_line(obj, p);
719 nl_dump_line(p,
" mtu %u ", link->l_mtu);
720 nl_dump(p,
"txqlen %u weight %u ", link->l_txqlen, link->l_weight);
722 if (link->ce_mask & LINK_ATTR_QDISC)
723 nl_dump(p,
"qdisc %s ", link->l_qdisc);
725 if (link->ce_mask & LINK_ATTR_MAP && link->l_map.lm_irq)
726 nl_dump(p,
"irq %u ", link->l_map.lm_irq);
728 if (link->ce_mask & LINK_ATTR_IFINDEX)
729 nl_dump(p,
"index %u ", link->l_index);
731 if (link->ce_mask & LINK_ATTR_PROMISCUITY && link->l_promiscuity > 0)
732 nl_dump(p,
"promisc-mode (%u users) ", link->l_promiscuity);
736 if (link->ce_mask & LINK_ATTR_IFALIAS)
737 nl_dump_line(p,
" alias %s\n", link->l_ifalias);
739 nl_dump_line(p,
" ");
741 if (link->ce_mask & LINK_ATTR_NUM_TX_QUEUES)
742 nl_dump(p,
"txq %u ", link->l_num_tx_queues);
744 if (link->ce_mask & LINK_ATTR_NUM_RX_QUEUES)
745 nl_dump(p,
"rxq %u ", link->l_num_rx_queues);
747 if (link->ce_mask & LINK_ATTR_BRD)
751 if ((link->ce_mask & LINK_ATTR_OPERSTATE) &&
752 link->l_operstate != IF_OPER_UNKNOWN) {
753 rtnl_link_operstate2str(link->l_operstate, buf,
sizeof(buf));
757 if (link->ce_mask & LINK_ATTR_NUM_VF)
758 nl_dump(p,
"num-vf %u ", link->l_num_vf);
761 rtnl_link_mode2str(link->l_linkmode, buf,
sizeof(buf)));
764 rtnl_link_carrier2str(link->l_carrier, buf,
sizeof(buf)));
771 do_foreach_af(link, af_dump_details, p);
774 static void link_dump_stats(
struct nl_object *obj,
struct nl_dump_params *p)
780 link_dump_details(obj, p);
782 nl_dump_line(p,
" Stats: bytes packets errors "
783 " dropped fifo-err compressed\n");
787 strcpy(fmt,
" RX %X.2f %s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
" %10" PRIu64
" %10" PRIu64
"\n");
788 fmt[9] = *unit ==
'B' ?
'9' :
'7';
790 nl_dump_line(p, fmt, res, unit,
799 strcpy(fmt,
" TX %X.2f %s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
" %10" PRIu64
" %10" PRIu64
"\n");
800 fmt[9] = *unit ==
'B' ?
'9' :
'7';
802 nl_dump_line(p, fmt, res, unit,
809 nl_dump_line(p,
" Errors: length over crc "
810 " frame missed multicast\n");
812 nl_dump_line(p,
" RX %10" PRIu64
" %10" PRIu64
" %10"
813 PRIu64
" %10" PRIu64
" %10" PRIu64
" %10"
822 nl_dump_line(p,
" aborted carrier heartbeat "
823 " window collision\n");
825 nl_dump_line(p,
" TX %10" PRIu64
" %10" PRIu64
" %10"
826 PRIu64
" %10" PRIu64
" %10" PRIu64
"\n",
833 if (link->l_info_ops && link->l_info_ops->io_dump[
NL_DUMP_STATS])
836 do_foreach_af(link, af_dump_stats, p);
840 static int link_handle_event(
struct nl_object *a,
struct rtnl_link_event_cb *cb)
843 struct nl_cache *c = dp_cache(a);
846 if (l->l_change == ~0U) {
847 if (l->ce_msgtype == RTM_NEWLINK)
850 cb->le_unregister(l);
855 if (l->l_change & IFF_SLAVE) {
856 if (l->l_flags & IFF_SLAVE) {
858 cb->le_new_bonding(l, m);
862 cb->le_cancel_bonding(l);
866 if (l->l_change & IFF_UP && l->l_change & IFF_RUNNING)
867 dp_dump_line(p, line++,
"link %s changed state to %s.\n",
868 l->l_name, l->l_flags & IFF_UP ?
"up" :
"down");
870 if (l->l_change & IFF_PROMISC) {
871 dp_new_line(p, line++);
872 dp_dump(p,
"link %s %s promiscuous mode.\n",
873 l->l_name, l->l_flags & IFF_PROMISC ?
"entered" :
"left");
877 dp_dump_line(p, line++,
"link %s sent unknown event.\n",
886 static void link_keygen(
struct nl_object *obj, uint32_t *hashkey,
890 unsigned int lkey_sz;
891 struct link_hash_key {
894 } __attribute__((packed)) lkey;
896 lkey_sz = sizeof(lkey);
897 lkey.l_index = link->l_index;
898 lkey.l_family = link->l_family;
900 *hashkey = nl_hash(&lkey, lkey_sz, 0) % table_sz;
902 NL_DBG(5, "link %p key (dev %d fam %d) keysz %d, hash 0x%x\n",
903 link, lkey.l_index, lkey.l_family, lkey_sz, *hashkey);
908 static
int link_compare(struct nl_object *_a, struct nl_object *_b,
909 uint32_t attrs,
int flags)
915 #define LINK_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, LINK_ATTR_##ATTR, a, b, EXPR)
917 diff |= LINK_DIFF(IFINDEX, a->l_index != b->l_index);
918 diff |= LINK_DIFF(MTU, a->l_mtu != b->l_mtu);
919 diff |= LINK_DIFF(LINK, a->l_link != b->l_link);
920 diff |= LINK_DIFF(LINK_NETNSID, a->l_link_netnsid != b->l_link_netnsid);
921 diff |= LINK_DIFF(TXQLEN, a->l_txqlen != b->l_txqlen);
922 diff |= LINK_DIFF(WEIGHT, a->l_weight != b->l_weight);
923 diff |= LINK_DIFF(MASTER, a->l_master != b->l_master);
924 diff |= LINK_DIFF(FAMILY, a->l_family != b->l_family);
925 diff |= LINK_DIFF(OPERSTATE, a->l_operstate != b->l_operstate);
926 diff |= LINK_DIFF(LINKMODE, a->l_linkmode != b->l_linkmode);
927 diff |= LINK_DIFF(QDISC, strcmp(a->l_qdisc, b->l_qdisc));
928 diff |= LINK_DIFF(IFNAME, strcmp(a->l_name, b->l_name));
929 diff |= LINK_DIFF(ADDR,
nl_addr_cmp(a->l_addr, b->l_addr));
930 diff |= LINK_DIFF(BRD,
nl_addr_cmp(a->l_bcast, b->l_bcast));
931 diff |= LINK_DIFF(IFALIAS, strcmp(a->l_ifalias, b->l_ifalias));
932 diff |= LINK_DIFF(NUM_VF, a->l_num_vf != b->l_num_vf);
933 diff |= LINK_DIFF(PROMISCUITY, a->l_promiscuity != b->l_promiscuity);
934 diff |= LINK_DIFF(NUM_TX_QUEUES,a->l_num_tx_queues != b->l_num_tx_queues);
935 diff |= LINK_DIFF(NUM_RX_QUEUES,a->l_num_rx_queues != b->l_num_rx_queues);
936 diff |= LINK_DIFF(GROUP, a->l_group != b->l_group);
938 if (flags & LOOSE_COMPARISON)
939 diff |= LINK_DIFF(FLAGS,
940 (a->l_flags ^ b->l_flags) & b->l_flag_mask);
942 diff |= LINK_DIFF(FLAGS, a->l_flags != b->l_flags);
947 if (a->l_family == b->l_family) {
949 goto protinfo_mismatch;
956 diff |= LINK_DIFF(PROTINFO, 1);
962 static const struct trans_tbl link_attrs[] = {
963 __ADD(LINK_ATTR_MTU, mtu),
964 __ADD(LINK_ATTR_LINK, link),
965 __ADD(LINK_ATTR_TXQLEN, txqlen),
966 __ADD(LINK_ATTR_WEIGHT, weight),
967 __ADD(LINK_ATTR_MASTER, master),
968 __ADD(LINK_ATTR_QDISC, qdisc),
969 __ADD(LINK_ATTR_MAP, map),
970 __ADD(LINK_ATTR_ADDR, address),
971 __ADD(LINK_ATTR_BRD, broadcast),
972 __ADD(LINK_ATTR_FLAGS, flags),
973 __ADD(LINK_ATTR_IFNAME, name),
974 __ADD(LINK_ATTR_IFINDEX, ifindex),
975 __ADD(LINK_ATTR_FAMILY, family),
976 __ADD(LINK_ATTR_ARPTYPE, arptype),
977 __ADD(LINK_ATTR_STATS, stats),
978 __ADD(LINK_ATTR_CHANGE, change),
979 __ADD(LINK_ATTR_OPERSTATE, operstate),
980 __ADD(LINK_ATTR_LINKMODE, linkmode),
981 __ADD(LINK_ATTR_IFALIAS, ifalias),
982 __ADD(LINK_ATTR_NUM_VF, num_vf),
983 __ADD(LINK_ATTR_PROMISCUITY, promiscuity),
984 __ADD(LINK_ATTR_NUM_TX_QUEUES, num_tx_queues),
985 __ADD(LINK_ATTR_NUM_RX_QUEUES, num_rx_queues),
986 __ADD(LINK_ATTR_GROUP, group),
987 __ADD(LINK_ATTR_CARRIER, carrier),
988 __ADD(LINK_ATTR_PHYS_PORT_ID, phys_port_id),
989 __ADD(LINK_ATTR_NS_FD, ns_fd),
990 __ADD(LINK_ATTR_NS_PID, ns_pid),
991 __ADD(LINK_ATTR_LINK_NETNSID, link_netnsid),
994 static char *link_attrs2str(
int attrs,
char *buf,
size_t len)
996 return __flags2str(attrs, buf, len, link_attrs,
997 ARRAY_SIZE(link_attrs));
1032 struct nl_cache * cache;
1039 cache->c_iarg1 = family;
1069 if (cache->c_ops != &rtnl_link_ops)
1072 nl_list_for_each_entry(link, &cache->c_items, ce_list) {
1073 if (link->l_index == ifindex) {
1102 if (cache->c_ops != &rtnl_link_ops)
1105 nl_list_for_each_entry(link, &cache->c_items, ce_list) {
1106 if (!strcmp(name, link->l_name)) {
1130 struct nl_msg **result)
1132 struct ifinfomsg ifi;
1135 if (ifindex <= 0 && !name) {
1136 APPBUG(
"ifindex or name must be specified");
1137 return -NLE_MISSING_ATTR;
1140 memset(&ifi, 0,
sizeof(ifi));
1146 ifi.ifi_index = ifindex;
1148 if (
nlmsg_append(msg, &ifi,
sizeof(ifi), NLMSG_ALIGNTO) < 0)
1149 goto nla_put_failure;
1159 return -NLE_MSGSIZE;
1186 struct nl_msg *msg = NULL;
1187 struct nl_object *obj;
1200 if (syserr == -EINVAL &&
1207 return -NLE_OPNOTSUPP;
1216 if (err == 0 && obj)
1242 strncpy(dst, link->l_name, len - 1);
1266 ifindex = link->l_index;
1275 int rtnl_link_fill_info(
struct nl_msg *msg,
struct rtnl_link *link)
1277 if (link->ce_mask & LINK_ATTR_ADDR)
1280 if (link->ce_mask & LINK_ATTR_BRD)
1283 if (link->ce_mask & LINK_ATTR_MTU)
1286 if (link->ce_mask & LINK_ATTR_TXQLEN)
1289 if (link->ce_mask & LINK_ATTR_WEIGHT)
1292 if (link->ce_mask & LINK_ATTR_IFNAME)
1295 if (link->ce_mask & LINK_ATTR_OPERSTATE)
1296 NLA_PUT_U8(msg, IFLA_OPERSTATE, link->l_operstate);
1298 if (link->ce_mask & LINK_ATTR_CARRIER)
1299 NLA_PUT_U8(msg, IFLA_CARRIER, link->l_carrier);
1301 if (link->ce_mask & LINK_ATTR_LINKMODE)
1302 NLA_PUT_U8(msg, IFLA_LINKMODE, link->l_linkmode);
1304 if (link->ce_mask & LINK_ATTR_IFALIAS)
1307 if (link->ce_mask & LINK_ATTR_LINK)
1310 if (link->ce_mask & LINK_ATTR_LINK_NETNSID)
1311 NLA_PUT_S32(msg, IFLA_LINK_NETNSID, link->l_link_netnsid);
1313 if (link->ce_mask & LINK_ATTR_MASTER)
1316 if (link->ce_mask & LINK_ATTR_NUM_TX_QUEUES)
1317 NLA_PUT_U32(msg, IFLA_NUM_TX_QUEUES, link->l_num_tx_queues);
1319 if (link->ce_mask & LINK_ATTR_NUM_RX_QUEUES)
1320 NLA_PUT_U32(msg, IFLA_NUM_RX_QUEUES, link->l_num_rx_queues);
1322 if (link->ce_mask & LINK_ATTR_NS_FD)
1325 if (link->ce_mask & LINK_ATTR_NS_PID)
1326 NLA_PUT_U32(msg, IFLA_NET_NS_PID, link->l_ns_pid);
1331 return -NLE_MSGSIZE;
1334 static int build_link_msg(
int cmd,
struct ifinfomsg *hdr,
1335 struct rtnl_link *link,
int flags,
struct nl_msg **result)
1338 struct nlattr *af_spec;
1344 if (
nlmsg_append(msg, hdr,
sizeof(*hdr), NLMSG_ALIGNTO) < 0)
1345 goto nla_put_failure;
1347 if (rtnl_link_fill_info(msg, link))
1348 goto nla_put_failure;
1350 if (link->ce_mask & LINK_ATTR_GROUP)
1353 if (link->ce_mask & LINK_ATTR_LINKINFO) {
1354 struct nlattr *info;
1357 goto nla_put_failure;
1361 if (link->l_info_ops) {
1362 if (link->l_info_ops->io_put_attrs &&
1363 link->l_info_ops->io_put_attrs(msg, link) < 0)
1364 goto nla_put_failure;
1371 goto nla_put_failure;
1373 if (do_foreach_af(link, af_fill, msg) < 0)
1374 goto nla_put_failure;
1383 return -NLE_MSGSIZE;
1408 struct nl_msg **result)
1410 struct ifinfomsg ifi = {
1411 .ifi_family = link->l_family,
1412 .ifi_index = link->l_index,
1413 .ifi_flags = link->l_flags,
1416 return build_link_msg(RTM_NEWLINK, &ifi, link, flags, result);
1470 struct nl_msg **result)
1472 struct ifinfomsg ifi = {
1473 .ifi_family = orig->l_family,
1474 .ifi_index = orig->l_index,
1478 if (changes->ce_mask & LINK_ATTR_FLAGS) {
1479 ifi.ifi_flags = orig->l_flags & ~changes->l_flag_mask;
1480 ifi.ifi_flags |= changes->l_flags;
1481 ifi.ifi_change = changes->l_flag_mask;
1484 if (changes->l_family && changes->l_family != orig->l_family) {
1485 APPBUG(
"link change: family is immutable");
1486 return -NLE_IMMUTABLE;
1490 if (orig->ce_mask & LINK_ATTR_IFINDEX &&
1491 orig->ce_mask & LINK_ATTR_IFNAME &&
1492 changes->ce_mask & LINK_ATTR_IFNAME &&
1493 !strcmp(orig->l_name, changes->l_name))
1494 changes->ce_mask &= ~LINK_ATTR_IFNAME;
1496 if ((err = build_link_msg(RTM_NEWLINK, &ifi, changes, flags, result)) < 0)
1551 err = wait_for_ack(sk);
1552 if (err == -NLE_OPNOTSUPP && msg->nm_nlh->nlmsg_type == RTM_NEWLINK) {
1553 msg->nm_nlh->nlmsg_type = RTM_SETLINK;
1583 struct nl_msg **result)
1586 struct ifinfomsg ifi = {
1587 .ifi_index = link->l_index,
1590 if (!(link->ce_mask & (LINK_ATTR_IFINDEX | LINK_ATTR_IFNAME))) {
1591 APPBUG(
"ifindex or name must be specified");
1592 return -NLE_MISSING_ATTR;
1598 if (
nlmsg_append(msg, &ifi,
sizeof(ifi), NLMSG_ALIGNTO) < 0)
1599 goto nla_put_failure;
1601 if (link->ce_mask & LINK_ATTR_IFNAME)
1609 return -NLE_MSGSIZE;
1690 strncpy(link->l_name, name,
sizeof(link->l_name) - 1);
1691 link->ce_mask |= LINK_ATTR_IFNAME;
1704 return link->ce_mask & LINK_ATTR_IFNAME ? link->l_name : NULL;
1714 link->l_group = group;
1715 link->ce_mask |= LINK_ATTR_GROUP;
1726 return link->l_group;
1729 static inline void __assign_addr(
struct rtnl_link *link,
struct nl_addr **pos,
1730 struct nl_addr *
new,
int flag)
1738 link->ce_mask |= flag;
1754 __assign_addr(link, &link->l_addr, addr, LINK_ATTR_ADDR);
1768 return link->ce_mask & LINK_ATTR_ADDR ? link->l_addr : NULL;
1785 __assign_addr(link, &link->l_bcast, addr, LINK_ATTR_BRD);
1799 return link->ce_mask & LINK_ATTR_BRD ? link->l_bcast : NULL;
1812 link->l_flag_mask |= flags;
1813 link->l_flags |= flags;
1814 link->ce_mask |= LINK_ATTR_FLAGS;
1827 link->l_flag_mask |= flags;
1828 link->l_flags &= ~flags;
1829 link->ce_mask |= LINK_ATTR_FLAGS;
1843 return link->l_flags;
1853 link->l_family = family;
1854 link->ce_mask |= LINK_ATTR_FAMILY;
1856 if (link->l_af_ops) {
1857 af_free(link, link->l_af_ops,
1858 link->l_af_data[link->l_af_ops->ao_family], NULL);
1859 link->l_af_data[link->l_af_ops->ao_family] = NULL;
1862 link->l_af_ops = af_lookup_and_alloc(link, family);
1874 return link->ce_mask & LINK_ATTR_FAMILY ? link->l_family : AF_UNSPEC;
1888 link->l_arptype = arptype;
1889 link->ce_mask |= LINK_ATTR_ARPTYPE;
1902 if (link->ce_mask & LINK_ATTR_ARPTYPE)
1903 return link->l_arptype;
1918 link->l_index = ifindex;
1919 link->ce_mask |= LINK_ATTR_IFINDEX;
1933 return link->l_index;
1947 link->ce_mask |= LINK_ATTR_MTU;
1975 link->l_txqlen = txqlen;
1976 link->ce_mask |= LINK_ATTR_TXQLEN;
1991 return link->ce_mask & LINK_ATTR_TXQLEN ? link->l_txqlen : 0;
1994 void rtnl_link_set_link(
struct rtnl_link *link,
int ifindex)
1996 link->l_link = ifindex;
1997 link->ce_mask |= LINK_ATTR_LINK;
2000 int rtnl_link_get_link(
struct rtnl_link *link)
2002 return link->l_link;
2015 link->l_link_netnsid = link_netnsid;
2016 link->ce_mask |= LINK_ATTR_LINK_NETNSID;
2032 if (!(link->ce_mask & LINK_ATTR_LINK_NETNSID))
2035 *out_link_netnsid = link->l_link_netnsid;
2048 link->l_master = ifindex;
2049 link->ce_mask |= LINK_ATTR_MASTER;
2061 return link->l_master;
2073 link->l_carrier = status;
2074 link->ce_mask |= LINK_ATTR_CARRIER;
2086 return link->l_carrier;
2099 link->l_operstate = status;
2100 link->ce_mask |= LINK_ATTR_OPERSTATE;
2113 return link->l_operstate;
2126 link->l_linkmode = mode;
2127 link->ce_mask |= LINK_ATTR_LINKMODE;
2140 return link->l_linkmode;
2153 return link->l_ifalias;
2170 free(link->l_ifalias);
2173 link->l_ifalias = strdup(alias);
2174 link->ce_mask |= LINK_ATTR_IFALIAS;
2176 link->l_ifalias = NULL;
2177 link->ce_mask &= ~LINK_ATTR_IFALIAS;
2196 strncpy(link->l_qdisc, name,
sizeof(link->l_qdisc) - 1);
2197 link->ce_mask |= LINK_ATTR_QDISC;
2210 return link->ce_mask & LINK_ATTR_QDISC ? link->l_qdisc : NULL;
2223 if (link->ce_mask & LINK_ATTR_NUM_VF) {
2224 *num_vf = link->l_num_vf;
2227 return -NLE_OPNOTSUPP;
2239 if (
id > RTNL_LINK_STATS_MAX)
2242 return link->l_stats[id];
2257 const uint64_t value)
2259 if (
id > RTNL_LINK_STATS_MAX)
2262 link->l_stats[id] = value;
2281 struct rtnl_link_info_ops *io;
2285 free(link->l_info_kind);
2286 link->ce_mask &= ~LINK_ATTR_LINKINFO;
2287 release_link_info(link);
2292 kind = strdup(type);
2298 if (io->io_alloc && (err = io->io_alloc(link)) < 0)
2301 link->l_info_ops = io;
2304 link->l_info_kind = kind;
2305 link->ce_mask |= LINK_ATTR_LINKINFO;
2323 return link->l_info_kind;
2337 link->l_promiscuity = count;
2338 link->ce_mask |= LINK_ATTR_PROMISCUITY;
2350 return link->l_promiscuity;
2369 link->l_num_tx_queues = nqueues;
2370 link->ce_mask |= LINK_ATTR_NUM_TX_QUEUES;
2381 return link->l_num_tx_queues;
2400 link->l_num_rx_queues = nqueues;
2401 link->ce_mask |= LINK_ATTR_NUM_RX_QUEUES;
2412 return link->l_num_rx_queues;
2423 return link->l_phys_port_id;
2426 void rtnl_link_set_ns_fd(
struct rtnl_link *link,
int fd)
2429 link->ce_mask |= LINK_ATTR_NS_FD;
2432 int rtnl_link_get_ns_fd(
struct rtnl_link *link)
2434 return link->l_ns_fd;
2437 void rtnl_link_set_ns_pid(
struct rtnl_link *link, pid_t pid)
2439 link->l_ns_pid = pid;
2440 link->ce_mask |= LINK_ATTR_NS_PID;
2443 pid_t rtnl_link_get_ns_pid(
struct rtnl_link *link)
2445 return link->l_ns_pid;
2495 err = -NLE_OPNOTSUPP;
2578 static const struct trans_tbl link_flags[] = {
2579 __ADD(IFF_LOOPBACK, loopback),
2580 __ADD(IFF_BROADCAST, broadcast),
2581 __ADD(IFF_POINTOPOINT, pointopoint),
2582 __ADD(IFF_MULTICAST, multicast),
2583 __ADD(IFF_NOARP, noarp),
2584 __ADD(IFF_ALLMULTI, allmulti),
2585 __ADD(IFF_PROMISC, promisc),
2586 __ADD(IFF_MASTER, master),
2587 __ADD(IFF_SLAVE, slave),
2588 __ADD(IFF_DEBUG, debug),
2589 __ADD(IFF_DYNAMIC, dynamic),
2590 __ADD(IFF_AUTOMEDIA, automedia),
2591 __ADD(IFF_PORTSEL, portsel),
2592 __ADD(IFF_NOTRAILERS, notrailers),
2594 __ADD(IFF_RUNNING, running),
2595 __ADD(IFF_LOWER_UP, lowerup),
2596 __ADD(IFF_DORMANT, dormant),
2597 __ADD(IFF_ECHO, echo),
2600 char *rtnl_link_flags2str(
int flags,
char *buf,
size_t len)
2602 return __flags2str(flags, buf, len, link_flags,
2603 ARRAY_SIZE(link_flags));
2606 int rtnl_link_str2flags(
const char *name)
2608 return __str2flags(name, link_flags, ARRAY_SIZE(link_flags));
2611 static const struct trans_tbl link_stats[] = {
2677 char *rtnl_link_stat2str(
int st,
char *buf,
size_t len)
2679 return __type2str(st, buf, len, link_stats, ARRAY_SIZE(link_stats));
2682 int rtnl_link_str2stat(
const char *name)
2684 return __str2type(name, link_stats, ARRAY_SIZE(link_stats));
2687 static const struct trans_tbl link_operstates[] = {
2688 __ADD(IF_OPER_UNKNOWN, unknown),
2689 __ADD(IF_OPER_NOTPRESENT, notpresent),
2690 __ADD(IF_OPER_DOWN, down),
2691 __ADD(IF_OPER_LOWERLAYERDOWN, lowerlayerdown),
2692 __ADD(IF_OPER_TESTING, testing),
2693 __ADD(IF_OPER_DORMANT, dormant),
2694 __ADD(IF_OPER_UP, up),
2697 char *rtnl_link_operstate2str(uint8_t st,
char *buf,
size_t len)
2699 return __type2str(st, buf, len, link_operstates,
2700 ARRAY_SIZE(link_operstates));
2703 int rtnl_link_str2operstate(
const char *name)
2705 return __str2type(name, link_operstates,
2706 ARRAY_SIZE(link_operstates));
2709 static const struct trans_tbl link_modes[] = {
2710 __ADD(IF_LINK_MODE_DEFAULT,
default),
2711 __ADD(IF_LINK_MODE_DORMANT, dormant),
2714 static const struct trans_tbl carrier_states[] = {
2715 __ADD(IF_CARRIER_DOWN, down),
2716 __ADD(IF_CARRIER_UP, up),
2719 char *rtnl_link_mode2str(uint8_t st,
char *buf,
size_t len)
2721 return __type2str(st, buf, len, link_modes, ARRAY_SIZE(link_modes));
2724 int rtnl_link_str2mode(
const char *name)
2726 return __str2type(name, link_modes, ARRAY_SIZE(link_modes));
2729 char *rtnl_link_carrier2str(uint8_t st,
char *buf,
size_t len)
2731 return __type2str(st, buf, len, carrier_states,
2732 ARRAY_SIZE(carrier_states));
2735 int rtnl_link_str2carrier(
const char *name)
2737 return __str2type(name, carrier_states, ARRAY_SIZE(carrier_states));
2767 link->l_weight = weight;
2768 link->ce_mask |= LINK_ATTR_WEIGHT;
2776 return link->l_weight;
2781 static struct nl_object_ops link_obj_ops = {
2782 .oo_name =
"route/link",
2784 .oo_free_data = link_free_data,
2785 .oo_clone = link_clone,
2791 .oo_compare = link_compare,
2792 .oo_keygen = link_keygen,
2793 .oo_attrs2str = link_attrs2str,
2794 .oo_id_attrs = LINK_ATTR_IFINDEX | LINK_ATTR_FAMILY,
2797 static struct nl_af_group link_groups[] = {
2798 { AF_UNSPEC, RTNLGRP_LINK },
2799 { AF_BRIDGE, RTNLGRP_LINK },
2800 { END_OF_GROUP_LIST },
2803 static struct nl_cache_ops rtnl_link_ops = {
2804 .co_name =
"route/link",
2805 .co_hdrsize =
sizeof(
struct ifinfomsg),
2807 { RTM_NEWLINK, NL_ACT_NEW,
"new" },
2808 { RTM_DELLINK, NL_ACT_DEL,
"del" },
2809 { RTM_GETLINK, NL_ACT_GET,
"get" },
2810 { RTM_SETLINK, NL_ACT_CHANGE,
"set" },
2811 END_OF_MSGTYPES_LIST,
2813 .co_protocol = NETLINK_ROUTE,
2814 .co_groups = link_groups,
2815 .co_request_update = link_request_update,
2816 .co_msg_parser = link_msg_parser,
2817 .co_obj_ops = &link_obj_ops,
2820 static void __init link_init(
void)
2825 static void __exit link_exit(
void)
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
Dump object briefly on one line.
int rtnl_link_get_link_netnsid(const struct rtnl_link *link, int32_t *out_link_netnsid)
Get the netnsid of the link.
uint32_t rtnl_link_get_group(struct rtnl_link *link)
Return the group identifier of link object.
int32_t nla_get_s32(const struct nlattr *nla)
Return payload of 32 bit signed integer attribute.
void nlmsg_free(struct nl_msg *msg)
Release a reference from an netlink message.
struct rtnl_link * rtnl_link_get_by_name(struct nl_cache *cache, const char *name)
Lookup link in cache by link name.
int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
Compare abstract addresses.
int nl_addr_guess_family(const struct nl_addr *addr)
Guess address family of abstract address based on address size.
void * nlmsg_data(const struct nlmsghdr *nlh)
Return pointer to message payload.
void rtnl_link_set_master(struct rtnl_link *link, int ifindex)
Set master link of link object.
void rtnl_link_set_ifindex(struct rtnl_link *link, int ifindex)
Set interface index of link object.
void rtnl_link_unset_flags(struct rtnl_link *link, unsigned int flags)
Unset flags of link object.
#define NLA_PUT_ADDR(msg, attrtype, addr)
Add address attribute to netlink message.
int rtnl_link_set_info_type(struct rtnl_link *link, const char *type)
void rtnl_link_set_arptype(struct rtnl_link *link, unsigned int arptype)
Set hardware type of link object.
char * rtnl_link_get_qdisc(struct rtnl_link *link)
Return name of queueing discipline of link object.
struct rtnl_link * rtnl_link_get(struct nl_cache *cache, int ifindex)
Lookup link in cache by interface index.
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
Attribute validation policy.
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
struct rtnl_link * rtnl_link_alloc(void)
Allocate link object.
Unspecified type, binary data chunk.
struct nl_cache * nl_cache_mngt_require_safe(const char *name)
Return cache previously provided via nl_cache_mngt_provide()
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
int nl_send_sync(struct nl_sock *sk, struct nl_msg *msg)
Finalize and transmit Netlink message and wait for ACK or error message.
char * nla_get_string(const struct nlattr *nla)
Return payload of string attribute.
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.
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name, struct rtnl_link **result)
Get a link object directly from kernel.
int rtnl_link_build_get_request(int ifindex, const char *name, struct nl_msg **result)
Construct RTM_GETLINK netlink message.
int rtnl_link_build_add_request(struct rtnl_link *link, int flags, struct nl_msg **result)
Build a netlink message requesting the addition of new virtual link.
int rtnl_link_build_delete_request(const struct rtnl_link *link, struct nl_msg **result)
Build a netlink message requesting the deletion of a link.
int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, struct nla_policy *policy)
parse attributes of a netlink message
struct nl_data * nl_data_alloc_attr(const struct nlattr *nla)
Allocate abstract data object based on netlink attribute.
void rtnl_link_set_carrier(struct rtnl_link *link, uint8_t status)
Set carrier of link object.
void rtnl_link_set_broadcast(struct rtnl_link *link, struct nl_addr *addr)
Set link layer broadcast address of link object.
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
void nl_addr_set_family(struct nl_addr *addr, int family)
Set address family.
struct nl_addr * nl_addr_alloc_attr(const struct nlattr *nla, int family)
Allocate abstract address based on Netlink attribute.
int rtnl_link_set_stat(struct rtnl_link *link, rtnl_link_stat_id_t id, const uint64_t value)
Set value of link statistics counter.
struct rtnl_link_af_ops * rtnl_link_af_ops_lookup(const unsigned int family)
Return operations of a specific link address family.
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
uint64_t rtnl_link_get_stat(struct rtnl_link *link, rtnl_link_stat_id_t id)
Return value of link statistics counter.
NUL terminated character string.
Dump all attributes but no statistics.
char * rtnl_link_get_name(struct rtnl_link *link)
Return name of link object.
uint8_t rtnl_link_get_linkmode(struct rtnl_link *link)
Return link mode of link object.
uint32_t rtnl_link_get_num_tx_queues(struct rtnl_link *link)
Return number of TX queues.
int nl_addr_iszero(const struct nl_addr *addr)
Returns true if the address consists of all zeros.
void rtnl_link_set_num_tx_queues(struct rtnl_link *link, uint32_t nqueues)
Set number of TX queues.
struct nl_data * rtnl_link_get_phys_port_id(struct rtnl_link *link)
Return physical port id of link object.
struct nl_addr * rtnl_link_get_addr(struct rtnl_link *link)
Return link layer address of link object.
void rtnl_link_set_promiscuity(struct rtnl_link *link, uint32_t count)
Set link promiscuity count.
int rtnl_link_delete(struct nl_sock *sk, const struct rtnl_link *link)
Delete link.
unsigned int rtnl_link_get_flags(struct rtnl_link *link)
Return flags of link object.
uint8_t rtnl_link_get_operstate(struct rtnl_link *link)
Return operational status of link object.
int rtnl_link_get_num_vf(struct rtnl_link *link, uint32_t *num_vf)
Return number of PCI virtual functions of link object.
void nl_cache_free(struct nl_cache *cache)
Free a cache.
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
int rtnl_link_enslave(struct nl_sock *sock, struct rtnl_link *master, struct rtnl_link *slave)
Enslave slave link to master link.
unsigned int rtnl_link_get_weight(struct rtnl_link *link)
unsigned int rtnl_link_get_arptype(struct rtnl_link *link)
Get hardware type of link object.
int rtnl_link_get_master(struct rtnl_link *link)
Return master link of link object.
int nl_rtgen_request(struct nl_sock *sk, int type, int family, int flags)
Send routing netlink request message.
double nl_cancel_down_bytes(unsigned long long l, char **unit)
Cancel down a byte counter.
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
uint8_t rtnl_link_get_carrier(struct rtnl_link *link)
Return carrier status of link object.
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, struct nla_policy *policy)
Create attribute index based on nested attribute.
int nla_type(const struct nlattr *nla)
Return type of the attribute.
void rtnl_link_set_ifalias(struct rtnl_link *link, const char *alias)
Set alias name of link object (SNMP IfAlias)
void rtnl_link_set_addr(struct rtnl_link *link, struct nl_addr *addr)
Set link layer address of link object.
void rtnl_link_set_family(struct rtnl_link *link, int family)
Set address family of link object.
void rtnl_link_set_name(struct rtnl_link *link, const char *name)
Set name of link object.
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
unsigned int rtnl_link_get_mtu(struct rtnl_link *link)
Return maximum transmission unit of link object.
int rtnl_link_set_type(struct rtnl_link *link, const char *type)
Set type of link object.
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
void * rtnl_link_af_alloc(struct rtnl_link *link, const struct rtnl_link_af_ops *ops)
Allocate and return data buffer for link address family modules.
struct nl_data * nl_data_clone(const struct nl_data *src)
Clone an abstract data object.
int rtnl_link_get_family(struct rtnl_link *link)
Return address family of link object.
uint32_t rtnl_link_get_num_rx_queues(struct rtnl_link *link)
Return number of RX queues.
int rtnl_link_change(struct nl_sock *sk, struct rtnl_link *orig, struct rtnl_link *changes, int flags)
Change link.
int rtnl_link_af_data_compare(struct rtnl_link *a, struct rtnl_link *b, int family)
Compare af data for a link address family.
#define nla_for_each_nested(pos, nla, rem)
Iterate over a stream of nested attributes.
int rtnl_link_set_link_netnsid(struct rtnl_link *link, int32_t link_netnsid)
Set the netnsid of the link.
void rtnl_link_set_num_rx_queues(struct rtnl_link *link, uint32_t nqueues)
Set number of RX queues.
int rtnl_link_alloc_cache(struct nl_sock *sk, int family, struct nl_cache **result)
Allocate link cache and fill in all configured links.
void rtnl_link_set_linkmode(struct rtnl_link *link, uint8_t mode)
Set link mode of link object.
const char * rtnl_link_get_ifalias(struct rtnl_link *link)
Return alias name of link object (SNMP IfAlias)
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
int nl_cache_refill(struct nl_sock *sk, struct nl_cache *cache)
(Re)fill a cache with the contents in the kernel.
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
#define NLA_PUT_STRING(msg, attrtype, value)
Add string attribute to netlink message.
int rtnl_link_release(struct nl_sock *sock, struct rtnl_link *slave)
Release slave link from its master.
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
uint16_t type
Type of attribute or NLA_UNSPEC.
unsigned int rtnl_link_get_txqlen(struct rtnl_link *link)
Return transmission queue length.
struct nl_msg * nlmsg_alloc_simple(int nlmsgtype, int flags)
Allocate a new netlink message.
char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst, size_t len)
Translate interface index to corresponding link name.
int rtnl_link_get_ifindex(struct rtnl_link *link)
Return interface index of link object.
uint32_t rtnl_link_get_promiscuity(struct rtnl_link *link)
Return link promiscuity count.
void rtnl_link_set_flags(struct rtnl_link *link, unsigned int flags)
Set flags of link object.
void rtnl_link_set_mtu(struct rtnl_link *link, unsigned int mtu)
Set Maximum Transmission Unit of link object.
void rtnl_link_set_qdisc(struct rtnl_link *link, const char *name)
Set queueing discipline name of link object.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
void rtnl_link_set_weight(struct rtnl_link *link, unsigned int weight)
char * rtnl_link_get_type(struct rtnl_link *link)
Return type of link.
void rtnl_link_put(struct rtnl_link *link)
Return a link object reference.
void rtnl_link_af_ops_put(struct rtnl_link_af_ops *ops)
Give back reference to a set of operations.
int rtnl_link_name2i(struct nl_cache *cache, const char *name)
Translate link name to corresponding interface index.
struct nl_addr * rtnl_link_get_broadcast(struct rtnl_link *link)
Return link layer broadcast address of link object.
void rtnl_link_set_txqlen(struct rtnl_link *link, unsigned int txqlen)
Set transmission queue length.
int rtnl_link_build_change_request(struct rtnl_link *orig, struct rtnl_link *changes, int flags, struct nl_msg **result)
Build a netlink message requesting the modification of link.
int nl_send_auto(struct nl_sock *sk, struct nl_msg *msg)
Finalize and transmit Netlink message.
char * rtnl_link_get_info_type(struct rtnl_link *link)
void rtnl_link_set_operstate(struct rtnl_link *link, uint8_t status)
Set operational status of link object.
int rtnl_link_add(struct nl_sock *sk, struct rtnl_link *link, int flags)
Add virtual link.
void rtnl_link_set_group(struct rtnl_link *link, uint32_t group)
Set the group identifier of a link object.
#define NLA_PUT_S32(msg, attrtype, value)
Add 32 bit signed integer attribute to netlink message.
Dump all attributes including statistics.
int rtnl_link_release_ifindex(struct nl_sock *sock, int slave)
Release slave link from its master.
void rtnl_link_info_ops_put(struct rtnl_link_info_ops *ops)
Give back reference to a set of operations.
size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
Copy string attribute payload to a buffer.
struct nl_cache * nl_cache_alloc(struct nl_cache_ops *ops)
Allocate new cache.
int rtnl_link_enslave_ifindex(struct nl_sock *sock, int master, int slave)
Enslave slave link to master link.
struct rtnl_link_info_ops * rtnl_link_info_ops_lookup(const char *name)
Return operations of a specific link info type.
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
void nl_data_free(struct nl_data *data)
Free an abstract data object.
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.