Thank you Hans, this made my day. On 1/17/17 6:34 AM, Toke Høiland-Jørgensen wrote: > Hans Dedecker <dedec...@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 <dedec...@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@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/lede-dev > _______________________________________________ Lede-dev mailing list Lede-dev@lists.infradead.org http://lists.infradead.org/mailman/listinfo/lede-dev