Compare commits
No commits in common. "9ab77a7d7e0af144c493e3f054e9a1194bcd04e5" and "6649ebeccd95848062ca114ec0aee7714eb62c9f" have entirely different histories.
9ab77a7d7e
...
6649ebeccd
87
THOUGHTS.txt
87
THOUGHTS.txt
@ -7109,90 +7109,3 @@ commit until I have some way to see if they're working. the pppoe test
|
|||||||
will check both firewall zones so _should_ start to fail with the
|
will check both firewall zones so _should_ start to fail with the
|
||||||
current watch-outputs (because only one service) and then pass when we
|
current watch-outputs (because only one service) and then pass when we
|
||||||
put the new one in
|
put the new one in
|
||||||
|
|
||||||
Fri Feb 28 01:00:03 GMT 2025
|
|
||||||
|
|
||||||
Well, it works at least well enough to pass the test. There is an awful hack
|
|
||||||
though, because nftables doesn't accept "elements = { }" as valid syntax
|
|
||||||
for a set with no elements, so we post-process the file to wipe those lines
|
|
||||||
|
|
||||||
I wonder if we could instead create the set empty and then use the "other"
|
|
||||||
nftables format to generate commands that add the elements. If it's
|
|
||||||
all in the same file (or included files) it will continue to be atomic
|
|
||||||
|
|
||||||
Other options
|
|
||||||
|
|
||||||
- is the nftables json format any better? we will have to rebuild it
|
|
||||||
with json support, may be bugger
|
|
||||||
- write lua bindings to libnftables
|
|
||||||
|
|
||||||
Fri Feb 28 23:31:06 GMT 2025
|
|
||||||
|
|
||||||
adding json would add 76 + 88k to the image, but I think it would also
|
|
||||||
mean we have to rewrite all the default rules in json format
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
with json
|
|
||||||
[dan@loaclhost:~/src/liminix]$ du result/
|
|
||||||
20 result/share/doc/nftables/examples
|
|
||||||
24 result/share/doc/nftables
|
|
||||||
28 result/share/doc
|
|
||||||
12 result/share/man/man3
|
|
||||||
16 result/share/man/man5
|
|
||||||
44 result/share/man/man8
|
|
||||||
76 result/share/man
|
|
||||||
60 result/share/nftables
|
|
||||||
168 result/share
|
|
||||||
36 result/etc/nftables/osf
|
|
||||||
40 result/etc/nftables
|
|
||||||
44 result/etc
|
|
||||||
76 result/bin
|
|
||||||
8 result/include/nftables
|
|
||||||
12 result/include
|
|
||||||
8 result/lib/pkgconfig
|
|
||||||
1172 result/lib
|
|
||||||
1476 result/
|
|
||||||
|
|
||||||
[dan@loaclhost:~/src/liminix]$ du /nix/store/l0zsvldsskiv52b4c9b21ziq5z1qr7vn-jansson-mips-unknown-linux-musl-2.14/
|
|
||||||
84 /nix/store/l0zsvldsskiv52b4c9b21ziq5z1qr7vn-jansson-mips-unknown-linux-musl-2.14/lib
|
|
||||||
88 /nix/store/l0zsvldsskiv52b4c9b21ziq5z1qr7vn-jansson-mips-unknown-linux-musl-2.14/
|
|
||||||
|
|
||||||
without:
|
|
||||||
[dan@loaclhost:~/src/liminix]$ du result/
|
|
||||||
20 result/share/doc/nftables/examples
|
|
||||||
24 result/share/doc/nftables
|
|
||||||
28 result/share/doc
|
|
||||||
12 result/share/man/man3
|
|
||||||
16 result/share/man/man5
|
|
||||||
44 result/share/man/man8
|
|
||||||
76 result/share/man
|
|
||||||
60 result/share/nftables
|
|
||||||
168 result/share
|
|
||||||
36 result/etc/nftables/osf
|
|
||||||
40 result/etc/nftables
|
|
||||||
44 result/etc
|
|
||||||
76 result/bin
|
|
||||||
8 result/include/nftables
|
|
||||||
12 result/include
|
|
||||||
8 result/lib/pkgconfig
|
|
||||||
1096 result/lib
|
|
||||||
1400 result/
|
|
||||||
|
|
||||||
|
|
||||||
Sat Mar 1 23:43:17 GMT 2025
|
|
||||||
|
|
||||||
I don't think json is going to help because either we'd have to do
|
|
||||||
|
|
||||||
elements = map (f: "{{ lookup(f, \"ifname\") }}") zones.${zone}
|
|
||||||
|
|
||||||
and there would be null elements in the places for the interfaces that don't exist
|
|
||||||
yet, or we'd have to write actual json syntax at runtime, at which point why don't
|
|
||||||
we write the trad nftables syntax instead?
|
|
||||||
|
|
||||||
let's write a firewall .nftables file consisting of the zone set
|
|
||||||
elements plus an "include" directive for the rest of the firewall. NOTE THAT
|
|
||||||
we may still need to template the rest of the firewall if we want to have
|
|
||||||
other variables (rate limits) in it, because the rules for that need to be
|
|
||||||
inserted ahead of the rules for accepting icmp, and there's no way to
|
|
||||||
do that without
|
|
||||||
|
@ -21,7 +21,7 @@ let
|
|||||||
inherit (lib.attrsets) mapAttrs' nameValuePair mapAttrsToList;
|
inherit (lib.attrsets) mapAttrs' nameValuePair mapAttrsToList;
|
||||||
inherit (lib.strings) concatStringsSep;
|
inherit (lib.strings) concatStringsSep;
|
||||||
inherit (lib.lists) flatten;
|
inherit (lib.lists) flatten;
|
||||||
inherit (builtins) concatLists toJSON attrValues;
|
inherit (builtins) concatLists attrValues;
|
||||||
inherit (liminix) outputRef;
|
inherit (liminix) outputRef;
|
||||||
mkSet =
|
mkSet =
|
||||||
family: name:
|
family: name:
|
||||||
@ -29,50 +29,38 @@ let
|
|||||||
kind = "set";
|
kind = "set";
|
||||||
inherit name family;
|
inherit name family;
|
||||||
type = "ifname";
|
type = "ifname";
|
||||||
extraText = ''
|
elements = map (s: "{{ output(${builtins.toJSON s}, \"ifname\", \"\") }}") zones.${name};
|
||||||
{{;
|
};
|
||||||
local services = { ${concatStringsSep ", " (map toJSON zones.${name})} }
|
|
||||||
local ifnames = {}
|
|
||||||
for _, v in ipairs(services) do
|
|
||||||
local o = output(v, "ifname")
|
|
||||||
if o then table.insert(ifnames, o) end
|
|
||||||
end
|
|
||||||
if (#ifnames > 0) then
|
|
||||||
return "elements = { " .. table.concat(ifnames, ", ") .. " }\n"
|
|
||||||
else
|
|
||||||
return ""
|
|
||||||
end
|
|
||||||
}}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
sets = (mapAttrs' (n: _: mkSet "ip" n) zones) //
|
sets = (mapAttrs' (n: _: mkSet "ip" n) zones) //
|
||||||
(mapAttrs' (n: _: mkSet "ip6" n) zones);
|
(mapAttrs' (n: _: mkSet "ip6" n) zones);
|
||||||
allRules = lib.recursiveUpdate extraRules (lib.recursiveUpdate sets rules);
|
allRules = lib.recursiveUpdate extraRules (lib.recursiveUpdate (builtins.trace sets sets) rules);
|
||||||
script = firewallgen "firewall1.nft" allRules;
|
script = firewallgen "firewall1.nft" allRules;
|
||||||
|
ifwatch = writeFennel "ifwatch" {
|
||||||
|
packages = [
|
||||||
|
anoia
|
||||||
|
lualinux
|
||||||
|
linotify
|
||||||
|
];
|
||||||
|
mainFunction = "run";
|
||||||
|
} ./ifwatch.fnl;
|
||||||
watchArg = z: intfs: map (i: "${z}:${i}/.outputs") intfs;
|
watchArg = z: intfs: map (i: "${z}:${i}/.outputs") intfs;
|
||||||
name = "firewall";
|
name = "firewall";
|
||||||
service = longrun {
|
service = longrun {
|
||||||
inherit name;
|
inherit name;
|
||||||
run = ''
|
run = ''
|
||||||
PATH=${nftables}/bin:${lua}/bin:$PATH
|
|
||||||
reload() {
|
|
||||||
echo reloading firewall
|
|
||||||
${output-template}/bin/output-template '{{' '}}' < ${script} > /run/${name}/fw.nft;
|
|
||||||
nft -f /run/${name}/fw.nft ;
|
|
||||||
}
|
|
||||||
trap reload SIGUSR1
|
|
||||||
mkdir -p /run/${name}; in_outputs ${name}
|
mkdir -p /run/${name}; in_outputs ${name}
|
||||||
reload
|
# exec > /dev/console 2>&1
|
||||||
while :; do
|
echo RESTARTING FIREWALL >/dev/console
|
||||||
# signals sent to ash won't interrupt sleep, but will interrupt wait
|
PATH=${nftables}/bin:${lua}/bin:$PATH
|
||||||
sleep 86400 & wait
|
${output-template}/bin/output-template '{{' '}}' < ${script} | lua -e 'for x in io.lines() do if not string.match(x, "elements = {%s+}") then print(x) end; end' > /run/${name}/fw.nft
|
||||||
done
|
# cat /run/${name}/fw.nft > /dev/console
|
||||||
|
nft -f /run/${name}/fw.nft
|
||||||
|
while sleep 86400 ; do : ; done
|
||||||
'';
|
'';
|
||||||
finish = "${nftables}/bin/nft flush ruleset";
|
finish = "${nftables}/bin/nft flush ruleset";
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
svc.secrets.subscriber.build {
|
svc.secrets.subscriber.build {
|
||||||
action = "usr1";
|
|
||||||
watch =
|
watch =
|
||||||
concatLists
|
concatLists
|
||||||
(mapAttrsToList (_zone : services : map (s: outputRef s "ifname") services) zones);
|
(mapAttrsToList (_zone : services : map (s: outputRef s "ifname") services) zones);
|
||||||
|
@ -28,9 +28,9 @@ let
|
|||||||
"quit" = "-s 3";
|
"quit" = "-s 3";
|
||||||
"kill" = "-s 9";
|
"kill" = "-s 9";
|
||||||
"term" = "-s 15";
|
"term" = "-s 15";
|
||||||
"winch" = "-s 20";
|
"winch" = "-s 28";
|
||||||
"usr1" = "-s usr1";
|
"usr1" = "-s 10";
|
||||||
"usr2" = "-s usr2";
|
"usr2" = "-s 12";
|
||||||
}
|
}
|
||||||
.${action};
|
.${action};
|
||||||
|
|
||||||
@ -56,5 +56,8 @@ service.overrideAttrs (o: {
|
|||||||
buildInputs = (lim.orEmpty o.buildInputs) ++ optional (watch != []) watcher;
|
buildInputs = (lim.orEmpty o.buildInputs) ++ optional (watch != []) watcher;
|
||||||
dependencies =
|
dependencies =
|
||||||
(lim.orEmpty o.dependencies)
|
(lim.orEmpty o.dependencies)
|
||||||
++ optional (watch != []) watcher;
|
# ++ optionals
|
||||||
|
# (watch != [])
|
||||||
|
# ([ watcher ] ++ watched-services);
|
||||||
|
;
|
||||||
})
|
})
|
||||||
|
@ -10,7 +10,6 @@ let
|
|||||||
splitString
|
splitString
|
||||||
hasInfix
|
hasInfix
|
||||||
substring
|
substring
|
||||||
optionalString
|
|
||||||
;
|
;
|
||||||
inherit (lib.lists) groupBy;
|
inherit (lib.lists) groupBy;
|
||||||
inherit (lib.attrsets) mapAttrsToList;
|
inherit (lib.attrsets) mapAttrsToList;
|
||||||
@ -57,14 +56,12 @@ let
|
|||||||
name,
|
name,
|
||||||
type,
|
type,
|
||||||
elements ? [ ],
|
elements ? [ ],
|
||||||
extraText ? null,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
''
|
''
|
||||||
set ${name} {
|
set ${name} {
|
||||||
type ${type}
|
type ${type}
|
||||||
${if elements != [ ] then "elements = { ${concatStringsSep ", " (builtins.trace elements elements)} }" else ""}
|
${if elements != [ ] then "elements = { ${concatStringsSep ", " (builtins.trace elements elements)} }" else ""}
|
||||||
${optionalString (extraText != null) extraText}
|
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
3
pkgs/output-template/Makefile
Normal file
3
pkgs/output-template/Makefile
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
check:
|
||||||
|
./output-template '{{' '}}' < example.ini > output
|
||||||
|
diff -u output example.ini.expected
|
@ -2,7 +2,6 @@
|
|||||||
fetchurl,
|
fetchurl,
|
||||||
writeFennel,
|
writeFennel,
|
||||||
fennel,
|
fennel,
|
||||||
fennelrepl,
|
|
||||||
runCommand,
|
runCommand,
|
||||||
lua,
|
lua,
|
||||||
anoia,
|
anoia,
|
||||||
@ -18,9 +17,9 @@ stdenv.mkDerivation {
|
|||||||
src = ./.;
|
src = ./.;
|
||||||
|
|
||||||
buildInputs = [ lua ];
|
buildInputs = [ lua ];
|
||||||
nativeBuildInputs = [ fennelrepl ] ;
|
doCheck = true;
|
||||||
|
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
fennelrepl --test ./output-template.fnl
|
|
||||||
cp -p ${
|
cp -p ${
|
||||||
writeFennel name {
|
writeFennel name {
|
||||||
packages = [
|
packages = [
|
||||||
@ -28,11 +27,11 @@ stdenv.mkDerivation {
|
|||||||
lualinux
|
lualinux
|
||||||
linotify
|
linotify
|
||||||
];
|
];
|
||||||
macros = [ anoia.dev ];
|
|
||||||
mainFunction = "run";
|
mainFunction = "run";
|
||||||
} ./output-template.fnl
|
} ./output-template.fnl
|
||||||
} ${name}
|
} ${name}
|
||||||
'';
|
'';
|
||||||
|
checkPhase = "make check";
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
install -D ${name} $out/bin/${name}
|
install -D ${name} $out/bin/${name}
|
||||||
'';
|
'';
|
||||||
|
@ -24,43 +24,21 @@
|
|||||||
(let [delim (.. opening "(.-)" closing)
|
(let [delim (.. opening "(.-)" closing)
|
||||||
myenv {
|
myenv {
|
||||||
: string
|
: string
|
||||||
: table
|
|
||||||
: ipairs
|
|
||||||
:output
|
:output
|
||||||
(fn [service-path path default]
|
(fn [service-path path default]
|
||||||
(let [s (assert (svc.open (.. service-path "/.outputs")))]
|
(let [s (assert (svc.open (.. service-path "/.outputs")))]
|
||||||
(or (s:output path) default)))
|
(or (s:output path) default)))
|
||||||
:lua_quote #(string.format "%q" $1)
|
:lua_quote #(string.format "%q" %1)
|
||||||
:json_quote (fn [x] (.. "\"" (json-escape x) "\""))
|
:json_quote (fn [x] (.. "\"" (json-escape x) "\""))
|
||||||
}]
|
}]
|
||||||
(string.gsub text delim
|
(string.gsub text delim
|
||||||
(fn [x]
|
(fn [x]
|
||||||
(let [chunk (if (= (x:sub 1 1) ";")
|
(assert ((load (.. "return " x) x :t myenv))
|
||||||
(x:sub 2)
|
(string.format "missing value for %q" x))))))
|
||||||
(.. "return " x))]
|
|
||||||
(assert ((load chunk x :t myenv))
|
|
||||||
(string.format "missing value for %q" x)))))))
|
|
||||||
|
|
||||||
(fn run []
|
(fn run []
|
||||||
(let [[opening closing] arg
|
(let [[opening closing] arg
|
||||||
out (substitute (: (io.input) :read "*a") opening closing)]
|
out (substitute (: (io.input) :read "*a") opening closing)]
|
||||||
(io.write out)))
|
(io.write out)))
|
||||||
|
|
||||||
(import-macros { : define-tests : expect : expect= } :anoia.assert)
|
|
||||||
(define-tests
|
|
||||||
(expect= (pick-values 1 (substitute "var={{ 2 + 3 }}" "{{" "}}")) "var=5")
|
|
||||||
(expect= (pick-values 1 (substitute "{{ json_quote(\"o'reilly\") }}" "{{" "}}"))
|
|
||||||
"\"o'reilly\"")
|
|
||||||
|
|
||||||
(expect= (pick-values 1 (substitute "{{; local a=9; return a }}" "{{" "}}")) "9")
|
|
||||||
|
|
||||||
;; "globals" set in one interpolation are available in subsequent ones
|
|
||||||
(expect= (pick-values 1 (substitute "{{; a=42; return a }} {{ a and 999 or 0 }}" "{{" "}}")) "42 999")
|
|
||||||
|
|
||||||
(fn slurp [name]
|
|
||||||
(with-open [f (assert (io.open name))] (f:read "*a")))
|
|
||||||
(expect=
|
|
||||||
(pick-values 1 (substitute (slurp "example.ini") "{{" "}}"))
|
|
||||||
(slurp "example.ini.expected")))
|
|
||||||
|
|
||||||
{ : run }
|
{ : run }
|
||||||
|
3
pkgs/watch-outputs/Makefile
Normal file
3
pkgs/watch-outputs/Makefile
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
check:
|
||||||
|
fennelrepl ./test.fnl '{{' '}}' < example.ini > output
|
||||||
|
diff -u output example.ini.expected
|
@ -34,6 +34,7 @@ stdenv.mkDerivation {
|
|||||||
mainFunction = "run";
|
mainFunction = "run";
|
||||||
} ./watch-outputs.fnl
|
} ./watch-outputs.fnl
|
||||||
} ${name}
|
} ${name}
|
||||||
|
make check
|
||||||
'';
|
'';
|
||||||
|
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
a11
|
@ -0,0 +1 @@
|
|||||||
|
a33
|
@ -0,0 +1 @@
|
|||||||
|
a55
|
@ -0,0 +1 @@
|
|||||||
|
a66
|
@ -0,0 +1 @@
|
|||||||
|
000000
|
1
pkgs/watch-outputs/example-service/.outputs/colours/blue
Normal file
1
pkgs/watch-outputs/example-service/.outputs/colours/blue
Normal file
@ -0,0 +1 @@
|
|||||||
|
0000ff
|
@ -0,0 +1 @@
|
|||||||
|
00ff00
|
1
pkgs/watch-outputs/example-service/.outputs/colours/red
Normal file
1
pkgs/watch-outputs/example-service/.outputs/colours/red
Normal file
@ -0,0 +1 @@
|
|||||||
|
ff0000
|
1
pkgs/watch-outputs/example-service/.outputs/name
Normal file
1
pkgs/watch-outputs/example-service/.outputs/name
Normal file
@ -0,0 +1 @@
|
|||||||
|
eth1
|
3
pkgs/watch-outputs/example.ini
Normal file
3
pkgs/watch-outputs/example.ini
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
wpa_passphrase={{ output("./example-service","colours/black") }}
|
||||||
|
think = {{ string.format("%q", output("./example-service","colours/blue")) }}
|
||||||
|
argonaut = {{ json_quote "hello\ngoodbye\tnext\027" }}
|
3
pkgs/watch-outputs/example.ini.expected
Normal file
3
pkgs/watch-outputs/example.ini.expected
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
wpa_passphrase=000000
|
||||||
|
think = "0000ff"
|
||||||
|
argonaut = "hello\ngoodbye\tnext\u001B"
|
44
pkgs/watch-outputs/output-template.fnl
Normal file
44
pkgs/watch-outputs/output-template.fnl
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
(local svc (require :anoia.svc))
|
||||||
|
|
||||||
|
(fn json-escape [s]
|
||||||
|
;; All Unicode characters may be placed within the quotation marks,
|
||||||
|
;; except for the characters that MUST be escaped:
|
||||||
|
;; quotation mark, reverse solidus, and the control characters (U+0000
|
||||||
|
;; through U+001F). (RFC 8259)
|
||||||
|
(-> s
|
||||||
|
(string.gsub
|
||||||
|
"[\"\b\f\n\r\t]" {
|
||||||
|
"\b" "\\b"
|
||||||
|
"\"" "\\\""
|
||||||
|
"\f" "\\f"
|
||||||
|
"\n" "\\n"
|
||||||
|
"\r" "\\r"
|
||||||
|
"\t" "\\t"
|
||||||
|
})
|
||||||
|
(string.gsub
|
||||||
|
"([\x00-\x1b])"
|
||||||
|
(fn [x] (string.format "\\u%04X" (string.byte x))))))
|
||||||
|
|
||||||
|
|
||||||
|
(fn substitute [text opening closing]
|
||||||
|
(let [delim (.. opening "(.-)" closing)
|
||||||
|
myenv {
|
||||||
|
: string
|
||||||
|
:output
|
||||||
|
(fn [service-path path]
|
||||||
|
(let [s (assert (svc.open (.. service-path "/.outputs")))]
|
||||||
|
(s:output path)))
|
||||||
|
:lua_quote #(string.format "%q" $1)
|
||||||
|
:json_quote (fn [x] (.. "\"" (json-escape x) "\""))
|
||||||
|
}]
|
||||||
|
(string.gsub text delim
|
||||||
|
(fn [x]
|
||||||
|
(assert ((load (.. "return " x) x :t myenv))
|
||||||
|
(string.format "missing value for %q" x))))))
|
||||||
|
|
||||||
|
(fn run []
|
||||||
|
(let [[opening closing] arg
|
||||||
|
out (substitute (: (io.input) :read "*a") opening closing)]
|
||||||
|
(io.write out)))
|
||||||
|
|
||||||
|
{ : run }
|
@ -58,7 +58,7 @@
|
|||||||
(case action
|
(case action
|
||||||
:restart (system (%% "s6-svc -r /run/service/%s" service))
|
:restart (system (%% "s6-svc -r /run/service/%s" service))
|
||||||
:restart-all (system (%% "s6-rc -b -d %q; s6-rc-up-tree %q" service service))
|
:restart-all (system (%% "s6-rc -b -d %q; s6-rc-up-tree %q" service service))
|
||||||
[:signal n] (system (%% "s6-svc -s %q /run/service/%s" n service))))
|
[:signal n] (system (%% "s6-svc -s %d /run/service/%s" n service))))
|
||||||
|
|
||||||
(local POLLIN 0x0001)
|
(local POLLIN 0x0001)
|
||||||
(local POLLHUP 0x0010)
|
(local POLLHUP 0x0010)
|
||||||
@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
(fn open-services [output-references]
|
(fn open-services [output-references]
|
||||||
(collect [s p (pairs output-references)]
|
(collect [s p (pairs output-references)]
|
||||||
(values (svc.open (.. s "/.outputs")) p)))
|
(values (assert (svc.open (.. s "/.outputs"))) p)))
|
||||||
|
|
||||||
(fn run []
|
(fn run []
|
||||||
(let [trees {}
|
(let [trees {}
|
||||||
@ -89,6 +89,7 @@
|
|||||||
(each [service paths (pairs services)]
|
(each [service paths (pairs services)]
|
||||||
(let [new-tree (service:output ".")]
|
(let [new-tree (service:output ".")]
|
||||||
(when (changed? paths (. trees service) new-tree)
|
(when (changed? paths (. trees service) new-tree)
|
||||||
|
(print "watched path event:" action controlled-service)
|
||||||
(do-action action controlled-service))))))))
|
(do-action action controlled-service))))))))
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,39 +8,29 @@ send "PS1=\$(echo 'I1JFQURZIyA=' | base64 -d); stty -echo\n"
|
|||||||
expect "#READY#"
|
expect "#READY#"
|
||||||
set FINISHED 0
|
set FINISHED 0
|
||||||
set EXIT "1"
|
set EXIT "1"
|
||||||
while { $FINISHED < 20 } {
|
while { $FINISHED < 10 } {
|
||||||
send "ip address show dev ppp0 | grep ppp0\n"
|
send "ip address show dev ppp0 | grep ppp0\n"
|
||||||
expect {
|
expect {
|
||||||
"192.168.100.1" { set FINISHED 200; set EXIT 0; }
|
"192.168.100.1" { set FINISHED 20; set EXIT 0; }
|
||||||
"can't find device" { send_user "waiting ..." ; sleep 3 }
|
"can't find device" { send_user "waiting ..." ; sleep 3 }
|
||||||
"DOWN" { send_user "waiting ..." ; sleep 3 }
|
"DOWN" { send_user "waiting ..." ; sleep 3 }
|
||||||
}
|
}
|
||||||
set FINISHED [ expr $FINISHED + 1 ]
|
set FINISHED [ expr $FINISHED + 1 ]
|
||||||
}
|
}
|
||||||
expect "#READY#"
|
expect "#READY#"
|
||||||
send "s6-svwait -U /run/service/wan.link.pppoe\n"
|
send "nft list set ip table-ip wan || touch /non/existent\n"
|
||||||
|
expect {
|
||||||
|
"ppp0" { puts "ppp0 found " }
|
||||||
|
"{ }" { puts "missing ifname"; exit 1 }
|
||||||
|
"No such file or directory" { exit 1 }
|
||||||
|
}
|
||||||
expect "#READY#"
|
expect "#READY#"
|
||||||
|
|
||||||
set timeout 30
|
|
||||||
send "nft list set ip table-ip lan || touch /non/existent\n"
|
send "nft list set ip table-ip lan || touch /non/existent\n"
|
||||||
expect {
|
expect {
|
||||||
"lan" { puts "lan found" }
|
"lan" { puts "lan found" }
|
||||||
"{ }" { puts "missing ifname"; exit 1 }
|
"{ }" { puts "missing ifname"; exit 1 }
|
||||||
"No such file or directory" { exit 1 }
|
"No such file or directory" { exit 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
expect "#READY#"
|
expect "#READY#"
|
||||||
|
|
||||||
# if the test fails for no apparent reason, it is quite likely because
|
|
||||||
# the firewall hasn't had time to reload after the new interface
|
|
||||||
# appears and you just have to make this sleep longer. Ew, yes
|
|
||||||
send "sleep 10; nft list set ip table-ip wan || touch /non/existent\n"
|
|
||||||
expect {
|
|
||||||
"ppp0" { puts "ppp0 found " }
|
|
||||||
"{ }" { puts "missing ifname"; exit 1 }
|
|
||||||
"No such file or directory" { exit 1 }
|
|
||||||
timeout { exit 1 }
|
|
||||||
}
|
|
||||||
expect "#READY#"
|
|
||||||
|
|
||||||
exit $EXIT
|
exit $EXIT
|
||||||
|
Loading…
Reference in New Issue
Block a user