Skip to content

Commit

Permalink
route: add support for getting permanent mac address of link.
Browse files Browse the repository at this point in the history
  • Loading branch information
precla committed Sep 12, 2024
1 parent afafe78 commit b292cdd
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 0 deletions.
11 changes: 11 additions & 0 deletions doc/route.txt
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,17 @@ void rtnl_link_set_addr(struct rtnl_link *link, struct nl_addr *addr);
struct nl_addr *rtnl_link_get_addr(struct rtnl_link *link);
-----

[[link_attr_permaddr]]
==== Permanent address
The permanent link layer address (e.g. MAC address).

[source,c]
-----
#include <netlink/route/link.h>

struct nl_addr *rtnl_link_get_perm_addr(struct rtnl_link *link);
-----

[[link_attr_broadcast]]
==== Broadcast Address
The link layer broadcast address
Expand Down
2 changes: 2 additions & 0 deletions include/netlink/route/link.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ extern unsigned int rtnl_link_get_arptype(struct rtnl_link *);
extern void rtnl_link_set_addr(struct rtnl_link *, struct nl_addr *);
extern struct nl_addr *rtnl_link_get_addr(struct rtnl_link *);

extern struct nl_addr *rtnl_link_get_perm_addr(struct rtnl_link *);

extern void rtnl_link_set_broadcast(struct rtnl_link *, struct nl_addr *);
extern struct nl_addr *rtnl_link_get_broadcast(struct rtnl_link *);

Expand Down
36 changes: 36 additions & 0 deletions lib/route/link.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
#define LINK_ATTR_GSO_MAX_SEGS ((uint64_t) 1 << 37)
#define LINK_ATTR_GSO_MAX_SIZE ((uint64_t) 1 << 38)
#define LINK_ATTR_LINKINFO_SLAVE_KIND ((uint64_t) 1 << 39)
#define LINK_ATTR_PERMANENT_ADDR ((uint64_t) 1 << 40)

static struct nl_cache_ops rtnl_link_ops;
static struct nl_object_ops link_obj_ops;
Expand Down Expand Up @@ -271,6 +272,7 @@ static void link_free_data(struct nl_object *c)

nl_addr_put(link->l_addr);
nl_addr_put(link->l_bcast);
nl_addr_put(link->l_paddr);

free(link->l_ifalias);
free(link->l_info_kind);
Expand All @@ -294,6 +296,7 @@ static int link_clone(struct nl_object *_dst, struct nl_object *_src)

dst->l_addr = NULL;
dst->l_bcast = NULL;
dst->l_paddr = NULL;
dst->l_info_kind = NULL;
dst->l_info_slave_kind = NULL;
dst->l_info_ops = NULL;
Expand All @@ -313,6 +316,10 @@ static int link_clone(struct nl_object *_dst, struct nl_object *_src)
if (!(dst->l_bcast = nl_addr_clone(src->l_bcast)))
return -NLE_NOMEM;

if (src->l_paddr)
if (!(dst->l_paddr = nl_addr_clone(src->l_paddr)))
return -NLE_NOMEM;

if (src->l_ifalias)
if (!(dst->l_ifalias = strdup(src->l_ifalias)))
return -NLE_NOMEM;
Expand Down Expand Up @@ -514,6 +521,15 @@ int rtnl_link_info_parse(struct rtnl_link *link, struct nlattr **tb)
link->ce_mask |= LINK_ATTR_ADDR;
}

if (tb[IFLA_PERM_ADDRESS]) {
link->l_paddr = nl_addr_alloc_attr(tb[IFLA_PERM_ADDRESS], AF_UNSPEC);
if (link->l_paddr == NULL)
return -NLE_NOMEM;
nl_addr_set_family(link->l_paddr,
nl_addr_guess_family(link->l_paddr));
link->ce_mask |= LINK_ATTR_PERMANENT_ADDR;
}

