123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- NETIFD_MAIN_DIR="${NETIFD_MAIN_DIR:-/lib/netifd}"
- . /usr/share/libubox/jshn.sh
- . $NETIFD_MAIN_DIR/utils.sh
- CMD_UP=0
- CMD_SET_DATA=1
- CMD_PROCESS_ADD=2
- CMD_PROCESS_KILL_ALL=3
- CMD_SET_RETRY=4
- add_driver() {
- return
- }
- wireless_setup_vif_failed() {
- local error="$1"
- echo "Interface $_w_iface setup failed: $error"
- }
- wireless_setup_failed() {
- local error="$1"
- echo "Device setup failed: $error"
- wireless_set_retry 0
- }
- prepare_key_wep() {
- local key="$1"
- local hex=1
- echo -n "$key" | grep -qE "[^a-fA-F0-9]" && hex=0
- [ "${#key}" -eq 10 -a $hex -eq 1 ] || \
- [ "${#key}" -eq 26 -a $hex -eq 1 ] || {
- [ "${key:0:2}" = "s:" ] && key="${key#s:}"
- key="$(echo -n "$key" | hexdump -ve '1/1 "%02x" ""')"
- }
- echo "$key"
- }
- _wdev_prepare_channel() {
- json_get_vars channel band hwmode
- auto_channel=0
- enable_ht=0
- htmode=
- hwmode="${hwmode##11}"
- case "$channel" in
- ""|0|auto)
- channel=0
- auto_channel=1
- ;;
- [0-9]*) ;;
- *)
- wireless_setup_failed "INVALID_CHANNEL"
- ;;
- esac
- case "$hwmode" in
- a|b|g|ad) ;;
- *)
- if [ "$channel" -gt 14 ]; then
- hwmode=a
- else
- hwmode=g
- fi
- ;;
- esac
- case "$band" in
- 2g) hwmode=g;;
- 5g|6g) hwmode=a;;
- 60g) hwmode=ad;;
- *)
- case "$hwmode" in
- *a) band=5g;;
- *ad) band=60g;;
- *b|*g) band=2g;;
- esac
- ;;
- esac
- }
- _wdev_handler() {
- json_load "$data"
- json_select config
- _wdev_prepare_channel
- json_select ..
- eval "drv_$1_$2 \"$interface\""
- }
- _wdev_msg_call() {
- local old_cb
- json_set_namespace wdev old_cb
- "$@"
- json_set_namespace $old_cb
- }
- _wdev_wrapper() {
- while [ -n "$1" ]; do
- eval "$1() { _wdev_msg_call _$1 \"\$@\"; }"
- shift
- done
- }
- _wdev_notify_init() {
- local command="$1"
- local name="$2"
- local value="$3"
- json_init
- json_add_int "command" "$command"
- json_add_string "device" "$__netifd_device"
- [ -n "$name" -a -n "$value" ] && json_add_string "$name" "$value"
- json_add_object "data"
- }
- _wdev_notify() {
- local options="$1"
- json_close_object
- ubus $options call network.wireless notify "$(json_dump)"
- }
- _wdev_add_variables() {
- while [ -n "$1" ]; do
- local var="${1%%=*}"
- local val="$1"
- shift
- [[ "$var" = "$val" ]] && continue
- val="${val#*=}"
- json_add_string "$var" "$val"
- done
- }
- _wireless_add_vif() {
- local name="$1"; shift
- local ifname="$1"; shift
- _wdev_notify_init $CMD_SET_DATA "interface" "$name"
- json_add_string "ifname" "$ifname"
- _wdev_add_variables "$@"
- _wdev_notify
- }
- _wireless_add_vlan() {
- local name="$1"; shift
- local ifname="$1"; shift
- _wdev_notify_init $CMD_SET_DATA "vlan" "$name"
- json_add_string "ifname" "$ifname"
- _wdev_add_variables "$@"
- _wdev_notify
- }
- _wireless_set_up() {
- _wdev_notify_init $CMD_UP
- _wdev_notify
- }
- _wireless_set_data() {
- _wdev_notify_init $CMD_SET_DATA
- _wdev_add_variables "$@"
- _wdev_notify
- }
- _wireless_add_process() {
- _wdev_notify_init $CMD_PROCESS_ADD
- local exe="$2"
- [ -L "$exe" ] && exe="$(readlink -f "$exe")"
- json_add_int pid "$1"
- json_add_string exe "$exe"
- [ -n "$3" ] && json_add_boolean required 1
- [ -n "$4" ] && json_add_boolean keep 1
- exe2="$(readlink -f /proc/$1/exe)"
- [ "$exe" != "$exe2" ] && echo "WARNING (wireless_add_process): executable path $exe does not match process $1 path ($exe2)"
- _wdev_notify
- }
- _wireless_process_kill_all() {
- _wdev_notify_init $CMD_PROCESS_KILL_ALL
- [ -n "$1" ] && json_add_int signal "$1"
- _wdev_notify
- }
- _wireless_set_retry() {
- _wdev_notify_init $CMD_SET_RETRY
- json_add_int retry "$1"
- _wdev_notify
- }
- _wdev_wrapper \
- wireless_add_vif \
- wireless_add_vlan \
- wireless_set_up \
- wireless_set_data \
- wireless_add_process \
- wireless_process_kill_all \
- wireless_set_retry \
- wireless_vif_parse_encryption() {
- json_get_vars encryption
- set_default encryption none
- auth_mode_open=1
- auth_mode_shared=0
- auth_type=none
- if [ "$hwmode" = "ad" ]; then
- wpa_cipher="GCMP"
- else
- wpa_cipher="CCMP"
- fi
- # WPA3 enterprise requires the GCMP-256 cipher (technically also CCMP and GCMP are possible
- # but many clients/devices do not support that)
- case "$encryption" in
- wpa3-mixed*) wpa_cipher="${wpa_cipher} GCMP-256";;
- wpa3*) wpa_cipher="GCMP-256";;
- esac
- case "$encryption" in
- *tkip+aes|*tkip+ccmp|*aes+tkip|*ccmp+tkip) wpa_cipher="CCMP TKIP";;
- *ccmp256) wpa_cipher="CCMP-256";;
- *aes|*ccmp|dpp) wpa_cipher="CCMP";;
- *tkip) wpa_cipher="TKIP";;
- *gcmp256) wpa_cipher="GCMP-256";;
- *gcmp) wpa_cipher="GCMP";;
- *modern) wpa_cipher="GCMP-256 GCMP CCMP-256 CCMP";;
- esac
- # 802.11n requires CCMP for WPA
- [ "$enable_ht:$wpa_cipher" = "1:TKIP" ] && wpa_cipher="CCMP TKIP"
- # Examples:
- # psk-mixed/tkip => WPA1+2 PSK, TKIP
- # wpa-psk2/tkip+aes => WPA2 PSK, CCMP+TKIP
- # wpa2/tkip+aes => WPA2 RADIUS, CCMP+TKIP
- case "$encryption" in
- wpa2*|wpa3*|*psk2*|psk3*|sae*|owe*|dpp)
- wpa=2
- ;;
- wpa*mixed*|*psk*mixed*)
- wpa=3
- ;;
- wpa*|*psk*)
- wpa=1
- ;;
- *)
- wpa=0
- wpa_cipher=
- ;;
- esac
- wpa_pairwise="$wpa_cipher"
- case "$encryption" in
- owe*)
- auth_type=owe
- ;;
- wpa3-mixed*)
- auth_type=eap-eap192
- ;;
- wpa3*)
- auth_type=eap192
- ;;
- psk3-mixed*|sae-mixed*)
- auth_type=psk-sae
- ;;
- psk3*|sae*)
- auth_type=sae
- ;;
- *psk*)
- auth_type=psk
- ;;
- *wpa*|*8021x*)
- auth_type=eap
- ;;
- dpp)
- auth_type=dpp
- ;;
- *wep*)
- auth_type=wep
- case "$encryption" in
- *shared*)
- auth_mode_open=0
- auth_mode_shared=1
- ;;
- *mixed*)
- auth_mode_shared=1
- ;;
- esac
- ;;
- esac
- case "$encryption" in
- *osen*)
- auth_osen=1
- ;;
- esac
- }
- _wireless_set_brsnoop_isolation() {
- local multicast_to_unicast="$1"
- local isolate
- json_get_vars isolate proxy_arp
- [ ${isolate:-0} -gt 0 -o -z "$network_bridge" ] && return
- [ ${multicast_to_unicast:-1} -gt 0 -o ${proxy_arp:-0} -gt 0 ] && json_add_boolean isolate 1
- }
- for_each_interface() {
- local _w_types="$1"; shift
- local _w_ifaces _w_iface
- local _w_type
- local _w_found
- local multicast_to_unicast
- json_get_keys _w_ifaces interfaces
- json_select interfaces
- for _w_iface in $_w_ifaces; do
- json_select "$_w_iface"
- if [ -n "$_w_types" ]; then
- json_get_var network_bridge bridge
- json_get_var network_ifname bridge-ifname
- json_get_var multicast_to_unicast multicast_to_unicast
- json_select config
- _wireless_set_brsnoop_isolation "$multicast_to_unicast"
- json_get_var _w_type mode
- json_select ..
- _w_types=" $_w_types "
- [[ "${_w_types%$_w_type*}" = "$_w_types" ]] && {
- json_select ..
- continue
- }
- fi
- "$@" "$_w_iface"
- json_select ..
- done
- json_select ..
- }
- for_each_vlan() {
- local _w_vlans _w_vlan
- json_get_keys _w_vlans vlans
- json_select vlans
- for _w_vlan in $_w_vlans; do
- json_select "$_w_vlan"
- json_select config
- "$@" "$_w_vlan"
- json_select ..
- json_select ..
- done
- json_select ..
- }
- for_each_station() {
- local _w_stas _w_sta
- json_get_keys _w_stas stas
- json_select stas
- for _w_sta in $_w_stas; do
- json_select "$_w_sta"
- json_select config
- "$@" "$_w_sta"
- json_select ..
- json_select ..
- done
- json_select ..
- }
- _wdev_common_device_config() {
- config_add_string channel hwmode band htmode noscan
- }
- _wdev_common_iface_config() {
- config_add_string mode ssid encryption 'key:wpakey'
- }
- _wdev_common_vlan_config() {
- config_add_string name vid iface
- }
- _wdev_common_station_config() {
- config_add_string mac key vid iface
- }
- init_wireless_driver() {
- name="$1"; shift
- cmd="$1"; shift
- case "$cmd" in
- dump)
- add_driver() {
- eval "drv_$1_cleanup"
- json_init
- json_add_string name "$1"
- json_add_array device
- _wdev_common_device_config
- eval "drv_$1_init_device_config"
- json_close_array
- json_add_array iface
- _wdev_common_iface_config
- eval "drv_$1_init_iface_config"
- json_close_array
- json_add_array vlan
- _wdev_common_vlan_config
- eval "drv_$1_init_vlan_config"
- json_close_array
- json_add_array station
- _wdev_common_station_config
- eval "drv_$1_init_station_config"
- json_close_array
- json_dump
- }
- ;;
- setup|teardown)
- interface="$1"; shift
- data="$1"; shift
- export __netifd_device="$interface"
- add_driver() {
- [[ "$name" == "$1" ]] || return 0
- _wdev_handler "$1" "$cmd"
- }
- ;;
- esac
- }
|