mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-31 10:28:06 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			286 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			286 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 4e4128e44fcb6c0f444e4aa481eb8941f47a801a Mon Sep 17 00:00:00 2001
 | |
| From: Felix Fietkau <nbd@nbd.name>
 | |
| Date: Fri, 15 Sep 2023 20:47:10 +0200
 | |
| Subject: [PATCH] netifd: add support for enabling/disabling wifi interfaces
 | |
|  via ifup/ifdown
 | |
| 
 | |
| Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| ---
 | |
|  package/network/config/netifd/files/sbin/ifup |  33 ---
 | |
|  .../patches/410-wireless_network_state.patch  | 194 ++++++++++++++++++
 | |
|  2 files changed, 194 insertions(+), 33 deletions(-)
 | |
|  create mode 100644 package/network/config/netifd/patches/410-wireless_network_state.patch
 | |
| 
 | |
| diff --git a/package/network/config/netifd/files/sbin/ifup b/package/network/config/netifd/files/sbin/ifup
 | |
| index 15be535bbfc9..fbf2fd80c7ea 100755
 | |
| --- a/package/network/config/netifd/files/sbin/ifup
 | |
| +++ b/package/network/config/netifd/files/sbin/ifup
 | |
| @@ -1,7 +1,6 @@
 | |
|  #!/bin/sh
 | |
|  
 | |
|  ifup_all=
 | |
| -setup_wifi=
 | |
|  
 | |
|  if_call() {
 | |
|  	local interface="$1"
 | |
| @@ -14,7 +13,6 @@ case "$0" in
 | |
|  	*ifdown) modes=down;;
 | |
|  	*ifup)
 | |
|  		modes="down up"
 | |
| -		setup_wifi=1
 | |
|  	;;
 | |
|  	*) echo "Invalid command: $0";;
 | |
|  esac
 | |
| @@ -25,10 +23,6 @@ while :; do
 | |
|  			ifup_all=1
 | |
|  			shift
 | |
|  		;;
 | |
| -		-w)
 | |
| -			setup_wifi=
 | |
| -			shift
 | |
| -		;;
 | |
|  		*)
 | |
|  			break
 | |
|  		;;
 | |
| @@ -40,7 +34,6 @@ if [ -n "$ifup_all" ]; then
 | |
|  	for interface in $(ubus -S list 'network.interface.*'); do
 | |
|  		if_call "${interface##network.interface.}"
 | |
|  	done
 | |
| -	[ -n "$setup_wifi" ] && /sbin/wifi up
 | |
|  	exit
 | |
|  else
 | |
|  	ubus -S list "network.interface.$1" > /dev/null || {
 | |
| @@ -49,29 +42,3 @@ else
 | |
|  	}
 | |
|  	if_call "$1"
 | |
|  fi
 | |
| -
 | |
| -if [ -n "$setup_wifi" ] && grep -sq config /etc/config/wireless; then
 | |
| -	. /lib/functions.sh
 | |
| -
 | |
| -	find_related_radios() {
 | |
| -		local wdev wnet
 | |
| -		config_get wdev "$1" device
 | |
| -		config_get wnet "$1" network
 | |
| -
 | |
| -		if [ -n "$wdev" ]; then
 | |
| -			for wnet in $wnet; do
 | |
| -				if [ "$wnet" = "$network" ]; then
 | |
| -					append radio_devs "$wdev" "$N"
 | |
| -				fi
 | |
| -			done
 | |
| -		fi
 | |
| -	}
 | |
| -
 | |
| -	network="$1"
 | |
| -	config_load wireless
 | |
| -	config_foreach find_related_radios wifi-iface
 | |
| -
 | |
| -	for dev in $(echo "$radio_devs" | sort -u); do
 | |
| -		/sbin/wifi up "$dev"
 | |
| -	done
 | |
| -fi
 | |
| diff --git a/package/network/config/netifd/patches/410-wireless_network_state.patch b/package/network/config/netifd/patches/410-wireless_network_state.patch
 | |
| new file mode 100644
 | |
| index 000000000000..4e9b905190b6
 | |
| --- /dev/null
 | |
| +++ b/package/network/config/netifd/patches/410-wireless_network_state.patch
 | |
