Compare commits
No commits in common. "e1ae986cf66c396f6d5970735abd2042c99ead1f" and "df395a4d5da80d6f89257ed921674bff434367c6" have entirely different histories.
e1ae986cf6
...
df395a4d5d
12
NEWS
12
NEWS
|
@ -103,15 +103,3 @@ a bit more useful :-)
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
2024-07-16
|
|
||||||
|
|
||||||
* structured parameters are available for the pppoe service
|
|
||||||
|
|
||||||
* The "wan" configuration in modules/profiles/gateway.nix has changed:
|
|
||||||
instead of passing options that are used to create a pppoe interface,
|
|
||||||
callers should create a (pppoe or other) interface and pass that as
|
|
||||||
the value of profile.gateway.wan. For the pppoe case this is now only
|
|
||||||
very slightly more verbose, and it allows using the gateway profile
|
|
||||||
with other kinds of upstream.
|
|
||||||
|
|
||||||
|
|
21
THOUGHTS.txt
21
THOUGHTS.txt
|
@ -5400,24 +5400,3 @@ generalising the failover example:
|
||||||
- usb stick may or may not need a modeswitch
|
- usb stick may or may not need a modeswitch
|
||||||
- may need a different chat script
|
- may need a different chat script
|
||||||
- usb ids
|
- usb ids
|
||||||
|
|
||||||
Mon Jul 15 17:52:57 BST 2024
|
|
||||||
|
|
||||||
DONE 1) Should round-robin be a callService service or a function a la
|
|
||||||
longrun/oneshot, or even an overridable package?
|
|
||||||
|
|
||||||
DONE 2) maybe we should replace all liminix.callService with
|
|
||||||
config.system.callService
|
|
||||||
|
|
||||||
3) for consistency, can we make the networking "primitives" into
|
|
||||||
services? answer: no. the only thing left there is `ifup` which is a
|
|
||||||
function returning a string, not a derivation
|
|
||||||
|
|
||||||
Tue Jul 16 18:25:41 BST 2024
|
|
||||||
|
|
||||||
can we make the gateway profile able to use failover? perhaps if we
|
|
||||||
add username and password as options to the pppoe service, then call
|
|
||||||
gateway with the pppoe service instead of building it _in_ the profile,
|
|
||||||
we can have gateways with other-than-pppoe for the wan
|
|
||||||
|
|
||||||
(for a straight lte uplink, could pass the wwan interface as wan)
|
|
||||||
|
|
|
@ -30,11 +30,6 @@
|
||||||
inherit (pkgs.pseudofile) dir symlink;
|
inherit (pkgs.pseudofile) dir symlink;
|
||||||
inherit (pkgs) serviceFns;
|
inherit (pkgs) serviceFns;
|
||||||
svc = config.system.service;
|
svc = config.system.service;
|
||||||
wirelessConfig = {
|
|
||||||
country_code = "GB";
|
|
||||||
inherit (rsecrets) wpa_passphrase;
|
|
||||||
wmm_enabled = 1;
|
|
||||||
};
|
|
||||||
in rec {
|
in rec {
|
||||||
boot = {
|
boot = {
|
||||||
tftp = {
|
tftp = {
|
||||||
|
@ -46,14 +41,12 @@ in rec {
|
||||||
imports = [
|
imports = [
|
||||||
../modules/wwan
|
../modules/wwan
|
||||||
../modules/network
|
../modules/network
|
||||||
# ../modules/vlan
|
../modules/vlan
|
||||||
../modules/ssh
|
../modules/ssh
|
||||||
../modules/usb.nix
|
../modules/usb.nix
|
||||||
# ../modules/watchdog
|
../modules/watchdog
|
||||||
# ../modules/mount
|
../modules/mount
|
||||||
../modules/ppp
|
../modules/ppp
|
||||||
../modules/round-robin
|
|
||||||
../modules/profiles/gateway.nix
|
|
||||||
];
|
];
|
||||||
hostname = "thing";
|
hostname = "thing";
|
||||||
|
|
||||||
|
@ -64,101 +57,99 @@ in rec {
|
||||||
authType = "chap";
|
authType = "chap";
|
||||||
};
|
};
|
||||||
|
|
||||||
profile.gateway = {
|
services.wan =
|
||||||
lan = {
|
let
|
||||||
interfaces = with config.hardware.networkInterfaces;
|
controller = longrun rec {
|
||||||
[
|
name = "wan-switcher";
|
||||||
# EDIT: these are the interfaces exposed by the gl.inet gl-ar750:
|
run = ''
|
||||||
# if your device has more or differently named lan interfaces,
|
in_outputs ${name}
|
||||||
# specify them here
|
exec ${pkgs.s6-rc-round-robin}/bin/s6-rc-round-robin \
|
||||||
wlan wlan5
|
-p ${proxy.name} \
|
||||||
lan
|
${lib.concatStringsSep " "
|
||||||
|
(builtins.map (f: f.name) [pppoe l2tp])}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
pppoe = (svc.pppoe.build {
|
||||||
|
interface = config.hardware.networkInterfaces.wan;
|
||||||
|
|
||||||
|
ppp-options = [
|
||||||
|
"debug" "+ipv6" "noauth"
|
||||||
|
"name" rsecrets.l2tp.name
|
||||||
|
"password" rsecrets.l2tp.password
|
||||||
];
|
];
|
||||||
inherit (rsecrets.lan) prefix;
|
}).overrideAttrs(o: { inherit controller; });
|
||||||
address = {
|
|
||||||
family = "inet"; address ="${rsecrets.lan.prefix}.1"; prefixLength = 24;
|
|
||||||
};
|
|
||||||
dhcp = {
|
|
||||||
start = 10;
|
|
||||||
end = 240;
|
|
||||||
hosts = { } // lib.optionalAttrs (builtins.pathExists ./static-leases.nix) (import ./static-leases.nix);
|
|
||||||
localDomain = "lan";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
wan = {
|
|
||||||
interface = let
|
|
||||||
pppoe = svc.pppoe.build {
|
|
||||||
interface = config.hardware.networkInterfaces.wan;
|
|
||||||
debug = true;
|
|
||||||
username = rsecrets.l2tp.name;
|
|
||||||
password = rsecrets.l2tp.password;
|
|
||||||
};
|
|
||||||
|
|
||||||
l2tp =
|
l2tp =
|
||||||
let
|
let
|
||||||
check-address = oneshot rec {
|
check-address = oneshot rec {
|
||||||
name = "check-lns-address";
|
name = "check-lns-address";
|
||||||
up = "grep -Fx ${lns.address} $(output_path ${services.lns-address} addresses)";
|
up = "grep -Fx ${ lns.address} $(output_path ${services.lns-address} addresses)";
|
||||||
dependencies = [ services.lns-address ];
|
dependencies = [ services.lns-address ];
|
||||||
};
|
|
||||||
route = svc.network.route.build {
|
|
||||||
via = "$(output ${services.bootstrap-dhcpc} router)";
|
|
||||||
target = lns.address;
|
|
||||||
dependencies = [services.bootstrap-dhcpc check-address];
|
|
||||||
};
|
|
||||||
in svc.l2tp.build {
|
|
||||||
lns = lns.address;
|
|
||||||
ppp-options = [
|
|
||||||
"debug" "+ipv6" "noauth"
|
|
||||||
"name" rsecrets.l2tp.name
|
|
||||||
"password" rsecrets.l2tp.password
|
|
||||||
];
|
|
||||||
dependencies = [config.services.lns-address route check-address];
|
|
||||||
};
|
};
|
||||||
in svc.round-robin.build {
|
route = svc.network.route.build {
|
||||||
name = "wan";
|
via = "$(output ${services.dhcpc} router)";
|
||||||
services = [ l2tp pppoe ];
|
target = lns.address;
|
||||||
|
dependencies = [services.dhcpc check-address];
|
||||||
|
};
|
||||||
|
in (svc.l2tp.build {
|
||||||
|
lns = lns.address;
|
||||||
|
ppp-options = [
|
||||||
|
"debug" "+ipv6" "noauth"
|
||||||
|
"name" rsecrets.l2tp.name
|
||||||
|
"password" rsecrets.l2tp.password
|
||||||
|
];
|
||||||
|
dependencies = [config.services.lns-address route check-address];
|
||||||
|
}).overrideAttrs(o: { inherit controller; });
|
||||||
|
proxy = oneshot rec {
|
||||||
|
name = "wan-proxy";
|
||||||
|
inherit controller;
|
||||||
|
buildInputs = [ pppoe l2tp];
|
||||||
|
up = ''
|
||||||
|
echo start proxy ${name}
|
||||||
|
set -x
|
||||||
|
(in_outputs ${name}
|
||||||
|
cp -rv $(output_path ${controller} active)/* .
|
||||||
|
)
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
dhcp6.enable = true;
|
in proxy;
|
||||||
};
|
|
||||||
|
|
||||||
wireless.networks = {
|
services.sshd = svc.ssh.build { };
|
||||||
"${rsecrets.ssid}" = {
|
|
||||||
interface = config.hardware.networkInterfaces.wlan;
|
services.resolvconf = oneshot rec {
|
||||||
hw_mode = "g";
|
dependencies = [ services.wan ];
|
||||||
channel = "6";
|
name = "resolvconf";
|
||||||
ieee80211n = 1;
|
up = ''
|
||||||
} // wirelessConfig;
|
. ${serviceFns}
|
||||||
"${rsecrets.ssid}5" = rec {
|
( in_outputs ${name}
|
||||||
interface = config.hardware.networkInterfaces.wlan5;
|
for i in ns1 ns2 ; do
|
||||||
hw_mode = "a";
|
ns=$(output ${services.wan} $i)
|
||||||
channel = 36;
|
echo "nameserver $ns" >> resolv.conf
|
||||||
ht_capab = "[HT40+]";
|
done
|
||||||
vht_oper_chwidth = 1;
|
)
|
||||||
vht_oper_centr_freq_seg0_idx = channel + 6;
|
'';
|
||||||
ieee80211n = 1;
|
};
|
||||||
ieee80211ac = 1;
|
filesystem = dir {
|
||||||
} // wirelessConfig;
|
etc = dir {
|
||||||
|
"resolv.conf" = symlink "${services.resolvconf}/.outputs/resolv.conf";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.bootstrap-dhcpc = svc.network.dhcp.client.build {
|
services.dhcpc = svc.network.dhcp.client.build {
|
||||||
interface = config.services.wwan;
|
interface = config.services.wwan;
|
||||||
dependencies = [ config.services.hostname ];
|
dependencies = [ config.services.hostname ];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.sshd = svc.ssh.build { };
|
|
||||||
|
|
||||||
services.lns-address = let
|
services.lns-address = let
|
||||||
ns = "$(output_word ${services.bootstrap-dhcpc} dns 1)";
|
ns = "$(output_word ${services.dhcpc} dns 1)";
|
||||||
route-to-bootstrap-nameserver = svc.network.route.build {
|
route-to-bootstrap-nameserver = svc.network.route.build {
|
||||||
via = "$(output ${services.bootstrap-dhcpc} router)";
|
via = "$(output ${services.dhcpc} router)";
|
||||||
target = ns;
|
target = ns;
|
||||||
dependencies = [services.bootstrap-dhcpc];
|
dependencies = [services.dhcpc];
|
||||||
};
|
};
|
||||||
in oneshot rec {
|
in oneshot rec {
|
||||||
name = "resolve-l2tp-server";
|
name = "resolve-l2tp-server";
|
||||||
dependencies = [ services.bootstrap-dhcpc route-to-bootstrap-nameserver ];
|
dependencies = [ services.dhcpc route-to-bootstrap-nameserver ];
|
||||||
up = ''
|
up = ''
|
||||||
(in_outputs ${name}
|
(in_outputs ${name}
|
||||||
DNSCACHEIP="${ns}" ${pkgs.s6-dns}/bin/s6-dnsip4 ${lns.hostname} \
|
DNSCACHEIP="${ns}" ${pkgs.s6-dns}/bin/s6-dnsip4 ${lns.hostname} \
|
||||||
|
@ -167,13 +158,18 @@ in rec {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# services.ntp = svc.ntp.build {
|
services.defaultroute4 = svc.network.route.build {
|
||||||
# pools = { "pool.ntp.org" = ["iburst"]; };
|
via = "$(output ${services.wan} peer-address)";
|
||||||
# makestep = { threshold = 1.0; limit = 3; };
|
target = "default";
|
||||||
# dependencies = with config.services; [ defaultroute4 defaultroute6 ];
|
dependencies = [services.wan];
|
||||||
# };
|
};
|
||||||
|
|
||||||
users.root = rsecrets.root;
|
# defaultProfile.packages = [ pkgs.go-l2tp ];
|
||||||
|
|
||||||
|
users.root = {
|
||||||
|
passwd = lib.mkForce secrets.root.passwd;
|
||||||
|
openssh.authorizedKeys.keys = secrets.root.keys;
|
||||||
|
};
|
||||||
|
|
||||||
programs.busybox.options = {
|
programs.busybox.options = {
|
||||||
FEATURE_FANCY_TAIL = "y";
|
FEATURE_FANCY_TAIL = "y";
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
# This is an example that uses the "gateway" profile to create a
|
# This is not part of Liminix per se. This is my "scratchpad"
|
||||||
# "typical home wireless router" configuration suitable for a Gl.inet
|
# configuration for the device I'm testing with.
|
||||||
# gl-ar750 router. It should be fairly simple to edit it for other
|
#
|
||||||
# devices: mostly you will need to attend to the number of wlan and lan
|
# Parts of it do do things that Liminix eventually needs to do, but
|
||||||
# interfaces
|
# don't look in here for solutions - just for identifying the
|
||||||
|
# problems.
|
||||||
|
|
||||||
|
|
||||||
{ config, pkgs, lib, modulesPath, ... } :
|
{ config, pkgs, lib, modulesPath, ... } :
|
||||||
let
|
let
|
||||||
|
@ -28,18 +30,21 @@ in rec {
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
"${modulesPath}/profiles/gateway.nix"
|
"${modulesPath}/profiles/gateway.nix"
|
||||||
|
"${modulesPath}/schnapps"
|
||||||
|
"${modulesPath}/outputs/btrfs.nix"
|
||||||
|
"${modulesPath}/outputs/extlinux.nix"
|
||||||
];
|
];
|
||||||
hostname = "rotuer";
|
hostname = "rotuer";
|
||||||
|
rootfsType = "btrfs";
|
||||||
|
rootOptions = "subvol=@";
|
||||||
|
boot.loader.extlinux.enable = true;
|
||||||
|
|
||||||
profile.gateway = {
|
profile.gateway = {
|
||||||
lan = {
|
lan = {
|
||||||
interfaces = with config.hardware.networkInterfaces;
|
interfaces = with config.hardware.networkInterfaces;
|
||||||
[
|
[
|
||||||
# EDIT: these are the interfaces exposed by the gl.inet gl-ar750:
|
|
||||||
# if your device has more or differently named lan interfaces,
|
|
||||||
# specify them here
|
|
||||||
wlan wlan5
|
wlan wlan5
|
||||||
lan
|
lan0 lan1 lan2 lan3 lan4
|
||||||
];
|
];
|
||||||
inherit (secrets.lan) prefix;
|
inherit (secrets.lan) prefix;
|
||||||
address = {
|
address = {
|
||||||
|
@ -53,17 +58,9 @@ in rec {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
wan = {
|
wan = {
|
||||||
# wan interface depends on your upstream - could be dhcp, static
|
interface = config.hardware.networkInterfaces.wan;
|
||||||
# ethernet, a pppoe, ppp over serial, a complicated bonded
|
username = secrets.l2tp.name;
|
||||||
# failover ... who knows what else?
|
password = secrets.l2tp.password;
|
||||||
interface = svc.pppoe.build {
|
|
||||||
interface = config.hardware.networkInterfaces.wan;
|
|
||||||
username = secrets.l2tp.name;
|
|
||||||
password = secrets.l2tp.password;
|
|
||||||
};
|
|
||||||
# once the wan has ipv4 connnectivity, should we run dhcp6
|
|
||||||
# client to potentially get an address range ("prefix
|
|
||||||
# delegation")
|
|
||||||
dhcp6.enable = true;
|
dhcp6.enable = true;
|
||||||
};
|
};
|
||||||
firewall = {
|
firewall = {
|
||||||
|
@ -71,10 +68,6 @@ in rec {
|
||||||
rules = secrets.firewallRules;
|
rules = secrets.firewallRules;
|
||||||
};
|
};
|
||||||
wireless.networks = {
|
wireless.networks = {
|
||||||
# EDIT: if you have more or fewer wireless radios, here is where
|
|
||||||
# you need to say so. hostapd tuning is hardware-specific and
|
|
||||||
# left as an exercise for the reader :-).
|
|
||||||
|
|
||||||
"${secrets.ssid}" = {
|
"${secrets.ssid}" = {
|
||||||
interface = config.hardware.networkInterfaces.wlan;
|
interface = config.hardware.networkInterfaces.wlan;
|
||||||
hw_mode = "g";
|
hw_mode = "g";
|
||||||
|
|
|
@ -12,8 +12,6 @@
|
||||||
let
|
let
|
||||||
inherit (lib) mkOption types;
|
inherit (lib) mkOption types;
|
||||||
inherit (pkgs) liminix;
|
inherit (pkgs) liminix;
|
||||||
mkStringOption =
|
|
||||||
description: mkOption { type = types.str; inherit description; };
|
|
||||||
in {
|
in {
|
||||||
options = {
|
options = {
|
||||||
system.service.pppoe = mkOption {
|
system.service.pppoe = mkOption {
|
||||||
|
@ -29,34 +27,9 @@ in {
|
||||||
type = liminix.lib.types.service;
|
type = liminix.lib.types.service;
|
||||||
description = "ethernet interface to run PPPoE over";
|
description = "ethernet interface to run PPPoE over";
|
||||||
};
|
};
|
||||||
username = mkStringOption "username";
|
|
||||||
password = mkStringOption "password";
|
|
||||||
lcpEcho = {
|
|
||||||
adaptive = mkOption {
|
|
||||||
description = "send LCP echo-request frames only if no traffic was received from the peer since the last echo-request was sent";
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
interval = mkOption {
|
|
||||||
type = types.nullOr types.int;
|
|
||||||
default = 3;
|
|
||||||
description = "send an LCP echo-request frame to the peer every n seconds";
|
|
||||||
};
|
|
||||||
failure = mkOption {
|
|
||||||
type = types.nullOr types.int;
|
|
||||||
default = 3;
|
|
||||||
description = "terminate connection if n LCP echo-requests are sent without receiving a valid LCP echo-reply";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
debug = mkOption {
|
|
||||||
description = "log the contents of all control packets sent or received";
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
};
|
|
||||||
ppp-options = mkOption {
|
ppp-options = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
description = "options supplied on ppp command line";
|
description = "options supplied on ppp command line";
|
||||||
default = [];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
system.service.l2tp = config.system.callService ./l2tp.nix {
|
system.service.l2tp = config.system.callService ./l2tp.nix {
|
||||||
|
|
|
@ -6,16 +6,11 @@
|
||||||
, writeAshScript
|
, writeAshScript
|
||||||
, serviceFns
|
, serviceFns
|
||||||
} :
|
} :
|
||||||
{ interface,
|
{ interface, ppp-options }:
|
||||||
ppp-options,
|
|
||||||
lcpEcho,
|
|
||||||
username,
|
|
||||||
password,
|
|
||||||
debug
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
inherit (liminix.services) longrun;
|
inherit (liminix.services) longrun;
|
||||||
inherit (lib) optional optionals;
|
lcp-echo-interval = 4;
|
||||||
|
lcp-echo-failure = 3;
|
||||||
name = "${interface.name}.pppoe";
|
name = "${interface.name}.pppoe";
|
||||||
ip-up = writeAshScript "ip-up" {} ''
|
ip-up = writeAshScript "ip-up" {} ''
|
||||||
. ${serviceFns}
|
. ${serviceFns}
|
||||||
|
@ -38,35 +33,25 @@ let
|
||||||
)
|
)
|
||||||
echo >/proc/self/fd/10
|
echo >/proc/self/fd/10
|
||||||
'';
|
'';
|
||||||
ppp-options' = ["+ipv6" "noauth"]
|
ppp-options' = ppp-options ++ [
|
||||||
++ optional debug "debug"
|
"ip-up-script" ip-up
|
||||||
++ optionals (username != null) ["name" username]
|
"ipv6-up-script" ip6-up
|
||||||
++ optionals (password != null) ["password" password]
|
"ipparam" name
|
||||||
++ optional lcpEcho.adaptive "lcp-echo-adaptive"
|
"nodetach"
|
||||||
++ optionals (lcpEcho.interval != null)
|
"usepeerdns"
|
||||||
["lcp-echo-interval" (builtins.toString lcpEcho.interval)]
|
"lcp-echo-interval" (builtins.toString lcp-echo-interval)
|
||||||
++ optionals (lcpEcho.failure != null)
|
"lcp-echo-failure" (builtins.toString lcp-echo-failure)
|
||||||
["lcp-echo-failure" (builtins.toString lcpEcho.failure)]
|
"logfd" "2"
|
||||||
++ ppp-options
|
];
|
||||||
++ ["ip-up-script" ip-up
|
|
||||||
"ipv6-up-script" ip6-up
|
|
||||||
"ipparam" name
|
|
||||||
"nodetach"
|
|
||||||
"usepeerdns"
|
|
||||||
"logfd" "2"
|
|
||||||
];
|
|
||||||
timeoutOpt = if lcpEcho.interval != null then "-T ${builtins.toString (4 * lcpEcho.interval)}" else "";
|
|
||||||
in
|
in
|
||||||
longrun {
|
longrun {
|
||||||
inherit name;
|
inherit name;
|
||||||
run = ''
|
run = ''
|
||||||
. ${serviceFns}
|
. ${serviceFns}
|
||||||
echo Starting pppoe, pppd pid is $$
|
echo Starting pppoe, pppd pid is $$
|
||||||
exec ${ppp}/bin/pppd pty "${pppoe}/bin/pppoe ${timeoutOpt} -I $(output ${interface} ifname)" ${lib.concatStringsSep " " ppp-options'}
|
exec ${ppp}/bin/pppd pty "${pppoe}/bin/pppoe -T ${builtins.toString (4 * lcp-echo-interval)} -I $(output ${interface} ifname)" ${lib.concatStringsSep " " ppp-options'}
|
||||||
'';
|
'';
|
||||||
notification-fd = 10;
|
notification-fd = 10;
|
||||||
timeout-up = if lcpEcho.failure != null
|
timeout-up = (10 + lcp-echo-failure * lcp-echo-interval) * 1000;
|
||||||
then (10 + lcpEcho.failure * lcpEcho.interval) * 1000
|
|
||||||
else 60 * 1000;
|
|
||||||
dependencies = [ interface ];
|
dependencies = [ interface ];
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,8 @@ in {
|
||||||
|
|
||||||
wan = {
|
wan = {
|
||||||
interface = mkOption { type = liminix.lib.types.interface; };
|
interface = mkOption { type = liminix.lib.types.interface; };
|
||||||
|
username = mkOption { type = types.str; };
|
||||||
|
password = mkOption { type = types.str; };
|
||||||
dhcp6.enable = mkOption { type = types.bool; };
|
dhcp6.enable = mkOption { type = types.bool; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,7 +86,14 @@ in {
|
||||||
members = cfg.lan.interfaces;
|
members = cfg.lan.interfaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
services.wan = cfg.wan.interface;
|
services.wan = svc.pppoe.build {
|
||||||
|
inherit (cfg.wan) interface;
|
||||||
|
ppp-options = [
|
||||||
|
"debug" "+ipv6" "noauth"
|
||||||
|
"name" cfg.wan.username
|
||||||
|
"password" cfg.wan.password
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
services.packet_forwarding = svc.network.forward.build { };
|
services.packet_forwarding = svc.network.forward.build { };
|
||||||
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
## Round Robin
|
|
||||||
##
|
|
||||||
## Given a list of services, run each in turn until it exits, then
|
|
||||||
## runs the next.
|
|
||||||
|
|
||||||
|
|
||||||
{ lib, pkgs, config, ...}:
|
|
||||||
let
|
|
||||||
inherit (lib) mkOption types;
|
|
||||||
inherit (pkgs) liminix;
|
|
||||||
inherit (pkgs.liminix.services) longrun;
|
|
||||||
in {
|
|
||||||
options = {
|
|
||||||
system.service.round-robin = mkOption {
|
|
||||||
description = "run services one at a time and failover to next";
|
|
||||||
type = liminix.lib.types.serviceDefn;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config.system.service.round-robin = config.system.callService ./service.nix {
|
|
||||||
services = mkOption {
|
|
||||||
type = types.listOf liminix.lib.types.service;
|
|
||||||
};
|
|
||||||
name = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
{
|
|
||||||
liminix, lib, s6-rc-round-robin
|
|
||||||
}:
|
|
||||||
{ services, name} :
|
|
||||||
let
|
|
||||||
inherit (liminix.services) oneshot longrun;
|
|
||||||
controlled-services = builtins.map
|
|
||||||
(s: s.overrideAttrs(o: { inherit controller; }))
|
|
||||||
services;
|
|
||||||
controller = let name' = "control-${name}"; in longrun {
|
|
||||||
name = name';
|
|
||||||
run = ''
|
|
||||||
in_outputs ${name'}
|
|
||||||
exec ${s6-rc-round-robin}/bin/s6-rc-round-robin \
|
|
||||||
-p ${proxy.name} \
|
|
||||||
${lib.concatStringsSep " "
|
|
||||||
(builtins.map (f: f.name) controlled-services)}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
proxy = oneshot rec {
|
|
||||||
inherit name;
|
|
||||||
inherit controller;
|
|
||||||
buildInputs = controlled-services;
|
|
||||||
up = ''
|
|
||||||
echo start proxy ${name}
|
|
||||||
set -x
|
|
||||||
(in_outputs ${name}
|
|
||||||
cp -rv $(output_path ${controller} active)/* .
|
|
||||||
)
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
in proxy
|
|
|
@ -9,7 +9,6 @@ let
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
../service-trigger
|
../service-trigger
|
||||||
../mdevd.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
@ -24,9 +23,6 @@ in {
|
||||||
USB_SERIAL = "y";
|
USB_SERIAL = "y";
|
||||||
USB_SERIAL_OPTION = "y";
|
USB_SERIAL_OPTION = "y";
|
||||||
};
|
};
|
||||||
programs.busybox.applets = [
|
|
||||||
"insmod" "rmmod"
|
|
||||||
];
|
|
||||||
|
|
||||||
# https://www.0xf8.org/2017/01/flashing-a-huawei-e3372h-4g-lte-stick-from-hilink-to-stick-mode/
|
# https://www.0xf8.org/2017/01/flashing-a-huawei-e3372h-4g-lte-stick-from-hilink-to-stick-mode/
|
||||||
system.service.wwan.huawei-e3372 =
|
system.service.wwan.huawei-e3372 =
|
||||||
|
|
|
@ -31,7 +31,7 @@ let
|
||||||
|
|
||||||
indent = text : indentLines 0 (splitString "\n" text);
|
indent = text : indentLines 0 (splitString "\n" text);
|
||||||
|
|
||||||
dochain = { name, type, family, rules,
|
dochain = { name, type, rules,
|
||||||
policy ? null,
|
policy ? null,
|
||||||
priority ? "filter",
|
priority ? "filter",
|
||||||
hook ? null } : ''
|
hook ? null } : ''
|
||||||
|
|
|
@ -13,7 +13,7 @@ stdenv.mkDerivation {
|
||||||
propagatedBuildInputs = [ s6-rc-up-tree ];
|
propagatedBuildInputs = [ s6-rc-up-tree ];
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
mkdir -p $out/bin
|
mkdir -p $out/bin
|
||||||
cp -p ${writeFennel "s6-rc-round-robin" {
|
cp -p ${writeFennel "uevent-watch" {
|
||||||
packages = [fennel anoia linotify lualinux s6-rc-up-tree] ;
|
packages = [fennel anoia linotify lualinux s6-rc-up-tree] ;
|
||||||
mainFunction = "run";
|
mainFunction = "run";
|
||||||
} ./robin.fnl} $out/bin/s6-rc-round-robin
|
} ./robin.fnl} $out/bin/s6-rc-round-robin
|
||||||
|
|
Loading…
Reference in New Issue