Skip to content

Instantly share code, notes, and snippets.

@gaoyifan
Created September 24, 2018 10:20
Show Gist options
  • Save gaoyifan/6c4457ff78184a8f5204ee5d6d58bddd to your computer and use it in GitHub Desktop.
Save gaoyifan/6c4457ff78184a8f5204ee5d6d58bddd to your computer and use it in GitHub Desktop.
Traffic control mark with nftables
#! /usr/sbin/nft -f
chain tc-wan {
# check default priority
mark & 0xff0 == 0x130 ip dscp set af22 return
# real-time application
## Dota2
udp dport 27000-27200 \
meta mark set mark & 0xfffff00f ^ 0x110 ip dscp set af41 return
## ICMP
ip protocol icmp \
meta mark set mark & 0xfffff00f ^ 0x110 ip dscp set af41 return
## TCP low-flow
meter wan-11-tcp { tcp sport . ip saddr timeout 10s limit rate 8 kbytes/second burst 16 kbytes } \
meta mark set mark & 0xfffff00f ^ 0x110 ip dscp set af42 return
## UDP low-flow
meter wan-11-udp { udp sport . ip saddr timeout 10s limit rate 8 kbytes/second burst 16 kbytes } \
meta mark set mark & 0xfffff00f ^ 0x110 ip dscp set af42 return
# TCP midium-flow
meter wan-12 { tcp sport . ip saddr timeout 3s limit rate 64 kbytes/second burst 512 kbytes } \
meta mark set mark & 0xfffff00f ^ 0x120 ip dscp set af31 return
# TCP high-flow & UDP {midium,high}-flow (default)
meta mark set mark & 0xfffff00f ^ 0x130 ip dscp set af22
}
chain tc-lan {
# check default priority
mark & 0xff0 == 0x130 ip dscp set af23 return
# internal traffic
ip saddr $lan_subnet \
meta mark set mark & 0xfffff00f ^ 0x200 ip dscp set af21 return
# real-time application
## Dota2
udp sport 27000-27200 \
meta mark set mark & 0xfffff00f ^ 0x110 ip dscp set af41 return
## ICMP
ip protocol icmp \
meta mark set mark & 0xfffff00f ^ 0x110 ip dscp set af41 return
## TCP low-flow
mark & 0xff0 != 0x120 \
meter lan-11-tcp { tcp dport . ip daddr timeout 10s limit rate 16 kbytes/second burst 32 kbytes } \
meta mark set mark & 0xfffff00f ^ 0x110 ip dscp set af42 return
## UDP low-flow
mark & 0xff0 != 0x120 \
meter lan-11-udp { udp dport . ip daddr timeout 10s limit rate 16 kbytes/second burst 32 kbytes } \
meta mark set mark & 0xfffff00f ^ 0x110 ip dscp set af42 return
# TCP midium-flow
meter lan-12 { tcp dport . ip daddr timeout 3s limit rate 512 kbytes/second burst 2 mbytes } \
meta mark set mark & 0xfffff00f ^ 0x120 ip dscp set af31 return
# TCP high-flow & UDP {midium,high}-flow (default)
meta mark set mark & 0xfffff00f ^ 0x130 ip dscp set af23
}
@adonespitogo
Copy link

Hi I'm just starting to learn packet filtering using nftables. Do you have good references or links to a good nftables documentation?

@gaoyifan
Copy link
Author

The Official nftables Wiki (https://wiki.nftables.org/) is the best starting point for learning nftables. It contains detailed explanations, examples, and tutorials.
However, nftables has numerous undocumented features and limitations, making it necessary to read the source code. This can make learning advanced nftables quite challenging and painful.

@adonespitogo
Copy link

adonespitogo commented Mar 17, 2023

Thanks for the response. I guess I'll have to make do what the nftables wiki documentation has provided. What I'm struggling to do right now is implement the ingress rate limit in the lan interface. It can be done using tc filter and ifb interface but as much as possible I'd like to use nftables implementation for future-proofing.

@gaoyifan
Copy link
Author

I believe nftables has a fundamental limitation when it comes to traffic shaping, specifically the lack of a queueing mechanism, like RED. While nftables can handle basic rate limiting, it falls short when it comes to advanced limitations. In my opinion, using tc for rate limiting is both more clear and more powerful than relying on nftables.
However, I still encourage you to learn nftables, as it can work in conjunction with tc to tackle more complex scenarios.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment