define icmp_protos = { ipv6-icmp, icmp, igmp }

table arp filter {
  limit lim_arp_local {
    rate over 50 mbytes/second burst 50 mbytes
  }
  limit lim_arp_dsl {
    rate over 1400 kbytes/second burst 1400 kbytes
  }

  counter arp-rx {}
  counter arp-tx {}

  counter arp-ratelimit-dsl-rx {}
  counter arp-ratelimit-dsl-tx {}

  counter arp-ratelimit-local-rx {}
  counter arp-ratelimit-local-tx {}

  chain input {
    type filter hook input priority filter
    policy accept

    iifname != dsl limit name lim_arp_local counter name arp-ratelimit-local-rx drop
    iifname dsl limit name lim_arp_dsl counter name arp-ratelimit-dsl-rx drop

    counter name arp-rx
  }

  chain output {
    type filter hook output priority filter
    policy accept

    oifname != dsl limit name lim_arp_local counter name arp-ratelimit-local-tx drop
    oifname dsl limit name lim_arp_dsl counter name arp-ratelimit-dsl-tx drop

    counter name arp-tx
  }
}

table inet filter {
  limit lim_reject {
    rate over 1000/second burst 1000 packets
  }

  limit lim_icmp_local {
    rate over 50 mbytes/second burst 50 mbytes
  }
  limit lim_icmp_dsl {
    rate over 1400 kbytes/second burst 1400 kbytes
  }

  counter icmp-ratelimit-dsl-fw {}
  counter icmp-ratelimit-local-fw {}

  counter icmp-fw {}

  counter invalid-fw {}
  counter fw-lo {}
  counter fw-lan {}
  counter fw-dsl {}

  counter reject-ratelimit-fw {}
  counter reject-fw {}
  counter reject-tcp-fw {}
  counter reject-icmp-fw {}


  counter invalid-rx {}
  counter rx-lo {}
  counter invalid-local4-rx {}
  counter invalid-local6-rx {}

  counter icmp-ratelimit-dsl-rx {}
  counter icmp-ratelimit-local-rx {}
  counter icmp-rx {}

  counter ssh-rx {}
  counter mosh-rx {}
  counter dns-rx {}
  counter nfs-rx {}
  counter wg-rx {}
  counter yggdrasil-gre-rx {}
  counter ipv6-pd-rx {}
  counter ntp-rx {}
  counter dhcp-rx {}
  counter samba-rx {}
  counter http-rx {}
  counter tftp-rx {}

  counter established-rx {}

  counter reject-ratelimit-rx {}
  counter reject-rx {}
  counter reject-tcp-rx {}
  counter reject-icmp-rx {}


  counter tx-lo {}

  counter icmp-ratelimit-dsl-tx {}
  counter icmp-ratelimit-local-tx {}
  counter icmp-tx {}

  counter ssh-tx {}
  counter mosh-tx {}
  counter dns-tx {}
  counter nfs-tx {}
  counter wg-tx {}
  counter yggdrasil-gre-tx {}
  counter ipv6-pd-tx {}
  counter ntp-tx {}
  counter dhcp-tx {}
  counter samba-tx {}
  counter http-tx {}
  counter tftp-tx {}

  counter tx {}


  chain forward_icmp_accept {
    oifname { dsl, bifrost } limit name lim_icmp_dsl counter name icmp-ratelimit-dsl-fw drop
    iifname { dsl, bifrost } limit name lim_icmp_dsl counter name icmp-ratelimit-dsl-fw drop
    oifname != { dsl, bifrost } limit name lim_icmp_local counter name icmp-ratelimit-local-fw drop
    iifname != { dsl, bifrost } limit name lim_icmp_local counter name icmp-ratelimit-local-fw drop
    counter name icmp-fw accept
  }
  chain forward {
    type filter hook forward priority filter
    policy drop


    ct state invalid log level debug prefix "drop invalid forward: " counter name invalid-fw drop


    iifname lo counter name fw-lo accept

    oifname { lan, dsl, bifrost } meta l4proto $icmp_protos jump forward_icmp_accept

    iifname lan oifname { dsl, bifrost } counter name fw-lan accept
    iifname dsl oifname { lan, dmz01 } ct state {established, related} counter name fw-dsl accept



    limit name lim_reject log level debug prefix "drop forward: " counter name reject-ratelimit-fw drop
    log level debug prefix "reject forward: " counter name reject-fw
    meta l4proto tcp ct state new counter name reject-tcp-fw reject with tcp reset
    ct state new counter name reject-icmp-fw reject
  }

  chain input {
    type filter hook input priority filter
    policy drop


    ct state invalid log level debug prefix "drop invalid input: " counter name invalid-rx drop


    iifname lo counter name rx-lo accept
    iif != lo ip daddr 127.0.0.1/8 counter name invalid-local4-rx reject
    iif != lo ip6 daddr ::1/128 counter name invalid-local6-rx reject

    iifname { bifrost, dsl } meta l4proto $icmp_protos limit name lim_icmp_dsl counter name icmp-ratelimit-dsl-rx drop
    iifname != { bifrost, dsl } meta l4proto $icmp_protos limit name lim_icmp_local counter name icmp-ratelimit-local-rx drop
    meta l4proto $icmp_protos counter name icmp-rx accept

    iifname { lan, mgmt, dsl, yggdrasil, bifrost } tcp dport 22 counter name ssh-rx accept
    iifname { lan, mgmt, dsl, yggdrasil, bifrost } udp dport 60000-61000 counter name mosh-rx accept

    iifname { lan, mgmt, dmz01, yggdrasil } meta l4proto { tcp, udp } th dport 53 counter name dns-rx accept

    iifname { lan, yggdrasil } tcp dport 2049 counter name nfs-rx accept

    iifname { lan, mgmt, dsl } meta protocol ip udp dport 51820 counter name wg-rx accept
    iifname { lan, mgmt, dsl } meta protocol ip6 udp dport 51821 counter name wg-rx accept
    iifname "yggdrasil-wg-*" meta l4proto gre counter name yggdrasil-gre-rx accept

    iifname dsl meta protocol ip6 udp dport 546 udp sport 547 counter name ipv6-pd-rx accept

    iifname mgmt udp dport 123 counter name ntp-rx accept

    iifname { lan, mgmt, dmz01 } udp dport 67 counter name dhcp-rx accept

    iifname lan udp dport { 137, 138, 3702 } counter name samba-rx accept
    iifname lan tcp dport { 445, 139, 5357 } counter name samba-rx accept

    iifname yggdrasil tcp dport { 80, 443 } counter name http-rx accept
    iifname lan tcp dport 80 counter name http-rx accept

    iifname { lan, mgmt } udp dport 69 counter name tftp-rx accept

    ct state {established, related} counter name established-rx accept


    limit name lim_reject log level debug prefix "drop input: " counter name reject-ratelimit-rx drop
    log level debug prefix "reject input: " counter name reject-rx
    meta l4proto tcp ct state new counter name reject-tcp-rx reject with tcp reset
    ct state new counter name reject-icmp-rx reject
  }

  chain output {
    type filter hook output priority filter
    policy accept


    oifname lo counter name tx-lo accept

    oifname { bifrost, dsl } meta l4proto $icmp_protos limit name lim_icmp_dsl counter name icmp-ratelimit-dsl-tx drop
    oifname != { bifrost, dsl } meta l4proto $icmp_protos limit name lim_icmp_local counter name icmp-ratelimit-local-tx drop
    meta l4proto $icmp_protos counter name icmp-tx accept


    tcp sport 22 counter name ssh-tx
    udp sport 60000-61000 counter name mosh-tx

    meta l4proto {tcp, udp} th sport 53 counter name dns-tx

    tcp sport 2049 counter name nfs-tx

    meta protocol ip udp sport 51820 counter name wg-tx
    meta protocol ip6 udp sport {51821,51822} counter name wg-tx
    iifname "yggdrasil-wg-*" meta l4proto gre counter name yggdrasil-gre-tx

    meta protocol ip6 udp sport 546 udp dport 547 counter name ipv6-pd-tx

    udp sport 123 counter name ntp-tx accept

    udp sport 67 counter name dhcp-tx accept

    udp sport { 137, 138, 3702 } counter name samba-tx accept
    tcp sport { 445, 139, 5357 } counter name samba-tx accept

    tcp sport { 80, 443 } counter name http-tx accept

    udp sport 69 counter name tftp-tx accept
    udp dport 69 counter name tftp-tx accept


    counter name tx
  }
}

table ip nat {
  counter dsl-nat {}

  chain postrouting {
    type nat hook postrouting priority srcnat
    policy accept


    oifname dsl counter name dsl-nat masquerade
  }
}

table ip mss_clamp {
  counter dsl-mss-clamp {}

  chain postrouting {
    type filter hook postrouting priority mangle
    policy accept


    oifname dsl tcp flags & (syn|rst) == syn counter name dsl-mss-clamp tcp option maxseg size set rt mtu
  }
}