ROUTE_TABLE,
ROUTE_SOURCE,
ROUTE_ONLINK,
+ ROUTE_TYPE,
__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 = {
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;
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)
__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
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;
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;
.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,
};
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);
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;
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)