From 65edb4ab0652bfbce1f1e1540e8f8a9d60053b15 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 16 May 2022 06:17:22 +0200 Subject: [PATCH] map-agent: traffic separation script rework --- map-agent/files/lib/wifi/traffic_separation | 553 ++++-------------- map-controller/files/etc/config/mapcontroller | 2 +- 2 files changed, 123 insertions(+), 432 deletions(-) diff --git a/map-agent/files/lib/wifi/traffic_separation b/map-agent/files/lib/wifi/traffic_separation index 3bbe15822..2da23923d 100755 --- a/map-agent/files/lib/wifi/traffic_separation +++ b/map-agent/files/lib/wifi/traffic_separation @@ -2,6 +2,9 @@ . /lib/functions.sh +AL_BRIDGE=${AL_BRIDGE-"br-lan"} +PRIMARY_VID=${PRIMARY_VID-1} + ### Traffic Separation ### dbg() { @@ -9,456 +12,150 @@ dbg() { } ts_sub() { - ts_usage() { cat < - create vlan device and rules for wifi fronthaul -create bh - create vlan device and rules for wifi backhaul -create eth - create vlan device and rules for logical ethernet interface -delete - delete vlan device -populate eth - add secondary network rules for logical ethernet interface -primary get - read primary VID for interface from driver (from Association Response frame IE) -reload - reload network with new configuration +create vid - create vlan configuration with vlan_id +reload - reload network with new configuration EOF exit 1 } - _get_bridge() { - local bridge=$(ip link show $1 | grep -o "master [^\s]*" | cut -d ' ' -f 2) - echo $bridge - } + ts_create() { + _net_setup() { + local name=$1 + local vid=$2 + local proto=$3 + local dev=$4 + local port_dev=$5 - set_wireless_bridge() { - config_load wireless + [ -z "$(uci -q get network.${name})" ] || return - _set_network() { - local sec=$1 - local iface=$2 - local bridge=$3 + local ip_addr="192.168.${vid}.1" + local br_dev="${AL_BRIDGE/-/_}" + local tag=":t" - config_get ifname $sec ifname - [ "$iface" != "$ifname" ] && continue + [ "${vid}" = "${PRIMARY_VID}" ] && { + tag="" - config_get mode $sec mode - config_get multi_ap $sec multi_ap "0" - [ "$mode" = "sta" -a "$multi_ap" = "1" ] && continue + # Global options + [ -z "$(uci -q get network.${br_dev}.vlan_filtering)" ] && { + uci -q set network.${br_dev}.vlan_filtering=1; + } - config_get network $sec network - local new_network=${bridge##br-} - if [ "$new_network" != "$network" ] ; then - uci -q set wireless.${sec}.network=${new_network} - uci commit wireless + uci -q delete network.lan.proto + uci -q delete network.lan.ipaddr + uci -q delete network.lan.netmask + uci -q delete network.lan.ip6assign + } + + uci -q set network.${name}="interface" + uci -q set network.${name}.device="$dev" + uci -q set network.${name}.is_lan="1" + + if [ "$proto" = "static" ] ; then + uci -q set network.${name}.proto="static" + # TODO vid > 255 + uci -q set network.${name}.ipaddr="${ip_addr}" + uci -q set network.${name}.netmask="255.255.255.0" + uci -q set network.${name}.ip6assign '60' + else + uci -q set network.${name}.proto="dhcp" fi - brctl addif $bridge $iface &> /dev/null - } + uci -q add network bridge-vlan + uci -q set network.@bridge-vlan[-1].device="$AL_BRIDGE" + uci -q set network.@bridge-vlan[-1].vlan="$vid" - config_foreach _set_network wifi-iface ${1} ${2} - } - - ts_create() { - - _create_vlan_dev() { - iface=$1 # real iface - vid=$2 # Vlan ID - bridge=$3 # bridge iface should be connected - vlan_dev=$4 - - old_bridge="$(_get_bridge $iface)" # bridge iface is connected to - - # remove interface from bridge if it is in one - [ -n "$old_bridge" ] && brctl delif $old_bridge $iface &> /dev/null - - # (re)create vlan device - ip link show $vlan_dev && vlanctl --if-delete $vlan_dev - vlanctl --mcast --if-create-name $iface $vlan_dev --if $iface --set-if-mode-rg - - vlanctl --if $iface --tx --tags 0 --default-miss-drop - vlanctl --if $iface --tx --tags 1 --default-miss-drop - vlanctl --if $iface --tx --tags 2 --default-miss-drop - vlanctl --if $iface --rx --tags 0 --default-miss-drop - vlanctl --if $iface --rx --tags 1 --default-miss-drop - vlanctl --if $iface --rx --tags 2 --default-miss-drop - - # bring the vlan device up and add back to bridge if it was in one - brctl addif $bridge $vlan_dev &> /dev/null - } - - ts_create_fh() { - iface=$1 # fh iface - vid=$2 # SSID specific (secondary) or primary vid - bridge=$3 - - [ -n "$iface" ] && [ -n "$vid" ] && [ -n "$bridge" ] || { - cat < /dev/null # make sure this is OFF, else driver won't handle vlan - wl -i $iface down &> /dev/null - wl -i $iface map_profile $profile &> /dev/null # only has effect on profile 2 - wl -i $iface map_8021q_settings $vid &> /dev/null # can only be set on bBSS (read-only on bSTA) - wl -i $iface up &> /dev/null - } - - ts_create_lei() { - vid=$1 # primary vid - pbits=$2 # default pbits to apply - vlan_bridge=$3 # name of ts subsystem bridge - lan_bridge=$4 # name of node local bridge - - [ -n "$vid" ] && [ -n "$pbits" ] && [ -n "$vlan_bridge" ] && [ -n "$lan_bridge" ] || { - cat < /dev/null || { - ip link add link lei name lei_lan type vlan id 1 2>/dev/null - } - - old_vid=$(ip -d link show lei_lan | sed -n 's/vlan.*id \([0-9][0-9]*\) .*/\1/p') - - [ "$old_vid" != "$vid" ] && { - ip link del lei_lan - ip link add link lei name lei_lan type vlan id ${vid} - } - - brctl addif ${lan_bridge} lei_lan &>/dev/null - brctl addif ${vlan_bridge} lei_map &>/dev/null - - ip link set lei up - ip link set lei_map up - ip link set lei_lan up - } - - _create_eth() { - iface=$1 # Multi-AP Logical Ethernet Interface - vid=$2 # primary vid - bridge=$3 # name of ts subsystem bridge - pbits=0 - - [ -n "$iface" ] && [ -n "$vid" ] && [ -n "$bridge" ] || { - cat < 255 - local ip_addr="192.168.${vid}.1" - [ "${vid}" = "1" ] && ip_addr="192.168.${vid}.2" - uci -q set network.${name}.ipaddr="${ip_addr}" - uci -q set network.${name}.netmask="255.255.255.0" + _process_zone() { + local section=$1 + local new_name=$2 + local name - diff="1" - } + config_get name $section name - [ "$diff" = "1" ] && uci -q commit network + [ "$name" == "$new_name" ] && zone_exist=1 } - _br_setup() { - local name=$1 - local sinkname=$2 - local vid=$3 + config_foreach _process_zone zone $name - [ -z "$(uci -q get network.${name}_dev)" ] && { - uci -q set network.${name}_dev="device" - uci -q set network.${name}_dev.name="br-${name}" - uci -q set network.${name}_dev.type="bridge" - uci -q set network.${name}_dev.bridge_empty="1" - uci -q add_list network.${name}_dev.ports="${sinkname}" + [ "$zone_exist" != "0" ] && return - diff="1" - } + uci -q add firewall zone + uci -q set firewall.@zone[-1].name="$name" + uci -q add_list firewall.@zone[-1].network="$network" + uci -q set firewall.@zone[-1].input='ACCEPT' + uci -q set firewall.@zone[-1].output='ACCEPT' + uci -q set firewall.@zone[-1].forward='ACCEPT' - [ -z "$(uci -q get network.${name})" ] && { - uci -q set network.${name}="interface" - uci -q set network.${name}.device="br-${name}" - uci -q set network.${name}.is_lan="1" - uci -q set network.${name}.proto="static" - uci -q set network.${name}.ipaddr="192.168.${vid}.1" - uci -q set network.${name}.netmask="255.255.255.0" + uci -q add firewall forwarding + uci -q set firewall.@forwarding[-1].src="$name" + uci -q set firewall.@forwarding[-1].dest="wan" - diff="1" - } - - [ "$diff" = "1" ] && uci -q commit network - } - - _dhcp_setup() { - local name=$1 - - [ -n "$(uci -q get dhcp.${name})" ] && return - - uci -q set dhcp.${name}=dhcp - uci -q set dhcp.${name}.interface="${name}" - uci -q set dhcp.${name}.start="100" - uci -q set dhcp.${name}.limit="150" - uci -q set dhcp.${name}.leasetime="1h" - uci -q set dhcp.${name}.dhcpv4="server" - uci -q set dhcp.${name}.dhcpv6="server" - uci -q set dhcp.${name}.ra="server" - uci -q set dhcp.${name}.ra_slaac="1" - uci -q add_list dhcp.${name}.ra_flags="managed-config" - uci -q add_list dhcp.${name}.ra_flags="other-config" - - diff="1" - uci -q commit dhcp - } - - _firewall_setup() { - local name=$1 - local network=$2 - local zone_exist=0 - - config_load firewall - - _process_zone() { - local section=$1 - local new_name=$2 - local name - - config_get name $section name - - [ "$name" == "$new_name" ] && zone_exist=1 - } - - config_foreach _process_zone zone $name - - [ "$zone_exist" != "0" ] && return - - uci -q add firewall zone - uci -q set firewall.@zone[-1].name="$name" - uci -q add_list firewall.@zone[-1].network="$network" - uci -q set firewall.@zone[-1].input='ACCEPT' - uci -q set firewall.@zone[-1].output='ACCEPT' - uci -q set firewall.@zone[-1].forward='ACCEPT' - - uci -q add firewall forwarding - uci -q set firewall.@forwarding[-1].src="$name" - uci -q set firewall.@forwarding[-1].dest="wan" - - diff="1" - uci -q commit firewall - } - - vid=$1 # primary vid - - [ -n "$vid" ] || { - cat < /dev/null + uci -q commit firewall } - local type=$1 - shift + vid=$1 # primary vid - case "$type" in - fh) ts_create_fh $@;; - bh) ts_create_bh $@;; - lei) ts_create_lei $@;; - eths) ts_create_eths $@;; - dhcp) ts_create_dhcp $@;; - --help|help) ts_usage;; - *) ts_usage; exit 1;; - esac - } - - ts_delete() { - iface=$1 - - path=$(ls -d /sys/class/net/${iface}/upper_*) - [ -z "$path" ] && exit 0 - - vlan_dev=${path##*upper_} - bridge="$(_get_bridge $vlan_dev)" - - [ -n "$bridge" ] && { - vlanctl --if-delete $vlan_dev # note: also removes rules and removes from bridge - brctl addif $bridge $iface &> /dev/null # needed to add again - } - - } - - ts_populate() { - local type=$1 - shift - - [ "$type" == "eth" ] || { + [ -n "$vid" ] || { cat < /dev/null || { + ip link add sink${vid} type veth peer name sink_peer${vid} + } - path=$(ls -d /sys/class/net/${iface}/upper_*) - [ -z "$path" ] && exit 1 - vlan_dev=${path##*upper_} + ip link set sink${vid} up + ip link set sink_peer${vid} up - # add rules - #vlanctl --if $iface --rx --tags 1 --filter-vid $vid 0 --set-rxif $vlan_dev --rule-append # note: retain secondary vids - #vlanctl --if $iface --tx --tags 1 --filter-vid $vid 0 --filter-txif $vlan_dev --rule-append # note: already default - } + proto="dhcp" + [ -x "/usr/sbin/mapcontroller" ] && proto="static" ; + _net_setup "vlan${vid}" ${vid} ${proto} "sink${vid}" "sink_peer${vid}" - ts_primary() { - local func=$1 - shift - - case "$func" in - get) vid=$(wl -i $1 map_8021q_settings); echo ${vid##* };; - *) ts_usage; exit 1;; - esac - } - - ts_unicast() { - local mac=$1 - local iface=$2 - - # TODO: improve? - res=$(ebtables -t broute -L | grep -i "$mac" | grep "$iface") - [ -n "$res" ] && return - - ebtables -t broute -D BROUTING -d "$mac" -p 0x893a -j DROP - ebtables -t broute -I BROUTING -i "$iface" -d "$mac" -p 0x893a -j DROP - } - - ts_multicast() { - local iface=$1 - - # TODO: improve? - res=$(ebtables -t broute -L | grep -i "1:80:C2:00:00:13" | grep "$iface") - [ -n "$res" ] && return - - ebtables -t broute -D BROUTING -d 01:80:C2:00:00:13 -p 0x893a -j DROP - ebtables -t broute -D BROUTING -i "$iface" -d 01:80:C2:00:00:13 -p 0x893a -j DROP - ebtables -t broute -I BROUTING -i "$iface" -d 01:80:C2:00:00:13 -p 0x893a -j DROP + [ -x "/usr/sbin/mapcontroller" ] && _dhcp_setup vlan${vid} + #_firewall_setup vlan${vid} sink${vid} } ts_reload() { @@ -466,32 +163,31 @@ EOF # workaround for missing backhaul wifi.ap.* ubus obj's: # iterate in config and setup bh - config_load wireless +# config_load wireless - _setup_bh_iface() { - local sec=$1 - local iface=$2 - local bridge=$3 +# _setup_bh_iface() { +# local sec=$1 +# local iface=$2 +# local bridge=$3 - config_get ifname $sec ifname +# config_get ifname $sec ifname - config_get mode $sec mode - config_get multi_ap $sec multi_ap "0" - [ "$mode" = "ap" -a "$multi_ap" = "1" ] && { - ts_create bh $ifname 1 2 br-map - } - } +# config_get mode $sec mode +# config_get multi_ap $sec multi_ap "0" +# [ "$mode" = "ap" -a "$multi_ap" = "1" ] && { +# ts_create bh $ifname 1 2 br-map +# } + #} - config_foreach _setup_bh_iface wifi-iface +# config_foreach _setup_bh_iface wifi-iface [ -n "dhcp_reload" ] && /etc/init.d/dnsmasq reload + /etc/init.d/network reload - # another workaround for netif? removed - # sink devices for br-map bridge - for sink in $(ubus list network.interface.sink*) ; do - local sink_vlan=${sink/network.interface./}_vlan - brctl addif br-map $sink_vlan &> /dev/null - done + + #for sink in $(ubus list network.interface.sink*) ; do + # local sink_vlan=${sink/network.interface./}_vlan + #done } local func=$1 @@ -499,11 +195,6 @@ EOF case "$func" in create) dbg "create $@"; ts_create $@;; - delete) dbg "delete $@"; ts_delete $@;; - populate) dbg "populate $@"; ts_populate $@;; - primary) dbg "primary $@"; ts_primary $@;; - unicast) dbg "unicast $@"; ts_unicast $@;; - multicast) dbg "multicast $@"; ts_multicast $@;; reload) dbg "reload $@"; ts_reload $@;; --help|help) ts_usage;; *) ts_usage; exit 1;; diff --git a/map-controller/files/etc/config/mapcontroller b/map-controller/files/etc/config/mapcontroller index 45933fa8b..1a5b035bd 100644 --- a/map-controller/files/etc/config/mapcontroller +++ b/map-controller/files/etc/config/mapcontroller @@ -6,7 +6,7 @@ config controller 'controller' option enable_bsta_steer '0' option use_bcn_metrics '0' option use_usta_metrics '0' - option primary_vid '1' + option primary_vid '0' option primary_pcp '0' option allow_bgdfs '0' option channel_plan '0'