mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 17:42:41 +00:00
503 lines
15 KiB
Diff
503 lines
15 KiB
Diff
From d5484e69a2476ff3bea5d402d06ed3c68d2ef24d Mon Sep 17 00:00:00 2001
|
|
From: John Crispin <john@phrozen.org>
|
|
Date: Wed, 6 Nov 2024 12:28:41 +0100
|
|
Subject: [PATCH] netifd: add various backports
|
|
|
|
Signed-off-by: John Crispin <john@phrozen.org>
|
|
---
|
|
.../netifd/patches/100-backport_fixes.patch | 482 ++++++++++++++++++
|
|
1 file changed, 482 insertions(+)
|
|
create mode 100644 package/network/config/netifd/patches/100-backport_fixes.patch
|
|
|
|
diff --git a/package/network/config/netifd/patches/100-backport_fixes.patch b/package/network/config/netifd/patches/100-backport_fixes.patch
|
|
new file mode 100644
|
|
index 0000000000..0442beb053
|
|
--- /dev/null
|
|
+++ b/package/network/config/netifd/patches/100-backport_fixes.patch
|
|
@@ -0,0 +1,482 @@
|
|
+--- a/device.c
|
|
++++ b/device.c
|
|
+@@ -166,12 +166,19 @@ static int set_device_state(struct devic
|
|
+ dev->orig_settings.flags &= dev->settings.flags;
|
|
+ system_if_apply_settings(dev, &dev->settings, dev->settings.flags);
|
|
+
|
|
+- system_if_up(dev);
|
|
++ if (!dev->external)
|
|
++ system_if_up(dev);
|
|
+
|
|
+ system_if_apply_settings_after_up(dev, &dev->settings);
|
|
+ } else {
|
|
+- system_if_down(dev);
|
|
++ if (!dev->external)
|
|
++ system_if_down(dev);
|
|
+ system_if_apply_settings(dev, &dev->orig_settings, dev->orig_settings.flags);
|
|
++
|
|
++ /* Restore any settings present in UCI which may have
|
|
++ * failed to apply so that they will be re-attempted
|
|
++ * the next time the device is brought up */
|
|
++ dev->settings.flags |= dev->settings.valid_flags;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+@@ -571,6 +578,9 @@ device_init_settings(struct device *dev,
|
|
+ s->flags |= DEV_OPT_EEE;
|
|
+ }
|
|
+
|
|
++ /* Remember the settings present in UCI */
|
|
++ s->valid_flags = s->flags;
|
|
++
|
|
+ cur = tb[DEV_ATTR_AUTH_VLAN];
|
|
+ free(dev->config_auth_vlans);
|
|
+ dev->config_auth_vlans = cur ? blob_memdup(cur) : NULL;
|
|
+@@ -609,11 +619,15 @@ static int device_broadcast_cb(void *ctx
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+-void device_broadcast_event(struct device *dev, enum device_event ev)
|
|
++static const char *device_event_name(enum device_event ev)
|
|
+ {
|
|
+ static const char * const event_names[] = {
|
|
+ [DEV_EVENT_ADD] = "add",
|
|
+ [DEV_EVENT_REMOVE] = "remove",
|
|
++ [DEV_EVENT_UPDATE_IFNAME] = "update_ifname",
|
|
++ [DEV_EVENT_UPDATE_IFINDEX] = "update_ifindex",
|
|
++ [DEV_EVENT_SETUP] = "setup",
|
|
++ [DEV_EVENT_TEARDOWN] = "teardown",
|
|
+ [DEV_EVENT_UP] = "up",
|
|
+ [DEV_EVENT_DOWN] = "down",
|
|
+ [DEV_EVENT_AUTH_UP] = "auth_up",
|
|
+@@ -621,12 +635,37 @@ void device_broadcast_event(struct devic
|
|
+ [DEV_EVENT_LINK_DOWN] = "link_down",
|
|
+ [DEV_EVENT_TOPO_CHANGE] = "topo_change",
|
|
+ };
|
|
++
|
|
++ if (ev >= ARRAY_SIZE(event_names) || !event_names[ev])
|
|
++ return "unknown";
|
|
++
|
|
++ return event_names[ev];
|
|
++}
|
|
++
|
|
++void device_broadcast_event(struct device *dev, enum device_event ev)
|
|
++{
|
|
++ const char *ev_name;
|
|
+ int dev_ev = ev;
|
|
+
|
|
+ safe_list_for_each(&dev->aliases, device_broadcast_cb, &dev_ev);
|
|
+ safe_list_for_each(&dev->users, device_broadcast_cb, &dev_ev);
|
|
+
|
|
+- if (ev >= ARRAY_SIZE(event_names) || !event_names[ev] || !dev->ifname[0])
|
|
++ switch (ev) {
|
|
++ case DEV_EVENT_ADD:
|
|
++ case DEV_EVENT_REMOVE:
|
|
++ case DEV_EVENT_UP:
|
|
++ case DEV_EVENT_DOWN:
|
|
++ case DEV_EVENT_AUTH_UP:
|
|
++ case DEV_EVENT_LINK_UP:
|
|
++ case DEV_EVENT_LINK_DOWN:
|
|
++ case DEV_EVENT_TOPO_CHANGE:
|
|
++ break;
|
|
++ default:
|
|
++ return;
|
|
++ }
|
|
++
|
|
++ ev_name = device_event_name(ev);
|
|
++ if (!dev->ifname[0])
|
|
+ return;
|
|
+
|
|
+ blob_buf_init(&b, 0);
|
|
+@@ -635,7 +674,7 @@ void device_broadcast_event(struct devic
|
|
+ blobmsg_add_u8(&b, "present", dev->present);
|
|
+ blobmsg_add_u8(&b, "active", dev->active);
|
|
+ blobmsg_add_u8(&b, "link_active", dev->link_active);
|
|
+- netifd_ubus_device_notify(event_names[ev], b.head, -1);
|
|
++ netifd_ubus_device_notify(ev_name, b.head, -1);
|
|
+ }
|
|
+
|
|
+ static void
|
|
+@@ -689,17 +728,7 @@ int device_claim(struct device_user *dep
|
|
+
|
|
+ device_broadcast_event(dev, DEV_EVENT_SETUP);
|
|
+ device_fill_default_settings(dev);
|
|
+- if (dev->external) {
|
|
+- /* Get ifindex for external claimed devices so a valid */
|
|
+- /* ifindex is in place avoiding possible race conditions */
|
|
+- device_set_ifindex(dev, system_if_resolve(dev));
|
|
+- if (!dev->ifindex)
|
|
+- ret = -1;
|
|
+-
|
|
+- system_if_get_settings(dev, &dev->orig_settings);
|
|
+- } else
|
|
+- ret = dev->set_state(dev, true);
|
|
+-
|
|
++ ret = dev->set_state(dev, true);
|
|
+ if (ret == 0)
|
|
+ device_broadcast_event(dev, DEV_EVENT_UP);
|
|
+ else {
|
|
+@@ -727,8 +756,7 @@ void device_release(struct device_user *
|
|
+ return;
|
|
+
|
|
+ device_broadcast_event(dev, DEV_EVENT_TEARDOWN);
|
|
+- if (!dev->external)
|
|
+- dev->set_state(dev, false);
|
|
++ dev->set_state(dev, false);
|
|
+
|
|
+ if (dev->active)
|
|
+ return;
|
|
+@@ -810,9 +838,6 @@ device_create_default(const char *name,
|
|
+ }
|
|
+
|
|
+ dev->default_config = true;
|
|
+- if (external)
|
|
+- system_if_apply_settings(dev, &dev->settings, dev->settings.flags);
|
|
+-
|
|
+ device_check_state(dev);
|
|
+
|
|
+ return dev;
|
|
+@@ -841,7 +866,6 @@ __device_get(const char *name, int creat
|
|
+
|
|
+ if (dev) {
|
|
+ if (create > 1 && !dev->external) {
|
|
+- system_if_apply_settings(dev, &dev->settings, dev->settings.flags);
|
|
+ dev->external = true;
|
|
+ device_set_present(dev, true);
|
|
+ }
|
|
+@@ -1164,11 +1188,6 @@ device_apply_config(struct device *dev,
|
|
+ enum dev_change_type change;
|
|
+
|
|
+ change = device_set_config(dev, type, config);
|
|
+- if (dev->external) {
|
|
+- system_if_apply_settings(dev, &dev->settings, dev->settings.flags);
|
|
+- change = DEV_CONFIG_APPLIED;
|
|
+- }
|
|
+-
|
|
+ switch (change) {
|
|
+ case DEV_CONFIG_RESTART:
|
|
+ case DEV_CONFIG_APPLIED:
|
|
+@@ -1180,7 +1199,7 @@ device_apply_config(struct device *dev,
|
|
+ int ret = 0;
|
|
+
|
|
+ device_set_present(dev, false);
|
|
+- if (dev->active && !dev->external) {
|
|
++ if (dev->active) {
|
|
+ ret = dev->set_state(dev, false);
|
|
+ if (!ret)
|
|
+ ret = dev->set_state(dev, true);
|
|
+--- a/interface.c
|
|
++++ b/interface.c
|
|
+@@ -1078,11 +1078,17 @@ interface_add_link(struct interface *ifa
|
|
+ {
|
|
+ struct device *mdev = iface->main_dev.dev;
|
|
+
|
|
+- if (mdev == dev)
|
|
++ if (mdev == dev) {
|
|
++ if (iface->state != IFS_UP) {
|
|
++ interface_set_available(iface, false);
|
|
++ if (dev->present)
|
|
++ interface_set_available(iface, true);
|
|
++ }
|
|
+ return 0;
|
|
++ }
|
|
+
|
|
+ if (iface->main_dev.hotplug)
|
|
+- device_remove_user(&iface->main_dev);
|
|
++ interface_set_main_dev(iface, NULL);
|
|
+
|
|
+ if (mdev) {
|
|
+ if (mdev->hotplug_ops)
|
|
+--- a/wireless.c
|
|
++++ b/wireless.c
|
|
+@@ -138,7 +138,7 @@ static void
|
|
+ put_container(struct blob_buf *buf, struct blob_attr *attr, const char *name)
|
|
+ {
|
|
+ void *c = blobmsg_open_table(buf, name);
|
|
+- blob_put_raw(buf, blob_data(attr), blob_len(attr));
|
|
++ blob_put_raw(buf, blobmsg_data(attr), blobmsg_len(attr));
|
|
+ blobmsg_close_table(buf, c);
|
|
+ }
|
|
+
|
|
+@@ -337,12 +337,39 @@ static void wireless_device_set_mcast_to
|
|
+ dev->settings.flags |= DEV_OPT_MULTICAST_TO_UNICAST;
|
|
+ }
|
|
+
|
|
++static void wireless_check_interface(struct blob_attr *list, int *enabled, int *ifindex)
|
|
++{
|
|
++ struct interface *iface;
|
|
++ struct blob_attr *cur;
|
|
++ size_t rem;
|
|
++
|
|
++ blobmsg_for_each_attr(cur, list, rem) {
|
|
++ struct device *mdev;
|
|
++
|
|
++ iface = vlist_find(&interfaces, blobmsg_get_string(cur), iface, node);
|
|
++ if (!iface)
|
|
++ continue;
|
|
++
|
|
++ if (iface->autostart)
|
|
++ *enabled = 1;
|
|
++ else if (*enabled != 1)
|
|
++ *enabled = 0;
|
|
++
|
|
++ mdev = iface->main_dev.dev;
|
|
++ if (!mdev || !mdev->hotplug_ops)
|
|
++ continue;
|
|
++
|
|
++ *ifindex = mdev->ifindex;
|
|
++ }
|
|
++}
|
|
++
|
|
+ static void wireless_interface_handle_link(struct wireless_interface *vif, const char *ifname, bool up)
|
|
+ {
|
|
+ struct interface *iface;
|
|
+ struct blob_attr *cur;
|
|
+ const char *network;
|
|
+ struct device *dev;
|
|
++ int enabled = -1;
|
|
+ size_t rem;
|
|
+
|
|
+ if (!vif->network || !vif->ifname)
|
|
+@@ -372,6 +399,7 @@ static void wireless_interface_handle_li
|
|
+ dev->bpdu_filter = dev->wireless_ap;
|
|
+
|
|
+ out:
|
|
++ wireless_check_interface(vif->network, &enabled, &vif->network_ifindex);
|
|
+ blobmsg_for_each_attr(cur, vif->network, rem) {
|
|
+ network = blobmsg_data(cur);
|
|
+
|
|
+@@ -388,6 +416,7 @@ static void wireless_vlan_handle_link(st
|
|
+ struct interface *iface;
|
|
+ struct blob_attr *cur;
|
|
+ const char *network;
|
|
++ int enabled = -1;
|
|
+ size_t rem;
|
|
+
|
|
+ if (!vlan->network || !vlan->ifname)
|
|
+@@ -406,6 +435,7 @@ static void wireless_vlan_handle_link(st
|
|
+ }
|
|
+ }
|
|
+
|
|
++ wireless_check_interface(vlan->network, &enabled, &vlan->network_ifindex);
|
|
+ blobmsg_for_each_attr(cur, vlan->network, rem) {
|
|
+ network = blobmsg_data(cur);
|
|
+
|
|
+@@ -838,7 +868,7 @@ wireless_interface_init_config(struct wi
|
|
+ struct blob_attr *cur;
|
|
+
|
|
+ vif->network = NULL;
|
|
+- blobmsg_parse(vif_policy, __VIF_ATTR_MAX, tb, blob_data(vif->config), blob_len(vif->config));
|
|
++ blobmsg_parse_attr(vif_policy, __VIF_ATTR_MAX, tb, vif->config);
|
|
+
|
|
+ if ((cur = tb[VIF_ATTR_NETWORK]))
|
|
+ vif->network = cur;
|
|
+@@ -922,7 +952,7 @@ wireless_vlan_init_config(struct wireles
|
|
+ struct blob_attr *cur;
|
|
+
|
|
+ vlan->network = NULL;
|
|
+- blobmsg_parse(vlan_policy, __VLAN_ATTR_MAX, tb, blob_data(vlan->config), blob_len(vlan->config));
|
|
++ blobmsg_parse_attr(vlan_policy, __VLAN_ATTR_MAX, tb, vlan->config);
|
|
+
|
|
+ if ((cur = tb[VLAN_ATTR_NETWORK]))
|
|
+ vlan->network = cur;
|
|
+@@ -1079,7 +1109,7 @@ wireless_device_create(struct wireless_d
|
|
+ struct blob_attr *tb[__WDEV_ATTR_MAX];
|
|
+ struct blob_attr *cur;
|
|
+
|
|
+- blobmsg_parse(wdev_policy, __WDEV_ATTR_MAX, tb, blob_data(data), blob_len(data));
|
|
++ blobmsg_parse_attr(wdev_policy, __WDEV_ATTR_MAX, tb, data);
|
|
+
|
|
+ wdev = calloc_a(sizeof(*wdev), &name_buf, strlen(name) + 1);
|
|
+
|
|
+@@ -1128,7 +1158,7 @@ wireless_station_create(struct wireless_
|
|
+ char *name_buf;
|
|
+ char name[8];
|
|
+
|
|
+- blobmsg_parse(sta_policy, __STA_ATTR_MAX, tb, blob_data(data), blob_len(data));
|
|
++ blobmsg_parse_attr(sta_policy, __STA_ATTR_MAX, tb, data);
|
|
+
|
|
+ cur = tb[STA_ATTR_DISABLED];
|
|
+ if (cur && blobmsg_get_bool(cur))
|
|
+@@ -1168,7 +1198,7 @@ wireless_vlan_create(struct wireless_int
|
|
+ char *name_buf;
|
|
+ char name[8];
|
|
+
|
|
+- blobmsg_parse(vlan_policy, __VLAN_ATTR_MAX, tb, blob_data(data), blob_len(data));
|
|
++ blobmsg_parse_attr(vlan_policy, __VLAN_ATTR_MAX, tb, data);
|
|
+
|
|
+ cur = tb[VLAN_ATTR_DISABLED];
|
|
+ if (cur && blobmsg_get_bool(cur))
|
|
+@@ -1208,7 +1238,7 @@ struct wireless_interface* wireless_inte
|
|
+ char *name_buf;
|
|
+ char name[8];
|
|
+
|
|
+- blobmsg_parse(vif_policy, __VIF_ATTR_MAX, tb, blob_data(data), blob_len(data));
|
|
++ blobmsg_parse_attr(vif_policy, __VIF_ATTR_MAX, tb, data);
|
|
+
|
|
+ cur = tb[VIF_ATTR_DISABLED];
|
|
+ if (cur && blobmsg_get_bool(cur))
|
|
+@@ -1232,7 +1262,15 @@ struct wireless_interface* wireless_inte
|
|
+
|
|
+ vlist_add(&wdev->interfaces, &vif->node, vif->name);
|
|
+
|
|
+- return vlist_find(&wdev->interfaces, name, vif, node);
|
|
++ vif = vlist_find(&wdev->interfaces, name, vif, node);
|
|
++ if (!vif)
|
|
++ return NULL;
|
|
++
|
|
++ vif->vlan_idx = vif->sta_idx = 0;
|
|
++ vlist_update(&vif->vlans);
|
|
++ vlist_update(&vif->stations);
|
|
++
|
|
++ return vif;
|
|
+ }
|
|
+
|
|
+ /* ubus callback network.wireless.status, runs for every interface */
|
|
+@@ -1321,8 +1359,7 @@ wireless_interface_set_data(struct wirel
|
|
+ struct blob_attr *tb[__VIF_DATA_MAX];
|
|
+ struct blob_attr *cur;
|
|
+
|
|
+- blobmsg_parse(data_policy, __VIF_DATA_MAX, tb,
|
|
+- blobmsg_data(vif->data), blobmsg_data_len(vif->data));
|
|
++ blobmsg_parse_attr(data_policy, __VIF_DATA_MAX, tb, vif->data);
|
|
+
|
|
+ if ((cur = tb[VIF_DATA_IFNAME]))
|
|
+ vif->ifname = blobmsg_data(cur);
|
|
+@@ -1342,8 +1379,7 @@ wireless_vlan_set_data(struct wireless_v
|
|
+ struct blob_attr *tb[__VLAN_DATA_MAX];
|
|
+ struct blob_attr *cur;
|
|
+
|
|
+- blobmsg_parse(data_policy, __VLAN_DATA_MAX, tb,
|
|
+- blobmsg_data(vlan->data), blobmsg_data_len(vlan->data));
|
|
++ blobmsg_parse_attr(data_policy, __VLAN_DATA_MAX, tb, vlan->data);
|
|
+
|
|
+ if ((cur = tb[VLAN_DATA_IFNAME]))
|
|
+ vlan->ifname = blobmsg_data(cur);
|
|
+@@ -1374,7 +1410,7 @@ wireless_device_add_process(struct wirel
|
|
+ if (!data)
|
|
+ return UBUS_STATUS_INVALID_ARGUMENT;
|
|
+
|
|
+- blobmsg_parse(proc_policy, __PROC_ATTR_MAX, tb, blobmsg_data(data), blobmsg_data_len(data));
|
|
++ blobmsg_parse_attr(proc_policy, __PROC_ATTR_MAX, tb, data);
|
|
+ if (!tb[PROC_ATTR_PID] || !tb[PROC_ATTR_EXE])
|
|
+ return UBUS_STATUS_INVALID_ARGUMENT;
|
|
+
|
|
+@@ -1420,7 +1456,7 @@ wireless_device_process_kill_all(struct
|
|
+ bool immediate = false;
|
|
+ int signal = SIGTERM;
|
|
+
|
|
+- blobmsg_parse(kill_policy, __KILL_ATTR_MAX, tb, blobmsg_data(data), blobmsg_data_len(data));
|
|
++ blobmsg_parse_attr(kill_policy, __KILL_ATTR_MAX, tb, data);
|
|
+
|
|
+ if ((cur = tb[KILL_ATTR_SIGNAL]))
|
|
+ signal = blobmsg_get_u32(cur);
|
|
+@@ -1451,7 +1487,7 @@ wireless_device_set_retry(struct wireles
|
|
+ };
|
|
+ struct blob_attr *val;
|
|
+
|
|
+- blobmsg_parse(&retry_policy, 1, &val, blobmsg_data(data), blobmsg_data_len(data));
|
|
++ blobmsg_parse_attr(&retry_policy, 1, &val, data);
|
|
+ if (val)
|
|
+ wdev->retry = blobmsg_get_u32(val);
|
|
+ else
|
|
+@@ -1492,7 +1528,7 @@ wireless_device_notify(struct wireless_d
|
|
+ struct blob_attr *tb[__NOTIFY_MAX];
|
|
+ struct blob_attr *cur, **pdata;
|
|
+
|
|
+- blobmsg_parse(notify_policy, __NOTIFY_MAX, tb, blob_data(data), blob_len(data));
|
|
++ blobmsg_parse_attr(notify_policy, __NOTIFY_MAX, tb, data);
|
|
+
|
|
+ if (!tb[NOTIFY_ATTR_COMMAND])
|
|
+ return UBUS_STATUS_INVALID_ARGUMENT;
|
|
+@@ -1555,33 +1591,41 @@ wireless_device_notify(struct wireless_d
|
|
+ }
|
|
+
|
|
+ static void
|
|
++wdev_vlan_check_network_enabled(struct wireless_device *wdev,
|
|
++ struct wireless_interface *vif)
|
|
++{
|
|
++ struct wireless_vlan *vlan;
|
|
++
|
|
++ vlist_for_each_element(&vif->vlans, vlan, node) {
|
|
++ int enabled = -1, ifindex = -1;
|
|
++
|
|
++ wireless_check_interface(vlan->network, &enabled, &ifindex);
|
|
++
|
|
++ if (wdev->state != IFS_UP || vlan->network_ifindex == ifindex)
|
|
++ continue;
|
|
++
|
|
++ vlan->network_ifindex = ifindex;
|
|
++ wdev->config_update = true;
|
|
++ }
|
|
++}
|
|
++
|
|
++static void
|
|
+ wdev_check_network_enabled(struct wireless_device *wdev)
|
|
+ {
|
|
+ struct wireless_interface *vif;
|
|
+- struct interface *iface;
|
|
+- struct blob_attr *cur;
|
|
+- size_t rem;
|
|
+
|
|
+ vlist_for_each_element(&wdev->interfaces, vif, node) {
|
|
+- int enabled = -1;
|
|
++ int enabled = -1, ifindex = -1;
|
|
+
|
|
+- blobmsg_for_each_attr(cur, vif->network, rem) {
|
|
+- iface = vlist_find(&interfaces, blobmsg_get_string(cur), iface, node);
|
|
+- if (!iface)
|
|
+- continue;
|
|
++ wireless_check_interface(vif->network, &enabled, &ifindex);
|
|
++ wdev_vlan_check_network_enabled(wdev, vif);
|
|
+
|
|
+- if (iface->autostart) {
|
|
+- enabled = 1;
|
|
+- break;
|
|
+- }
|
|
+- if (enabled != 1)
|
|
+- enabled = 0;
|
|
+- }
|
|
+-
|
|
+- if (vif->disabled == !enabled)
|
|
++ if (vif->disabled == !enabled &&
|
|
++ (wdev->state != IFS_UP || vif->network_ifindex == ifindex))
|
|
+ continue;
|
|
+
|
|
+ vif->disabled = !enabled;
|
|
++ vif->network_ifindex = ifindex;
|
|
+ wdev->config_update = true;
|
|
+ }
|
|
+ }
|
|
+@@ -1639,10 +1683,8 @@ void wireless_device_hotplug_event(const
|
|
+ return;
|
|
+
|
|
+ len = s - name;
|
|
+- } else if (!device_find(name)) {
|
|
+- len = strlen(name);
|
|
+ } else {
|
|
+- return;
|
|
++ len = strlen(name);
|
|
+ }
|
|
+
|
|
+ vlist_for_each_element(&wireless_devices, wdev, node) {
|
|
+--- a/wireless.h
|
|
++++ b/wireless.h
|
|
+@@ -96,6 +96,8 @@ struct wireless_interface {
|
|
+ int vlan_idx;
|
|
+ int sta_idx;
|
|
+ bool disabled;
|
|
++
|
|
++ int network_ifindex;
|
|
+ };
|
|
+
|
|
+ struct wireless_vlan {
|
|
+@@ -112,6 +114,8 @@ struct wireless_vlan {
|
|
+ int multicast_to_unicast;
|
|
+ bool isolate;
|
|
+ bool bridge_isolate;
|
|
++
|
|
++ int network_ifindex;
|
|
+ };
|
|
+
|
|
+ struct wireless_station {
|
|
--
|
|
2.34.1
|
|
|