if (tb[IFLA_BROADCAST]) {
link->l_bcast = nl_addr_alloc_attr(tb[IFLA_BROADCAST],
AF_UNSPEC);
Expand Down Expand Up @@ -863,6 +879,9 @@ static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p)
if (link->l_addr && !nl_addr_iszero(link->l_addr))
nl_dump(p, "%s ", nl_addr2str(link->l_addr, buf, sizeof(buf)));

if (link->l_paddr && !nl_addr_iszero(link->l_paddr))
nl_dump(p, "permanent address %s ", nl_addr2str(link->l_paddr, buf, sizeof(buf)));

if (link->ce_mask & LINK_ATTR_MASTER) {
if (cache) {
_nl_auto_rtnl_link struct rtnl_link *master = rtnl_link_get(cache, link->l_master);
Expand Down Expand Up @@ -1130,6 +1149,7 @@ static uint64_t link_compare(struct nl_object *_a, struct nl_object *_b,
diff |= _DIFF(LINK_ATTR_IFNAME, strcmp(a->l_name, b->l_name));
diff |= _DIFF(LINK_ATTR_ADDR, nl_addr_cmp(a->l_addr, b->l_addr));
diff |= _DIFF(LINK_ATTR_BRD, nl_addr_cmp(a->l_bcast, b->l_bcast));
diff |= _DIFF(LINK_ATTR_PERMANENT_ADDR, nl_addr_cmp(a->l_paddr, b->l_paddr));
diff |= _DIFF(LINK_ATTR_IFALIAS, strcmp(a->l_ifalias, b->l_ifalias));
diff |= _DIFF(LINK_ATTR_NUM_VF, a->l_num_vf != b->l_num_vf);
diff |= _DIFF(LINK_ATTR_PROMISCUITY,
Expand Down Expand Up @@ -1565,6 +1585,9 @@ int rtnl_link_fill_info(struct nl_msg *msg, struct rtnl_link *link)
if (link->ce_mask & LINK_ATTR_NS_PID)
NLA_PUT_U32(msg, IFLA_NET_NS_PID, link->l_ns_pid);

if (link->ce_mask & LINK_ATTR_PERMANENT_ADDR)
NLA_PUT_ADDR(msg, IFLA_PERM_ADDRESS, link->l_paddr);

return 0;

nla_put_failure:
Expand Down Expand Up @@ -2024,6 +2047,19 @@ struct nl_addr *rtnl_link_get_addr(struct rtnl_link *link)
return link->ce_mask & LINK_ATTR_ADDR ? link->l_addr : NULL;
}

/**
* Return permanent link layer adress of link object
* @arg link Link object
*
* @copydoc pointer_lifetime_warning
* @route_doc{link_attr_permaddr, Permanent Link Layer Address}
* @return Permanent link layer address or NULL if not set.
*/
struct nl_addr *rtnl_link_get_perm_addr(struct rtnl_link *link)
{
return link->ce_mask & LINK_ATTR_PERMANENT_ADDR ? link->l_paddr : NULL;
}

/**
* Set link layer broadcast address of link object
* @arg link Link object
Expand Down
1 change: 1 addition & 0 deletions lib/route/nl-route.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ struct rtnl_link {
uint32_t l_master;
struct nl_addr *l_addr;
struct nl_addr *l_bcast;
struct nl_addr *l_paddr;
char l_qdisc[IFQDISCSIZ];
struct rtnl_link_map l_map;
uint64_t l_stats[RTNL_LINK_STATS_MAX + 1];
Expand Down
1 change: 1 addition & 0 deletions libnl-route-3.sym
Original file line number Diff line number Diff line change
Expand Up @@ -1340,4 +1340,5 @@ global:
rtnl_link_bond_get_miimon;
rtnl_link_bond_get_min_links;
rtnl_link_bond_get_mode;
rtnl_link_get_perm_addr;
} libnl_3_10;

0 comments on commit b292cdd

Please sign in to comment.