NFtables and QoS in 2021

ok good i will test in 10 min on hap ac2

for see

thanks for all

ok I must have done something wrong, I have no internet when I deactivate the firewall I did the following

Capture d’écran 2021-11-15 à 22.17.27
Capture d’écran 2021-11-15 à 22.17.05
maybe interface br-lan

and wan eth1 on my hap ac2

on my belkin i has wan on wan and br-lan lan

Perhaps follow the wiki first to enable nftables.

3 Likes

Yes, It looks like you need to install related packages. Let's figure out what those are, and then I'll stick it in the README. Nice find @dave14305 I'll put that in the README as well

Ok I pushed the very basic README

1 Like

ok i has this error

/etc/nftables.conf:109:44-44: Error: syntax error, unexpected '$', expecting string or quoted string or string with a trailing asterisk
            type filter hook ingress device $wan priority 0;
                                            ^

Capture d’écran 2021-11-15 à 22.37.31

Sounds similar to previous errors with variables:

1 Like

right, I pushed a "fix" but this "fix" means you have to go in an explicitly change the name of the ingress interface in the ingress chain...

OK, I added commentary in the README about how to do this stuff.

1 Like

Since snapshot is on nftables 1.0, wouldn’t this commit be applicable?

http://git.netfilter.org/nftables/commit/?id=d100e2d811749bf34bb6aeac322052c56661c124

`root@OpenWrt:~# nft -f /etc/nftables.conf
/etc/nftables.conf:109:29-35: Error: The inet family does not support this hook
            type filter hook ingress device eth1 priority 0; ## FIXME, this can't be a variable so put your WAN device here
                             ^^^^^^^
root@OpenWrt:~# nft -f /etc/nftables.conf
/etc/nftables.conf:109:29-32: Error: unknown chain hook
            type filter hook eth1 device eth1 priority 0; ## FIXME, this can't be a variable so put your WAN device here
                             ^^^^
root@OpenWrt:~# nft -f /etc/nftables.conf
/etc/nftables.conf:109:29-32: Error: unknown chain hook
            type filter hook eth1 device WAN priority 0; ## FIXME, this can't be a variable so put your WAN device here
                             ^^^^
root@OpenWrt:~# nft -f /etc/nftables.conf
/etc/nftables.conf:109:29-31: Error: unknown chain hook
            type filter hook WAN device eth1 priority 0; ## FIXME, this can't be a variable so put your WAN device here
                             ^^^
root@OpenWrt:~# nft -f /etc/nftables.conf
/etc/nftables.conf:109:29-31: Error: unknown chain hook
            type filter hook wan device eth1 priority 0; ## FIXME, this can't be a variable so put your WAN device here
                             ^^^
root@OpenWrt:~#
`

i can install snapshot if you want maybe for that this error ? 

