if (!route)
return;
+ route->flags = v6 ? DEVADDR_INET6 : DEVADDR_INET4;
route->mask = v6 ? 128 : 32;
if ((cur = tb[ROUTE_MASK]) != NULL) {
route->mask = parse_netmask_string(blobmsg_data(cur), v6);
DPRINTF("Failed to parse route gateway: %s\n", (char *) blobmsg_data(cur));
goto error;
}
- } else {
- route->flags |= DEVADDR_DEVICE;
}
- if ((cur = tb[ROUTE_METRIC]) != NULL)
+ if ((cur = tb[ROUTE_METRIC]) != NULL) {
route->metric = blobmsg_get_u32(cur);
- else
- route->metric = -1;
+ route->flags |= DEVROUTE_METRIC;
+ }
if ((cur = tb[ROUTE_MTU]) != NULL)
route->mtu = blobmsg_get_u32(cur);
- vlist_add(&ip->route, &route->node);
+ vlist_add(&ip->route, &route->node, &route->mask);
return;
error:
struct interface_ip_settings *ip;
struct interface *iface;
struct device *dev;
- struct device_addr *addr;
+ struct device_addr *a_new = NULL, *a_old = NULL;
bool keep = false;
ip = container_of(tree, struct interface_ip_settings, addr);
iface = ip->iface;
dev = iface->l3_dev->dev;
- if (node_old && node_new)
+ if (node_new) {
+ a_new = container_of(node_new, struct device_addr, node);
+
+ if ((a_new->flags & DEVADDR_FAMILY) == DEVADDR_INET4 &&
+ !a_new->broadcast) {
+
+ uint32_t mask = ~0;
+ uint32_t *a = (uint32_t *) &a_new->addr;
+
+ mask >>= a_new->mask;
+ a_new->broadcast = *a | mask;
+ }
+ }
+
+ if (node_old)
+ a_old = container_of(node_old, struct device_addr, node);
+
+ if (a_new && a_old) {
keep = true;
+ if (a_old->flags != a_new->flags)
+ keep = false;
+
+ if ((a_new->flags & DEVADDR_FAMILY) == DEVADDR_INET4 &&
+ a_new->broadcast != a_old->broadcast)
+ keep = false;
+ }
+
if (node_old) {
- addr = container_of(node_old, struct device_addr, node);
- if (!(addr->flags & DEVADDR_EXTERNAL) && addr->enabled && !keep)
- system_del_address(dev, addr);
- free(addr);
+ if (!(a_old->flags & DEVADDR_EXTERNAL) && a_old->enabled && !keep)
+ system_del_address(dev, a_old);
+ free(a_old);
}
if (node_new) {
- addr = container_of(node_new, struct device_addr, node);
- if (!(addr->flags & DEVADDR_EXTERNAL) && !keep)
- system_add_address(dev, addr);
- addr->enabled = true;
+ if (!(a_new->flags & DEVADDR_EXTERNAL) && !keep)
+ system_add_address(dev, a_new);
+ a_new->enabled = true;
}
}
if (route->enabled == _enabled)
continue;
- if (_enabled)
+ if (_enabled) {
+ if (!(route->flags & DEVROUTE_METRIC))
+ route->metric = ip->iface->metric;
+
system_add_route(dev, route);
- else
+ } else
system_del_route(dev, route);
route->enabled = _enabled;
}
ip->enabled = true;
vlist_simple_init(&ip->dns_search, struct dns_search_domain, node);
vlist_simple_init(&ip->dns_servers, struct dns_server, node);
- vlist_init(&ip->route, route_cmp, interface_update_proto_route,
- struct device_route, node, mask);
- vlist_init(&ip->addr, addr_cmp, interface_update_proto_addr,
- struct device_addr, node, mask);
+ vlist_init(&ip->route, route_cmp, interface_update_proto_route);
+ vlist_init(&ip->addr, addr_cmp, interface_update_proto_addr);
}