diff --git a/examples/rotuer.nix b/examples/rotuer.nix index bfe1c41..eef0748 100644 --- a/examples/rotuer.nix +++ b/examples/rotuer.nix @@ -9,10 +9,6 @@ { config, pkgs, lib, ... } : let secrets = import ./rotuer-secrets.nix; - inherit (pkgs.liminix.networking) - address - interface - route; inherit (pkgs.liminix.services) oneshot longrun bundle target; inherit (pkgs) dropbear @@ -144,19 +140,16 @@ in rec { }; - services.defaultroute4 = route { - name = "defaultroute4"; + services.defaultroute4 = svc.network.route.build { via = "$(output ${services.wan} address)"; target = "default"; dependencies = [ services.wan ]; }; - services.defaultroute6 = route { - name = "defaultroute6"; + services.defaultroute6 = svc.network.route.build { via = "$(output ${services.wan} ipv6-peer-address)"; target = "default"; - dev = "$(output ${services.wan} ifname)"; - dependencies = [ services.wan ]; + interface = services.wan; }; services.firewall = svc.firewall.build { diff --git a/modules/network/default.nix b/modules/network/default.nix index 8bdcee2..7e82145 100644 --- a/modules/network/default.nix +++ b/modules/network/default.nix @@ -21,6 +21,9 @@ in { description = "network interface address"; type = liminix.lib.types.serviceDefn; }; + route = mkOption { + type = liminix.lib.types.serviceDefn; + }; dhcp = { client = mkOption { # this needs to move to its own service as it has @@ -82,6 +85,28 @@ in { type = types.ints.between 0 128; }; }; + + route = liminix.callService ./route.nix { + interface = mkOption { + type = types.nullOr liminix.lib.types.interface; + default = null; + description = "Interface to route through. May be omitted if it can be inferred from \"via\""; + }; + target = mkOption { + type = types.str; + description = "host or network to add route to"; + }; + via = mkOption { + type = types.str; + description = "address of next hop"; + }; + metric = mkOption { + type = types.int; + description = "route metric"; + default = 100; + }; + }; + dhcp.client = liminix.callService ./dhcpc.nix { interface = mkOption { type = liminix.lib.types.service; diff --git a/modules/network/route.nix b/modules/network/route.nix new file mode 100644 index 0000000..25c817a --- /dev/null +++ b/modules/network/route.nix @@ -0,0 +1,20 @@ +{ + liminix +, ifwait +, serviceFns +, lib +}: +{ target, via, interface ? null, metric }: +let + inherit (liminix.services) oneshot; + with_dev = if interface != null then "dev $(input ${interface} ifname)" else ""; +in oneshot { + name = "route-${target}-${builtins.substring 0 12 (builtins.hashString "sha256" "${via}-${if interface!=null then interface.name else ""}")}"; + up = '' + ip route add ${target} via ${via} metric ${toString metric} ${with_dev} + ''; + down = '' + ip route del ${target} via ${via} ${with_dev} + ''; + dependencies = [] ++ lib.optional (interface != null) interface; +}