table inet foomuuri
delete table inet foomuuri

table inet foomuuri {

	chain allow_icmp_4 {
		icmp type {
			destination-unreachable,  # 3, Destination Unreachable
			time-exceeded,            # 11, Time Exceeded
			parameter-problem         # 12, Parameter Problem
		} accept
	}

	chain allow_icmp_6 {
		icmpv6 type {
			destination-unreachable,  # 1, Destination Unreachable
			packet-too-big,           # 2, Packet Too Big
			time-exceeded,            # 3, Time Exceeded
			parameter-problem,        # 4, Parameter Problem
			nd-router-solicit,        # 133, Router Solicitation
			nd-neighbor-solicit,      # 135, Neighbor Solicitation
			nd-neighbor-advert,       # 136, Neighbor Advertisement
			ind-neighbor-solicit,     # 141, Inverse Neighbor Discovery Solicitation Message
			ind-neighbor-advert       # 142, Inverse Neighbor Discovery Advertisement Message
		} accept
		icmpv6 type . ip6 saddr {
			nd-router-advert . fe80::/10,      # 134, Router Advertisement
			mld-listener-query . fe80::/10,    # 130, Multicast Listener Query
			mld-listener-report . fe80::/10,   # 131, Multicast Listener Report
			mld-listener-done . fe80::/10,     # 132, Multicast Listener Done
			149 . fe80::/10,                   # 149, Certification Path Advertisement Message
			151 . fe80::/10,                   # 151, Multicast Router Advertisement
			152 . fe80::/10,                   # 152, Multicast Router Solicitation
			153 . fe80::/10,                   # 153, Multicast Router Termination
			mld2-listener-report . fe80::/10,  # 143, Version 2 Multicast Listener Report
			mld2-listener-report . ::,
			148 . fe80::/10,                   # 148, Certification Path Solicitation Message
			148 . ::
		} accept
	}

	chain smurfs_4 {
		ip saddr 0.0.0.0 return
		fib saddr type { broadcast, multicast } jump smurfs_drop
	}

	chain smurfs_6 {
		fib saddr type multicast jump smurfs_drop
	}

	chain invalid_drop {
		drop
	}

	chain smurfs_drop {
		drop
	}

	chain rpfilter_drop {
		udp sport 67 udp dport 68 return
		update @_lograte_set_4 { ip saddr limit rate 1/second burst 3 packets } log prefix "RPFILTER DROP " level info flags skuid
		update @_lograte_set_6 { ip6 saddr limit rate 1/second burst 3 packets } log prefix "RPFILTER DROP " level info flags skuid
		drop
	}

	chain input {
		type filter hook input priority filter + 5
		iifname vmap @input_zones
		update @_lograte_set_4 { ip saddr limit rate 1/second burst 3 packets } log prefix "INPUT DROP " level info flags skuid
		update @_lograte_set_6 { ip6 saddr limit rate 1/second burst 3 packets } log prefix "INPUT DROP " level info flags skuid
		drop
	}

	chain output {
		type filter hook output priority filter + 5
		oifname vmap @output_zones
		ip protocol igmp ip daddr 224.0.0.22 accept
		ip6 saddr :: icmpv6 type mld2-listener-report accept
		update @_lograte_set_4 { ip saddr limit rate 1/second burst 3 packets } log prefix "OUTPUT REJECT " level info flags skuid
		update @_lograte_set_6 { ip6 saddr limit rate 1/second burst 3 packets } log prefix "OUTPUT REJECT " level info flags skuid
		reject with icmpx admin-prohibited
	}

	chain forward {
		type filter hook forward priority filter + 5
		iifname . oifname vmap @forward_zones
		update @_lograte_set_4 { ip saddr limit rate 1/second burst 3 packets } log prefix "FORWARD DROP " level info flags skuid
		update @_lograte_set_6 { ip6 saddr limit rate 1/second burst 3 packets } log prefix "FORWARD DROP " level info flags skuid
		drop
	}

	set _rate_set_1_4 {
		type ipv4_addr
		size 65535
		flags dynamic,timeout
		timeout 1m
	}

	set _rate_set_1_6 {
		type ipv6_addr
		size 65535
		flags dynamic,timeout
		timeout 1m
	}

	set _rate_set_2_4 {
		type ipv4_addr
		size 65535
		flags dynamic,timeout
		timeout 1m
	}

	set _rate_set_2_6 {
		type ipv6_addr
		size 65535
		flags dynamic,timeout
		timeout 1m
	}

	set _rate_set_3_4 {
		type ipv4_addr
		size 65535
		flags dynamic,timeout
		timeout 1m
	}

	set _rate_set_3_6 {
		type ipv6_addr
		size 65535
		flags dynamic,timeout
		timeout 1m
	}

	map input_zones {
		type ifname : verdict
		elements = {
			"lo" : accept,
		}
	}

	map output_zones {
		type ifname : verdict
		elements = {
			"lo" : accept,
		}
	}

	map forward_zones {
		type ifname . ifname : verdict
		elements = {
			"lo" . "lo" : accept,
		}
	}

	chain public-localhost {
		meta nfproto vmap {
			ipv4 : jump public-localhost_4,
			ipv6 : jump public-localhost_6
		}
	}

	chain public-localhost_4 {
		icmp type echo-request update @_rate_set_1_4 { ip saddr limit rate 5/second burst 20 packets } accept
		icmp type echo-request drop
		jump allow_icmp_4
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_4,
			untracked : jump smurfs_4
		}
		meta pkttype broadcast udp dport 68 accept
		ip protocol igmp ip daddr 224.0.0.1 accept
		meta pkttype { broadcast, multicast } drop
		udp dport 68 accept
		tcp dport 22 update @_rate_set_3_4 { ip saddr limit rate 5/minute burst 5 packets } accept
		update @_lograte_set_4 { ip saddr limit rate 1/second burst 3 packets } log prefix "public-localhost DROP " level info flags skuid
		drop
	}

	chain public-localhost_6 {
		icmpv6 type echo-request update @_rate_set_2_6 { ip6 saddr limit rate 5/second burst 20 packets } accept
		icmpv6 type echo-request drop
		jump allow_icmp_6
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_6,
			untracked : jump smurfs_6
		}
		meta pkttype multicast drop
		ip6 daddr fe80::/10 udp sport 547 udp dport 546 accept
		tcp dport 22 update @_rate_set_3_6 { ip6 saddr limit rate 5/minute burst 5 packets } accept
		update @_lograte_set_6 { ip6 saddr limit rate 1/second burst 3 packets } log prefix "public-localhost DROP " level info flags skuid
		drop
	}

	chain home-localhost {
		meta nfproto vmap {
			ipv4 : jump home-localhost_4,
			ipv6 : jump home-localhost_6
		}
	}

	chain home-localhost_4 {
		icmp type echo-request accept
		jump allow_icmp_4
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_4,
			untracked : jump smurfs_4
		}
		ip protocol igmp ip daddr 224.0.0.1 accept
		meta pkttype multicast ip daddr 224.0.0.251 udp dport 5353 accept
		meta pkttype multicast ip daddr 224.0.0.251 ip protocol igmp accept
		meta pkttype multicast ip daddr 239.255.255.250 udp dport 1900 accept
		meta pkttype multicast ip daddr 239.255.255.250 ip protocol igmp accept
		meta pkttype broadcast udp dport { 11430, 68 } accept
		meta pkttype { broadcast, multicast } drop
		udp dport 68 accept
		udp sport { 1900, 5353 } accept
		tcp dport 22 accept
		update @_lograte_set_4 { ip saddr limit rate 1/second burst 3 packets } log prefix "home-localhost DROP " level info flags skuid
		drop
	}

	chain home-localhost_6 {
		icmpv6 type echo-request accept
		jump allow_icmp_6
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_6,
			untracked : jump smurfs_6
		}
		meta pkttype multicast ip6 daddr ff02::fb udp dport 5353 accept
		meta pkttype multicast ip6 daddr ff02::c udp dport 1900 accept
		meta pkttype multicast drop
		udp sport { 1900, 5353 } accept
		tcp dport 22 accept
		ip6 daddr fe80::/10 udp sport 547 udp dport 546 accept
		update @_lograte_set_6 { ip6 saddr limit rate 1/second burst 3 packets } log prefix "home-localhost DROP " level info flags skuid
		drop
	}

	chain localhost-public {
		meta nfproto vmap {
			ipv4 : jump localhost-public_4,
			ipv6 : jump localhost-public_6
		}
	}

	chain localhost-public_4 {
		icmp type echo-request accept
		jump allow_icmp_4
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_4,
			untracked : jump smurfs_4
		}
		udp dport { 123, 443, 53, 67 } accept
		tcp dport { 143, 22, 25, 443, 53, 80 } accept
		ip protocol igmp ip daddr 224.0.0.22 accept
		update @_lograte_set_4 { ip saddr limit rate 1/second burst 3 packets } log prefix "localhost-public REJECT " level info flags skuid
		reject with icmpx admin-prohibited
	}

	chain localhost-public_6 {
		icmpv6 type echo-request accept
		jump allow_icmp_6
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_6,
			untracked : jump smurfs_6
		}
		udp dport { 123, 443, 53 } accept
		tcp dport { 143, 22, 25, 443, 53, 80 } accept
		ip6 daddr ff02::1:2 udp sport 546 udp dport 547 accept
		update @_lograte_set_6 { ip6 saddr limit rate 1/second burst 3 packets } log prefix "localhost-public REJECT " level info flags skuid
		reject with icmpx admin-prohibited
	}

	chain localhost-home {
		meta nfproto vmap {
			ipv4 : jump localhost-home_4,
			ipv6 : jump localhost-home_6
		}
	}

	chain localhost-home_4 {
		icmp type echo-request accept
		jump allow_icmp_4
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_4,
			untracked : jump smurfs_4
		}
		udp dport { 123, 19302-19309, 3478, 443, 53, 67 } accept
		udp sport { 1900, 5353 } accept
		tcp dport { 143, 22, 25, 443, 53, 631, 80 } accept
		ip protocol igmp ip daddr 224.0.0.22 accept
		ip daddr 224.0.0.251 udp dport 5353 accept
		ip daddr 224.0.0.251 ip protocol igmp accept
		ip daddr 239.255.255.250 udp dport 1900 accept
		ip daddr 239.255.255.250 ip protocol igmp accept
		update @_lograte_set_4 { ip saddr limit rate 1/second burst 3 packets } log prefix "localhost-home REJECT " level info flags skuid
		reject with icmpx admin-prohibited
	}

	chain localhost-home_6 {
		icmpv6 type echo-request accept
		jump allow_icmp_6
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_6,
			untracked : jump smurfs_6
		}
		udp dport { 123, 19302-19309, 3478, 443, 53 } accept
		udp sport { 1900, 5353 } accept
		tcp dport { 143, 22, 25, 443, 53, 631, 80 } accept
		ip6 daddr ff02::1:2 udp sport 546 udp dport 547 accept
		ip6 daddr ff02::fb udp dport 5353 accept
		ip6 daddr ff02::c udp dport 1900 accept
		update @_lograte_set_6 { ip6 saddr limit rate 1/second burst 3 packets } log prefix "localhost-home REJECT " level info flags skuid
		reject with icmpx admin-prohibited
	}

	chain localhost-localhost {
		meta nfproto vmap {
			ipv4 : jump localhost-localhost_4,
			ipv6 : jump localhost-localhost_6
		}
	}

	chain localhost-localhost_4 {
		jump allow_icmp_4
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_4,
			untracked : jump smurfs_4
		}
		accept
	}

	chain localhost-localhost_6 {
		jump allow_icmp_6
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_6,
			untracked : jump smurfs_6
		}
		accept
	}

	chain public-public {
		meta nfproto vmap {
			ipv4 : jump public-public_4,
			ipv6 : jump public-public_6
		}
	}

	chain public-public_4 {
		jump allow_icmp_4
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_4,
			untracked : jump smurfs_4
		}
		meta pkttype { broadcast, multicast } drop
		update @_lograte_set_4 { ip saddr limit rate 1/second burst 3 packets } log prefix "public-public DROP " level info flags skuid
		drop
	}

	chain public-public_6 {
		jump allow_icmp_6
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_6,
			untracked : jump smurfs_6
		}
		meta pkttype multicast drop
		update @_lograte_set_6 { ip6 saddr limit rate 1/second burst 3 packets } log prefix "public-public DROP " level info flags skuid
		drop
	}

	chain public-home {
		meta nfproto vmap {
			ipv4 : jump public-home_4,
			ipv6 : jump public-home_6
		}
	}

	chain public-home_4 {
		jump allow_icmp_4
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_4,
			untracked : jump smurfs_4
		}
		meta pkttype { broadcast, multicast } drop
		update @_lograte_set_4 { ip saddr limit rate 1/second burst 3 packets } log prefix "public-home DROP " level info flags skuid
		drop
	}

	chain public-home_6 {
		jump allow_icmp_6
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_6,
			untracked : jump smurfs_6
		}
		meta pkttype multicast drop
		update @_lograte_set_6 { ip6 saddr limit rate 1/second burst 3 packets } log prefix "public-home DROP " level info flags skuid
		drop
	}

	chain home-public {
		meta nfproto vmap {
			ipv4 : jump home-public_4,
			ipv6 : jump home-public_6
		}
	}

	chain home-public_4 {
		jump allow_icmp_4
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_4,
			untracked : jump smurfs_4
		}
		meta pkttype { broadcast, multicast } drop
		update @_lograte_set_4 { ip saddr limit rate 1/second burst 3 packets } log prefix "home-public DROP " level info flags skuid
		drop
	}

	chain home-public_6 {
		jump allow_icmp_6
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_6,
			untracked : jump smurfs_6
		}
		meta pkttype multicast drop
		update @_lograte_set_6 { ip6 saddr limit rate 1/second burst 3 packets } log prefix "home-public DROP " level info flags skuid
		drop
	}

	chain home-home {
		meta nfproto vmap {
			ipv4 : jump home-home_4,
			ipv6 : jump home-home_6
		}
	}

	chain home-home_4 {
		jump allow_icmp_4
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_4,
			untracked : jump smurfs_4
		}
		meta pkttype { broadcast, multicast } drop
		update @_lograte_set_4 { ip saddr limit rate 1/second burst 3 packets } log prefix "home-home DROP " level info flags skuid
		drop
	}

	chain home-home_6 {
		jump allow_icmp_6
		ct state vmap {
			established : accept,
			related : accept,
			invalid : jump invalid_drop,
			new : jump smurfs_6,
			untracked : jump smurfs_6
		}
		meta pkttype multicast drop
		update @_lograte_set_6 { ip6 saddr limit rate 1/second burst 3 packets } log prefix "home-home DROP " level info flags skuid
		drop
	}

	set _lograte_set_4 {
		type ipv4_addr
		size 65535
		flags dynamic,timeout
		timeout 1m
	}

	set _lograte_set_6 {
		type ipv6_addr
		size 65535
		flags dynamic,timeout
		timeout 1m
	}

	chain rpfilter {
		type filter hook prerouting priority filter + 5
		fib saddr . mark . iif oif 0 meta ipsec missing jump rpfilter_drop
	}

}
