summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJohn Hurley <john.hurley@netronome.com>2018-06-28 17:03:04 +0100
committerSimon Horman <simon.horman@netronome.com>2018-06-29 14:57:32 +0200
commit135ee7ef362f77c8b3f132c004e79005ff368a6b (patch)
treec8104ecb9c095c4f8ecce397f9283ae0c8ba2071 /lib
parent88dcf2aa82347da7bfcf4f6e1d72c2d3012b4c12 (diff)
downloadopenvswitch-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.c43
-rwxr-xr-x[-rw-r--r--]lib/rtnetlink.h4
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