anchor.diff:      fi
     '';
   
  -in
  -
  -{
  -
  -  ###### interface
  -
  -  options = {
  -
  -    networking.firewall.enable = mkOption {
  -      type = types.bool;
  -      default = true;
  -      description =
  -        ''
  -          Whether to enable the firewall.  This is a simple stateful
  -          firewall that blocks connection attempts to unauthorised TCP
  -          or UDP ports on this machine.  It does not affect packet
  -          forwarding.
  -        '';
  -    };
  -
  -    networking.firewall.logRefusedConnections = mkOption {
  -      type = types.bool;
  -      default = true;
  -      description =
  -        ''
  -          Whether to log rejected or dropped incoming connections.
  -        '';
  -    };
  -
  -    networking.firewall.logRefusedPackets = mkOption {
  -      type = types.bool;
  -      default = false;
  -      description =
  -        ''
  -          Whether to log all rejected or dropped incoming packets.
  -          This tends to give a lot of log messages, so it's mostly
  -          useful for debugging.
  -        '';
  -    };
  -
  -    networking.firewall.logRefusedUnicastsOnly = mkOption {
  -      type = types.bool;
  -      default = true;
  -      description =
  -        ''
  -          If <option>networking.firewall.logRefusedPackets</option>
  -          and this option are enabled, then only log packets
  -          specifically directed at this machine, i.e., not broadcasts
  -          or multicasts.
  -        '';
  -    };
  -
  -    networking.firewall.rejectPackets = mkOption {
  -      type = types.bool;
  -      default = false;
  -      description =
  -        ''
  -          If set, refused packets are rejected rather than dropped
  -          (ignored).  This means that an ICMP "port unreachable" error
  -          message is sent back to the client (or a TCP RST packet in
  -          case of an existing connection).  Rejecting packets makes
  -          port scanning somewhat easier.
  -        '';
  -    };
  -
  -    networking.firewall.trustedInterfaces = mkOption {
  -      type = types.listOf types.str;
  -      default = [ ];
  -      example = [ "enp0s2" ];
  -      description =
  -        ''
  -          Traffic coming in from these interfaces will be accepted
  -          unconditionally.  Traffic from the loopback (lo) interface
  -          will always be accepted.
  -        '';
  -    };
  -
  -    networking.firewall.allowedTCPPorts = mkOption {
  +  commonOptions = {
  +    allowedTCPPorts = mkOption {
         type = types.listOf types.int;
         default = [ ];
         example = [ 22 80 ];
         description =
  -        ''
  +        '' 
             List of TCP ports on which incoming connections are
             accepted.
           '';
       };
   
  -    networking.firewall.allowedTCPPortRanges = mkOption {
  +    allowedTCPPortRanges = mkOption {
         type = types.listOf (types.attrsOf types.int);
         default = [ ];
         example = [ { from = 8999; to = 9003; } ];
         description =
  -        ''
  +        '' 
             A range of TCP ports on which incoming connections are
             accepted.
           '';
       };
   
  -    networking.firewall.allowedUDPPorts = mkOption {
  +    allowedUDPPorts = mkOption {
         type = types.listOf types.int;
         default = [ ];
         example = [ 53 ];
  
positive.code:         '';
      };
  
      networking.firewall.allowedUDPPortRanges = mkOption {
        type = types.listOf (types.attrsOf types.int);
        default = [ ];
        example = [ { from = 60000; to = 61000; } ];
  
negative.code:     ip46tables -A nixos-fw -m conntrack --ctstate ESTABLISHED,RELATED -j nixos-fw-accept
  
      # Accept connections to the allowed TCP ports.
      ${concatStrings (mapAttrsToList (iface: cfg:
        concatMapStrings (port:
          ''
            ip46tables -A nixos-fw -p tcp --dport ${toString port} -j nixos-fw-accept ${optionalString (iface != "default") "-i ${iface}"}
          ''
        ) cfg.allowedTCPPorts
      ) cfg.interfaces)}
  
      # Accept connections to the allowed TCP port ranges.
      ${concatStrings (mapAttrsToList (iface: cfg:
        concatMapStrings (rangeAttr:
          let range = toString rangeAttr.from + ":" + toString rangeAttr.to; in
          ''
            ip46tables -A nixos-fw -p tcp --dport ${range} -j nixos-fw-accept ${optionalString (iface != "default") "-i ${iface}"}
          ''
        ) cfg.allowedTCPPortRanges
      ) cfg.interfaces)}
  
      # Accept packets on the allowed UDP ports.
      ${concatStrings (mapAttrsToList (iface: cfg:
        concatMapStrings (port:
          ''
            ip46tables -A nixos-fw -p udp --dport ${toString port} -j nixos-fw-accept ${optionalString (iface != "default") "-i ${iface}"}
          ''
        ) cfg.allowedUDPPorts
      ) cfg.interfaces)}
  
      # Accept packets on the allowed UDP port ranges.
      ${concatStrings (mapAttrsToList (iface: cfg:
        concatMapStrings (rangeAttr:
          let range = toString rangeAttr.from + ":" + toString rangeAttr.to; in
          ''
            ip46tables -A nixos-fw -p udp --dport ${range} -j nixos-fw-accept ${optionalString (iface != "default") "-i ${iface}"}
          ''
        ) cfg.allowedUDPPortRanges
      ) cfg.interfaces)}
  
      # Accept IPv4 multicast.  Not a big security risk since
      # probably nobody is listening anyway.
  