[OpenWrt-Devel] [PATCH 5/5] netifd: Route type support

Hans Dedecker dedeckeh at gmail.com
Wed Jun 18 02:55:48 EDT 2014


Patch adds route type support in netifd by means of the route parameter type.
By default the route type was unicast; the parameter adss support for local/broadcast/multicast/unicast routes which will be put into the appropriate routing table.
If route type parameter is unset the route type will be unicast as before.

Signed-off-by: Hans Dedecker <dedeckeh at gmail.com>
---
 interface-ip.c |   14 ++++++-
 interface-ip.h |    4 ++
 system-dummy.c |    6 +++
 system-linux.c |  103 ++++++++++++++++++++++++++++++++++---------------------
 system.h       |    1 +
 ubus.c         |    3 ++
 6 files changed, 90 insertions(+), 41 deletions(-)

diff --git a/interface-ip.c b/interface-ip.c
index bd6f164..715e498 100644
--- a/interface-ip.c
+++ b/interface-ip.c
@@ -39,6 +39,7 @@ enum {
 	ROUTE_TABLE,
 	ROUTE_SOURCE,
 	ROUTE_ONLINK,
+	ROUTE_TYPE,
 	__ROUTE_MAX
 };
 
@@ -53,6 +54,7 @@ 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 }
 };
 
 const struct uci_blob_param_list route_attr_list = {
@@ -374,6 +376,14 @@ interface_ip_add_route(struct interface *iface, struct blob_attr *attr, bool v6)
 			route->valid_until = valid_until;
 	}
 
+	if ((cur = tb[ROUTE_TYPE]) != NULL) {
+		if (!system_resolve_rt_type(blobmsg_data(cur), &route->type)) {
+			DPRINTF("Failed to resolve routing type: %s\n", (char *) blobmsg_data(cur));
+			goto error;
+		}
+		route->flags |= DEVROUTE_TYPE;
+	}
+
 	vlist_add(&ip->route, &route->node, route);
 	return;
 
@@ -586,7 +596,8 @@ 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->failed;
+			(route_old->mtu == route_new->mtu) && (route_old->type == route_new->type) &&
+			!route_old->failed;
 
 	if (node_old) {
 		if (!(route_old->flags & DEVADDR_EXTERNAL) && route_old->enabled && !keep)
@@ -1223,7 +1234,6 @@ interface_ip_init(struct interface *iface)
 	__interface_ip_init(&iface->proto_ip, iface);
 	__interface_ip_init(&iface->config_ip, iface);
 	vlist_init(&iface->host_routes, route_cmp, interface_update_host_route);
-
 }
 
 static void
diff --git a/interface-ip.h b/interface-ip.h
index 93d55ee..a5612e5 100644
--- a/interface-ip.h
+++ b/interface-ip.h
@@ -45,6 +45,9 @@ enum device_addr_flags {
 
 	/* route is on-link */
 	DEVROUTE_ONLINK		= (1 << 9),
+
+	/* route overrides the default route type */
+	DEVROUTE_TYPE		= (1 << 10),
 };
 
 union if_addr {
@@ -107,6 +110,7 @@ struct device_route {
 
 	union if_addr nexthop;
 	int mtu;
+	unsigned int type;
 	time_t valid_until;
 
 	/* must be last */
diff --git a/system-dummy.c b/system-dummy.c
index bb94781..f2988f2 100644
--- a/system-dummy.c
+++ b/system-dummy.c
@@ -193,6 +193,12 @@ int system_flush_routes(void)
 	return 0;
 }
 
+bool system_resolve_rt_type(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 8a07247..5dc0d51 100644
--- a/system-linux.c
+++ b/system-linux.c
@@ -164,6 +164,46 @@ create_event_socket(struct event_socket *ev, int protocol,
 	return true;
 }
 
+static bool
+system_rtn_aton(const char *src, unsigned int *dst)
+{
+	char *e;
+	unsigned int n;
+
+	if (!strcmp(src, "local"))
+		n = RTN_LOCAL;
+	else if (!strcmp(src, "nat"))
+		n = RTN_NAT;
+	else if (!strcmp(src, "broadcast"))
+		n = RTN_BROADCAST;
+	else if (!strcmp(src, "anycast"))
+		n = RTN_ANYCAST;
+	else if (!strcmp(src, "multicast"))
+		n = RTN_MULTICAST;
+	else if (!strcmp(src, "prohibit"))
+		n = RTN_PROHIBIT;
+	else if (!strcmp(src, "unreachable"))
+		n = RTN_UNREACHABLE;
+	else if (!strcmp(src, "blackhole"))
+		n = RTN_BLACKHOLE;
+	else if (!strcmp(src, "xresolve"))
+		n = RTN_XRESOLVE;
+	else if (!strcmp(src, "unicast"))
+		n = RTN_UNICAST;
+	else if (!strcmp(src, "throw"))
+		n = RTN_THROW;
+	else if (!strcmp(src, "failed_policy"))
+		n = RTN_FAILED_POLICY;
+	else {
+		n = strtoul(src, &e, 0);
+		if (!e || *e || e == src || n > 255)
+			return false;
+	}
+
+	*dst = n;
+	return true;
+}
+
 int system_init(void)
 {
 	static struct event_socket rtnl_event;
@@ -1281,9 +1321,6 @@ static int system_rt(struct device *dev, struct device_route *route, int cmd)
 			route->nexthop.in6.s6_addr32[2] ||
 			route->nexthop.in6.s6_addr32[3];
 
-	unsigned char scope = (cmd == RTM_DELROUTE) ? RT_SCOPE_NOWHERE :
-			(have_gw) ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK;
-
 	unsigned int table = (route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE))
 			? route->table : RT_TABLE_MAIN;
 
@@ -1293,7 +1330,7 @@ static int system_rt(struct device *dev, struct device_route *route, int cmd)
 		.rtm_src_len = route->sourcemask,
 		.rtm_table = (table < 256) ? table : RT_TABLE_UNSPEC,
 		.rtm_protocol = (route->flags & DEVADDR_KERNEL) ? RTPROT_KERNEL : RTPROT_STATIC,
-		.rtm_scope = scope,
+		.rtm_scope = RT_SCOPE_NOWHERE,
 		.rtm_type = (cmd == RTM_DELROUTE) ? 0: RTN_UNICAST,
 		.rtm_flags = (route->flags & DEVROUTE_ONLINK) ? RTNH_F_ONLINK : 0,
 	};
@@ -1306,6 +1343,23 @@ static int system_rt(struct device *dev, struct device_route *route, int cmd)
 			rtm.rtm_scope = RT_SCOPE_UNIVERSE;
 			rtm.rtm_type = RTN_UNREACHABLE;
 		}
