[PATCH libnl v2 4/4] route: Add support for MPLS to netconf

David Ahern dsahern at gmail.com
Wed May 3 14:05:09 PDT 2017


Add support to netconf for MPLS address family.

v2
- change get method to return 0/error and take 'int *val'
  which is set to the value requested
- added rtnl_netconf_get_input to libnl-route-3.sym

Signed-off-by: David Ahern <dsa at cumulusnetworks.com>
---
 include/linux-private/linux/netconf.h   |  1 +
 include/linux-private/linux/rtnetlink.h |  2 ++
 include/netlink/netlink-compat.h        |  4 ++++
 include/netlink/route/netconf.h         |  1 +
 lib/route/netconf.c                     | 40 +++++++++++++++++++++++++++++++++
 libnl-route-3.sym                       |  1 +
 src/nl-monitor.c                        |  1 +
 7 files changed, 50 insertions(+)

diff --git a/include/linux-private/linux/netconf.h b/include/linux-private/linux/netconf.h
index ec14058e9b33..76ecfcc2e91f 100644
--- a/include/linux-private/linux/netconf.h
+++ b/include/linux-private/linux/netconf.h
@@ -16,6 +16,7 @@ enum {
 	NETCONFA_MC_FORWARDING,
 	NETCONFA_PROXY_NEIGH,
 	NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
+	NETCONFA_INPUT,
 	__NETCONFA_MAX
 };
 #define NETCONFA_MAX	(__NETCONFA_MAX - 1)
diff --git a/include/linux-private/linux/rtnetlink.h b/include/linux-private/linux/rtnetlink.h
index 7d94908c04ae..a92c7c41cdf5 100644
--- a/include/linux-private/linux/rtnetlink.h
+++ b/include/linux-private/linux/rtnetlink.h
@@ -647,6 +647,8 @@ enum rtnetlink_groups {
 #define RTNLGRP_MPLS_ROUTE	RTNLGRP_MPLS_ROUTE
 	RTNLGRP_NSID,
 #define RTNLGRP_NSID		RTNLGRP_NSID
+	RTNLGRP_MPLS_NETCONF,
+#define RTNLGRP_MPLS_NETCONF	RTNLGRP_MPLS_NETCONF
 	__RTNLGRP_MAX
 };
 #define RTNLGRP_MAX	(__RTNLGRP_MAX - 1)
diff --git a/include/netlink/netlink-compat.h b/include/netlink/netlink-compat.h
index 17ec9fc8d1df..2839ed034d49 100644
--- a/include/netlink/netlink-compat.h
+++ b/include/netlink/netlink-compat.h
@@ -47,4 +47,8 @@ typedef unsigned short  sa_family_t;
 #define AF_LLC		26
 #endif
 
+#ifndef AF_MPLS
+#define AF_MPLS		28
+#endif
+
 #endif
diff --git a/include/netlink/route/netconf.h b/include/netlink/route/netconf.h
index d2d1f9b5261e..19934381241a 100644
--- a/include/netlink/route/netconf.h
+++ b/include/netlink/route/netconf.h
@@ -35,6 +35,7 @@ int rtnl_netconf_get_mc_forwarding(struct rtnl_netconf *nc, int *val);
 int rtnl_netconf_get_rp_filter(struct rtnl_netconf *nc, int *val);
 int rtnl_netconf_get_proxy_neigh(struct rtnl_netconf *nc, int *val);
 int rtnl_netconf_get_ignore_routes_linkdown(struct rtnl_netconf *nc, int *val);
+int rtnl_netconf_get_input(struct rtnl_netconf *nc, int *val);
 
 #ifdef __cplusplus
 }
diff --git a/lib/route/netconf.c b/lib/route/netconf.c
index 2073c94544fe..0635dd7f2bcd 100644
--- a/lib/route/netconf.c
+++ b/lib/route/netconf.c
@@ -22,6 +22,7 @@
 #include <netlink/utils.h>
 #include <netlink/route/netconf.h>
 #include <linux/netconf.h>
+#include <linux/socket.h>
 #include <netlink/hashtable.h>
 
 /** @cond SKIP */
@@ -32,6 +33,7 @@
 #define NETCONF_ATTR_MC_FWDING		0x0010
 #define NETCONF_ATTR_PROXY_NEIGH	0x0020
 #define NETCONF_ATTR_IGNORE_RT_LINKDWN	0x0040
+#define NETCONF_ATTR_INPUT		0x0080
 
 struct rtnl_netconf
 {
@@ -44,6 +46,7 @@ struct rtnl_netconf
 	int	mc_forwarding;
 	int	proxy_neigh;
 	int	ignore_routes_linkdown;
+	int	input;
 };
 
 static struct nl_cache_ops rtnl_netconf_ops;
@@ -67,6 +70,11 @@ static struct nla_policy devconf_ipv6_policy[NETCONFA_MAX+1] = {
 	[NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN]  = { .type = NLA_S32 },
 };
 
