netifd: bridge: Fix format string position
[project/netifd.git] / wireless.c
index 29feb6aad7a9da5ef2c6659a3ebdd83696702635..705d6dd028e39d740526957d40b4623fe0b6ab04 100644 (file)
@@ -65,6 +65,7 @@ enum {
        VIF_ATTR_ISOLATE,
        VIF_ATTR_MODE,
        VIF_ATTR_PROXYARP,
+       VIF_ATTR_MCAST_TO_UCAST,
        __VIF_ATTR_MAX,
 };
 
@@ -74,6 +75,7 @@ static const struct blobmsg_policy vif_policy[__VIF_ATTR_MAX] = {
        [VIF_ATTR_ISOLATE] = { .name = "isolate", .type = BLOBMSG_TYPE_BOOL },
        [VIF_ATTR_MODE] = { .name = "mode", .type = BLOBMSG_TYPE_STRING },
        [VIF_ATTR_PROXYARP] = { .name = "proxy_arp", .type = BLOBMSG_TYPE_BOOL },
+       [VIF_ATTR_MCAST_TO_UCAST] = { .name = "multicast_to_unicast", .type = BLOBMSG_TYPE_BOOL },
 };
 
 static const struct uci_blob_param_list vif_param = {
@@ -85,6 +87,7 @@ enum {
        VLAN_ATTR_DISABLED,
        VLAN_ATTR_NETWORK,
        VLAN_ATTR_ISOLATE,
+       VLAN_ATTR_MCAST_TO_UCAST,
        __VLAN_ATTR_MAX,
 };
 
@@ -92,6 +95,7 @@ static const struct blobmsg_policy vlan_policy[__VLAN_ATTR_MAX] = {
        [VLAN_ATTR_DISABLED] = { .name = "disabled", .type = BLOBMSG_TYPE_BOOL },
        [VLAN_ATTR_NETWORK] = { .name = "network", .type = BLOBMSG_TYPE_ARRAY },
        [VLAN_ATTR_ISOLATE] = { .name = "isolate", .type = BLOBMSG_TYPE_BOOL },
+       [VLAN_ATTR_MCAST_TO_UCAST] = { .name = "multicast_to_unicast", .type = BLOBMSG_TYPE_BOOL },
 };
 
 static const struct uci_blob_param_list vlan_param = {
@@ -315,6 +319,17 @@ wireless_device_free_state(struct wireless_device *wdev)
        }
 }
 
+static void wireless_device_set_mcast_to_unicast(struct device *dev, int val)
+{
+       if (val < 0) {
+               dev->settings.flags &= ~DEV_OPT_MULTICAST_TO_UNICAST;
+               return;
+       }
+
+       dev->settings.multicast_to_unicast = !!val;
+       dev->settings.flags |= DEV_OPT_MULTICAST_TO_UNICAST;
+}
+
 static void wireless_interface_handle_link(struct wireless_interface *vif, const char *ifname, bool up)
 {
        struct interface *iface;
@@ -328,13 +343,15 @@ static void wireless_interface_handle_link(struct wireless_interface *vif, const
        if (!ifname)
                ifname = vif->ifname;
 
-       if (up && ifname != vif->ifname) {
-               struct device *dev = device_get(ifname, 2);
-               if (dev) {
+       if (up) {
+               struct device *dev = __device_get(ifname, 2, false);
+
+               if (dev && !strcmp(ifname, vif->ifname)) {
                        dev->wireless_isolate = vif->isolate;
                        dev->wireless_proxyarp = vif->proxyarp;
                        dev->wireless = true;
                        dev->wireless_ap = vif->ap_mode;
+                       wireless_device_set_mcast_to_unicast(dev, vif->multicast_to_unicast);
                        dev->bpdu_filter = dev->wireless_ap;
                }
        }
@@ -367,6 +384,7 @@ static void wireless_vlan_handle_link(struct wireless_vlan *vlan, bool up)
                        dev->wireless = true;
                        dev->wireless_ap = true;
                        dev->bpdu_filter = true;
+                       wireless_device_set_mcast_to_unicast(dev, vlan->multicast_to_unicast);
                }
        }
 
@@ -431,6 +449,9 @@ wireless_device_run_handler(struct wireless_device *wdev, bool up)
        argv[i] = NULL;
 
        if (up && pipe(fds) == 0) {
+               if (wdev->script_proc_fd.fd >= 0)
+                       wireless_close_script_proc_fd(wdev);
+
                wdev->script_proc_fd.fd = fds[0];
                uloop_fd_add(&wdev->script_proc_fd,
                             ULOOP_READ | ULOOP_EDGE_TRIGGER);
@@ -499,8 +520,11 @@ wdev_handle_config_change(struct wireless_device *wdev)
        enum interface_config_state state = wdev->config_state;
 
        switch(state) {
-       case IFC_NORMAL:
        case IFC_RELOAD:
+               wdev->retry = WIRELESS_SETUP_RETRY;
+               wdev->retry_setup_failed = false;
+               fallthrough;
+       case IFC_NORMAL:
                __wireless_device_set_up(wdev, 0);
 
                wdev->config_state = IFC_NORMAL;
@@ -517,7 +541,7 @@ wireless_device_mark_down(struct wireless_device *wdev)
        struct wireless_interface *vif;
        struct wireless_vlan *vlan;
 
-       D(WIRELESS, "Wireless device '%s' is now down\n", wdev->name);
+       netifd_log_message(L_NOTICE, "Wireless device '%s' is now down\n", wdev->name);
 
        vlist_for_each_element(&wdev->vlans, vlan, node)
                wireless_vlan_handle_link(vlan, false);
@@ -592,7 +616,8 @@ wireless_device_mark_up(struct wireless_device *wdev)
                return;
        }
 
-       D(WIRELESS, "Wireless device '%s' is now up\n", wdev->name);
+       netifd_log_message(L_NOTICE, "Wireless device '%s' is now up\n", wdev->name);
+       wdev->retry = WIRELESS_SETUP_RETRY;
        wdev->state = IFS_UP;
        vlist_for_each_element(&wdev->interfaces, vif, node)
                wireless_interface_handle_link(vif, NULL, true);
@@ -606,6 +631,9 @@ wireless_device_retry_setup(struct wireless_device *wdev)
        if (wdev->state == IFS_TEARDOWN || wdev->state == IFS_DOWN || wdev->cancel)
                return;
 
+       netifd_log_message(wdev->retry ? L_WARNING : L_CRIT,
+                          "Wireless device '%s' setup failed, retry=%d\n",
+                          wdev->name, wdev->retry);
        if (--wdev->retry < 0)
                wdev->retry_setup_failed = true;
 
@@ -681,7 +709,6 @@ wdev_change_config(struct wireless_device *wdev, struct wireless_device *wd_new)
        free(wdev->config);
        wdev->config = blob_memdup(new_config);
        wdev->disabled = disabled;
-       wdev->retry_setup_failed = false;
        wdev_set_config_state(wdev, IFC_RELOAD);
 }
 
@@ -793,17 +820,17 @@ wireless_interface_init_config(struct wireless_interface *vif)
        if ((cur = tb[VIF_ATTR_NETWORK]))
                vif->network = cur;
 
+       cur = tb[VIF_ATTR_MODE];
+       vif->ap_mode = cur && !strcmp(blobmsg_get_string(cur), "ap");
+
        cur = tb[VIF_ATTR_ISOLATE];
-       if (cur)
-               vif->isolate = blobmsg_get_bool(cur);
+       vif->isolate = vif->ap_mode && cur && blobmsg_get_bool(cur);
 
        cur = tb[VIF_ATTR_PROXYARP];
-       if (cur)
-               vif->proxyarp = blobmsg_get_bool(cur);
+       vif->proxyarp = vif->ap_mode && cur && blobmsg_get_bool(cur);
 
-       cur = tb[VIF_ATTR_MODE];
-       if (cur)
-               vif->ap_mode = !strcmp(blobmsg_get_string(cur), "ap");
+       cur = tb[VIF_ATTR_MCAST_TO_UCAST];
+       vif->multicast_to_unicast = cur ? blobmsg_get_bool(cur) : -1;
 }
 
 /* vlist update call for wireless interface list */
@@ -832,8 +859,6 @@ vif_update(struct vlist_tree *tree, struct vlist_node *node_new,
                wireless_interface_handle_link(vif_old, NULL, false);
                free(vif_old->config);
                vif_old->config = blob_memdup(vif_new->config);
-               vif_old->isolate = vif_new->isolate;
-               vif_old->ap_mode = vif_new->ap_mode;
                wireless_interface_init_config(vif_old);
                free(vif_new);
        } else if (vif_new) {
@@ -868,6 +893,9 @@ wireless_vlan_init_config(struct wireless_vlan *vlan)
        cur = tb[VLAN_ATTR_ISOLATE];
        if (cur)
                vlan->isolate = blobmsg_get_bool(cur);
+
+       cur = tb[VLAN_ATTR_MCAST_TO_UCAST];
+       vlan->multicast_to_unicast = cur ? blobmsg_get_bool(cur) : -1;
 }
 
 /* vlist update call for vlan list */
@@ -1076,7 +1104,7 @@ wireless_station_create(struct wireless_device *wdev, char *vif, struct blob_att
        if (cur && blobmsg_get_bool(cur))
                return;
 
-       sprintf(name, "%d", wdev->vlan_idx++);
+       sprintf(name, "%d", wdev->sta_idx++);
 
        sta = calloc_a(sizeof(*sta),
                       &name_buf, strlen(name) + 1,
@@ -1398,10 +1426,12 @@ wireless_device_set_retry(struct wireless_device *wdev, struct blob_attr *data)
        struct blob_attr *val;
 
        blobmsg_parse(&retry_policy, 1, &val, blobmsg_data(data), blobmsg_data_len(data));
-       if (!val)
-               return UBUS_STATUS_INVALID_ARGUMENT;
-
-       wdev->retry = blobmsg_get_u32(val);
+       if (val)
+               wdev->retry = blobmsg_get_u32(val);
+       else
+               wdev->retry = WIRELESS_SETUP_RETRY;
+       __wireless_device_set_up(wdev, 0);
+       netifd_log_message(L_NOTICE, "Wireless device '%s' set retry=%d\n", wdev->name, wdev->retry);
        return 0;
 }