[LEDE-DEV] [PATCH netifd] interface-ip: route proto config support (FS#170)

Hans Dedecker dedeckeh at gmail.com
Tue Jan 17 06:08:44 PST 2017


Route proto support is usefull when using route distribution
via a routing daemon.
The route proto parameter can be specified via the route proto
uci config parameter and can hold the string values redirect,
kernel, static, gated, ra, mrt, zebra, bind, dnrouted, xorp,
ntk, dhcp, mrouted, babel or a numerical value

Signed-off-by: Hans Dedecker <dedeckeh at gmail.com>
---
 interface-ip.c | 21 +++++++++++++++++----
 interface-ip.h |  5 +++--
 system-dummy.c |  6 ++++++
 system-linux.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 system.h       |  1 +
 ubus.c         |  3 +++
 6 files changed, 81 insertions(+), 7 deletions(-)

diff --git a/interface-ip.c b/interface-ip.c
index 24ea054..f8dab84 100644
--- a/interface-ip.c
+++ b/interface-ip.c
@@ -40,6 +40,7 @@ enum {
 	ROUTE_SOURCE,
 	ROUTE_ONLINK,
 	ROUTE_TYPE,
+	ROUTE_PROTO,
 	__ROUTE_MAX
 };
 
@@ -54,7 +55,8 @@ static const struct blobmsg_policy route_attr[__ROUTE_MAX] = {
 	[ROUTE_VALID] = { .name = "valid", .type = BLOBMSG_TYPE_INT32 },
 	[ROUTE_SOURCE] = { .name = "source", .type = BLOBMSG_TYPE_STRING },
 	[ROUTE_ONLINK] = { .name = "onlink", .type = BLOBMSG_TYPE_BOOL },
-	[ROUTE_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_STRING }
+	[ROUTE_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_STRING },
+	[ROUTE_PROTO] = { .name = "proto", .type = BLOBMSG_TYPE_STRING },
 };
 
 const struct uci_blob_param_list route_attr_list = {
@@ -405,6 +407,14 @@ interface_ip_add_route(struct interface *iface, struct blob_attr *attr, bool v6)
 		route->flags |= DEVROUTE_TYPE;
 	}
 
+	if ((cur = tb[ROUTE_PROTO]) != NULL) {
+		if (!system_resolve_rt_proto(blobmsg_data(cur), &route->proto)) {
+			DPRINTF("Failed to resolve proto type: %s\n", (char *) blobmsg_data(cur));
+			goto error;
+		}
+		route->flags |= DEVROUTE_PROTO;
+	}
+
 	interface_set_route_info(iface, route);
 	vlist_add(&ip->route, &route->node, route);
 	return;
@@ -478,10 +488,13 @@ interface_handle_subnet_route(struct interface *iface, struct device_addr *addr,
 	memcpy(&r->addr, &addr->addr, sizeof(r->addr));
 	clear_if_addr(&r->addr, r->mask);
 
-	r->flags |= DEVADDR_KERNEL;
+	if (!system_resolve_rt_proto("kernel", &r->proto))
+		return;
+
+	r->flags |= DEVROUTE_PROTO;
 	system_del_route(dev, r);
 
-	r->flags &= ~DEVADDR_KERNEL;
+	r->flags &= ~DEVROUTE_PROTO;
 	interface_set_route_info(iface, r);
 
 	system_add_route(dev, r);
@@ -634,7 +647,7 @@ interface_update_proto_route(struct vlist_tree *tree,
 	if (node_old && node_new)
 		keep = !memcmp(&route_old->nexthop, &route_new->nexthop, sizeof(route_old->nexthop)) &&
 			(route_old->mtu == route_new->mtu) && (route_old->type == route_new->type) &&
-			!route_old->failed;
+			(route_old->proto == route_new->proto) && !route_old->failed;
 
 	if (node_old) {
 		if (!(route_old->flags & DEVADDR_EXTERNAL) && route_old->enabled && !keep)
diff --git a/interface-ip.h b/interface-ip.h
index bbef62c..01727c9 100644
--- a/interface-ip.h
+++ b/interface-ip.h
@@ -31,8 +31,8 @@ enum device_addr_flags {
 	/* route overrides the default interface mtu */
 	DEVROUTE_MTU		= (1 << 4),
 
-	/* route automatically added by kernel */
-	DEVADDR_KERNEL		= (1 << 5),
+	/* route overrides the default proto type */
+	DEVROUTE_PROTO		= (1 << 5),
 
 	/* address is off-link (no subnet-route) */
 	DEVADDR_OFFLINK		= (1 << 6),
@@ -92,6 +92,7 @@ struct device_route {
 	union if_addr nexthop;
 	int mtu;
 	unsigned int type;
+	unsigned int proto;
 	time_t valid_until;
 
 	/* must be last */
diff --git a/system-dummy.c b/system-dummy.c
index 9c734ea..2ea25ac 100644
--- a/system-dummy.c
+++ b/system-dummy.c
@@ -202,6 +202,12 @@ bool system_resolve_rt_type(const char *type, unsigned int *id)
 	return true;
 }
 
+bool system_resolve_rt_proto(const char *type, unsigned int *id)
+{
+	*id = 0;
+	return true;
+}
+
 bool system_resolve_rt_table(const char *name, unsigned int *id)
 {
 	*id = 0;
diff --git a/system-linux.c b/system-linux.c
index 2f15bf1..6e92685 100644
--- a/system-linux.c
+++ b/system-linux.c
@@ -52,6 +52,13 @@
 #define IFA_FLAGS (IFA_MULTICAST + 1)
 #endif
 
+#ifndef RTPROT_MROUTED
+#define RTPROT_MROUTED 17
+#endif
+
+#ifndef RTPROT_BABEL
+#define RTPROT_BABEL 42
+#endif
 
 #include <string.h>
 #include <fcntl.h>
@@ -1782,7 +1789,7 @@ static int system_rt(struct device *dev, struct device_route *route, int cmd)
 		.rtm_dst_len = route->mask,
 		.rtm_src_len = route->sourcemask,
 		.rtm_table = (table < 256) ? table : RT_TABLE_UNSPEC,
-		.rtm_protocol = (route->flags & DEVADDR_KERNEL) ? RTPROT_KERNEL : RTPROT_STATIC,
+		.rtm_protocol = (route->flags & DEVROUTE_PROTO) ? route->proto : RTPROT_STATIC,
 		.rtm_scope = RT_SCOPE_NOWHERE,
 		.rtm_type = (cmd == RTM_DELROUTE) ? 0: RTN_UNICAST,
 		.rtm_flags = (route->flags & DEVROUTE_ONLINK) ? RTNH_F_ONLINK : 0,
@@ -1900,6 +1907,49 @@ bool system_resolve_rt_type(const char *type, unsigned int *id)
 	return system_rtn_aton(type, id);
 }
 
+bool system_resolve_rt_proto(const char *type, unsigned int *id)
+{
+	char *e;
+	unsigned int n;
+
+	if (!strcmp(type, "redirect"))
+		n = RTPROT_REDIRECT;
+	else if (!strcmp(type, "kernel"))
+		n = RTPROT_KERNEL;
+	else if (!strcmp(type, "static"))
+		n = RTPROT_STATIC;
+	else if (!strcmp(type, "gated"))
+		n = RTPROT_GATED;
+	else if (!strcmp(type, "ra"))
+		n = RTPROT_RA;
+	else if (!strcmp(type, "mrt"))
+		n = RTPROT_MRT;
+	else if (!strcmp(type, "zebra"))
+		n = RTPROT_ZEBRA;
+	else if (!strcmp(type, "bird"))
+		n = RTPROT_BIRD;
+	else if (!strcmp(type, "dnrouted"))
+		n = RTPROT_DNROUTED;
+	else if (!strcmp(type, "xorp"))
+		n = RTPROT_XORP;
+	else if (!strcmp(type, "ntk"))
+		n = RTPROT_NTK;
+	else if (!strcmp(type, "dhcp"))
+		n = RTPROT_DHCP;
+	else if (!strcmp(type, "mrouted"))
+		n = RTPROT_MROUTED;
+	else if (!strcmp(type, "babel"))
+		n = RTPROT_BABEL;
+	else {
+		n = strtoul(type, &e, 0);
+		if (!e || *e || e == type || n > 255)
+			return false;
+	}
+
+	*id = n;
+	return true;
+}
+
 bool system_resolve_rt_table(const char *name, unsigned int *id)
 {
 	FILE *f;
diff --git a/system.h b/system.h
index d5cb4e3..e810ed9 100644
--- a/system.h
+++ b/system.h
@@ -146,6 +146,7 @@ int system_del_route(struct device *dev, struct device_route *route);
 int system_flush_routes(void);
 
 bool system_resolve_rt_type(const char *type, unsigned int *id);
+bool system_resolve_rt_proto(const char *type, unsigned int *id);
 bool system_resolve_rt_table(const char *name, unsigned int *id);
 bool system_is_default_rt_table(unsigned int id);
 bool system_resolve_rpfilter(const char *filter, unsigned int *id);
diff --git a/ubus.c b/ubus.c
index 29924c1..0123b17 100644
--- a/ubus.c
+++ b/ubus.c
@@ -486,6 +486,9 @@ interface_ip_dump_route_list(struct interface_ip_settings *ip, bool enabled)
 		if (route->flags & DEVROUTE_TYPE)
 			blobmsg_add_u32(&b, "type", route->type);
 
+		if (route->flags & DEVROUTE_PROTO)
+			blobmsg_add_u32(&b, "proto", route->proto);
+
 		if (route->flags & DEVROUTE_MTU)
 			blobmsg_add_u32(&b, "mtu", route->mtu);
 
-- 
2.11.0




More information about the Lede-dev mailing list