diff --git a/default.nix b/default.nix
index de10968..5394efb 100644
--- a/default.nix
+++ b/default.nix
@@ -4,7 +4,6 @@ with lib;
 
 let
   cfg = config.ffnix;
-  activeDomains = attrsets.filterAttrs (n: v: v.enable) cfg.domains;
 in
 {
   options.ffnix = {
@@ -52,6 +51,13 @@ in
           routingTable = mkOption {
             type = types.int;
           };
+          defaultNullRoute = mkOption {
+            type = types.bool;
+            default = true;
+            description = ''
+              Create a Null-Route in the routing-table to allow traffic leaks on the gateways default route when uplink is down.
+            '';
+          };
           mtu = mkOption {
             type = types.int;
           };
@@ -71,6 +77,10 @@ in
             default = [];
             type = types.listOf types.str;
           };
+          batmanAlgorithm = mkOption {
+            default = "batman-iv";
+            type = types.str;
+          };
           tunnels = mkOption {
             default = {};
             type = (pkgs.formats.json {}).type;
@@ -85,10 +95,10 @@ in
 
     programs.mtr.enable = true;
 
-    environment.etc."ffnix.json".source = pkgs.writeText "ffnix.json" (generators.toJSON {} activeDomains);
   };
 
   imports = [
+    ./modules
     ./modules/batman.nix
     ./modules/fastd.nix
     ./modules/bird
diff --git a/modules/bird/default.nix b/modules/bird/default.nix
index e17b80c..72ec071 100644
--- a/modules/bird/default.nix
+++ b/modules/bird/default.nix
@@ -1,7 +1,5 @@
 { config, lib, pkgs, ... }:
 
-with import ../common-vars.nix { inherit lib config; };
-
 let
   cfg = config.ffnix.bird;
 in {
diff --git a/modules/default.nix b/modules/default.nix
new file mode 100644
index 0000000..5ead52f
--- /dev/null
+++ b/modules/default.nix
@@ -0,0 +1,95 @@
+{ pkgs, config, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.ffnix;
+  activeDomains = attrsets.filterAttrs (n: v: v.enable) cfg.domains;
+
+  mkDomain = name: domCfg:
+    let
+      mkIfName = type:
+        if type == "bridge" then "br-${name}" else
+        if type == "batman" then "bat-${name}" else
+        throw "unknown interface type ${type}, coud not generate name";
+    in {
+      networks."10-lo" = {
+        routes = if !domCfg.defaultNullRoute then [] else [
+          {
+            routeConfig = {
+              Destination = "0.0.0.0/0";
+              Metric = 200;
+              Type = "unreachable";
+              Table = domCfg.routingTable;
+            };
+          }
+          {
+            routeConfig = {
+              Destination = "::/0";
+              Metric = 200;
+              Type = "unreachable";
+              Table = domCfg.routingTable;
+            };
+          }
+        ];
+      };
+
+      netdevs."30-${mkIfName "bridge"}".netdevConfig = {
+        Name = mkIfName "bridge";
+        Kind = "bridge";
+      };
+      networks."30-${mkIfName "bridge"}" = {
+        matchConfig.Name = mkIfName "bridge";
+        linkConfig.RequiredForOnline = "no";
+        address = domCfg.addresses;
+        routes = map (prefix: {
+          routeConfig = {
+            Destination = prefix;
+            Scope = "link";
+            Table = domCfg.routingTable;
+          };
+        }) (domCfg.ipv6Prefixes ++ [ domCfg.ipv4Prefix ]);
+        routingPolicyRules = [
+          {
+            routingPolicyRuleConfig = {
+              IncomingInterface = mkIfName "bridge";
+              Table = domCfg.routingTable;
+              Family = "both";
+            };
+          }
+        ] ++ map (prefix: {
+          routingPolicyRuleConfig = {
+            From = prefix;
+            Table = domCfg.routingTable;
+          };
+        }) (domCfg.ipv6Prefixes ++ [ domCfg.ipv4Prefix ]);
+      };
+
+      netdevs."30-${mkIfName "batman"}" = mkIf (!cfg.batmanLegacy) {
+        netdevConfig = {
+          Kind = "batadv";
+          Name = mkIfName "batman";
+        };
+        batmanAdvancedConfig = {
+          GatewayMode = "server";
+          RoutingAlgorithm = domCfg.batmanAlgorithm;
+          OriginatorIntervalSec = 5;
+        };
+      };
+      networks."30-${mkIfName "batman"}" = {
+        matchConfig.Name = mkIfName "batman";
+        bridge = [ "${mkIfName "bridge"}" ];
+      };
+    };
+
+    domConfigs = map (key: getAttr key (mapAttrs mkDomain activeDomains)) (attrNames activeDomains);
+    mergedConfigs = mapAttrs (name: value: mkMerge value) (attrsets.zipAttrs (map (x: removeAttrs x [ "foo" ]) domConfigs));
+
+in
+{
+  config = mkIf cfg.enable {
+    environment.etc."ffnix.json".source = pkgs.writeText "ffnix.json" (generators.toJSON {} activeDomains);
+    systemd.network.netdevs = mergedConfigs.netdevs;
+    systemd.network.networks = mergedConfigs.networks;
+  };
+}