![Capture d’écran 2021-11-15 à 23.00.05|182x286](upload://4s54MM39GJrGHc2UW6HXqgMlIMS.png)

Capture d’écran 2021-11-15 à 23.00.05

for the moment i has install this packages

nftables 

opkg update 

opkg install kmod-nf-conntrack kmod-nf-conntrack6 kmod-nf-nat kmod-nf-reject kmod-nf-reject6 kmod-nfnetlink kmod-nft-core kmod-nft-nat

opkg instal kmod-nft-arp kmod-nft-bridge kmod-nft-fib kmod-nft-nat6 kmod-nft-netdev kmod-nft-offload

opkg install nftables libnftnl11

hmmm ... let's start without an ingress hook and just do postrouting ... so comment out like this:

      # chain wanin {
      # 	    type filter hook ingress device eth1 priority 0; ## FIXME, this can't be a variable so put your WAN device here
      # 	    jump tagchain
      # }

1 Like

ok so i has lost interface luci

and no internet ...

i write while my box fai

i has this no error apparently

root@OpenWrt:~# nft -f /etc/nftables.conf
root@OpenWrt:~#

you might need to explicitly load the NAT module!

modprobe nf_nat

maybe, or modprobe nft_masq or both.

1 Like

Ok in putty ?

I run this command ?

Modprobe nf_nat

yes, we'll figure out how to get it auto-loaded later

modprobe nf_nat
modprobe nft_masq
modprobe nft_chain_nat

I'm just guessing here based on what's loaded on my desktop.

You can put those commands before the nft command in rc.local

Not sure because I don't have an openwrt device available right now, but it might be enough to list those modules in /etc/modules

1 Like

No Always not

My router renew each every 3 secondes the new dhcp at my pc

But i has access to putty and winscp

ok is good now :wink: i has changed my name of interface !

firewall is disabled i has access to internet

my firewall is empty

i has put the script like this


## this assumes eth0 is LAN and eth1 is WAN, modify as needed

flush ruleset

## change these

define wan = eth1
define lan = br-lan
define guest = eth0.10 # or remove these if you don't use guest or iot networks
define iot = eth0.5 ## but be sure to also remove the reference to them below

define bulksize = 35000000 ## total transfer before being sent to CS1
define voipservers = {10.0.98.113} ## add ipv4 addresses of fixed voip / telephone servers you use here

table inet filter {
	chain input {
		type filter hook input priority 0; policy drop;

		# established/related connections
		ct state established,related accept

		# loopback interface
		iifname lo accept

		## icmpv6 is a critical part of the protocol, we just
		## accept everything, you can lookin to making this
		## more restrictive but be careful
		ip6 nexthdr icmpv6 accept

		# we are more restrictive for ipv4 icmp
		ip protocol icmp icmp type { destination-unreachable, router-solicitation, router-advertisement, time-exceeded, parameter-problem } accept

		ip protocol igmp accept

		ip protocol icmp meta iifname $lan accept

		## ntp protocol accept from LAN
		udp dport ntp iifname $lan accept

		## DHCP accept
		iifname $lan ip protocol udp udp sport bootpc udp dport bootps log prefix "FIREWALL ACCEPT DHCP: " accept

		## DHCPv6 accept from LAN
		iifname $lan udp sport dhcpv6-client udp dport dhcpv6-server accept

		## allow dhcpv6 from router to ISP
		iifname $wan udp sport dhcpv6-server udp dport dhcpv6-client accept

		# SSH (port 22), limited to 10 connections per minute per source host,
		# you might prefer to not allow this from WAN for
		# OpenWrt, in which case you should also add an
		# iifname $lan filter in the front so we're only
		# allowing from LAN
		
		ct state new tcp dport ssh meter ssh-meter4 {ip saddr limit rate 10/minute burst 15 packets} accept
		ct state new ip6 nexthdr tcp tcp dport ssh meter ssh-meter6 {ip6 saddr limit rate 10/minute burst 15 packets} accept 

		## allow access to LUCI from LAN
		iifname $lan tcp dport {http,https} accept

		## DNS for main LAN, we limit the rates allowed from each LAN host to reduce chance of denial of service
		iifname $lan udp dport domain meter dommeter4 { ip saddr limit rate 240/minute burst 240 packets} accept
		iifname $lan udp dport domain meter dommeter6 { ip6 saddr limit rate 240/minute burst 240 packets} accept

		iifname $lan tcp dport domain meter dommeter4tcp { ip saddr limit rate 240/minute burst 240 packets} accept
		iifname $lan tcp dport domain meter dommeter6tcp { ip6 saddr limit rate 240/minute burst 240 packets} accept

		## allow remote syslog input? you might want this, or remove this
		
		# iifname $lan udp dport 514 accept

		counter log prefix "FIREWALL INPUT DROP: " drop
	}

	chain forward {
	    type filter hook forward priority 0; policy drop;

	    ct state established,related accept

	    iifname lo accept
	    iifname {$guest,$iot} oifname $lan drop ## guests can't connect to LAN
	    iifname {$lan,$guest,$iot} oifname $wan accept ## allow inside to forward to WAN

	    counter log prefix "FIREWALL FAIL FORWARDING: " drop
	}
}

## masquerading for ipv4 output on WAN
table ip masq {
	chain masqout {
	    type nat hook postrouting priority 0; policy accept;
	    oifname $wan masquerade

	}

	## this empty table is required to make the kernel do the unmasquerading
	chain masqin {
	    type nat hook prerouting priority 0; policy accept;

	}
	
}

## lets create a tagger table

table inet tags {
      #chain wanin {
      #	    type filter hook eth1 device eth1 priority 0; ## FIXME, this can't be a variable so put your WAN device here
		# jump tagchain
      #}

      chain tagrouted {
      	    type filter hook postrouting priority 0; policy accept;
	    jump cttags
      }


      chain cttags {
	    ip protocol tcp tcp sport != {2049} ip dscp < af41 ct bytes ge $bulksize ip dscp set cs1
            ip6 nexthdr tcp tcp sport != {2049} ip6 dscp < af41 ct bytes ge $bulksize ip6 dscp set cs1
  	    ip protocol udp ip dscp < cs5 udp dport != {http,https,domain} udp sport != {http,https,domain} meter udp4meter {ip saddr . ip daddr . udp sport . udp dport limit rate over 200/second burst 100 packets } counter ct mark set 0x55
            ip6 nexthdr udp ip6 dscp < cs5 udp dport != {http,https,domain} udp sport != {http,https,domain} meter udp6meter {ip6 saddr . ip6 daddr . udp sport . udp dport limit rate over 200/second burst 100 packets } counter ct mark set 0x55

            ct mark 0x55 numgen random mod 10000 < 5 ct mark set 0x00 comment "small probability to unmark over-threshold connections"

## prioritize small packet udp flows on any ports:
            ct mark != 0x55 ip protocol udp ip dscp < cs5 udp dport != {http,https,domain} udp sport != {http,https, domain} ct avgpkt 0-450 counter ip dscp set cs5
            ct mark != 0x55 ip6 nexthdr udp ip6 dscp < cs5 udp dport != {http,https,domain} udp sport != {http,https,domain} ct avgpkt 0-450 counter ip6 dscp set cs5
	    jump tagchain
      }

      chain tagchain {


	    ## VOIP servers UDP traffic
            ip saddr $voipservers ip protocol udp ip dscp set cs6
            ip daddr $voipservers ip protocol udp ip dscp set cs6

	    ## tag UDP that stays below 200pps and 450 bytes per packet to CS5 priority

            ## udp flows that have more than 200 packets per second get marked 0x55, then non 0x55 flows
            ## with avg packetsize less than 450 bytes get marked cs5
          
	  #playstation network port
	  udp dport 3478-3479 ip dscp set cs5
	  udp dport 3478-3479 ip6 dscp set cs5
	  udp sport 3478-3479 ip dscp set cs5
	  udp sport 3478-3479 ip6 dscp set cs5

          # minecraft java edition source
          tcp sport 25565 ip dscp set cs5
          tcp sport 25565 ip6 dscp set cs5

          # minecraft java edition dest
          tcp dport 25565 ip dscp set cs5
          tcp dport 25565 ip6 dscp set cs5

          # jitsi meet:
          udp sport 10000 ip dscp set af41
          udp dport 10000 ip dscp set af41
          # zoom udp
          udp sport {3478,3479,8801-8810} ip dscp set af41
          udp dport {3478,3479,8801-8810} ip dscp set af41


      }
      
}

Good it sounds like you got it working at the basic level. Try playing a game and do a packet capture on br-lan and see if the game packets from the internet get tagged because they are UDP that doesn't send too fast. (the ones from your game machine won't appear tagged because you capture them before the tagging happens)