+		else
+			rtm.rtm_scope = (have_gw) ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK;
+	}
+
+	if (route->flags & DEVROUTE_TYPE) {
+		rtm.rtm_type = route->type;
+		if (!(route->flags & (DEVROUTE_TABLE | DEVROUTE_SRCTABLE))) {
+			if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_BROADCAST ||
+			    rtm.rtm_type == RTN_NAT || rtm.rtm_type == RTN_ANYCAST)
+				rtm.rtm_table = RT_TABLE_LOCAL;
+		}
+
+		if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_NAT)
+			rtm.rtm_scope = RT_SCOPE_HOST;
+		else if (rtm.rtm_type == RTN_BROADCAST || rtm.rtm_type == RTN_MULTICAST ||
+			rtm.rtm_type == RTN_ANYCAST)
+			rtm.rtm_scope = RT_SCOPE_LINK;
 	}
 
 	msg = nlmsg_alloc_simple(cmd, flags);
@@ -1379,6 +1433,11 @@ int system_flush_routes(void)
 	return 0;
 }
 
+bool system_resolve_rt_type(const char *type, unsigned int *id)
+{
+	return system_rtn_aton(type, id);
+}
+
 bool system_resolve_rt_table(const char *name, unsigned int *id)
 {
 	FILE *f;
@@ -1564,41 +1623,7 @@ int system_flush_iprules(void)
 
 bool system_resolve_iprule_action(const char *action, unsigned int *id)
 {
-	char *e;
-	unsigned int n;
-
-	if (!strcmp(action, "local"))
-		n = RTN_LOCAL;
-	else if (!strcmp(action, "nat"))
-		n = RTN_NAT;
-	else if (!strcmp(action, "broadcast"))
-		n = RTN_BROADCAST;
-	else if (!strcmp(action, "anycast"))
-		n = RTN_ANYCAST;
-	else if (!strcmp(action, "multicast"))
-		n = RTN_MULTICAST;
-	else if (!strcmp(action, "prohibit"))
-		n = RTN_PROHIBIT;
-	else if (!strcmp(action, "unreachable"))
-		n = RTN_UNREACHABLE;
-	else if (!strcmp(action, "blackhole"))
-		n = RTN_BLACKHOLE;
-	else if (!strcmp(action, "xresolve"))
-		n = RTN_XRESOLVE;
-	else if (!strcmp(action, "unicast"))
-		n = RTN_UNICAST;
-	else if (!strcmp(action, "throw"))
-		n = RTN_THROW;
-	else if (!strcmp(action, "failed_policy"))
-		n = RTN_FAILED_POLICY;
-	else {
-		n = strtoul(action, &e, 0);
-		if (!e || *e || e == action || n > 255)
-			return false;
-	}
-
-	*id = n;
-	return true;
+	return system_rtn_aton(action, id);
 }
 
 time_t system_get_rtime(void)
diff --git a/system.h b/system.h
index 76eee23..4c80eb0 100644
--- a/system.h
+++ b/system.h
@@ -128,6 +128,7 @@ int system_add_route(struct device *dev, struct device_route *route);
 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_table(const char *name, unsigned int *id);
 
 int system_del_ip_tunnel(const char *name);
diff --git a/ubus.c b/ubus.c
index cec2e88..9a573c6 100644
--- a/ubus.c
+++ b/ubus.c
@@ -486,6 +486,9 @@ interface_ip_dump_route_list(struct interface_ip_settings *ip, bool enabled)
 		inet_ntop(af, &route->nexthop, buf, buflen);
 		blobmsg_add_string_buffer(&b);
 
+		if (route->flags & DEVROUTE_TYPE)
+			blobmsg_add_u32(&b, "type", route->type);
+
 		if (route->flags & DEVROUTE_MTU)
 			blobmsg_add_u32(&b, "mtu", route->mtu);
 
-- 
1.7.1
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list