struct blob_attr *tb[__ROUTE_MAX], *cur;
struct device_route *route;
int af = v6 ? AF_INET6 : AF_INET;
+ bool no_device = false;
blobmsg_parse(route_attr, __ROUTE_MAX, tb, blobmsg_data(attr), blobmsg_data_len(attr));
return;
if (!iface) {
- if ((cur = tb[ROUTE_INTERFACE]) == NULL)
- return;
+ if ((cur = tb[ROUTE_INTERFACE]) == NULL) {
+ iface = vlist_find(&interfaces, "loopback", iface, node);
+ no_device = true;
+ } else {
+ iface = vlist_find(&interfaces, blobmsg_data(cur), iface, node);
+ }
- iface = vlist_find(&interfaces, blobmsg_data(cur), iface, node);
if (!iface)
return;
DPRINTF("Failed to parse route target: %s\n", (char *) blobmsg_data(cur));
goto error;
}
+
+ /* Mask out IPv4 host bits to avoid "Invalid prefix for given prefix length" */
+ if (af == AF_INET && route->mask < 32)
+ route->addr.in.s_addr &= ((1u << route->mask) - 1);
}
if ((cur = tb[ROUTE_GATEWAY]) != NULL) {
route->flags |= DEVROUTE_PROTO;
}
- interface_set_route_info(iface, route);
+ if (no_device)
+ route->flags |= DEVROUTE_NODEV;
+ else
+ interface_set_route_info(iface, route);
+
vlist_add(&ip->route, &route->node, route);
return;
interface_add_dns_server_list(struct interface_ip_settings *ip, struct blob_attr *list)
{
struct blob_attr *cur;
- int rem;
+ size_t rem;
blobmsg_for_each_attr(cur, list, rem) {
if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING)
interface_add_dns_search_list(struct interface_ip_settings *ip, struct blob_attr *list)
{
struct blob_attr *cur;
- int rem;
+ size_t rem;
blobmsg_for_each_attr(cur, list, rem) {
if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING)