anchor.diff:          '';
         };
   
  -
  -  generateSetupServiceUnit = name: values:
  +  generatePeerUnit = { interfaceName, interfaceCfg, peer }:
  +    let
  +      keyToUnitName = replaceChars
  +        [ "/" "-"    " "     "+"     "="      ]
  +        [ "-" "\\x2d" "\\x20" "\\x2b" "\\x3d" ];
  +      unitName = keyToUnitName peer.publicKey;
  +      psk =
  +        if peer.presharedKey != null
  +          then pkgs.writeText "wg-psk" peer.presharedKey
  +          else peer.presharedKeyFile;
  +    in nameValuePair "wireguard-${interfaceName}-peer-${unitName}"
  +      {
  +        description = "WireGuard Peer - ${interfaceName} - ${peer.publicKey}";
  +        requires = [ "wireguard-${interfaceName}.service" ];
  +        after = [ "wireguard-${interfaceName}.service" ];
  +        wantedBy = [ "multi-user.target" ];
  +        environment.DEVICE = interfaceName;
  +        path = with pkgs; [ iproute wireguard-tools ];
  +
  +        serviceConfig = {
  +          Type = "oneshot";
  +          RemainAfterExit = true;
  +        };
  +
  +        script = let
  +          wg_setup = "wg set ${interfaceName} peer ${peer.publicKey}" +
  +            optionalString (psk != null) " preshared-key ${psk}" +
  +            optionalString (peer.endpoint != null) " endpoint ${peer.endpoint}" +
  +            optionalString (peer.persistentKeepalive != null) " persistent-keepalive ${toString peer.persistentKeepalive}" +
  +            optionalString (peer.allowedIPs != []) " allowed-ips ${concatStringsSep "," peer.allowedIPs}";
  +          route_setup =
  +            optionalString (interfaceCfg.allowedIPsAsRoutes != false)
  +              (concatMapStringsSep "\n"
  +                (allowedIP:
  +                  "ip route replace ${allowedIP} dev ${interfaceName} table ${interfaceCfg.table}"
  +                ) peer.allowedIPs);
  +        in ''
  +          ${wg_setup}
  +          ${route_setup}
  +        '';
  +
  +        postStop = let
  +          route_destroy = optionalString (interfaceCfg.allowedIPsAsRoutes != false)
  +            (concatMapStringsSep "\n"
  +              (allowedIP:
  +                "ip route delete ${allowedIP} dev ${interfaceName} table ${interfaceCfg.table}"
  +              ) peer.allowedIPs);
  +        in ''
  +          wg set ${interfaceName} peer ${peer.publicKey} remove
  +          ${route_destroy}
  +        '';
  +      };
  +
  +  generateInterfaceUnit = name: values:
       # exactly one way to specify the private key must be set
       #assert (values.privateKey != null) != (values.privateKeyFile != null);
       let privKey = if values.privateKeyFile != null then values.privateKeyFile else pkgs.writeText "wg-key" values.privateKey;
  
positive.code:         path = with pkgs; [ kmod iproute wireguard-tools ];
  
          serviceConfig = {
            Type = "simple";
            Restart = "on-failure";
            RestartSec = "5s";
            RemainAfterExit = true;
          };
  
  
negative.code: 
    ###### implementation
  
    config = mkIf cfg.enable (let
      all_peers = flatten
        (mapAttrsToList (interfaceName: interfaceCfg:
          map (peer: { inherit interfaceName interfaceCfg peer;}) interfaceCfg.peers
        ) cfg.interfaces);
    in {
  
      assertions = (attrValues (
          mapAttrs (name: value: {
  