diff --git a/modules/bridge/default.nix b/modules/bridge/default.nix index fd779f8..4c2911a 100644 --- a/modules/bridge/default.nix +++ b/modules/bridge/default.nix @@ -20,6 +20,7 @@ in system.service.bridge = { primary = mkOption { type = liminix.lib.types.serviceDefn; }; members = mkOption { type = liminix.lib.types.serviceDefn; }; + ready = mkOption { type = liminix.lib.types.serviceDefn; }; }; }; config.system.service.bridge = { @@ -46,6 +47,19 @@ in description = "interfaces to add to the bridge"; }; }; + + # TODO: generalize it outside + ready = config.system.callService ./ready.nix { + primary = mkOption { + type = liminix.lib.types.service; + description = "primary bridge interface"; + }; + + members = mkOption { + type = liminix.lib.types.service; + description = "members service"; + }; + }; }; config.kernel.config = { BRIDGE = "y"; diff --git a/modules/bridge/members.nix b/modules/bridge/members.nix index 114bc2e..2171eda 100644 --- a/modules/bridge/members.nix +++ b/modules/bridge/members.nix @@ -10,26 +10,19 @@ let inherit (liminix.networking) interface; inherit (liminix.services) bundle oneshot; inherit (lib) mkOption types; - addif = member : - # how do we get sight of services from here? maybe we need to - # implement ifwait as a regualr derivation instead of a - # servicedefinition - svc.ifwait.build { - state = "running"; - interface = member; - dependencies = [ primary member ]; - service = oneshot { - name = "${primary.name}.member.${member.name}"; - up = '' - echo "attaching $(output ${member} ifname) to $(output ${primary} ifname) bridge" - ip link set dev $(output ${member} ifname) master $(output ${primary} ifname) - ''; - down = '' - echo "detaching $(output ${member} ifname) from any bridge" - ip link set dev $(output ${member} ifname) nomaster - ''; - }; - }; + addif = member : oneshot { + name = "${primary.name}.member.${member.name}"; + up = '' + echo "attaching $(output ${member} ifname) to $(output ${primary} ifname) bridge" + ip link set dev $(output ${member} ifname) master $(output ${primary} ifname) + ''; + down = '' + echo "detaching $(output ${member} ifname) from any bridge" + ip link set dev $(output ${member} ifname) nomaster + ''; + + dependencies = [ primary member ]; + }; in bundle { name = "${primary.name}.members"; contents = map addif members; diff --git a/modules/bridge/primary.nix b/modules/bridge/primary.nix index aa7822c..f5e1219 100644 --- a/modules/bridge/primary.nix +++ b/modules/bridge/primary.nix @@ -14,9 +14,13 @@ in oneshot rec { "ip link add name ${ifname} type bridge" else "ip link add name ${ifname} address $(output ${macAddressFromInterface} ether) type bridge"} - ${liminix.networking.ifup name ifname} + + (in_outputs ${name} + echo ${ifname} > ifname + cat /sys/class/net/${ifname}/address > ether + ) ''; - down = "ip link set down dev ${ifname}"; + down = "ip link delete ${ifname}"; dependencies = optional (macAddressFromInterface != null) macAddressFromInterface; } diff --git a/modules/bridge/ready.nix b/modules/bridge/ready.nix new file mode 100644 index 0000000..f8c40b3 --- /dev/null +++ b/modules/bridge/ready.nix @@ -0,0 +1,18 @@ +{ + liminix +, ifwait +, lib +}: +{ primary, members } : +let + inherit (liminix.services) oneshot; +in oneshot { + name = "${primary.name}.oper"; + up = '' + ip link set up dev $(output ${primary} ifname) + ${ifwait}/bin/ifwait -v $(output ${primary} ifname) running + ''; + down = "ip link set down dev $(output ${primary} ifname)"; + + dependencies = [ members ]; +}