diff options
author | John Hurley <john.hurley@netronome.com> | 2018-06-28 17:03:04 +0100 |
---|---|---|
committer | Simon Horman <simon.horman@netronome.com> | 2018-06-29 14:57:32 +0200 |
commit | 135ee7ef362f77c8b3f132c004e79005ff368a6b (patch) | |
tree | c8104ecb9c095c4f8ecce397f9283ae0c8ba2071 /lib | |
parent | 88dcf2aa82347da7bfcf4f6e1d72c2d3012b4c12 (diff) | |
download | openvswitch-135ee7ef362f77c8b3f132c004e79005ff368a6b.tar.gz |
rtnetlink: extend parser to include kind of master and slave
Extend the rtnetlink_parse function to look for linkinfo attributes and,
in turn, store pointers to the master and slave kinds (if any) in the
rtnetlink_change struct.
Signed-off-by: John Hurley <john.hurley@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/rtnetlink.c | 43 | ||||
-rwxr-xr-x[-rw-r--r--] | lib/rtnetlink.h | 4 |
2 files changed, 47 insertions, 0 deletions
diff --git a/lib/rtnetlink.c b/lib/rtnetlink.c index 4d9003b52..f822dffc7 100644 --- a/lib/rtnetlink.c +++ b/lib/rtnetlink.c @@ -27,6 +27,10 @@ #include "openvswitch/ofpbuf.h" #include "packets.h" +#if IFLA_INFO_MAX < 5 +#define IFLA_INFO_SLAVE_KIND 4 +#endif + static struct nln *nln = NULL; static struct rtnetlink_change rtn_change; @@ -45,6 +49,36 @@ rtnetlink_type_is_rtnlgrp_addr(uint16_t type) return type == RTM_NEWADDR || type == RTM_DELADDR; } +/* Parses nested nlattr for link info. Returns false if unparseable, else + * populates 'change' and returns true. */ +static bool +rtnetlink_parse_link_info(const struct nlattr *nla, + struct rtnetlink_change *change) +{ + bool parsed = false; + + static const struct nl_policy linkinfo_policy[] = { + [IFLA_INFO_KIND] = { .type = NL_A_STRING, .optional = true }, + [IFLA_INFO_SLAVE_KIND] = { .type = NL_A_STRING, .optional = true }, + }; + + struct nlattr *linkinfo[ARRAY_SIZE(linkinfo_policy)]; + + parsed = nl_parse_nested(nla, linkinfo_policy, linkinfo, + ARRAY_SIZE(linkinfo_policy)); + + if (parsed) { + change->master = (linkinfo[IFLA_INFO_KIND] + ? nl_attr_get_string(linkinfo[IFLA_INFO_KIND]) + : NULL); + change->slave = (linkinfo[IFLA_INFO_SLAVE_KIND] + ? nl_attr_get_string(linkinfo[IFLA_INFO_SLAVE_KIND]) + : NULL); + } + + return parsed; +} + /* Parses a rtnetlink message 'buf' into 'change'. If 'buf' is unparseable, * leaves 'change' untouched and returns false. Otherwise, populates 'change' * and returns true. */ @@ -64,6 +98,7 @@ rtnetlink_parse(struct ofpbuf *buf, struct rtnetlink_change *change) [IFLA_MASTER] = { .type = NL_A_U32, .optional = true }, [IFLA_MTU] = { .type = NL_A_U32, .optional = true }, [IFLA_ADDRESS] = { .type = NL_A_UNSPEC, .optional = true }, + [IFLA_LINKINFO] = { .type = NL_A_NESTED, .optional = true }, }; struct nlattr *attrs[ARRAY_SIZE(policy)]; @@ -94,6 +129,14 @@ rtnetlink_parse(struct ofpbuf *buf, struct rtnetlink_change *change) } else { memset(&change->mac, 0, ETH_ADDR_LEN); } + + if (attrs[IFLA_LINKINFO]) { + parsed = rtnetlink_parse_link_info(attrs[IFLA_LINKINFO], + change); + } else { + change->master = NULL; + change->slave = NULL; + } } } else if (rtnetlink_type_is_rtnlgrp_addr(nlmsg->nlmsg_type)) { /* Policy for RTNLGRP_IPV4_IFADDR/RTNLGRP_IPV6_IFADDR messages. diff --git a/lib/rtnetlink.h b/lib/rtnetlink.h index 518320f73..422d1db11 100644..100755 --- a/lib/rtnetlink.h +++ b/lib/rtnetlink.h @@ -48,6 +48,10 @@ struct rtnetlink_change { /* Network device address status. */ /* xxx To be added when needed. */ + + /* Link info. */ + const char *master; /* Kind of master (NULL if not master). */ + const char *slave; /* Kind of slave (NULL if not slave). */ }; /* Function called to report that a netdev has changed. 'change' describes the |