From 4dd8635f6b87aa30cbece48ed8f1669b15af8390 Mon Sep 17 00:00:00 2001 From: bol-van Date: Tue, 15 Feb 2022 23:11:43 +0300 Subject: [PATCH] init: nft_fill_ifsets universal --- common/base.sh | 25 ++++++++++++++++++ common/nft.sh | 57 +++++++++++++++++++++++++++++++++++++--- init.d/openwrt/functions | 56 ++++++--------------------------------- init.d/sysv/functions | 33 ++--------------------- 4 files changed, 89 insertions(+), 82 deletions(-) diff --git a/common/base.sh b/common/base.sh index 46758a4..38ebf42 100644 --- a/common/base.sh +++ b/common/base.sh @@ -75,6 +75,11 @@ make_comma_list() shift make_separator_list $var , "$@" } +unique() +{ + local i + for i in "$@"; do echo $i; done | sort -u | xargs +} is_linked_to_busybox() { @@ -133,3 +138,23 @@ create_dev_stdin() { [ -e /dev/stdin ] || ln -s /proc/self/fd/0 /dev/stdin } + +call_for_multiple_items() +{ + # $1 - function to get an item + # $2 - variable name to put result into + # $3 - space separated parameters to function $1 + + local i item items + for i in $3; do + $1 item $i + [ -n "$item" ] && { + if [ -n "$items" ]; then + items="$items $item" + else + items="$item" + fi + } + done + eval $2=\"$items\" +} diff --git a/common/nft.sh b/common/nft.sh index 6241080..129a25e 100644 --- a/common/nft.sh +++ b/common/nft.sh @@ -119,7 +119,7 @@ nft_list_ifsets() nft list set inet $ZAPRET_NFT_TABLE lanif nft list set inet $ZAPRET_NFT_TABLE wanif nft list set inet $ZAPRET_NFT_TABLE wanif6 - nft list flowtable inet $ZAPRET_NFT_TABLE ft + nft list flowtable inet $ZAPRET_NFT_TABLE ft 2>/dev/null } nft_create_firewall() @@ -223,6 +223,57 @@ nft_filter_apply_ipset_target() nft_filter_apply_ipset_target6 $2 } + +nft_script_add_ifset_element() +{ + # $1 - set name + # $2 - space separated elements + local elements + [ -n "$2" ] && { + make_comma_list elements $2 + script="${script} +add element inet $ZAPRET_NFT_TABLE $1 { $elements }" + } +} +nft_fill_ifsets() +{ + # $1 - space separated lan interface names + # $2 - space separated wan interface names + # $3 - space separated wan6 interface names + + local script i ALLDEVS + + # if large sets exist nft works very ineffectively + # looks like it analyzes the whole table blob to find required data pieces + # calling all in one shot helps not to waste cpu time many times + + script="flush set inet $ZAPRET_NFT_TABLE wanif +flush set inet $ZAPRET_NFT_TABLE wanif6 +flush set inet $ZAPRET_NFT_TABLE lanif" + + [ "$DISABLE_IPV4" = "1" ] || nft_script_add_ifset_element wanif "$2" + [ "$DISABLE_IPV6" = "1" ] || nft_script_add_ifset_element wanif6 "$3" + nft_script_add_ifset_element lanif "$1" + + echo "$script" | nft -f - + + case "$FLOWOFFLOAD" in + software) + ALLDEVS=$(unique $1 $2 $3) + nft_create_or_update_flowtable '' $ALLDEVS + ;; + hardware) + ALLDEVS=$(unique $1 $2 $3) + # first create unbound flowtable. may cause error in older nft version + nft_create_or_update_flowtable 'offload' 2>/dev/null + # then add elements. some of them can cause error because unsupported + for i in $ALLDEVS; do + nft_hw_offload_supported $i && nft_create_or_update_flowtable 'offload' $i + done + ;; + esac +} + nft_only() { linux_fwtype @@ -236,7 +287,7 @@ nft_only() zapret_reload_ifsets() { - nft_only nft_create_table ; nft_fill_ifsets + nft_only nft_create_table ; nft_fill_ifsets_overload return 0 } zapret_list_ifsets() @@ -264,7 +315,7 @@ zapret_apply_firewall_nft() create_ipset no-update nft_create_firewall - nft_fill_ifsets + nft_fill_ifsets_overload case "$mode" in tpws) diff --git a/init.d/openwrt/functions b/init.d/openwrt/functions index e7a8b32..6079ec6 100644 --- a/init.d/openwrt/functions +++ b/init.d/openwrt/functions @@ -384,59 +384,19 @@ flow_offloading_unexempt() } - -nft_fill_ifsets() +nft_fill_ifsets_overload() { - local script elements i wan_iface DEVICE DLAN DWAN DWAN6 ALLDEVS flags + local script ifaces DLAN DWAN DWAN6 - # if large sets exist nft works very ineffectively - # looks like it analyzes the whole table blob to find required data pieces - # calling all in one shot helps not to waste cpu time many times + call_for_multiple_items network_get_device DLAN "$OPENWRT_LAN" - script="flush set inet $ZAPRET_NFT_TABLE wanif -flush set inet $ZAPRET_NFT_TABLE wanif6 -flush set inet $ZAPRET_NFT_TABLE lanif" + network_find_wan_all ifaces + call_for_multiple_items network_get_device DWAN "$ifaces" - [ "$DISABLE_IPV4" = "1" ] || { - network_find_wan_all wan_iface - for i in $wan_iface; do - network_get_device DEVICE $i - DWAN="$DWAN $DEVICE" - done - [ -n "$DWAN" ] && { - make_comma_list elements $DWAN - script="${script} -add element inet $ZAPRET_NFT_TABLE wanif { $elements }" - } - } - [ "$DISABLE_IPV6" = "1" ] || { - network_find_wan6_all wan_iface - for i in $wan_iface; do - network_get_device DEVICE $i - DWAN6="$DWAN6 $DEVICE" - done - [ -n "$DWAN6" ] && { - make_comma_list elements $DWAN6 - script="${script} -add element inet $ZAPRET_NFT_TABLE wanif6 { $elements }" - } - } - for i in $OPENWRT_LAN; do - network_get_device DEVICE $i - DLAN="$DLAN $DEVICE" - done - [ -n "$DLAN" ] && { - make_comma_list elements $DLAN - script="${script} -add element inet $ZAPRET_NFT_TABLE lanif { $elements }" - } - echo "$script" | nft -f - + network_find_wan6_all ifaces + call_for_multiple_items network_get_device DWAN6 "$ifaces" - [ "$FLOWOFFLOAD" = 'software' -o "$FLOWOFFLOAD" = 'hardware' ] && { - ALLDEVS=$(for i in $DLAN $DWAN $DWAN6; do echo $i; done | sort -u | xargs) - [ "$FLOWOFFLOAD" = 'hardware' ] && nft_hw_offload_supported $ALLDEVS && flags=offload - nft_create_or_update_flowtable "$flags" $ALLDEVS - } + nft_fill_ifsets "$DLAN" "$DWAN" "$DWAN6" } nft_fw_tpws4() diff --git a/init.d/sysv/functions b/init.d/sysv/functions index 7566a44..c8d2143 100644 --- a/init.d/sysv/functions +++ b/init.d/sysv/functions @@ -521,38 +521,9 @@ zapret_stop_daemons() } -nft_fill_ifsets() +nft_fill_ifsets_overload() { - local script elements i ALLDEVS flags - - # if large sets exist nft works very ineffectively - # looks like it analyzes the whole table blob to find required data pieces - # calling all in one shot helps not to waste cpu time many times - - script="flush set inet $ZAPRET_NFT_TABLE wanif -flush set inet $ZAPRET_NFT_TABLE wanif6 -flush set inet $ZAPRET_NFT_TABLE lanif" - - [ -n "$IFACE_LAN" ] && { - make_comma_list elements $IFACE_LAN - script="${script} -add element inet $ZAPRET_NFT_TABLE lanif { $elements }" - } - [ -n "$IFACE_WAN" ] && { - make_comma_list elements $IFACE_WAN - script="${script} -add element inet $ZAPRET_NFT_TABLE wanif { $elements } -add element inet $ZAPRET_NFT_TABLE wanif6 { $elements }" - } - echo "$script" | nft -f - - - [ "$FLOWOFFLOAD" = 'software' -o "$FLOWOFFLOAD" = 'hardware' ] && { - ALLDEVS=$(for i in $IFACE_LAN $IFACE_WAN; do echo $i; done | sort -u | xargs) - [ -n "$ALLDEVS" ] && { - [ "$FLOWOFFLOAD" = 'hardware' ] && nft_hw_offload_supported $ALLDEVS && flags=offload - nft_create_or_update_flowtable "$flags" $ALLDEVS - } - } + nft_fill_ifsets "$IFACE_LAN" "$IFACE_WAN" "$IFACE_WAN" } nft_print_op()