wireless: add support for defining wifi interfaces via procd service data
[project/netifd.git] / config.c
index dbf44257cce205189666fb2b7b682acfc12a7691..d187152b37ae9a3ac8d46a0d06890db6ae5f2bfb 100644 (file)
--- a/config.c
+++ b/config.c
@@ -27,6 +27,7 @@
 #include "proto.h"
 #include "wireless.h"
 #include "config.h"
 #include "proto.h"
 #include "wireless.h"
 #include "config.h"
+#include "ubus.h"
 
 bool config_init = false;
 
 
 bool config_init = false;
 
@@ -146,7 +147,7 @@ config_parse_bridge_interface(struct uci_section *s, struct device_type *devtype
        config_fixup_bridge_vlan_filtering(s, name);
        uci_to_blob(&b, s, devtype->config_params);
        if (!device_create(name, devtype, b.head)) {
        config_fixup_bridge_vlan_filtering(s, name);
        uci_to_blob(&b, s, devtype->config_params);
        if (!device_create(name, devtype, b.head)) {
-               D(INTERFACE, "Failed to create '%s' device for interface '%s'\n",
+               D(INTERFACE, "Failed to create '%s' device for interface '%s'",
                        devtype->name, s->e.name);
        }
 
                        devtype->name, s->e.name);
        }
 
@@ -599,10 +600,6 @@ config_parse_wireless_interface(struct wireless_device *wdev, struct uci_section
        if (!vif)
                return;
 
        if (!vif)
                return;
 
-       vif->vlan_idx = vif->sta_idx = 0;
-       vlist_update(&vif->vlans);
-       vlist_update(&vif->stations);
-
        if (s->anonymous)
                goto out;
 
        if (s->anonymous)
                goto out;
 
@@ -637,6 +634,73 @@ out:
        vlist_flush(&vif->stations);
 }
 
        vlist_flush(&vif->stations);
 }
 
+static void
+config_init_procd_wireless_interface(const char *wdev_name, const char *vif_name,
+                                    struct blob_attr *config,
+                                    struct blob_attr *vlans,
+                                    struct blob_attr *stations)
+{
+       struct wireless_interface *vif;
+       struct wireless_device *wdev;
+       struct blob_attr *cur;
+       char name[16];
+       int idx = 0;
+       int rem;
+
+       wdev = vlist_find(&wireless_devices, wdev_name, wdev, node);
+       if (!wdev) {
+               D(WIRELESS, "device %s not found!", wdev_name);
+               return;
+       }
+
+       vif = wireless_interface_create(wdev, config, vif_name);
+       if (!vif)
+               return;
+
+       blobmsg_for_each_attr(cur, vlans, rem) {
+               snprintf(name, sizeof(name), "%d", ++idx);
+               wireless_vlan_create(vif, cur, name);
+       }
+
+       blobmsg_for_each_attr(cur, stations, rem) {
+               snprintf(name, sizeof(name), "%d", ++idx);
+               wireless_station_create(vif, cur, name);
+       }
+
+       vlist_flush(&vif->vlans);
+       vlist_flush(&vif->stations);
+}
+
+static void
+config_procd_wireless_interface_cb(struct blob_attr *data)
+{
+       enum {
+               UDATA_ATTR_DEVICE,
+               UDATA_ATTR_CONFIG,
+               UDATA_ATTR_STATIONS,
+               UDATA_ATTR_VLANS,
+               __UDATA_ATTR_MAX,
+       };
+       static const struct blobmsg_policy policy[__UDATA_ATTR_MAX] = {
+               [UDATA_ATTR_DEVICE] = { "device", BLOBMSG_TYPE_STRING },
+               [UDATA_ATTR_CONFIG] = { "config", BLOBMSG_TYPE_TABLE },
+               [UDATA_ATTR_STATIONS] = { "stations", BLOBMSG_TYPE_ARRAY },
+               [UDATA_ATTR_VLANS] = { "vlans", BLOBMSG_TYPE_ARRAY },
+       };
+       struct blob_attr *tb[__UDATA_ATTR_MAX];
+       const char *dev;
+
+       blobmsg_parse_attr(policy, __UDATA_ATTR_MAX, tb, data);
+       if (!tb[UDATA_ATTR_DEVICE] || !tb[UDATA_ATTR_CONFIG])
+               return;
+
+       dev = blobmsg_get_string(tb[UDATA_ATTR_DEVICE]);
+       config_init_procd_wireless_interface(dev, blobmsg_name(data),
+                                            tb[UDATA_ATTR_CONFIG],
+                                            tb[UDATA_ATTR_VLANS],
+                                            tb[UDATA_ATTR_STATIONS]);
+}
+
 static void
 config_init_wireless(void)
 {
 static void
 config_init_wireless(void)
 {
@@ -645,7 +709,7 @@ config_init_wireless(void)
        const char *dev_name;
 
        if (!uci_wireless) {
        const char *dev_name;
 
        if (!uci_wireless) {
-               DPRINTF("No wireless configuration found\n");
+               D(WIRELESS, "No wireless configuration found");
                return;
        }
 
                return;
        }
 
@@ -678,13 +742,15 @@ config_init_wireless(void)
 
                wdev = vlist_find(&wireless_devices, dev_name, wdev, node);
                if (!wdev) {
 
                wdev = vlist_find(&wireless_devices, dev_name, wdev, node);
                if (!wdev) {
-                       DPRINTF("device %s not found!\n", dev_name);
+                       D(WIRELESS, "device %s not found!", dev_name);
                        continue;
                }
 
                config_parse_wireless_interface(wdev, s);
        }
 
                        continue;
                }
 
                config_parse_wireless_interface(wdev, s);
        }
 
+       netifd_ubus_get_procd_data("wifi-iface", config_procd_wireless_interface_cb);
+
        vlist_for_each_element(&wireless_devices, wdev, node)
                vlist_flush(&wdev->interfaces);
 }
        vlist_for_each_element(&wireless_devices, wdev, node)
                vlist_flush(&wdev->interfaces);
 }
@@ -719,6 +785,42 @@ struct ether_addr *config_get_default_macaddr(const char *ifname)
        return ether_aton(blobmsg_get_string(cur));
 }
 
        return ether_aton(blobmsg_get_string(cur));
 }
 
+int config_get_default_gro(const char *ifname)
+{
+       struct blob_attr *cur;
+
+       if (!board_netdevs)
+               return -1;
+
+       cur = config_find_blobmsg_attr(board_netdevs, ifname, BLOBMSG_TYPE_TABLE);
+       if (!cur)
+               return -1;
+
+       cur = config_find_blobmsg_attr(cur, "gro", BLOBMSG_TYPE_BOOL);
+       if (!cur)
+               return -1;
+
+       return blobmsg_get_bool(cur);
+}
+
+const char *config_get_default_conduit(const char *ifname)
+{
+       struct blob_attr *cur;
+
+       if (!board_netdevs)
+               return NULL;
+
+       cur = config_find_blobmsg_attr(board_netdevs, ifname, BLOBMSG_TYPE_TABLE);
+       if (!cur)
+               return NULL;
+
+       cur = config_find_blobmsg_attr(cur, "conduit", BLOBMSG_TYPE_STRING);
+       if (!cur)
+               return NULL;
+
+       return blobmsg_get_string(cur);
+}
+
 static void
 config_init_board(void)
 {
 static void
 config_init_board(void)
 {
@@ -732,7 +834,7 @@ config_init_board(void)
        free(board_netdevs);
        board_netdevs = NULL;
 
        free(board_netdevs);
        board_netdevs = NULL;
 
-       cur = config_find_blobmsg_attr(b.head, "network-device",
+       cur = config_find_blobmsg_attr(b.head, "network_device",
                                       BLOBMSG_TYPE_TABLE);
        if (!cur)
                return;
                                       BLOBMSG_TYPE_TABLE);
        if (!cur)
                return;