fix flushing routes/addresses on connection loss
[project/netifd.git] / interface-ip.c
index 7f10120..bbf2ccf 100644 (file)
@@ -64,6 +64,7 @@ interface_ip_add_route(struct interface *iface, struct blob_attr *attr, bool v6)
        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);
@@ -83,19 +84,17 @@ interface_ip_add_route(struct interface *iface, struct blob_attr *attr, bool 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:
@@ -129,7 +128,7 @@ interface_update_proto_addr(struct vlist_tree *tree,
 
        ip = container_of(tree, struct interface_ip_settings, addr);
        iface = ip->iface;
-       dev = iface->l3_dev->dev;
+       dev = iface->l3_dev.dev;
 
        if (node_new) {
                a_new = container_of(node_new, struct device_addr, node);
@@ -194,7 +193,7 @@ interface_update_proto_route(struct vlist_tree *tree,
 
        ip = container_of(tree, struct interface_ip_settings, route);
        iface = ip->iface;
-       dev = iface->l3_dev->dev;
+       dev = iface->l3_dev.dev;
 
        route_old = container_of(node_old, struct device_route, node);
        route_new = container_of(node_new, struct device_route, node);
@@ -354,7 +353,7 @@ void interface_ip_set_enabled(struct interface_ip_settings *ip, bool enabled)
        struct device *dev;
 
        ip->enabled = enabled;
-       dev = ip->iface->l3_dev->dev;
+       dev = ip->iface->l3_dev.dev;
        if (!dev)
                return;
 
@@ -378,9 +377,12 @@ void interface_ip_set_enabled(struct interface_ip_settings *ip, bool enabled)
                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;
        }
@@ -420,8 +422,6 @@ interface_ip_init(struct interface_ip_settings *ip, struct interface *iface)
        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);
 }