diff options
Diffstat (limited to '')
-rw-r--r-- | doc/payload-expression.txt | 973 |
1 files changed, 973 insertions, 0 deletions
diff --git a/doc/payload-expression.txt b/doc/payload-expression.txt new file mode 100644 index 0000000..c7c267d --- /dev/null +++ b/doc/payload-expression.txt @@ -0,0 +1,973 @@ +ETHERNET HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~~~~~ +[verse] +*ether* {*daddr* | *saddr* | *type*} + +.Ethernet header expression types +[options="header"] +|================== +|Keyword| Description| Type +|daddr| +Destination MAC address| +ether_addr +|saddr| +Source MAC address| +ether_addr +|type| +EtherType| +ether_type +|================== + +VLAN HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~ +[verse] +*vlan* {*id* | *dei* | *pcp* | *type*} + +The vlan expression is used to match on the vlan header fields. +This expression will not work in the *ip*, *ip6* and *inet* families, +unless the vlan interface is configured with the *reorder_hdr off* setting. +The default is *reorder_hdr on* which will automatically remove the vlan tag +from the packet. See ip-link(8) for more information. +For these families its easier to match the vlan interface name +instead, using the *meta iif* or *meta iifname* expression. + +.VLAN header expression +[options="header"] +|================== +|Keyword| Description| Type +|id| +VLAN ID (VID) | +integer (12 bit) +|dei| +Drop Eligible Indicator| +integer (1 bit) +|pcp| +Priority code point| +integer (3 bit) +|type| +EtherType| +ether_type +|================== + +ARP HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~ +[verse] +*arp* {*htype* | *ptype* | *hlen* | *plen* | *operation* | *saddr* { *ip* | *ether* } | *daddr* { *ip* | *ether* } + +.ARP header expression +[options="header"] +|================== +|Keyword| Description| Type +|htype| +ARP hardware type| +integer (16 bit) +|ptype| +EtherType| +ether_type +|hlen| +Hardware address len| +integer (8 bit) +|plen| +Protocol address len | +integer (8 bit) +|operation| +Operation | +arp_op +|saddr ether| +Ethernet sender address| +ether_addr +|daddr ether| +Ethernet target address| +ether_addr +|saddr ip| +IPv4 sender address| +ipv4_addr +|daddr ip| +IPv4 target address| +ipv4_addr +|====================== + +IPV4 HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~ +[verse] +*ip* {*version* | *hdrlength* | *dscp* | *ecn* | *length* | *id* | *frag-off* | *ttl* | *protocol* | *checksum* | *saddr* | *daddr* } + +.IPv4 header expression +[options="header"] +|================== +|Keyword| Description| Type +|version| +IP header version (4)| +integer (4 bit) +|hdrlength| +IP header length including options| +integer (4 bit) FIXME scaling +|dscp| +Differentiated Services Code Point| +dscp +|ecn| +Explicit Congestion Notification| +ecn +|length| +Total packet length | +integer (16 bit) +|id| +IP ID| +integer (16 bit) +|frag-off| +Fragment offset | +integer (16 bit) +|ttl| +Time to live| +integer (8 bit) +|protocol| +Upper layer protocol | +inet_proto +|checksum| +IP header checksum| +integer (16 bit) +|saddr| +Source address| +ipv4_addr +|daddr| +Destination address | +ipv4_addr +|====================== + +Careful with matching on *ip length*: If GRO/GSO is enabled, then the Linux +kernel might aggregate several packets into one big packet that is larger than +MTU. Moreover, if GRO/GSO maximum size is larger than 65535 (see man ip-link(8), +specifically gro_ipv6_max_size and gso_ipv6_max_size), then *ip length* might +be 0 for such jumbo packets. *meta length* allows you to match on the packet +length including the IP header size. If you want to perform heuristics on the +*ip length* field, then disable GRO/GSO. + +ICMP HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~ +[verse] +*icmp* {*type* | *code* | *checksum* | *id* | *sequence* | *gateway* | *mtu*} + +This expression refers to ICMP header fields. When using it in *inet*, +*bridge* or *netdev* families, it will cause an implicit dependency on IPv4 to +be created. To match on unusual cases like ICMP over IPv6, one has to add an +explicit *meta protocol ip6* match to the rule. + +.ICMP header expression +[options="header"] +|================== +|Keyword|Description| Type +|type| +ICMP type field | +icmp_type +|code| +ICMP code field | +integer (8 bit) +|checksum| +ICMP checksum field | +integer (16 bit) +|id| +ID of echo request/response | +integer (16 bit) +|sequence| +sequence number of echo request/response| +integer (16 bit) +|gateway| +gateway of redirects| +integer (32 bit) +|mtu| +MTU of path MTU discovery| +integer (16 bit) +|============================ + +IGMP HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~ +[verse] +*igmp* {*type* | *mrt* | *checksum* | *group*} + +This expression refers to IGMP header fields. When using it in *inet*, +*bridge* or *netdev* families, it will cause an implicit dependency on IPv4 to +be created. To match on unusual cases like IGMP over IPv6, one has to add an +explicit *meta protocol ip6* match to the rule. + +.IGMP header expression +[options="header"] +|================== +|Keyword|Description| Type +|type| +IGMP type field | +igmp_type +|mrt| +IGMP maximum response time field | +integer (8 bit) +|checksum| +IGMP checksum field | +integer (16 bit) +|group| +Group address| +integer (32 bit) +|============================ + +IPV6 HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~ +[verse] +*ip6* {*version* | *dscp* | *ecn* | *flowlabel* | *length* | *nexthdr* | *hoplimit* | *saddr* | *daddr*} + +This expression refers to the ipv6 header fields. Caution when using *ip6 +nexthdr*, the value only refers to the next header, i.e. *ip6 nexthdr tcp* will +only match if the ipv6 packet does not contain any extension headers. Packets +that are fragmented or e.g. contain a routing extension headers will not be +matched. Please use *meta l4proto* if you wish to match the real transport header +and ignore any additional extension headers instead. + +.IPv6 header expression +[options="header"] +|================== +|Keyword|Description| Type +|version| +IP header version (6)| +integer (4 bit) +|dscp| +Differentiated Services Code Point| +dscp +|ecn| +Explicit Congestion Notification| +ecn +|flowlabel| +Flow label| +integer (20 bit) +|length| +Payload length| +integer (16 bit) +|nexthdr| +Nexthdr protocol| +inet_proto +|hoplimit| +Hop limit| +integer (8 bit) +|saddr| +Source address| +ipv6_addr +|daddr| +Destination address | +ipv6_addr +|======================= + +Careful with matching on *ip6 length*: If GRO/GSO is enabled, then the Linux +kernel might aggregate several packets into one big packet that is larger than +MTU. Moreover, if GRO/GSO maximum size is larger than 65535 (see man ip-link(8), +specifically gro_ipv6_max_size and gso_ipv6_max_size), then *ip6 length* might +be 0 for such jumbo packets. *meta length* allows you to match on the packet +length including the IP header size. If you want to perform heuristics on the +*ip6 length* field, then disable GRO/GSO. + +.Using ip6 header expressions +----------------------------- +# matching if first extension header indicates a fragment +ip6 nexthdr ipv6-frag +----------------------------- + +ICMPV6 HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~~~ +[verse] +*icmpv6* {*type* | *code* | *checksum* | *parameter-problem* | *packet-too-big* | *id* | *sequence* | *max-delay* | *taddr* | *daddr*} + +This expression refers to ICMPv6 header fields. When using it in *inet*, +*bridge* or *netdev* families, it will cause an implicit dependency on IPv6 to +be created. To match on unusual cases like ICMPv6 over IPv4, one has to add an +explicit *meta protocol ip* match to the rule. + +.ICMPv6 header expression +[options="header"] +|================== +|Keyword| Description| Type +|type| +ICMPv6 type field| +icmpv6_type +|code| +ICMPv6 code field| +integer (8 bit) +|checksum| +ICMPv6 checksum field| +integer (16 bit) +|parameter-problem| +pointer to problem| +integer (32 bit) +|packet-too-big| +oversized MTU| +integer (32 bit) +|id| +ID of echo request/response | +integer (16 bit) +|sequence| +sequence number of echo request/response| +integer (16 bit) +|max-delay| +maximum response delay of MLD queries| +integer (16 bit) +|taddr| +target address of neighbor solicit/advert, redirect or MLD| +ipv6_addr +|daddr| +destination address of redirect| +ipv6_addr +|============================== + +TCP HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~ +[verse] +*tcp* {*sport* | *dport* | *sequence* | *ackseq* | *doff* | *reserved* | *flags* | *window* | *checksum* | *urgptr*} + +.TCP header expression +[options="header"] +|================== +|Keyword| Description| Type +|sport| +Source port| +inet_service +|dport| +Destination port| +inet_service +|sequence| +Sequence number| +integer (32 bit) +|ackseq| +Acknowledgement number | +integer (32 bit) +|doff| +Data offset | +integer (4 bit) FIXME scaling +|reserved| +Reserved area | +integer (4 bit) +|flags| +TCP flags| +tcp_flag +|window| +Window| +integer (16 bit) +|checksum| +Checksum| +integer (16 bit) +|urgptr| +Urgent pointer| +integer (16 bit) +|====================== + +UDP HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~ +[verse] +*udp* {*sport* | *dport* | *length* | *checksum*} + +.UDP header expression +[options="header"] +|================== +|Keyword| Description| Type +|sport| +Source port| +inet_service +|dport| +Destination port| +inet_service +|length| +Total packet length| +integer (16 bit) +|checksum| +Checksum| +integer (16 bit) +|================ + +UDP-LITE HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +[verse] +*udplite* {*sport* | *dport* | *checksum*} + +.UDP-Lite header expression +[options="header"] +|================== +|Keyword| Description| Type +|sport| +Source port| +inet_service +|dport| +Destination port| +inet_service +|checksum| +Checksum| +integer (16 bit) +|================ + +SCTP HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~~ +[verse] +____ +*sctp* {*sport* | *dport* | *vtag* | *checksum*} +*sctp chunk* 'CHUNK' [ 'FIELD' ] + +'CHUNK' := *data* | *init* | *init-ack* | *sack* | *heartbeat* | + *heartbeat-ack* | *abort* | *shutdown* | *shutdown-ack* | *error* | + *cookie-echo* | *cookie-ack* | *ecne* | *cwr* | *shutdown-complete* + | *asconf-ack* | *forward-tsn* | *asconf* + +'FIELD' := 'COMMON_FIELD' | 'DATA_FIELD' | 'INIT_FIELD' | 'INIT_ACK_FIELD' | + 'SACK_FIELD' | 'SHUTDOWN_FIELD' | 'ECNE_FIELD' | 'CWR_FIELD' | + 'ASCONF_ACK_FIELD' | 'FORWARD_TSN_FIELD' | 'ASCONF_FIELD' + +'COMMON_FIELD' := *type* | *flags* | *length* +'DATA_FIELD' := *tsn* | *stream* | *ssn* | *ppid* +'INIT_FIELD' := *init-tag* | *a-rwnd* | *num-outbound-streams* | + *num-inbound-streams* | *initial-tsn* +'INIT_ACK_FIELD' := 'INIT_FIELD' +'SACK_FIELD' := *cum-tsn-ack* | *a-rwnd* | *num-gap-ack-blocks* | + *num-dup-tsns* +'SHUTDOWN_FIELD' := *cum-tsn-ack* +'ECNE_FIELD' := *lowest-tsn* +'CWR_FIELD' := *lowest-tsn* +'ASCONF_ACK_FIELD' := *seqno* +'FORWARD_TSN_FIELD' := *new-cum-tsn* +'ASCONF_FIELD' := *seqno* +____ + +.SCTP header expression +[options="header"] +|================== +|Keyword| Description| Type +|sport| +Source port| +inet_service +|dport| +Destination port| +inet_service +|vtag| +Verification Tag| +integer (32 bit) +|checksum| +Checksum| +integer (32 bit) +|chunk| +Search chunk in packet| +without 'FIELD', boolean indicating existence +|================ + +.SCTP chunk fields +[options="header"] +|================== +|Name| Width in bits | Chunk | Notes +|type| 8 | all | not useful, defined by chunk type +|flags| 8 | all | semantics defined on per-chunk basis +|length| 16 | all | length of this chunk in bytes excluding padding +|tsn| 32 | data | transmission sequence number +|stream| 16 | data | stream identifier +|ssn| 16 | data | stream sequence number +|ppid| 32 | data | payload protocol identifier +|init-tag| 32 | init, init-ack | initiate tag +|a-rwnd| 32 | init, init-ack, sack | advertised receiver window credit +|num-outbound-streams| 16 | init, init-ack | number of outbound streams +|num-inbound-streams| 16 | init, init-ack | number of inbound streams +|initial-tsn| 32 | init, init-ack | initial transmit sequence number +|cum-tsn-ack| 32 | sack, shutdown | cumulative transmission sequence number acknowledged +|num-gap-ack-blocks| 16 | sack | number of Gap Ack Blocks included +|num-dup-tsns| 16 | sack | number of duplicate transmission sequence numbers received +|lowest-tsn| 32 | ecne, cwr | lowest transmission sequence number +|seqno| 32 | asconf-ack, asconf | sequence number +|new-cum-tsn| 32 | forward-tsn | new cumulative transmission sequence number +|================== + +DCCP HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~ +[verse] +*dccp* {*sport* | *dport* | *type*} + +.DCCP header expression +[options="header"] +|================== +|Keyword| Description| Type +|sport| +Source port| +inet_service +|dport| +Destination port| +inet_service +|type| +Packet type| +dccp_pkttype +|======================== + +AUTHENTICATION HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +[verse] +*ah* {*nexthdr* | *hdrlength* | *reserved* | *spi* | *sequence*} + +.AH header expression +[options="header"] +|================== +|Keyword| Description| Type +|nexthdr| +Next header protocol| +inet_proto +|hdrlength| +AH Header length| +integer (8 bit) +|reserved| +Reserved area| +integer (16 bit) +|spi| +Security Parameter Index | +integer (32 bit) +|sequence| +Sequence number| +integer (32 bit) +|======================== + +ENCRYPTED SECURITY PAYLOAD HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +[verse] +*esp* {*spi* | *sequence*} + +.ESP header expression +[options="header"] +|================== +|Keyword| Description| Type +|spi| +Security Parameter Index | +integer (32 bit) +|sequence| +Sequence number| +integer (32 bit) +|=========================== + +IPCOMP HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~~~~ +*comp* {*nexthdr* | *flags* | *cpi*} + +.IPComp header expression +[options="header"] +|================== +|Keyword| Description| Type +|nexthdr| +Next header protocol| +inet_proto +|flags| +Flags| +bitmask +|cpi| +compression Parameter Index | +integer (16 bit) +|============================ + +GRE HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~~ +[verse] +*gre* {*flags* | *version* | *protocol*} +*gre* *ip* {*version* | *hdrlength* | *dscp* | *ecn* | *length* | *id* | *frag-off* | *ttl* | *protocol* | *checksum* | *saddr* | *daddr* } +*gre* *ip6* {*version* | *dscp* | *ecn* | *flowlabel* | *length* | *nexthdr* | *hoplimit* | *saddr* | *daddr*} + +The gre expression is used to match on the gre header fields. This expression +also allows to match on the IPv4 or IPv6 packet within the gre header. + +.GRE header expression +[options="header"] +|================== +|Keyword| Description| Type +|flags| +checksum, routing, key, sequence and strict source route flags| +integer (5 bit) +|version| +gre version field, 0 for GRE and 1 for PPTP| +integer (3 bit) +|protocol| +EtherType of encapsulated packet| +integer (16 bit) +|================== + +.Matching inner IPv4 destination address encapsulated in gre +------------------------------------------------------------ +netdev filter ingress gre ip daddr 9.9.9.9 counter +------------------------------------------------------------ + +GENEVE HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~~~ +[verse] +*geneve* {*vni* | *flags*} +*geneve* *ether* {*daddr* | *saddr* | *type*} +*geneve* *vlan* {*id* | *dei* | *pcp* | *type*} +*geneve* *ip* {*version* | *hdrlength* | *dscp* | *ecn* | *length* | *id* | *frag-off* | *ttl* | *protocol* | *checksum* | *saddr* | *daddr* } +*geneve* *ip6* {*version* | *dscp* | *ecn* | *flowlabel* | *length* | *nexthdr* | *hoplimit* | *saddr* | *daddr*} +*geneve* *tcp* {*sport* | *dport* | *sequence* | *ackseq* | *doff* | *reserved* | *flags* | *window* | *checksum* | *urgptr*} +*geneve* *udp* {*sport* | *dport* | *length* | *checksum*} + +The geneve expression is used to match on the geneve header fields. The geneve +header encapsulates a ethernet frame within a *udp* packet. This expression +requires that you restrict the matching to *udp* packets (usually at +port 6081 according to IANA-assigned ports). + +.GENEVE header expression +[options="header"] +|================== +|Keyword| Description| Type +|protocol| +EtherType of encapsulated packet| +integer (16 bit) +|vni| +Virtual Network ID (VNI)| +integer (24 bit) +|================== + +.Matching inner TCP destination port encapsulated in geneve +---------------------------------------------------------- +netdev filter ingress udp dport 4789 geneve tcp dport 80 counter +---------------------------------------------------------- + +GRETAP HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~~~ +[verse] +*gretap* {*vni* | *flags*} +*gretap* *ether* {*daddr* | *saddr* | *type*} +*gretap* *vlan* {*id* | *dei* | *pcp* | *type*} +*gretap* *ip* {*version* | *hdrlength* | *dscp* | *ecn* | *length* | *id* | *frag-off* | *ttl* | *protocol* | *checksum* | *saddr* | *daddr* } +*gretap* *ip6* {*version* | *dscp* | *ecn* | *flowlabel* | *length* | *nexthdr* | *hoplimit* | *saddr* | *daddr*} +*gretap* *tcp* {*sport* | *dport* | *sequence* | *ackseq* | *doff* | *reserved* | *flags* | *window* | *checksum* | *urgptr*} +*gretap* *udp* {*sport* | *dport* | *length* | *checksum*} + +The gretap expression is used to match on the encapsulated ethernet frame +within the gre header. Use the *gre* expression to match on the *gre* header +fields. + +.Matching inner TCP destination port encapsulated in gretap +---------------------------------------------------------- +netdev filter ingress gretap tcp dport 80 counter +---------------------------------------------------------- + +VXLAN HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~~ +[verse] +*vxlan* {*vni* | *flags*} +*vxlan* *ether* {*daddr* | *saddr* | *type*} +*vxlan* *vlan* {*id* | *dei* | *pcp* | *type*} +*vxlan* *ip* {*version* | *hdrlength* | *dscp* | *ecn* | *length* | *id* | *frag-off* | *ttl* | *protocol* | *checksum* | *saddr* | *daddr* } +*vxlan* *ip6* {*version* | *dscp* | *ecn* | *flowlabel* | *length* | *nexthdr* | *hoplimit* | *saddr* | *daddr*} +*vxlan* *tcp* {*sport* | *dport* | *sequence* | *ackseq* | *doff* | *reserved* | *flags* | *window* | *checksum* | *urgptr*} +*vxlan* *udp* {*sport* | *dport* | *length* | *checksum*} + +The vxlan expression is used to match on the vxlan header fields. The vxlan +header encapsulates a ethernet frame within a *udp* packet. This expression +requires that you restrict the matching to *udp* packets (usually at +port 4789 according to IANA-assigned ports). + +.VXLAN header expression +[options="header"] +|================== +|Keyword| Description| Type +|flags| +vxlan flags| +integer (8 bit) +|vni| +Virtual Network ID (VNI)| +integer (24 bit) +|================== + +.Matching inner TCP destination port encapsulated in vxlan +---------------------------------------------------------- +netdev filter ingress udp dport 4789 vxlan tcp dport 80 counter +---------------------------------------------------------- + +ARP HEADER EXPRESSION +~~~~~~~~~~~~~~~~~~~~~ +[verse] +*arp* {*htype* | *ptype* | *hlen* | *plen* | *operation* | *saddr* { *ip* | *ether* } | *daddr* { *ip* | *ether* } + +.ARP header expression +[options="header"] +|================== +|Keyword| Description| Type +|htype| +ARP hardware type| +integer (16 bit) +|ptype| +EtherType| +ether_type +|hlen| +Hardware address len| +integer (8 bit) +|plen| +Protocol address len | +integer (8 bit) +|operation| +Operation | +arp_op +|saddr ether| +Ethernet sender address| +ether_addr +|daddr ether| +Ethernet target address| +ether_addr +|saddr ip| +IPv4 sender address| +ipv4_addr +|daddr ip| +IPv4 target address| +ipv4_addr +|====================== + +RAW PAYLOAD EXPRESSION +~~~~~~~~~~~~~~~~~~~~~~ +[verse] +*@*'base'*,*'offset'*,*'length' + +The raw payload expression instructs to load 'length' bits starting at 'offset' bits. +Bit 0 refers to the very first bit -- in the C programming language, this +corresponds to the topmost bit, i.e. 0x80 in case of an octet. They are useful +to match headers that do not have a human-readable template expression yet. Note +that nft will not add dependencies for Raw payload expressions. If you e.g. want +to match protocol fields of a transport header with protocol number 5, you need +to manually exclude packets that have a different transport header, for instance +by using *meta l4proto 5* before the raw expression. + +.Supported payload protocol bases +[options="header"] +|================== +|Base| Description +|ll| +Link layer, for example the Ethernet header +|nh| +Network header, for example IPv4 or IPv6 +|th| +Transport Header, for example TCP +|ih| +Inner Header / Payload, i.e. after the L4 transport level header +|============================== + +.Matching destination port of both UDP and TCP +---------------------------------------------- +inet filter input meta l4proto {tcp, udp} @th,16,16 { 53, 80 } +----------------------------------------------------------------- +The above can also be written as +----------------------------------------------------------------- +inet filter input meta l4proto {tcp, udp} th dport { 53, 80 } +----------------------------------------------------------------- +it is more convenient, but like the raw expression notation no +dependencies are created or checked. It is the users responsibility +to restrict matching to those header types that have a notion of ports. +Otherwise, rules using raw expressions will errnously match unrelated +packets, e.g. mis-interpreting ESP packets SPI field as a port. + +.Rewrite arp packet target hardware address if target protocol address matches a given address +---------------------------------------------------------------------------------------------- +input meta iifname enp2s0 arp ptype 0x0800 arp htype 1 arp hlen 6 arp plen 4 @nh,192,32 0xc0a88f10 @nh,144,48 set 0x112233445566 accept +----------------------------------------------------------------------------------------------- + +EXTENSION HEADER EXPRESSIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Extension header expressions refer to data from variable-sized protocol headers, such as IPv6 extension headers, TCP options and IPv4 options. + +nftables currently supports matching (finding) a given ipv6 extension header, TCP option or IPv4 option. +[verse] +*hbh* {*nexthdr* | *hdrlength*} +*frag* {*nexthdr* | *frag-off* | *more-fragments* | *id*} +*rt* {*nexthdr* | *hdrlength* | *type* | *seg-left*} +*dst* {*nexthdr* | *hdrlength*} +*mh* {*nexthdr* | *hdrlength* | *checksum* | *type*} +*srh* {*flags* | *tag* | *sid* | *seg-left*} +*tcp option* {*eol* | *nop* | *maxseg* | *window* | *sack-perm* | *sack* | *sack0* | *sack1* | *sack2* | *sack3* | *timestamp*} 'tcp_option_field' +*ip option* { lsrr | ra | rr | ssrr } 'ip_option_field' + +The following syntaxes are valid only in a relational expression with boolean type on right-hand side for checking header existence only: +[verse] +*exthdr* {*hbh* | *frag* | *rt* | *dst* | *mh*} +*tcp option* {*eol* | *nop* | *maxseg* | *window* | *sack-perm* | *sack* | *sack0* | *sack1* | *sack2* | *sack3* | *timestamp*} +*ip option* { lsrr | ra | rr | ssrr } +*dccp option* 'dccp_option_type' + +.IPv6 extension headers +[options="header"] +|================== +|Keyword| Description +|hbh| +Hop by Hop +|rt| +Routing Header +|frag| +Fragmentation header +|dst| +dst options +|mh| +Mobility Header +|srh| +Segment Routing Header +|===================== + +.TCP Options +[options="header"] +|================== +|Keyword| Description | TCP option fields +|eol| +End if option list| +- +|nop| +1 Byte TCP Nop padding option | +- +|maxseg| +TCP Maximum Segment Size| +length, size +|window| +TCP Window Scaling | +length, count +|sack-perm | +TCP SACK permitted | +length +|sack| +TCP Selective Acknowledgement (alias of block 0) | +length, left, right +|sack0| +TCP Selective Acknowledgement (block 0) | +length, left, right +|sack1| +TCP Selective Acknowledgement (block 1) | +length, left, right +|sack2| +TCP Selective Acknowledgement (block 2) | +length, left, right +|sack3| +TCP Selective Acknowledgement (block 3) | +length, left, right +|timestamp| +TCP Timestamps | +length, tsval, tsecr +|============================ + +TCP option matching also supports raw expression syntax to access arbitrary options: +[verse] +*tcp option* +[verse] +*tcp option* *@*'number'*,*'offset'*,*'length' + +.IP Options +[options="header"] +|================== +|Keyword| Description | IP option fields +|lsrr| +Loose Source Route | +type, length, ptr, addr +|ra| +Router Alert | +type, length, value +|rr| +Record Route | +type, length, ptr, addr +|ssrr| +Strict Source Route | +type, length, ptr, addr +|============================ + +.finding TCP options +-------------------- +filter input tcp option sack-perm exists counter +-------------------- + +.matching TCP options +-------------------- +filter input tcp option maxseg size lt 536 +-------------------- + +.matching IPv6 exthdr +--------------------- +ip6 filter input frag more-fragments 1 counter +--------------------------------------- + +.finding IP option +------------------ +filter input ip option lsrr exists counter +--------------------------------------- + +.finding DCCP option +------------------ +filter input dccp option 40 exists counter +--------------------------------------- + +CONNTRACK EXPRESSIONS +~~~~~~~~~~~~~~~~~~~~~ +Conntrack expressions refer to meta data of the connection tracking entry associated with a packet. + + +There are three types of conntrack expressions. Some conntrack expressions +require the flow direction before the conntrack key, others must be used +directly because they are direction agnostic. The *packets*, *bytes* and +*avgpkt* keywords can be used with or without a direction. If the direction is +omitted, the sum of the original and the reply direction is returned. The same +is true for the *zone*, if a direction is given, the zone is only matched if the +zone id is tied to the given direction. + + +[verse] +*ct* {*state* | *direction* | *status* | *mark* | *expiration* | *helper* | *label* | *count* | *id*} +*ct* [*original* | *reply*] {*l3proto* | *protocol* | *bytes* | *packets* | *avgpkt* | *zone*} +*ct* {*original* | *reply*} {*proto-src* | *proto-dst*} +*ct* {*original* | *reply*} {*ip* | *ip6*} {*saddr* | *daddr*} + +The conntrack-specific types in this table are described in the sub-section CONNTRACK TYPES above. + +.Conntrack expressions +[options="header"] +|================== +|Keyword| Description | Type +|state| +State of the connection | +ct_state +|direction| +Direction of the packet relative to the connection | +ct_dir +|status| +Status of the connection | +ct_status +|mark| +Connection mark | +mark +|expiration| +Connection expiration time | +time +|helper| +Helper associated with the connection| +string +|label| +Connection tracking label bit or symbolic name defined in connlabel.conf in the nftables include path| +ct_label +|l3proto| +Layer 3 protocol of the connection| +nf_proto +|saddr| +Source address of the connection for the given direction | +ipv4_addr/ipv6_addr +|daddr| +Destination address of the connection for the given direction | +ipv4_addr/ipv6_addr +|protocol| +Layer 4 protocol of the connection for the given direction | +inet_proto +|proto-src| +Layer 4 protocol source for the given direction| +integer (16 bit) +|proto-dst| +Layer 4 protocol destination for the given direction | +integer (16 bit) +|packets| +packet count seen in the given direction or sum of original and reply | +integer (64 bit) +|bytes| +byte count seen, see description for *packets* keyword | +integer (64 bit) +|avgpkt| +average bytes per packet, see description for *packets* keyword | +integer (64 bit) +|zone| +conntrack zone | +integer (16 bit) +|count| +number of current connections| +integer (32 bit) +|id| +Connection id| +ct_id| +|========================================== + +.restrict the number of parallel connections to a server +-------------------- +nft add set filter ssh_flood '{ type ipv4_addr; flags dynamic; }' +nft add rule filter input tcp dport 22 add @ssh_flood '{ ip saddr ct count over 2 }' reject +-------------------- |