From 8ecd0c36dd9bb4725e523d48d325ee3787bb08e9 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 7 Nov 2024 17:43:44 +0100 Subject: [PATCH] netifd: various backports from HEAD branch Signed-off-by: John Crispin --- .../0078-netifd-add-various-backports.patch | 502 ++++++++++++++++++ 1 file changed, 502 insertions(+) create mode 100644 patches/0078-netifd-add-various-backports.patch diff --git a/patches/0078-netifd-add-various-backports.patch b/patches/0078-netifd-add-various-backports.patch new file mode 100644 index 00000000..62d65b7c --- /dev/null +++ b/patches/0078-netifd-add-various-backports.patch @@ -0,0 +1,502 @@ +From d5484e69a2476ff3bea5d402d06ed3c68d2ef24d Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Wed, 6 Nov 2024 12:28:41 +0100 +Subject: [PATCH] netifd: add various backports + +Signed-off-by: John Crispin +--- + .../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 +