| @@ -0,0 +1,194 @@
 | |
| +--- a/config.c
 | |
| ++++ b/config.c
 | |
| +@@ -784,7 +784,7 @@ config_init_all(void)
 | |
| + 	vlist_flush(&interfaces);
 | |
| + 	interface_refresh_assignments(false);
 | |
| + 	interface_start_pending();
 | |
| +-	wireless_start_pending();
 | |
| ++	wireless_start_pending(0);
 | |
| + 
 | |
| + 	return ret;
 | |
| + }
 | |
| +--- a/interface.c
 | |
| ++++ b/interface.c
 | |
| +@@ -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);
 | |
| +@@ -1125,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;
 | |
| +@@ -1157,6 +1159,7 @@ interface_set_down(struct interface *ifa
 | |
| + 			__interface_set_down(iface, false);
 | |
| + 	} else {
 | |
| + 		iface->autostart = false;
 | |
| ++		wireless_check_network_enabled();
 | |
| + 		__interface_set_down(iface, false);
 | |
| + 	}
 | |
| + }
 | |
| +--- a/wireless.c
 | |
| ++++ b/wireless.c
 | |
| +@@ -198,6 +198,9 @@ prepare_config(struct wireless_device *w
 | |
| + 
 | |
| + 	l = blobmsg_open_table(&b, "interfaces");
 | |
| + 	vlist_for_each_element(&wdev->interfaces, vif, node) {
 | |
| ++		if (vif->disabled)
 | |
| ++			continue;
 | |
| ++
 | |
| + 		i = blobmsg_open_table(&b, vif->name);
 | |
| + 		vif_config_add_bridge(&b, vif->network, up);
 | |
| + 		put_container(&b, vif->config, "config");
 | |
| +@@ -438,6 +441,8 @@ wireless_device_run_handler(struct wirel
 | |
| + 		wdev->prev_config = NULL;
 | |
| + 	} else {
 | |
| + 		prepare_config(wdev, &b, up);
 | |
| ++		free(wdev->prev_config);
 | |
| ++		wdev->prev_config = up ? blob_memdup(b.head) : NULL;
 | |
| + 		config = blobmsg_format_json(b.head, true);
 | |
| + 	}
 | |
| + 
 | |
| +@@ -495,8 +500,6 @@ __wireless_device_set_up(struct wireless
 | |
| + 	if ((!force && wdev->state != IFS_DOWN) || config_init)
 | |
| + 		return;
 | |
| + 
 | |
| +-	free(wdev->prev_config);
 | |
| +-	wdev->prev_config = NULL;
 | |
| + 	wdev->state = IFS_SETUP;
 | |
| + 	wireless_device_run_handler(wdev, true);
 | |
| + }
 | |
| +@@ -690,16 +693,6 @@ wdev_set_config_state(struct wireless_de
 | |
| + }
 | |
| + 
 | |
| + static void
 | |
| +-wdev_prepare_prev_config(struct wireless_device *wdev)
 | |
| +-{
 | |
| +-	if (wdev->prev_config)
 | |
| +-		return;
 | |
| +-
 | |
| +-	prepare_config(wdev, &b, false);
 | |
| +-	wdev->prev_config = blob_memdup(b.head);
 | |
| +-}
 | |
| +-
 | |
| +-static void
 | |
| + wdev_change_config(struct wireless_device *wdev, struct wireless_device *wd_new)
 | |
| + {
 | |
| + 	struct blob_attr *new_config = wd_new->config;
 | |
| +@@ -709,7 +702,6 @@ wdev_change_config(struct wireless_devic
 | |
| + 	wdev->serialize = wd_new->serialize;
 | |
| + 	free(wd_new);
 | |
| + 
 | |
| +-	wdev_prepare_prev_config(wdev);
 | |
| + 	if (blob_attr_equal(wdev->config, new_config) && wdev->disabled == disabled)
 | |
| + 		return;
 | |
| + 
 | |
| +@@ -1533,19 +1525,78 @@ wireless_device_notify(struct wireless_d
 | |
| + 	return 0;
 | |
| + }
 | |
| + 
 | |
| +-/* called on startup and by netifd reload() */
 | |
| +-void
 | |
| +-wireless_start_pending(void)
 | |
| ++static void
 | |
| ++wdev_check_network_enabled(struct wireless_device *wdev)
 | |
| ++{
 | |
| ++	struct wireless_interface *vif;
 | |
| ++	struct interface *iface;
 | |
| ++	struct blob_attr *cur;
 | |
| ++	int rem;
 | |
| ++
 | |
| ++	vlist_for_each_element(&wdev->interfaces, vif, node) {
 | |
| ++		int enabled = -1;
 | |
| ++
 | |
| ++		blobmsg_for_each_attr(cur, vif->network, rem) {
 | |
| ++			iface = vlist_find(&interfaces, blobmsg_get_string(cur), iface, node);
 | |
| ++			if (!iface)
 | |
| ++				continue;
 | |
| ++
 | |
| ++			if (iface->autostart) {
 | |
| ++				enabled = 1;
 | |
| ++				break;
 | |
| ++			}
 | |
| ++			if (enabled != 1)
 | |
| ++				enabled = 0;
 | |
| ++		}
 | |
| ++
 | |
| ++		if (vif->disabled == !enabled)
 | |
| ++			continue;
 | |
| ++
 | |
| ++		vif->disabled = !enabled;
 | |
| ++		wdev->config_update = true;
 | |
| ++	}
 | |
| ++}
 | |
| ++
 | |
| ++static void
 | |
| ++__wireless_start_pending(struct uloop_timeout *t)
 | |
| + {
 | |
| + 	struct wireless_device *wdev;
 | |
| + 
 | |
| + 	vlist_for_each_element(&wireless_devices, wdev, node) {
 | |
| ++		wdev_check_network_enabled(wdev);
 | |
| + 		if (wdev->config_update)
 | |
| + 			wdev_set_config_state(wdev, IFC_RELOAD);
 | |
| + 		__wireless_device_set_up(wdev, 0);
 | |
| + 	}
 | |
| + }
 | |
| + 
 | |
| ++void wireless_start_pending(int timeout)
 | |
| ++{
 | |
| ++	static struct uloop_timeout timer = {
 | |
| ++		.cb = __wireless_start_pending
 | |
| ++	};
 | |
| ++
 | |
| ++	if (timeout) {
 | |
| ++		uloop_timeout_set(&timer, timeout);
 | |
| ++		return;
 | |
| ++	}
 | |
| ++
 | |
| ++	uloop_timeout_cancel(&timer);
 | |
| ++	timer.cb(&timer);
 | |
| ++}
 | |
| ++
 | |
| ++void wireless_check_network_enabled(void)
 | |
| ++{
 | |
| ++	struct wireless_device *wdev;
 | |
| ++
 | |
| ++	vlist_for_each_element(&wireless_devices, wdev, node) {
 | |
| ++		wdev_check_network_enabled(wdev);
 | |
| ++
 | |
| ++		if (wdev->config_update)
 | |
| ++			wireless_start_pending(1000);
 | |
| ++	}
 | |
| ++}
 | |
| ++
 | |
| + void wireless_device_hotplug_event(const char *name, bool add)
 | |
| + {
 | |
| + 	struct wireless_interface *vif;
 | |
| +--- a/wireless.h
 | |
| ++++ b/wireless.h
 | |
| +@@ -94,6 +94,7 @@ struct wireless_interface {
 | |
| + 	int multicast_to_unicast;
 | |
| + 	int vlan_idx;
 | |
| + 	int sta_idx;
 | |
| ++	bool disabled;
 | |
| + };
 | |
| + 
 | |
| + struct wireless_vlan {
 | |
| +@@ -142,7 +143,8 @@ void wireless_station_create(struct wire
 | |
| + int wireless_device_notify(struct wireless_device *wdev, struct blob_attr *data,
 | |
| + 			   struct ubus_request_data *req);
 | |
| + 
 | |
| +-void wireless_start_pending(void);
 | |
| ++void wireless_check_network_enabled(void);
 | |
| ++void wireless_start_pending(int timeout);
 | |
| + void wireless_init(void);
 | |
| + void wireless_device_hotplug_event(const char *name, bool add);
 | |
| + 
 | |
| -- 
 | |
| 2.39.2
 | |
| 
 | 
