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

Dave Täht dave at taht.net
Tue Jan 17 08:00:56 PST 2017


Thank you Hans, this made my day.

On 1/17/17 6:34 AM, Toke Høiland-Jørgensen wrote:
> Hans Dedecker <dedeckeh at gmail.com> writes:
> 
>> 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;
> 
> Shouldn't these be read from somewhere rather than hard-coded (iproute2
> gets them from /etc/iproute/rt_protos)?

This file has changed twice in the last 20 years, and I think of the
effort required to parse it, vs storing these strings locally in the
daemon, the latter would be fine. Move it to a table perhaps that
can be reused elsewhere?

That said, there is a new proto on the block (the homenet (hnetd)),
which uses proto 43 presently. Also "boot". Let me go look at a
couple other daemons... (bbl)

Disambiguating dhcp(v6,v6-pd) derived routes would be the most helpful
of these, and generally you wouldn't want to specify a specific routing
daemon proto in uci. Except when you do. (people do use zebra in
incomprehensible ways)

The undefined proto numbers are useful for when you are injecting things
from oddball sources that you need to treat separately (notably
vpns that are also doing address assignment and routing where I hope we
can move to source specific routing rather than policy routing)

thx for the patch! totally made my day.




> -Toke
> 
> _______________________________________________
> Lede-dev mailing list
> Lede-dev at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/lede-dev
> 



More information about the Lede-dev mailing list