system: fix treatment of RT_TABLE_MAIN
[project/netifd.git] / interface.c
index c861b7d..b0fe9de 100644 (file)
@@ -319,7 +319,7 @@ interface_cb(struct device_user *dep, enum device_event ev)
                new_state = true;
        case DEV_EVENT_REMOVE:
                interface_set_available(iface, new_state);
-               if (!new_state && dep->dev->external)
+               if (!new_state && dep->dev && dep->dev->external)
                        interface_set_main_dev(iface, NULL);
                break;
        case DEV_EVENT_UP:
@@ -581,6 +581,9 @@ interface_proto_cb(struct interface_proto_state *state, enum interface_proto_eve
                        return;
                }
 
+               if (!iface->l3_dev.dev)
+                       interface_set_l3_dev(iface, iface->main_dev.dev);
+
                interface_ip_set_enabled(&iface->config_ip, true);
                system_flush_routes();
                iface->state = IFS_UP;
@@ -763,8 +766,10 @@ interface_set_l3_dev(struct interface *iface, struct device *dev)
        device_add_user(&iface->l3_dev, dev);
 
        if (dev) {
-               if (claimed)
-                       device_claim(&iface->l3_dev);
+               if (claimed) {
+                       if (device_claim(&iface->l3_dev) < 0)
+                               return;
+               }
                interface_ip_set_enabled(&iface->config_ip, enabled);
        }
 }
@@ -772,23 +777,22 @@ interface_set_l3_dev(struct interface *iface, struct device *dev)
 void
 interface_set_main_dev(struct interface *iface, struct device *dev)
 {
-       bool set_l3 = (!dev || iface->main_dev.dev == iface->l3_dev.dev);
        bool claimed = iface->l3_dev.claimed;
 
        if (iface->main_dev.dev == dev)
                return;
 
-       if (set_l3)
-               interface_set_l3_dev(iface, dev);
-
+       interface_set_available(iface, false);
        device_add_user(&iface->main_dev, dev);
        if (!dev) {
                interface_set_link_state(iface, false);
                return;
        }
 
-       if (claimed)
-               device_claim(&iface->l3_dev);
+       if (claimed) {
+               if (device_claim(&iface->l3_dev) < 0)
+                       return;
+       }
 
        if (!iface->l3_dev.dev)
                interface_set_l3_dev(iface, dev);
@@ -808,7 +812,7 @@ interface_remove_link(struct interface *iface, struct device *dev)
        if (dev != iface->main_dev.dev)
                return UBUS_STATUS_INVALID_ARGUMENT;
 
-       device_remove_user(&iface->main_dev);
+       interface_set_main_dev(iface, NULL);
        return 0;
 }
 
@@ -1020,7 +1024,8 @@ interface_change_config(struct interface *if_old, struct interface *if_new)
        }
 
        interface_write_resolv_conf();
-       interface_check_state(if_old);
+       if (if_old->main_dev.dev)
+               interface_check_state(if_old);
 
 out:
        if_new->config = NULL;