Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib/route/link: add support for getting permanent mac address of link. #404

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
33 changes: 33 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 @@ -2024,6 +2044,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;
Loading