[ovs-dev] [PATCH 3/6] rtnetlink: extend parser to include kind of master and slave

John Hurley john.hurley at netronome.com
Thu Jun 21 13:35:58 UTC 2018


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 at netronome.com>
Reviewed-by: Simon Horman <simon.horman at netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe at netronome.com>
---
 lib/rtnetlink.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 lib/rtnetlink.h |  4 ++++
 2 files changed, 47 insertions(+)
 mode change 100644 => 100755 lib/rtnetlink.h

diff --git a/lib/rtnetlink.c b/lib/rtnetlink.c
index 4d9003b..f822dff 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
old mode 100644
new mode 100755
index 518320f..422d1db
--- 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
-- 
2.7.4



More information about the dev mailing list