1 Like

ok with wireshark then?

I have the mirroring port on hap ac2 I will configure it

mirrot source port lan2 my pc

mirror monitor port lan 4 my console game ?

hmmm I think mirror source port your CPU, mirror monitor port your PC, that means everything your CPU sends to the switch will get mirrored to your PC so you can see what's going on from your PC.

Also it looks like inet ingress is in kernel 5.10 and later: https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains so we will need to do something else for ingress, but we don't need ingress if we use Cake on egress of WAN and egress of LAN and don't use IFB

1 Like

ok so do you want configure cake and i has an idea i will add port in script like this you think ?

#call of duty  port
	  udp dport 3074 ip dscp set cs5
	  udp dport 3074 ip6 dscp set cs5
	  udp sport 3074 ip dscp set cs5
	  udp sport 3074 ip6 dscp set cs5

just a suggestion

i cofnigure sqm just like that ?

config queue 'eth1'
	option interface 'eth1'
	option qdisc 'cake'
	option script 'piece_of_cake.qos'
	option enabled '1'
	option download '56000'
	option upload '3200'
	option debug_logging '0'
	option verbosity '5'
	option linklayer 'ethernet'
	option overhead '44'

or like this ?

config queue 'eth1'
	option interface 'eth1'
	option qdisc 'cake'
	option script 'piece_of_cake.qos'
	option enabled '1'
	option upload '3200'
	option debug_logging '0'
	option verbosity '5'
	option linklayer 'ethernet'
	option overhead '44'
	option download '0'

config queue
	option enabled '1'
	option interface 'br-lan'
	option download '0'
	option upload '56000'
	option debug_logging '0'
	option verbosity '5'
	option qdisc 'cake'
	option script 'piece_of_cake.qos'
	option linklayer 'ethernet'
	option overhead '44'

So i'm modérate nat in my games is normal ?? @dlakelan

Maybe has a not firewall

I suggest to add all the game ports you think are relevant into a set and handle them all at once:

define gameports = {1234,3898,2924,15002} ## or whatever
....


	  udp dport $gameports ip dscp set cs5
	  udp dport $gameports ip6 dscp set cs5
	   udp sport $gameports ip dscp set cs5
	  udp sport $gameports ip6 dscp set cs5

In SQM config, I suggest to use layer_cake and diffserv4, and two queues, one on wan and one one br-lan

2 Likes