CMake: bump the minimum required CMake version to 3.5
[project/netifd.git] / interface.c
index 89654f952c15b571e866dbcf2b84773c63a84d6a..43525593c30222e806fd7fc37866a9703d9b925c 100644 (file)
@@ -25,6 +25,7 @@
 #include "ubus.h"
 #include "config.h"
 #include "system.h"
+#include "wireless.h"
 
 struct vlist_tree interfaces;
 static LIST_HEAD(iface_all_users);
@@ -232,7 +233,8 @@ interface_add_data(struct interface *iface, const struct blob_attr *data)
 int interface_parse_data(struct interface *iface, const struct blob_attr *attr)
 {
        struct blob_attr *cur;
-       int rem, ret;
+       size_t rem;
+       int ret;
 
        iface->updated = 0;
 
@@ -435,7 +437,7 @@ interface_main_dev_cb(struct device_user *dep, enum device_event ev)
                break;
        case DEV_EVENT_REMOVE:
                interface_set_available(iface, false);
-               if (dep->dev && dep->dev->external)
+               if (dep->dev && dep->dev->external && !dep->dev->sys_present)
                        interface_set_main_dev(iface, NULL);
                break;
        case DEV_EVENT_UP:
@@ -482,7 +484,7 @@ interface_set_available(struct interface *iface, bool new_state)
        if (iface->available == new_state)
                return;
 
-       D(INTERFACE, "Interface '%s', available=%d\n", iface->name, new_state);
+       D(INTERFACE, "Interface '%s', available=%d", iface->name, new_state);
        iface->available = new_state;
 
        if (new_state) {
@@ -517,7 +519,7 @@ static void
 interface_add_assignment_classes(struct interface *iface, 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)
@@ -772,7 +774,7 @@ interface_proto_event_cb(struct interface_proto_state *state, enum interface_pro
                netifd_log_message(L_NOTICE, "Interface '%s' is now down\n", iface->name);
                mark_interface_down(iface);
                interface_write_resolv_conf(iface->jail);
-               if (iface->main_dev.dev)
+               if (iface->main_dev.dev && !(iface->config_state == IFC_NORMAL && iface->autostart && iface->available))
                        device_release(&iface->main_dev);
                if (iface->l3_dev.dev)
                        device_remove_user(&iface->l3_dev);
@@ -909,12 +911,12 @@ interface_alloc(const char *name, struct blob_attr *config, bool dynamic)
 
        if ((cur = tb[IFACE_ATTR_IP4TABLE])) {
                if (!system_resolve_rt_table(blobmsg_data(cur), &iface->ip4table))
-                       DPRINTF("Failed to resolve routing table: %s\n", (char *) blobmsg_data(cur));
+                       D(INTERFACE, "Failed to resolve routing table: %s", (char *) blobmsg_data(cur));
        }
 
        if ((cur = tb[IFACE_ATTR_IP6TABLE])) {
                if (!system_resolve_rt_table(blobmsg_data(cur), &iface->ip6table))
-                       DPRINTF("Failed to resolve routing table: %s\n", (char *) blobmsg_data(cur));
+                       D(INTERFACE, "Failed to resolve routing table: %s", (char *) blobmsg_data(cur));
        }
 
        iface->proto_ip.no_delegation = !blobmsg_get_bool_default(tb[IFACE_ATTR_DELEGATE], true);
@@ -1124,6 +1126,7 @@ interface_set_up(struct interface *iface)
        const char *error = NULL;
 
        iface->autostart = true;
+       wireless_check_network_enabled();
 
        if (iface->state != IFS_DOWN)
                return;
@@ -1156,6 +1159,7 @@ interface_set_down(struct interface *iface)
                        __interface_set_down(iface, false);
        } else {
                iface->autostart = false;
+               wireless_check_network_enabled();
                __interface_set_down(iface, false);
        }
 }
@@ -1244,7 +1248,7 @@ interface_device_config_changed(struct interface *if_old, struct interface *if_n
        struct blob_attr *ntb[__DEV_ATTR_MAX];
        struct blob_attr *otb[__DEV_ATTR_MAX];
        struct device *dev = if_old->main_dev.dev;
-       unsigned long diff = 0;
+       unsigned long diff[2] = {};
 
        BUILD_BUG_ON(sizeof(diff) < __DEV_ATTR_MAX / 8);
 
@@ -1263,8 +1267,9 @@ interface_device_config_changed(struct interface *if_old, struct interface *if_n
        blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, ntb,
                blob_data(if_new->config), blob_len(if_new->config));
 
-       uci_blob_diff(ntb, otb, &device_attr_list, &diff);
-       return diff;
+       uci_blob_diff(ntb, otb, &device_attr_list, diff);
+
+       return diff[0] | diff[1];
 }
 
 static void
@@ -1292,7 +1297,7 @@ interface_change_config(struct interface *if_old, struct interface *if_new)
                reload = true;
 
        if (!if_old->proto_handler->config_params)
-               D(INTERFACE, "No config parameters for interface '%s'\n",
+               D(INTERFACE, "No config parameters for interface '%s'",
                  if_old->name);
        else if (!uci_blob_check_equal(if_old->config, if_new->config,
                                       if_old->proto_handler->config_params))
@@ -1355,7 +1360,7 @@ interface_change_config(struct interface *if_old, struct interface *if_new)
 #undef UPDATE
 
        if (reload) {
-               D(INTERFACE, "Reload interface '%s' because of config changes\n",
+               D(INTERFACE, "Reload interface '%s' because of config changes",
                  if_old->name);
                interface_clear_errors(if_old);
                set_config_state(if_old, IFC_RELOAD);
@@ -1394,13 +1399,13 @@ interface_update(struct vlist_tree *tree, struct vlist_node *node_new,
        struct interface *if_new = container_of(node_new, struct interface, node);
 
        if (node_old && node_new) {
-               D(INTERFACE, "Update interface '%s'\n", if_new->name);
+               D(INTERFACE, "Update interface '%s'", if_new->name);
                interface_change_config(if_old, if_new);
        } else if (node_old) {
-               D(INTERFACE, "Remove interface '%s'\n", if_old->name);
+               D(INTERFACE, "Remove interface '%s'", if_old->name);
                set_config_state(if_old, IFC_REMOVE);
        } else if (node_new) {
-               D(INTERFACE, "Create interface '%s'\n", if_new->name);
+               D(INTERFACE, "Create interface '%s'", if_new->name);
                interface_event(if_new, IFEV_CREATE);
                proto_init_interface(if_new, if_new->config);
                interface_claim_device(if_new);