+static struct nla_policy devconf_mpls_policy[NETCONFA_MAX+1] = {
+	[NETCONFA_IFINDEX]	 = { .type = NLA_S32 },
+	[NETCONFA_INPUT]	 = { .type = NLA_S32 },
+};
+
 static struct rtnl_netconf *rtnl_netconf_alloc(void)
 {
 	return (struct rtnl_netconf *) nl_object_alloc(&netconf_obj_ops);
@@ -104,6 +112,12 @@ static int netconf_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
 		if (err < 0)
 			return err;
 		break;
+	case AF_MPLS:
+		err = nlmsg_parse(nlh, sizeof(*ncm), tb, NETCONFA_MAX,
+				  devconf_mpls_policy);
+		if (err < 0)
+			return err;
+		break;
 	default:
 		printf("unexpected netconf family: %d\n", ncm->ncm_family);
 		return -1;
@@ -153,6 +167,12 @@ static int netconf_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
 		nc->ce_mask |= NETCONF_ATTR_IGNORE_RT_LINKDWN;
 	}
 
+	if (tb[NETCONFA_INPUT]) {
+		attr = tb[NETCONFA_INPUT];
+		nc->input = nla_get_s32(attr);
+		nc->ce_mask |= NETCONF_ATTR_INPUT;
+	}
+
 	return pp->pp_cb((struct nl_object *) nc, pp);
 }
 
@@ -178,6 +198,9 @@ static void netconf_dump_line(struct nl_object *obj, struct nl_dump_params *p)
 	case AF_INET6:
 		nl_dump(p, "ipv6 ");
 		break;
+	case AF_MPLS:
+		nl_dump(p, "mpls ");
+		break;
 	default:
 		return;
 	}
@@ -229,6 +252,9 @@ static void netconf_dump_line(struct nl_object *obj, struct nl_dump_params *p)
 			nc->ignore_routes_linkdown ? "on" : "off");
 	}
 
+	if (nc->ce_mask & NETCONF_ATTR_INPUT)
+		nl_dump(p, "input %s ", nc->input ? "on" : "off");
+
 	nl_dump(p, "\n");
 }
 
@@ -240,6 +266,7 @@ static const struct trans_tbl netconf_attrs[] = {
 	__ADD(NETCONF_ATTR_MC_FWDING, mc_forwarding),
 	__ADD(NETCONF_ATTR_PROXY_NEIGH, proxy_neigh),
 	__ADD(NETCONF_ATTR_IGNORE_RT_LINKDWN, ignore_routes_with_linkdown),
+	__ADD(NETCONF_ATTR_INPUT, input),
 };
 
 static char *netconf_attrs2str(int attrs, char *buf, size_t len)
@@ -285,6 +312,7 @@ static uint64_t netconf_compare(struct nl_object *_a, struct nl_object *_b,
 	diff |= NETCONF_DIFF(PROXY_NEIGH, a->proxy_neigh != b->proxy_neigh);
 	diff |= NETCONF_DIFF(IGNORE_RT_LINKDWN,
 			a->ignore_routes_linkdown != b->ignore_routes_linkdown);
+	diff |= NETCONF_DIFF(INPUT,	a->input != b->input);
 
 #undef NETCONF_DIFF
 
@@ -486,6 +514,17 @@ int rtnl_netconf_get_ignore_routes_linkdown(struct rtnl_netconf *nc, int *val)
 		*val = nc->ignore_routes_linkdown;
 	return 0;
 }
+int rtnl_netconf_get_input(struct rtnl_netconf *nc, int *val)
+{
+	if (!nc)
+		return -NLE_INVAL;
+	if (!(nc->ce_mask & NETCONF_ATTR_INPUT))
+		return -NLE_MISSING_ATTR;
+	if (val)
+		*val = nc->input;
+	return 0;
+}
+
 
 /** @} */
 
@@ -508,6 +547,7 @@ static struct nl_object_ops netconf_obj_ops = {
 static struct nl_af_group netconf_groups[] = {
 	{ AF_INET,	RTNLGRP_IPV4_NETCONF },
 	{ AF_INET6,	RTNLGRP_IPV6_NETCONF },
+	{ AF_MPLS,	RTNLGRP_MPLS_NETCONF },
 	{ END_OF_GROUP_LIST },
 };
 
diff --git a/libnl-route-3.sym b/libnl-route-3.sym
index b17434c87a89..4fd8c0f96825 100644
--- a/libnl-route-3.sym
+++ b/libnl-route-3.sym
@@ -1050,4 +1050,5 @@ libnl_3_4 {
 	rtnl_netconf_get_forwarding;
 	rtnl_netconf_get_mc_forwarding;
 	rtnl_netconf_get_rp_filter;
+	rtnl_netconf_get_input;
 } libnl_3_2_29;
diff --git a/src/nl-monitor.c b/src/nl-monitor.c
index d9c32f86b7ff..4400df5aceb5 100644
--- a/src/nl-monitor.c
+++ b/src/nl-monitor.c
@@ -34,6 +34,7 @@ static const struct {
 	{ RTNLGRP_IPV6_PREFIX, "ipv6-prefix" },
 	{ RTNLGRP_IPV4_NETCONF, "ipv4-netconf" },
 	{ RTNLGRP_IPV6_NETCONF, "ipv6-netconf" },
+	{ RTNLGRP_MPLS_NETCONF, "mpls-netconf" },
 	{ RTNLGRP_NONE, NULL }
 };
 
-- 
2.1.4




More information about the libnl mailing list