<*>"/" { return SLASH; }
"-" { return DASH; }
"*" { return ASTERISK; }
-"@" { scanner_push_start_cond(yyscanner, SCANSTATE_AT); return AT; }
+<*>"@" { scanner_push_start_cond(yyscanner, SCANSTATE_AT); return AT; }
"$" { return '$'; }
"=" { return '='; }
"vmap" { return VMAP; }
"table" { return TABLE; }
"chain" { return CHAIN; }
"rule" { return RULE; }
-"set" { return SET; }
+<*>"set" { return SET; }
"element" { return ELEMENT; }
"map" { return MAP; }
"flowtable" { return FLOWTABLE; }
"handle" { return HANDLE; }
"ruleset" { return RULESET; }
-"socket" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_SOCKET); return SOCKET; }
+<*>"socket" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_SOCKET); return SOCKET; }
<SCANSTATE_EXPR_SOCKET>{
"transparent" { return TRANSPARENT; }
"wildcard" { return WILDCARD; }
"cgroupv2" { return CGROUPV2; }
"level" { return LEVEL; }
}
-"tproxy" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_TPROXY); return TPROXY; }
+<*>"tproxy" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_TPROXY); return TPROXY; }
-"accept" { return ACCEPT; }
-"drop" { return DROP; }
-"continue" { return CONTINUE; }
-"jump" { return JUMP; }
-"goto" { return GOTO; }
-"return" { return RETURN; }
-<SCANSTATE_EXPR_QUEUE,SCANSTATE_STMT_DUP,SCANSTATE_STMT_FWD,SCANSTATE_STMT_NAT,SCANSTATE_STMT_TPROXY,SCANSTATE_IP,SCANSTATE_IP6>"to" { return TO; } /* XXX: SCANSTATE_IP is a workaround */
+<*>"accept" { return ACCEPT; }
+<*>"drop" { return DROP; }
+<*>"continue" { return CONTINUE; }
+<*>"jump" { return JUMP; }
+<*>"goto" { return GOTO; }
+<*>"return" { return RETURN; }
+<SCANSTATE_EXPR_QUEUE,SCANSTATE_STMT_DUP,SCANSTATE_STMT_FWD,SCANSTATE_STMT_NAT,SCANSTATE_STMT_TPROXY,SCANSTATE_IP,SCANSTATE_IP6>"to" { return TO; } /* XXX: SCANSTATE_IP(6) is a workaround (lookahead after nf_key_proto) */
"inet" { return INET; }
"netdev" { return NETDEV; }
-"add" { return ADD; }
+<*>"add" { return ADD; }
"replace" { return REPLACE; }
-"update" { return UPDATE; }
+<*>"update" { return UPDATE; }
"create" { return CREATE; }
"insert" { return INSERT; }
-"delete" { return DELETE; }
+<*>"delete" { return DELETE; }
"get" { return GET; }
"list" { scanner_push_start_cond(yyscanner, SCANSTATE_CMD_LIST); return LIST; }
-"reset" { scanner_push_start_cond(yyscanner, SCANSTATE_CMD_RESET); return RESET; }
+<*>"reset" { scanner_push_start_cond(yyscanner, SCANSTATE_CMD_RESET); return RESET; }
"flush" { return FLUSH; }
"rename" { return RENAME; }
"import" { scanner_push_start_cond(yyscanner, SCANSTATE_CMD_IMPORT); return IMPORT; }
"memory" { return MEMORY; }
}
-"flow" { return FLOW; }
+<*>"flow" { return FLOW; }
"offload" { return OFFLOAD; }
-"meter" { return METER; }
+<*>"meter" { return METER; }
<SCANSTATE_CMD_LIST>{
"meters" { return METERS; }
<SCANSTATE_LIMIT,SCANSTATE_QUOTA,SCANSTATE_RATE>"kbytes" { return KBYTES; }
<SCANSTATE_LIMIT,SCANSTATE_QUOTA,SCANSTATE_RATE>"mbytes" { return MBYTES; }
-"last" { scanner_push_start_cond(yyscanner, SCANSTATE_LAST); return LAST; }
+<*>"last" { scanner_push_start_cond(yyscanner, SCANSTATE_LAST); return LAST; }
<SCANSTATE_LAST>{
"never" { return NEVER; }
}
"rules" { return RULES; }
}
-<*>"log" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_LOG); return LOG; }
+<*>"log" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_LOG); return LOG; }
<SCANSTATE_STMT_LOG,SCANSTATE_STMT_NAT,SCANSTATE_IP,SCANSTATE_IP6>"prefix" { return PREFIX; }
<SCANSTATE_STMT_LOG>{
"snaplen" { return SNAPLEN; }
"audit" { return AUDIT; }
}
-"queue" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_QUEUE); return QUEUE;}
+<*>"queue" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_QUEUE); return QUEUE;}
<SCANSTATE_EXPR_QUEUE>{
"num" { return QUEUENUM;}
"bypass" { return BYPASS;}
"fanout" { return FANOUT;}
}
-"limit" { scanner_push_start_cond(yyscanner, SCANSTATE_LIMIT); return LIMIT; }
+<*>"limit" { scanner_push_start_cond(yyscanner, SCANSTATE_LIMIT); return LIMIT; }
<SCANSTATE_LIMIT,SCANSTATE_RATE>{
"rate" { scanner_push_start_cond(yyscanner, SCANSTATE_RATE); return RATE; }
"burst" { return BURST; }
}
<SCANSTATE_CT,SCANSTATE_LIMIT,SCANSTATE_QUOTA,SCANSTATE_RATE>"over" { return OVER; }
-"quota" { scanner_push_start_cond(yyscanner, SCANSTATE_QUOTA); return QUOTA; }
+<*>"quota" { scanner_push_start_cond(yyscanner, SCANSTATE_QUOTA); return QUOTA; }
<SCANSTATE_QUOTA,SCANSTATE_RATE>{
"until" { return UNTIL; }
}
<*>"hour" { return HOUR; }
<*>"day" { return DAY; }
-"reject" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_REJECT); return _REJECT; }
+<*>"reject" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_REJECT); return _REJECT; }
<SCANSTATE_STMT_REJECT>{
"with" { return WITH; }
"icmpx" { return ICMPX; }
}
-"snat" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return SNAT; }
-"dnat" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return DNAT; }
-"masquerade" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return MASQUERADE; }
-"redirect" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return REDIRECT; }
+<*>"snat" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return SNAT; }
+<*>"dnat" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return DNAT; }
+<*>"masquerade" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return MASQUERADE; }
+<*>"redirect" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return REDIRECT; }
"random" { return RANDOM; }
<SCANSTATE_STMT_NAT>{
"fully-random" { return FULLY_RANDOM; }
"ll" { return LL_HDR; }
"nh" { return NETWORK_HDR; }
}
-"th" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_TH); return TRANSPORT_HDR; }
+<*>"th" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_TH); return TRANSPORT_HDR; }
"bridge" { return BRIDGE; }
-"ether" { scanner_push_start_cond(yyscanner, SCANSTATE_ETH); return ETHER; }
+<*>"ether" { scanner_push_start_cond(yyscanner, SCANSTATE_ETH); return ETHER; }
<SCANSTATE_ARP,SCANSTATE_CT,SCANSTATE_ETH,SCANSTATE_IP,SCANSTATE_IP6,SCANSTATE_EXPR_FIB,SCANSTATE_EXPR_IPSEC>{
"saddr" { return SADDR; }
"daddr" { return DADDR; }
"type" { scanner_push_start_cond(yyscanner, SCANSTATE_TYPE); return TYPE; }
"typeof" { return TYPEOF; }
-"vlan" { scanner_push_start_cond(yyscanner, SCANSTATE_VLAN); return VLAN; }
+<*>"vlan" { scanner_push_start_cond(yyscanner, SCANSTATE_VLAN); return VLAN; }
<SCANSTATE_CT,SCANSTATE_EXPR_FRAG,SCANSTATE_VLAN,SCANSTATE_IP,SCANSTATE_ICMP>"id" { return ID; }
<SCANSTATE_VLAN>{
"cfi" { return CFI; }
"8021ad" { yylval->string = xstrdup(yytext); return STRING; }
"8021q" { yylval->string = xstrdup(yytext); return STRING; }
-"arp" { scanner_push_start_cond(yyscanner, SCANSTATE_ARP); return ARP; }
+<*>"arp" { scanner_push_start_cond(yyscanner, SCANSTATE_ARP); return ARP; }
<SCANSTATE_ARP>{
"htype" { return HTYPE; }
"ptype" { return PTYPE; }
"operation" { return OPERATION; }
}
-"ip" { scanner_push_start_cond(yyscanner, SCANSTATE_IP); return IP; }
+<*>"ip" { scanner_push_start_cond(yyscanner, SCANSTATE_IP); return IP; }
<SCANSTATE_IP,SCANSTATE_IP6,SCANSTATE_EXPR_OSF,SCANSTATE_GRE>{
"version" { return HDRVERSION; }
}
"options" { return OPTIONS; }
"option" { return OPTION; }
}
-"time" { return TIME; }
+<*>"time" { return TIME; }
-"icmp" { scanner_push_start_cond(yyscanner, SCANSTATE_ICMP); return ICMP; }
-"icmpv6" { scanner_push_start_cond(yyscanner, SCANSTATE_ICMP); return ICMP6; }
+<*>"icmp" { scanner_push_start_cond(yyscanner, SCANSTATE_ICMP); return ICMP; }
+<*>"icmpv6" { scanner_push_start_cond(yyscanner, SCANSTATE_ICMP); return ICMP6; }
<SCANSTATE_ICMP>{
"gateway" { return GATEWAY; }
"code" { return CODE; }
"sequence" { return SEQUENCE; }
}
-"igmp" { scanner_push_start_cond(yyscanner, SCANSTATE_IGMP); return IGMP; }
+<*>"igmp" { scanner_push_start_cond(yyscanner, SCANSTATE_IGMP); return IGMP; }
<SCANSTATE_IGMP>{
"mrt" { return MRT; }
"group" { return GROUP; }
}
-"ip6" { scanner_push_start_cond(yyscanner, SCANSTATE_IP6); return IP6; }
+<*>"ip6" { scanner_push_start_cond(yyscanner, SCANSTATE_IP6); return IP6; }
"priority" { return PRIORITY; }
<SCANSTATE_IP6>{
"flowlabel" { return FLOWLABEL; }
"nexthdr" { return NEXTHDR; }
}
-"ah" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_AH); return AH; }
+<*>"ah" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_AH); return AH; }
<SCANSTATE_EXPR_AH,SCANSTATE_EXPR_FRAG,SCANSTATE_EXPR_MH,SCANSTATE_TCP>{
"reserved" { return RESERVED; }
}
<SCANSTATE_EXPR_AH,SCANSTATE_EXPR_ESP,SCANSTATE_EXPR_IPSEC>"spi" { return SPI; }
-"esp" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_ESP); return ESP; }
+<*>"esp" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_ESP); return ESP; }
-"comp" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_COMP); return COMP; }
+<*>"comp" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_COMP); return COMP; }
<SCANSTATE_EXPR_COMP>{
"cpi" { return CPI; }
}
"flags" { return FLAGS; }
-"udp" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_UDP); return UDP; }
-"udplite" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_UDPLITE); return UDPLITE; }
+<*>"udp" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_UDP); return UDP; }
+<*>"udplite" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_UDPLITE); return UDPLITE; }
<SCANSTATE_EXPR_UDPLITE>{
"csumcov" { return CSUMCOV; }
}
"option" { return OPTION; }
}
-"vxlan" { return VXLAN; }
+<*>"vxlan" { return VXLAN; }
"vni" { return VNI; }
-"geneve" { return GENEVE; }
+<*>"geneve" { return GENEVE; }
-"gre" { scanner_push_start_cond(yyscanner, SCANSTATE_GRE); return GRE; }
-"gretap" { scanner_push_start_cond(yyscanner, SCANSTATE_GRE); return GRETAP; }
+<*>"gre" { scanner_push_start_cond(yyscanner, SCANSTATE_GRE); return GRE; }
+<*>"gretap" { scanner_push_start_cond(yyscanner, SCANSTATE_GRE); return GRETAP; }
-"tcp" { scanner_push_start_cond(yyscanner, SCANSTATE_TCP); return TCP; }
+<*>"tcp" { scanner_push_start_cond(yyscanner, SCANSTATE_TCP); return TCP; }
-"dccp" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_DCCP); return DCCP; }
+<*>"dccp" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_DCCP); return DCCP; }
-"sctp" { scanner_push_start_cond(yyscanner, SCANSTATE_SCTP); return SCTP; }
+<*>"sctp" { scanner_push_start_cond(yyscanner, SCANSTATE_SCTP); return SCTP; }
<SCANSTATE_SCTP>{
"chunk" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_SCTP_CHUNK); return CHUNK; }
"new-cum-tsn" { return NEW_CUM_TSN; }
}
-"rt" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_RT); return RT; }
-"rt0" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_RT); return RT0; }
-"rt2" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_RT); return RT2; }
-"srh" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_RT); return RT4; }
+<*>"rt" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_RT); return RT; }
+<*>"rt0" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_RT); return RT0; }
+<*>"rt2" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_RT); return RT2; }
+<*>"srh" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_RT); return RT4; }
<SCANSTATE_EXPR_RT,SCANSTATE_STMT_NAT,SCANSTATE_IP,SCANSTATE_IP6>"addr" { return ADDR; }
-"hbh" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_HBH); return HBH; }
+<*>"hbh" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_HBH); return HBH; }
-"frag" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_FRAG); return FRAG; }
+<*>"frag" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_FRAG); return FRAG; }
<SCANSTATE_EXPR_FRAG>{
"reserved2" { return RESERVED2; }
"more-fragments" { return MORE_FRAGMENTS; }
}
-"dst" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_DST); return DST; }
-
-"mh" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_MH); return MH; }
-
-"meta" { scanner_push_start_cond(yyscanner, SCANSTATE_META); return META; }
-"mark" { return MARK; }
-"iif" { return IIF; }
-"iifname" { return IIFNAME; }
-"iiftype" { return IIFTYPE; }
-"oif" { return OIF; }
-"oifname" { return OIFNAME; }
-"oiftype" { return OIFTYPE; }
-"skuid" { return SKUID; }
-"skgid" { return SKGID; }
-"nftrace" { return NFTRACE; }
-"rtclassid" { return RTCLASSID; }
-"ibriport" { return IBRIDGENAME; } /* backwards compat */
-"ibrname" { return IBRIDGENAME; }
-"obriport" { return OBRIDGENAME; } /* backwards compat */
-"obrname" { return OBRIDGENAME; }
-"pkttype" { return PKTTYPE; }
-"cpu" { return CPU; }
-"iifgroup" { return IIFGROUP; }
-"oifgroup" { return OIFGROUP; }
-"cgroup" { return CGROUP; }
+<*>"dst" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_DST); return DST; }
+
+<*>"mh" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_MH); return MH; }
+
+<*>"meta" { scanner_push_start_cond(yyscanner, SCANSTATE_META); return META; }
+<*>"mark" { return MARK; }
+<*>"iif" { return IIF; }
+<*>"iifname" { return IIFNAME; }
+<*>"iiftype" { return IIFTYPE; }
+<*>"oif" { return OIF; }
+<*>"oifname" { return OIFNAME; }
+<*>"oiftype" { return OIFTYPE; }
+<*>"skuid" { return SKUID; }
+<*>"skgid" { return SKGID; }
+<*>"nftrace" { return NFTRACE; }
+<*>"rtclassid" { return RTCLASSID; }
+<*>"ibriport" { return IBRIDGENAME; } /* backwards compat */
+<*>"ibrname" { return IBRIDGENAME; }
+<*>"obriport" { return OBRIDGENAME; } /* backwards compat */
+<*>"obrname" { return OBRIDGENAME; }
+<*>"pkttype" { return PKTTYPE; }
+<*>"cpu" { return CPU; }
+<*>"iifgroup" { return IIFGROUP; }
+<*>"oifgroup" { return OIFGROUP; }
+<*>"cgroup" { return CGROUP; }
<SCANSTATE_META>{
"nfproto" { return NFPROTO; }
"l4proto" { return L4PROTO; }
"classid" { return CLASSID; }
}
-"ct" { scanner_push_start_cond(yyscanner, SCANSTATE_CT); return CT; }
+<*>"ct" { scanner_push_start_cond(yyscanner, SCANSTATE_CT); return CT; }
<SCANSTATE_CT>{
"avgpkt" { return AVGPKT; }
"l3proto" { return L3PROTOCOL; }
"count" { return COUNT; }
}
-"numgen" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_NUMGEN); return NUMGEN; }
+<*>"numgen" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_NUMGEN); return NUMGEN; }
<SCANSTATE_EXPR_NUMGEN>{
"inc" { return INC; }
}
-"jhash" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_HASH); return JHASH; }
-"symhash" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_HASH); return SYMHASH; }
+<*>"jhash" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_HASH); return JHASH; }
+<*>"symhash" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_HASH); return SYMHASH; }
<SCANSTATE_EXPR_HASH>{
"seed" { return SEED; }
"mod" { return MOD; }
"offset" { return OFFSET; }
}
-"dup" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_DUP); return DUP; }
-"fwd" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_FWD); return FWD; }
+<*>"dup" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_DUP); return DUP; }
+<*>"fwd" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_FWD); return FWD; }
-"fib" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_FIB); return FIB; }
+<*>"fib" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_FIB); return FIB; }
<SCANSTATE_EXPR_FIB>{
"check" { return CHECK; }
}
-"osf" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_OSF); return OSF; }
+<*>"osf" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_OSF); return OSF; }
-"synproxy" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_SYNPROXY); return SYNPROXY; }
+<*>"synproxy" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_SYNPROXY); return SYNPROXY; }
<SCANSTATE_STMT_SYNPROXY>{
"wscale" { return WSCALE; }
"maxseg" { return MSS; }
"sack-perm" { return SACK_PERM; }
}
-"tunnel" { scanner_push_start_cond(yyscanner, SCANSTATE_TUNNEL); return TUNNEL; }
+<*>"tunnel" { scanner_push_start_cond(yyscanner, SCANSTATE_TUNNEL); return TUNNEL; }
<SCANSTATE_TUNNEL>{
"id" { return ID; }
"sport" { return SPORT; }
"data" { return DATA; }
}
-"notrack" { return NOTRACK; }
+<*>"notrack" { return NOTRACK; }
"all" { return ALL; }
"exists" { return EXISTS; }
"missing" { return MISSING; }
-"exthdr" { return EXTHDR; }
+<*>"exthdr" { return EXTHDR; }
-"ipsec" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_IPSEC); return IPSEC; }
+<*>"ipsec" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_IPSEC); return IPSEC; }
<SCANSTATE_EXPR_IPSEC>{
"reqid" { return REQID; }
"spnum" { return SPNUM; }
"secmark" { scanner_push_start_cond(yyscanner, SCANSTATE_SECMARK); return SECMARK; }
-"xt" { scanner_push_start_cond(yyscanner, SCANSTATE_XT); return XT; }
+<*>"xt" { scanner_push_start_cond(yyscanner, SCANSTATE_XT); return XT; }
{addrstring} {
yylval->string = xstrdup(yytext);
--- /dev/null
+#!/bin/bash
+
+stmts=()
+tcp_stmts=()
+udp_stmts=()
+ip6_stmts=()
+arp_stmts=()
+br_stmts=()
+netdev_stmts=()
+
+# verdict_stmt
+stmts+=(accept drop continue "jump c2" "goto c2" return)
+# verdict_map_stmt starts with concat_expr which eventually starts with primary_expr which starts with expr
+# match_stmt starts with relational_expr
+# meter_stmt
+stmts+=("meter foo { ip saddr counter }")
+# payload_stmt starts with payload_expr
+# stateful_stmt
+stmts+=(counter "limit rate 1/day" "quota 1bytes" "ct count 1" "last used 1d")
+# meta_stmt, defer to meta_expr with meta_key and meta_key_unqualified
+stmts+=(notrack "flow offload @ft" "nftrace set 1")
+# log_stmt
+stmts+=(log)
+# reject_stmt
+stmts+=(reject)
+# nat_stmt
+stmts+=("snat to 1" "dnat to 1")
+# tproxy_stmt
+tcp_stmts+=("tproxy to 1")
+# queue_stmt
+stmts+=("queue to 1")
+# ct_stmt
+stmts+=("ct mark set 1")
+# masq_stmt
+stmts+=(masquerade)
+# redir_stmt
+stmts+=(redirect)
+# dup_stmt
+netdev_stmts+=('dup to "lo"')
+# fwd_stmt
+netdev_stmts+=('fwd to "lo"')
+# set_stmt / map_stmt
+stmts+=("set add ip saddr @foo" "add @foo { ip saddr }" "update @foo { ip saddr }" "delete @foo { ip saddr }")
+# synproxy_stmt
+stmts+=(synproxy)
+# chain_stmt starts with jump/goto, covered by verdict_stmt above
+# optstrip_stmt
+stmts+=("reset tcp option echo")
+# XXX: xt_stmt is special, have to expect failure
+#stmts+=("xt foo bar")
+# objref_stmt is mostly covered by stateful_stmt above
+netdev_stmts+=("tunnel id 0")
+
+# primary_expr
+# XXX: parser_bison.y formally accepts string, integer_expr and variable_expr
+# (via primary_expr/symbol_expr) on LHS, but it is relevant for map
+# elements (data part) only it seems
+
+# selector_expr:
+# payload_expr
+stmts+=("@nh,0,4 0" "ether saddr 0" "vlan id 0")
+arp_stmts+=("arp htype 0")
+stmts+=("ip saddr 0" "icmp type 0" "igmp type 0")
+ip6_stmts+=("ip6 saddr ::")
+stmts+=("icmpv6 type 0" "ah spi 0" "esp spi 0" "comp cpi 0")
+stmts+=("udp sport 0" "udplite sport 0" "tcp sport 0" "dccp sport 0")
+stmts+=("sctp sport 0" "th sport 0")
+udp_stmts+=("vxlan vni 0" "geneve vni 0")
+stmts+=("gre flags 0" "gretap ip saddr 0")
+# exthdr_expr
+ip6_stmts+=("hbh nexthdr 0" "rt nexthdr 0" "rt0 addr[0] 0")
+ip6_stmts+=("rt2 addr ::" "srh tag 0" "frag nexthdr 0")
+ip6_stmts+=("dst nexthdr 0" "mh nexthdr 0" "exthdr hbh 0")
+# meta_expr
+stmts+=("meta length 0" "mark 0" "iif 0" "iifname foo" "iiftype 0")
+stmts+=("oif 0" "oifname foo" "oiftype 0" "skuid 0" "skgid 0" "rtclassid 0")
+stmts+=("pkttype 0" "cpu 0" "iifgroup 0" "oifgroup 0" "cgroup 0" "ipsec 0")
+stmts+=("time 0" "day 0" "hour 0")
+br_stmts+=("ibriport foo" "ibrname foo" "obriport foo" "obrname foo")
+# tunnel_expr covered by objref_stmt above
+# socket_expr
+stmts+=("socket mark 0")
+# rt_expr covered by exthdr_expr above
+# ct_expr covered by ct_stmt above
+# numgen_expr
+stmts+=("numgen inc mod 3 0")
+# hash_expr
+stmts+=("jhash ip saddr mod 3 seed 1 0" "symhash mod 3 0")
+# fib_expr
+stmts+=("fib daddr . iif check exists")
+# osf_expr
+stmts+=("osf name foo")
+# xfrm_expr
+stmts+=("ipsec in spi 0")
+
+$NFT -f - <<EOF
+table t {
+ flowtable ft {
+ hook ingress priority 0;
+ }
+ chain c {
+ }
+ chain c2 {
+ }
+}
+table ip6 t {
+ chain c {
+ }
+}
+table arp t {
+ chain c {
+ }
+}
+table bridge t {
+ chain c {
+ }
+}
+table netdev t {
+ chain c {
+ }
+}
+EOF
+
+RC=0
+for stmt in "${stmts[@]}"; do
+ $NFT add rule t c "limit rate 1/second $stmt" || {
+ echo "appending $stmt failed"
+ RC=1
+ }
+done
+for stmt in "${tcp_stmts[@]}"; do
+ $NFT add rule t c "meta l4proto tcp limit rate 1/second $stmt" || {
+ echo "appending $stmt failed"
+ RC=1
+ }
+done
+for stmt in "${udp_stmts[@]}"; do
+ $NFT add rule t c "meta l4proto udp limit rate 1/second $stmt" || {
+ echo "appending $stmt failed"
+ RC=1
+ }
+done
+for stmt in "${ip6_stmts[@]}"; do
+ $NFT add rule ip6 t c "meta l4proto tcp limit rate 1/second $stmt" || {
+ echo "appending $stmt failed"
+ RC=1
+ }
+done
+for stmt in "${arp_stmts[@]}"; do
+ $NFT add rule arp t c "meta l4proto tcp limit rate 1/second $stmt" || {
+ echo "appending $stmt failed"
+ RC=1
+ }
+done
+for stmt in "${br_stmts[@]}"; do
+ $NFT add rule bridge t c "meta l4proto tcp limit rate 1/second $stmt" || {
+ echo "appending $stmt failed"
+ RC=1
+ }
+done
+for stmt in "${netdev_stmts[@]}"; do
+ $NFT add rule netdev t c "meta l4proto tcp limit rate 1/second $stmt" || {
+ echo "appending $stmt failed"
+ RC=1
+ }
+done
+exit $RC
+