{
  pkgs,
  lib,
  meta,
  name,
  ...
}:

let
  inherit (lib) mapAttrs' nameValuePair;

  uplink = {
    ip = "10.120.33.250";
    prefix = 30;

    router = "10.120.33.249";
  };

  mkNetwork =
    name:
    {
      address ? [ ],
      extraNetwork ? { },
      ...
    }:
    nameValuePair "10-${name}" ({ inherit name address; } // extraNetwork);

  mkNetdev =
    name:
    { Id, ... }:
    nameValuePair "10-${name}" {
      netdevConfig = {
        Name = name;
        Kind = "vlan";
      };
      vlanConfig.Id = Id;
    };

  mkUserVlan =
    {
      vlan,
      netIP,
      servIP,
      interfaceName,
      ...
    }:
    {
      name = interfaceName;
      value = {
        Id = vlan;
        extraNetwork = {
          networkConfig = {
            LinkLocalAddressing = "no";
            DHCPServer = "yes";
          };
          linkConfig.Promiscuous = true;
          addresses = [
            {
              addressConfig = {
                Address = "${servIP}/27";
                AddPrefixRoute = false;
              };
            }
          ];
          routes = [
            {
              routeConfig = {
                Destination = "${netIP}/27";
                Table = "user";
              };
            }
          ];
          routingPolicyRules = [
            {
              routingPolicyRuleConfig = {
                From = "${netIP}/27";
                To = "10.0.0.0/27";
                IncomingInterface = interfaceName;
                Table = "user";
              };
            }
          ];
        };
      };
    };

  userVlans = builtins.genList (id: rec {
    vlan = 4094 - id;
    prefix24nb = (id + 1) / 8;
    prefix27nb = (id + 1 - prefix24nb * 8) * 32;
    netIP = "10.0.${toString prefix24nb}.${toString prefix27nb}";
    servIP = "10.0.${toString prefix24nb}.${toString (prefix27nb + 1)}";
    interfaceName = "vlan-user-${toString vlan}";
  }) 850;

  vlans = {
    vlan-uplink-cri = {
      Id = 223;
      address = with uplink; [ "${ip}/${builtins.toString prefix}" ];

      extraNetwork.routes = [
        {
          routeConfig = {
            # Get the public ip from the metadata
            PreferredSource = builtins.head meta.network.${name}.addresses.ipv4;
            Gateway = uplink.router;
          };
        }
      ];
    };

    vlan-admin = {
      Id = 3000;
      address = [ "fd26:baf9:d250:8000::1/64" ];
    };

    vlan-admin-ap = {
      Id = 3001;
      address = [ "fd26:baf9:d250:8001::1/64" ];
      extraNetwork.ipv6Prefixes = [
        {
          ipv6PrefixConfig = {
            AddressAutoconfiguration = false;
            OnLink = false;
            Prefix = "fd26:baf9:d250:8001::/64";
          };
        }
      ];
    };

    vlan-apro = {
      Id = 2000;
      address = [ "10.0.255.1/24" ];

      extraNetwork.networkConfig.DHCPServer = "yes";
    };
  } // builtins.listToAttrs (map mkUserVlan userVlans);
in

{
  systemd = {
    network = {
      config.routeTables."user" = 1000;
      networks = {
        "10-lo" = {
          name = "lo";
          address = [
            "::1/128"
            "127.0.0.1/8"
            "10.0.0.1/27"
          ];
          routes = [
            {
              routeConfig = {
                Destination = "10.0.0.0/27";
                Table = "user";
              };
            }
          ];
          routingPolicyRules = [
            {
              routingPolicyRuleConfig = {
                IncomingInterface = "lo";
                Table = "user";
              };
            }
          ];
        };
        "10-enp67s0f0np0" = {
          name = "enp67s0f0np0";
          linkConfig.Promiscuous = true;
          networkConfig = {
            VLAN = builtins.attrNames vlans;

            LinkLocalAddressing = false;
            LLDP = false;
            EmitLLDP = false;
            IPv6AcceptRA = false;
            IPv6SendRA = false;
          };
        };
      } // (mapAttrs' mkNetwork vlans);

      netdevs = mapAttrs' mkNetdev vlans;
    };

    services = {
      ethtoolConfig = {
        wantedBy = [ "systemd-networkd.service" ];
        after = [ "sys-subsystem-net-devices-enp67s0f0np0.device" ];
        bindsTo = [ "sys-subsystem-net-devices-enp67s0f0np0.device" ];
        script = builtins.concatStringsSep "\n" (
          builtins.map (name: "${lib.getExe pkgs.ethtool} -K enp67s0f0np0 ${name} off") [
            "rxvlan"
            "txvlan"
            "rx-vlan-filter"
            "rx-vlan-offload"
            "tx-vlan-offload"
            "tx-vlan-stag-hw-insert"
          ]
        );
      };

      systemd-networkd.serviceConfig.LimitNOFILE = 4096;

      net-checker = {
        path = [
          pkgs.iputils
          pkgs.systemd
        ];
        script = ''
          if ping -c 1 8.8.8.8 > /dev/null || ping -c 1 1.1.1.1 > /dev/null; then
            ${
              lib.concatMapStringsSep "\n  " ({ interfaceName, ... }: "networkctl up ${interfaceName}") userVlans
            }
          else
            ${
              lib.concatMapStringsSep "\n  " (
                { interfaceName, ... }: "networkctl down ${interfaceName}"
              ) userVlans
            }
          fi
        '';
      };
    };

    timers.net-checker = {
      wantedBy = [ "timers.target" ];
      timerConfig.OnCalendar = "*-*-* *:*:42";
    };
  };

  networking = {
    nftables = {
      enable = true;
      tables.nat = {
        family = "ip";
        content = ''
          chain postrouting {
            type nat hook postrouting priority 100;
            ip saddr 10.0.0.0/16 ip saddr != 10.0.255.0/24 snat ip to 129.199.195.130-129.199.195.158
            ether saddr e0:2b:e9:b5:b4:cc snat to 129.199.195.130 comment "Elias"
            ether saddr { 1c:1b:b5:14:9c:e5, e6:ce:e2:b6:e3:82 } snat to 129.199.195.131 comment "Lubin"
            ether saddr d0:49:7c:46:f6:39 snat to 129.199.195.132 comment "Jean-Marc"
            ether saddr { 5c:64:8e:f4:09:06 } snat to 129.199.195.158 comment "APs"
          }
        '';
      };
    };
    firewall = {
      allowedUDPPorts = [ 67 ];
      checkReversePath = false;
    };
  };

  boot.kernel.sysctl."net.ipv4.ip_forward" = true;
}