Currently, for every address one table is created when using nftables.
This is not neccessary, so split out the common table rules in one
single table and add the per address rules to it subsequently.

Signed-off-by: Julian Wollrath <[email protected]>
---
 src/wg-quick/linux.bash | 33 ++++++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/src/wg-quick/linux.bash b/src/wg-quick/linux.bash
index e4d4c4f..f5bed66 100755
--- a/src/wg-quick/linux.bash
+++ b/src/wg-quick/linux.bash
@@ -209,6 +209,26 @@ remove_firewall() {
 }

 HAVE_SET_FIREWALL=0
+HAS_NFT_SKELETON=0
+add_nft_skeleton() {
+       [[ HAS_NFT_SKELETON -eq 0 ]] || return 0
+
+       local table
+       if ! get_fwmark table; then
+               table=51820
+       fi
+
+       local nftable="wg-quick-$INTERFACE" nftcmd pf=inet
+       printf -v nftcmd '%sadd table inet %s\n' "$nftcmd" "$nftable"
+       printf -v nftcmd '%sadd chain inet %s preraw { type filter hook 
prerouting priority -300; }\n' "$nftcmd" "$nftable"
+       printf -v nftcmd '%sadd chain inet %s premangle { type filter hook 
prerouting priority -150; }\n' "$nftcmd" "$nftable"
+       printf -v nftcmd '%sadd chain inet %s postmangle { type filter hook 
postrouting priority -150; }\n' "$nftcmd" "$nftable"
+       printf -v nftcmd '%sadd rule inet %s postmangle meta l4proto udp mark 
%d ct mark set mark \n' "$nftcmd" "$nftable" $table
+       printf -v nftcmd '%sadd rule inet %s premangle meta l4proto udp meta 
mark set ct mark \n' "$nftcmd" "$nftable"
+       cmd nft -f <(echo -n "$nftcmd")
+       HAS_NFT_SKELETON=1
+}
+
 add_default() {
        local table line
        if ! get_fwmark table; then
@@ -225,18 +245,12 @@ add_default() {
        cmd ip $proto rule add table main suppress_prefixlength 0

        local marker="-m comment --comment \"wg-quick(8) rule for $INTERFACE\"" 
restore=$'*raw\n' nftable="wg-quick-$INTERFACE" nftcmd
-       printf -v nftcmd '%sadd table %s %s\n' "$nftcmd" "$pf" "$nftable"
-       printf -v nftcmd '%sadd chain %s %s preraw { type filter hook 
prerouting priority -300; }\n' "$nftcmd" "$pf" "$nftable"
-       printf -v nftcmd '%sadd chain %s %s premangle { type filter hook 
prerouting priority -150; }\n' "$nftcmd" "$pf" "$nftable"
-       printf -v nftcmd '%sadd chain %s %s postmangle { type filter hook 
postrouting priority -150; }\n' "$nftcmd" "$pf" "$nftable"
        while read -r line; do
                [[ $line =~ .*inet6?\ ([0-9a-f:.]+)/[0-9]+.* ]] || continue
                printf -v restore '%s-I PREROUTING ! -i %s -d %s -m addrtype ! 
--src-type LOCAL -j DROP %s\n' "$restore" "$INTERFACE" "${BASH_REMATCH[1]}" 
"$marker"
-               printf -v nftcmd '%sadd rule %s %s preraw iifname != "%s" %s 
daddr %s fib saddr type != local drop\n' "$nftcmd" "$pf" "$nftable" 
"$INTERFACE" "$pf" "${BASH_REMATCH[1]}"
+               printf -v nftcmd '%sadd rule inet %s preraw iifname != "%s" %s 
daddr %s fib saddr type != local drop\n' "$nftcmd" "$nftable" "$INTERFACE" 
"$pf" "${BASH_REMATCH[1]}"
        done < <(ip -o $proto addr show dev "$INTERFACE" 2>/dev/null)
        printf -v restore '%sCOMMIT\n*mangle\n-I POSTROUTING -m mark --mark %d 
-p udp -j CONNMARK --save-mark %s\n-I PREROUTING -p udp -j CONNMARK 
--restore-mark %s\nCOMMIT\n' "$restore" $table "$marker" "$marker"
-       printf -v nftcmd '%sadd rule %s %s postmangle meta l4proto udp mark %d 
ct mark set mark \n' "$nftcmd" "$pf" "$nftable" $table
-       printf -v nftcmd '%sadd rule %s %s premangle meta l4proto udp meta mark 
set ct mark \n' "$nftcmd" "$pf" "$nftable"
        [[ $proto == -4 ]] && cmd sysctl -q net.ipv4.conf.all.src_valid_mark=1
        if type -p nft >/dev/null; then
                cmd nft -f <(echo -n "$nftcmd")
@@ -336,6 +350,11 @@ cmd_up() {
        set_mtu_up
        set_dns
        for i in $(while read -r _ i; do for i in $i; do [[ $i =~ 
^[0-9a-z:.]+/[0-9]+$ ]] && echo "$i"; done; done < <(wg show "$INTERFACE" 
allowed-ips) | sort -nr -k 2 -t /); do
+               if type -p nft >/dev/null; then
+                       if [[ $TABLE -eq auto && $i == */0 ]]; then
+                               add_nft_skeleton
+                       fi
+               fi
                add_route "$i"
        done
        execute_hooks "${POST_UP[@]}"
--
2.28.0.rc0

Reply via email to