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 <dedec...@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@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to