commit 626a365f790f628dc8deff27b2296545f239d3fe
parent 14dacb80565c6e6d7080d2cd85abfbd19b875198
Author: Daniel Barlow <dan@telent.net>
Date: Wed, 1 Mar 2023 17:55:52 +0000
replace waitup with more generally useful ifwait
* wait for $interface present before ip link set up dev
* wait for wlan0 running before adding to bridge
Diffstat:
9 files changed, 134 insertions(+), 79 deletions(-)
diff --git a/overlay.nix b/overlay.nix
@@ -87,7 +87,7 @@ final: prev: {
};
netlink-lua = final.callPackage ./pkgs/netlink-lua {};
- waitup = final.callPackage ./pkgs/waitup {};
+ ifwait = final.callPackage ./pkgs/ifwait {};
serviceFns = final.writeText "service-fns.sh" ''
output() { cat $1/.outputs/$2; }
diff --git a/pkgs/ifwait/.#README b/pkgs/ifwait/.#README
@@ -0,0 +1 @@
+dan@noetbook.911352349782478447
+\ No newline at end of file
diff --git a/pkgs/ifwait/default.nix b/pkgs/ifwait/default.nix
@@ -0,0 +1,32 @@
+{
+ lua5_3
+, netlink-lua
+, stdenv
+, makeWrapper
+}:
+let
+ lua = lua5_3;
+ netlink = netlink-lua.override {inherit lua;};
+ fennel = lua.pkgs.fennel;
+in stdenv.mkDerivation rec {
+ pname = "ifwait";
+ version = "1";
+ phases = [ "installPhase" ];
+
+ buildInputs = [ lua netlink ];
+ nativeBuildInputs = [ makeWrapper fennel ];
+
+ LUA_CPATH = "${netlink}/lib/lua/${lua.luaversion}/\?.so"; # for nix-shell
+
+ installPhase = ''
+ mkdir -p $out/bin $out/lib
+ fennel --compile ${./ifwait.fnl} > $out/lib/${pname}.lua
+
+ makeWrapper ${lua}/bin/lua $out/bin/${pname} \
+ --prefix LUA_CPATH ";" ${netlink}/lib/lua/${lua.luaversion}/\?.so \
+ --add-flags $out/lib/${pname}.lua
+ '';
+}
+
+# to use fennel.view,
+# --prefix LUA_PATH ";" ${fennel}/share/lua/5.2/\?.lua \
diff --git a/pkgs/ifwait/ifwait.fnl b/pkgs/ifwait/ifwait.fnl
@@ -0,0 +1,52 @@
+(local netlink (require :netlink))
+(local sock (netlink.socket))
+
+; (local { : view} (require :fennel))
+
+(fn assoc [tbl k v]
+ (tset tbl k v)
+ tbl)
+
+(fn parse-args [args]
+ (match args
+ ["-v" & rest] (assoc (parse-args rest) :verbose true)
+ ["-t" timeout & rest] (assoc (parse-args rest) :timeout (tonumber timeout))
+ [linkname "up"] {:link linkname :expecting "up"}
+ [linkname "running"] {:link linkname :expecting "running"}
+ [linkname "present"] {:link linkname :expecting "present"}
+ [linkname nil] {:link linkname :expecting "present"}
+ _ nil))
+
+(local parameters
+ (or
+ (parse-args arg)
+ (assert false (.. "Usage: " (. arg 0) " [-v] ifname [present|up|running]"))))
+
+(fn run-events [evs]
+ (each [_ v (ipairs evs)]
+ (let [got
+ (match v
+ ;; - up: Reflects the administrative state of the interface (IFF_UP)
+ ;; - running: Reflects the operational state (IFF_RUNNING).
+ {:event "newlink" :name parameters.link :up :yes :running :yes}
+ {:present true :up true :running true}
+
+ {:event "newlink" :name parameters.link :up :yes}
+ {:present :true :up true}
+
+ {:event "newlink" :name parameters.link}
+ {:present true }
+
+ _
+ {})]
+ (when (. got parameters.expecting)
+ (os.exit 0)))))
+
+
+(when parameters.verbose
+ (print (.. (. arg 0) ": waiting for "
+ parameters.link " to be " parameters.expecting)))
+
+(run-events (sock:query {:link true}))
+
+(while (sock:poll) (run-events (sock:event)))
diff --git a/pkgs/ifwait/waitup.fnl b/pkgs/ifwait/waitup.fnl
@@ -0,0 +1,38 @@
+(local netlink (require :netlink))
+(local sock (netlink.socket))
+
+(when (< (# arg) 2)
+ (print "usage: waitup ifname fd")
+ (os.exit 1))
+
+(local ifname (. arg 1))
+(local fd (tonumber (. arg 2)))
+(local stream (io.open (.. "/proc/self/fd/" fd) "w"))
+
+(fn notify-ready []
+ (when (= "file" (io.type stream))
+ (stream:write "\n")
+ (stream:close))
+ (print (.. (. arg 0) ": received netlink operstate up for " ifname)))
+
+
+(fn run-events [evs]
+ (each [_ v (ipairs evs)]
+ (print :event v.event v.name)
+
+ (match v
+ ;; - up: Reflects the administrative state of the interface (IFF_UP)
+ ;; - running: Reflects the operational state (IFF_RUNNING).
+ {:event "newlink" :name ifname :up :yes :running :yes}
+ (notify-ready)
+
+ {:event "newlink" :name ifname :up :no}
+ (os.exit 0))))
+
+(run-events (sock:query {:link true}))
+
+(print (.. (. arg 0) ": waiting for netlink NEWLINK " ifname))
+
+(while (sock:poll)
+ (let [ev (sock:event)]
+ (run-events ev)))
diff --git a/pkgs/liminix-tools/networking/default.nix b/pkgs/liminix-tools/networking/default.nix
@@ -1,6 +1,7 @@
{
callPackage
, liminix
+, ifwait
, lib
}:
let
@@ -12,6 +13,7 @@ in {
[]
++ optional (type == "bridge")
"ip link add name ${device} type bridge"
+ ++ ["${ifwait}/bin/ifwait -v ${device} present"]
++ ["ip link set up dev ${device}"]
++ optional (primary != null)
"ip link set dev ${device} master ${primary.device}";
diff --git a/pkgs/waitup/default.nix b/pkgs/waitup/default.nix
@@ -1,31 +0,0 @@
-{
- lua5_3
-, netlink-lua
-, stdenv
-, makeWrapper
-}:
-let
- lua = lua5_3;
- netlink = netlink-lua.override {inherit lua;};
- fennel = lua.pkgs.fennel;
-in stdenv.mkDerivation rec {
- pname = "waitup";
- version = "1";
-
- buildInputs = [ lua netlink-lua ];
- nativeBuildInputs = [ makeWrapper fennel ];
-
- src = ./.;
-
- installPhase = ''
- mkdir -p $out/bin $out/lib
- fennel --compile ${./waitup.fnl} > $out/lib/waitup.lua
-
- makeWrapper ${lua}/bin/lua $out/bin/${pname} \
- --prefix LUA_CPATH ";" ${netlink}/lib/lua/${lua.luaversion}/\?.so \
- --add-flags $out/lib/waitup.lua
- '';
-}
-
-# to use fennel.view,
-# --prefix LUA_PATH ";" ${fennel}/share/lua/5.2/\?.lua \
diff --git a/pkgs/waitup/waitup.fnl b/pkgs/waitup/waitup.fnl
@@ -1,36 +0,0 @@
-(local netlink (require :netlink))
-(local sock (netlink.socket))
-
-(when (< (# arg) 2)
- (print "usage: waitup ifname fd")
- (os.exit 1))
-
-(local ifname (. arg 1))
-(local fd (tonumber (. arg 2)))
-(local stream (io.open (.. "/proc/self/fd/" fd) "w"))
-
-(fn notify-ready []
- (stream:write "\n")
- (print (.. (. arg 0) ": received netlink operstate up for " ifname))
- (stream:close))
-
-(fn run-events [evs]
- (each [_ v (ipairs evs)]
- (print :event v.event v.name)
-
- (match v
- ;; - up: Reflects the administrative state of the interface (IFF_UP)
- ;; - running: Reflects the operational state (IFF_RUNNING).
- {:event "newlink" :name ifname :up :yes :running :yes}
- (notify-ready)
-
- {:event "newlink" :name ifname :up :no}
- (os.exit 0))))
-
-(run-events (sock:query {:link true}))
-
-(print (.. (. arg 0) ": waiting for netlink NEWLINK " ifname))
-
-(while (sock:poll)
- (let [ev (sock:event)]
- (run-events ev)))
diff --git a/rotuer.nix b/rotuer.nix
@@ -19,7 +19,7 @@ let
route;
inherit (pkgs.liminix.services) oneshot longrun bundle target;
inherit (pkgs)
- waitup
+ ifwait
serviceFns
iptables;
in rec {
@@ -122,17 +122,13 @@ in rec {
};
services.bridgewlan =
- let waitup-wlan = longrun {
- name = "waitup-wlan0";
- run = "${waitup}/bin/waitup wlan0 10";
- notification-fd = 10;
- dependencies = [ services.wireless services.hostap ];
- };
+ let dev = services.wireless.device;
in oneshot {
- name = "add-wlan-to-bridge";
- up = "ip link set dev ${services.wireless.device} master ${services.lan.device}";
- down = "ip link set dev ${services.wireless.device} nomaster";
- dependencies = [ waitup-wlan ];
+ name = "add-wlan2-to-bridge";
+ up = "${ifwait}/bin/ifwait -v ${dev} running && ip link set dev ${dev} master ${services.lan.device}";
+ down = "ip link set dev ${dev} nomaster";
+ dependencies = [ services.wireless ];
+ };
};
users.dnsmasq = {