forked from dan/liminix
Compare commits
192 Commits
Author | SHA1 | Date |
---|---|---|
Daniel Barlow | 2663f58807 | |
Daniel Barlow | 9dbc285605 | |
Daniel Barlow | 8b6aa2134e | |
Daniel Barlow | 3df1ec76ff | |
Daniel Barlow | 0d3218127f | |
Daniel Barlow | e94bf62ec1 | |
Daniel Barlow | 16a2499d74 | |
Daniel Barlow | d4d8093f97 | |
Daniel Barlow | 7c9c801afc | |
Daniel Barlow | c4185617c0 | |
Daniel Barlow | 06d28e9b08 | |
Daniel Barlow | 9540fc2641 | |
Daniel Barlow | adc84108ad | |
Daniel Barlow | eae99051fa | |
Daniel Barlow | 49d1703428 | |
Daniel Barlow | 1d337588f9 | |
Daniel Barlow | 29a869b4fa | |
Daniel Barlow | 5ae1b0a193 | |
Daniel Barlow | 473a4947a5 | |
Daniel Barlow | 50bad5c604 | |
Daniel Barlow | c22e3fb2ef | |
Daniel Barlow | f898e4dca2 | |
Daniel Barlow | 5121a8563d | |
Daniel Barlow | 78be354b6e | |
Daniel Barlow | be13ab23ca | |
Daniel Barlow | 4b30cd7a75 | |
Daniel Barlow | b15542b668 | |
Daniel Barlow | 6daeaf29a0 | |
Daniel Barlow | e6ca5ea064 | |
Daniel Barlow | e6e4665a18 | |
Daniel Barlow | 2c10790a6d | |
Daniel Barlow | 571adf84c0 | |
Daniel Barlow | c8c79fd75a | |
Daniel Barlow | 884d8d194e | |
Daniel Barlow | f091bbd706 | |
Daniel Barlow | 37d7e20582 | |
Daniel Barlow | 04b068f7a3 | |
Daniel Barlow | 53f57c1a8c | |
Daniel Barlow | 19aba0d873 | |
Daniel Barlow | 7d00b39249 | |
Daniel Barlow | 7aa8633cde | |
Daniel Barlow | 58bec8a40f | |
Daniel Barlow | a3fca5bf05 | |
Daniel Barlow | e0bd7aec1e | |
Daniel Barlow | e815f61bb5 | |
Daniel Barlow | af9200a136 | |
Daniel Barlow | 898958fa10 | |
Daniel Barlow | fa0f262706 | |
Daniel Barlow | 71aeb27b2f | |
Daniel Barlow | 530b4080c9 | |
Daniel Barlow | 58cd007ccc | |
Daniel Barlow | 3a56798eb5 | |
Daniel Barlow | 758c7ef657 | |
Daniel Barlow | 73225a70b2 | |
Daniel Barlow | ab304dd3f1 | |
Daniel Barlow | 0d49f0f7a7 | |
Daniel Barlow | e64390460a | |
Daniel Barlow | c0ef6ce282 | |
Daniel Barlow | bd6ec5201f | |
Daniel Barlow | b4068da9fe | |
Daniel Barlow | aa4b09da85 | |
Daniel Barlow | 471c63b399 | |
Daniel Barlow | 782feaeafa | |
Daniel Barlow | ac54c89427 | |
Daniel Barlow | 5a3646cb29 | |
Daniel Barlow | e249f48cff | |
Daniel Barlow | 6661e42684 | |
Daniel Barlow | b9ba9ef835 | |
Daniel Barlow | 8b69dcc209 | |
Daniel Barlow | 9b3a3b9ff7 | |
Daniel Barlow | 7d08497bcb | |
Daniel Barlow | 0e84adaa0e | |
Daniel Barlow | 660ed5df8f | |
Daniel Barlow | 792a11c8c0 | |
Daniel Barlow | 7e4a05bbf8 | |
Daniel Barlow | a4ba5c85e1 | |
Daniel Barlow | 723ef73d5a | |
Daniel Barlow | 3d4e782929 | |
Daniel Barlow | 1b6a05aec5 | |
Daniel Barlow | 80628a3d90 | |
Daniel Barlow | bf0cafffed | |
Daniel Barlow | e49aba127c | |
Daniel Barlow | 324465bc18 | |
Daniel Barlow | b33249a050 | |
Daniel Barlow | b9c084415e | |
Daniel Barlow | cf9cadd212 | |
Daniel Barlow | a116fe084a | |
Daniel Barlow | 74cf3e0711 | |
Daniel Barlow | 9795f03da4 | |
Daniel Barlow | cdb23b147c | |
Daniel Barlow | dbd1264352 | |
Daniel Barlow | 834858d5bc | |
Daniel Barlow | 18335b95e3 | |
Daniel Barlow | 6bee2f67ac | |
Daniel Barlow | b4ba3eea21 | |
Daniel Barlow | 16af3984c9 | |
Daniel Barlow | ce7e395295 | |
Daniel Barlow | 7e13e017eb | |
Daniel Barlow | bbf2f53c0e | |
Daniel Barlow | 032d0f8aca | |
Daniel Barlow | b8ac9e5279 | |
Daniel Barlow | ff2604ca5d | |
Daniel Barlow | 72789984ce | |
Daniel Barlow | 90d9d0e811 | |
Daniel Barlow | 97a8ae1c84 | |
Daniel Barlow | 52eb283a26 | |
Daniel Barlow | cbb1de804e | |
Daniel Barlow | f9c03998b8 | |
Daniel Barlow | 50de1b090f | |
Daniel Barlow | 648382f64a | |
Daniel Barlow | e9370358ae | |
Daniel Barlow | 762ce7b6b8 | |
Daniel Barlow | b1c0560f4f | |
Daniel Barlow | e34135c41a | |
Daniel Barlow | 712c9b266f | |
Daniel Barlow | 4df963996c | |
Daniel Barlow | 349bfecbb8 | |
Daniel Barlow | 450d3820b2 | |
Daniel Barlow | 771585546d | |
Daniel Barlow | 73abf952d5 | |
Daniel Barlow | 8af4e9fd5b | |
Daniel Barlow | 7e19d80130 | |
Daniel Barlow | 0f0688c802 | |
Daniel Barlow | b43f17f655 | |
Daniel Barlow | adf62d4483 | |
Daniel Barlow | 68eb1360f6 | |
Daniel Barlow | 19ad6cd278 | |
Daniel Barlow | 00076c7b81 | |
Daniel Barlow | 721e7499f3 | |
Daniel Barlow | fc723b9a35 | |
Daniel Barlow | a5f16dfa81 | |
Daniel Barlow | 41a4b1f7ef | |
Daniel Barlow | 42a5699326 | |
Daniel Barlow | ea2b25168e | |
Daniel Barlow | 5564cf0554 | |
Daniel Barlow | f3a13630d3 | |
Daniel Barlow | f233acf9ff | |
Daniel Barlow | b6a054c588 | |
Daniel Barlow | b231664a06 | |
Daniel Barlow | f4bf3029fa | |
Daniel Barlow | 05f2c9a2f7 | |
Daniel Barlow | 5df5c822ea | |
Daniel Barlow | 4795dd05b7 | |
Daniel Barlow | a192f08881 | |
Daniel Barlow | a873dc6608 | |
Daniel Barlow | 2fb4756a7f | |
Daniel Barlow | 04f5174425 | |
Daniel Barlow | dca2e4def1 | |
Daniel Barlow | b60126775a | |
Daniel Barlow | 76f11bcc93 | |
Daniel Barlow | efcfdcc21d | |
Daniel Barlow | 77f1a78331 | |
Daniel Barlow | 28a5dec7dd | |
Daniel Barlow | fad0a47b75 | |
Daniel Barlow | af52aafc84 | |
Daniel Barlow | 34442b6069 | |
Daniel Barlow | b8a46fc05e | |
Daniel Barlow | 8ac2c6cec1 | |
Daniel Barlow | 8879b2d1ba | |
Daniel Barlow | 83e346d5a0 | |
Daniel Barlow | 156b1fe64a | |
Daniel Barlow | 1a314e55b7 | |
Daniel Barlow | 9263b21faa | |
Daniel Barlow | 0a820a702a | |
Daniel Barlow | 4ea518e296 | |
Daniel Barlow | 98318b450d | |
Daniel Barlow | e4ac7f19dc | |
Daniel Barlow | 9c22744850 | |
Daniel Barlow | c697be8c28 | |
dan | 202a37221a | |
Florian Klink | 436eb03a7b | |
Daniel Barlow | e5963ae3f7 | |
Daniel Barlow | f164f19d95 | |
Daniel Barlow | dd4ab41f6a | |
Daniel Barlow | 5d5dff6729 | |
Daniel Barlow | 570d29c368 | |
Daniel Barlow | 725af00dc9 | |
Daniel Barlow | e1b932ec27 | |
Daniel Barlow | 7173b6fb1c | |
Daniel Barlow | ed9548f21d | |
Daniel Barlow | 0787807a7f | |
Daniel Barlow | 38ed91f641 | |
Daniel Barlow | ffe9603c39 | |
Daniel Barlow | cbd3dfefc5 | |
Daniel Barlow | 018c1868b5 | |
Daniel Barlow | 5184ff63f7 | |
Daniel Barlow | 35909c9a23 | |
Daniel Barlow | 4383462199 | |
Daniel Barlow | 9730cdd63b | |
dan | 095853214b | |
sinavir | 27c7735f02 | |
sinavir | 29c9de248d |
21
NEWS
21
NEWS
|
@ -83,4 +83,23 @@ sponsoring this development (and funding the hardware)
|
||||||
2024-02-21
|
2024-02-21
|
||||||
|
|
||||||
New port! Thanks to Raito Bezarius, Liminix now runs on the Zyxel NWA50AX,
|
New port! Thanks to Raito Bezarius, Liminix now runs on the Zyxel NWA50AX,
|
||||||
an MT7621 (MIPS EL) dual radio WiFi AP.
|
an MT7621 (MIPS EL) dual radio WiFi AP.
|
||||||
|
|
||||||
|
2024-04-29
|
||||||
|
|
||||||
|
The setup for using `levitate` has changed: now it accepts an entire
|
||||||
|
config fragment, not just a list of services. Hopefully this makes it
|
||||||
|
a bit more useful :-)
|
||||||
|
|
||||||
|
defaultProfile.packages = with pkgs; [
|
||||||
|
...
|
||||||
|
(levitate.override {
|
||||||
|
config = {
|
||||||
|
services = {
|
||||||
|
inherit (config.services) dhcpc sshd watchdog;
|
||||||
|
};
|
||||||
|
defaultProfile.packages = [ mtdutils ];
|
||||||
|
users.root.openssh.authorizedKeys.keys = secrets.root.keys;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
1024
THOUGHTS.txt
1024
THOUGHTS.txt
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,20 @@
|
||||||
|
# This is for use with minicom, but needs you to configure it to
|
||||||
|
# use expect as its "Script program" instead of runscript. Try
|
||||||
|
# Ctrl+A O -> Filenames and paths -> D
|
||||||
|
|
||||||
|
log_user 0
|
||||||
|
log_file -a -open stderr
|
||||||
|
set f [open "result/boot.scr"]
|
||||||
|
send "version\r"
|
||||||
|
set timeout 60
|
||||||
|
while {[gets $f line] >= 0} {
|
||||||
|
puts stderr "next line $line\r"
|
||||||
|
puts stderr "waiting for prompt\r"
|
||||||
|
expect {
|
||||||
|
"ath>" {}
|
||||||
|
"BusyBox" { puts stderr "DONE"; exit 0 }
|
||||||
|
}
|
||||||
|
send "$line\r\n"
|
||||||
|
}
|
||||||
|
puts stderr "done\r\n"
|
||||||
|
close $f
|
|
@ -4,6 +4,10 @@ let
|
||||||
inherit (lib) mkOption mkEnableOption mdDoc types optional optionals;
|
inherit (lib) mkOption mkEnableOption mdDoc types optional optionals;
|
||||||
in {
|
in {
|
||||||
options.bordervm = {
|
options.bordervm = {
|
||||||
|
keys = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
l2tp = {
|
l2tp = {
|
||||||
host = mkOption {
|
host = mkOption {
|
||||||
description = mdDoc ''
|
description = mdDoc ''
|
||||||
|
@ -51,18 +55,17 @@ in {
|
||||||
<nixpkgs/nixos/modules/virtualisation/qemu-vm.nix>
|
<nixpkgs/nixos/modules/virtualisation/qemu-vm.nix>
|
||||||
];
|
];
|
||||||
config = {
|
config = {
|
||||||
boot.kernelParams = [
|
boot.kernelParams = [ "loglevel=9" ];
|
||||||
"loglevel=9"
|
|
||||||
];
|
|
||||||
systemd.services.pppoe =
|
systemd.services.pppoe =
|
||||||
let conf = pkgs.writeText "kpppoed.toml"
|
let
|
||||||
''
|
conf = pkgs.writeText "kpppoed.toml" ''
|
||||||
interface_name = "eth1"
|
interface_name = "eth1"
|
||||||
services = [ "myservice" ]
|
services = [ "myservice" ]
|
||||||
lns_ipaddr = "${cfg.l2tp.host}:${builtins.toString cfg.l2tp.port}"
|
lns_ipaddr = "${cfg.l2tp.host}:${builtins.toString cfg.l2tp.port}"
|
||||||
ac_name = "kpppoed-1.0"
|
ac_name = "kpppoed-1.0"
|
||||||
'';
|
'';
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
@ -76,24 +79,36 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
services.openssh.enable = true;
|
services.openssh.enable = true;
|
||||||
|
services.dnsmasq = {
|
||||||
|
enable = true;
|
||||||
|
resolveLocalQueries = false;
|
||||||
|
settings = {
|
||||||
|
# domain-needed = true;
|
||||||
|
dhcp-range = [ "10.0.0.10,10.0.0.240" ];
|
||||||
|
interface = "eth1";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
systemd.services.sshd.wantedBy = pkgs.lib.mkForce [ "multi-user.target" ];
|
systemd.services.sshd.wantedBy = pkgs.lib.mkForce [ "multi-user.target" ];
|
||||||
|
|
||||||
virtualisation = {
|
virtualisation = {
|
||||||
qemu = {
|
qemu = {
|
||||||
networkingOptions = [];
|
networkingOptions = [ ];
|
||||||
options = [] ++
|
options =
|
||||||
optional cfg.ethernet.pci.enable
|
[ ]
|
||||||
"-device vfio-pci,host=${cfg.ethernet.pci.id}" ++
|
++ optional cfg.ethernet.pci.enable "-device vfio-pci,host=${cfg.ethernet.pci.id}"
|
||||||
optionals cfg.ethernet.usb.enable [
|
++ optionals cfg.ethernet.usb.enable [
|
||||||
"-device usb-ehci,id=ehci"
|
"-device usb-ehci,id=ehci"
|
||||||
"-device usb-host,bus=ehci.0,vendorid=${cfg.ethernet.usb.vendor},productid=${cfg.ethernet.usb.product}"
|
"-device usb-host,bus=ehci.0,vendorid=${cfg.ethernet.usb.vendor},productid=${cfg.ethernet.usb.product}"
|
||||||
] ++ [
|
]
|
||||||
|
++ [
|
||||||
"-nographic"
|
"-nographic"
|
||||||
"-serial mon:stdio"
|
"-serial mon:stdio"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
sharedDirectories = {
|
sharedDirectories = {
|
||||||
liminix = {
|
liminix = {
|
||||||
|
securityModel = "none";
|
||||||
source = builtins.toString ./.;
|
source = builtins.toString ./.;
|
||||||
target = "/home/liminix/liminix";
|
target = "/home/liminix/liminix";
|
||||||
};
|
};
|
||||||
|
@ -108,6 +123,7 @@ in {
|
||||||
tufted
|
tufted
|
||||||
iptables
|
iptables
|
||||||
usbutils
|
usbutils
|
||||||
|
busybox
|
||||||
];
|
];
|
||||||
security.sudo.wheelNeedsPassword = false;
|
security.sudo.wheelNeedsPassword = false;
|
||||||
networking = {
|
networking = {
|
||||||
|
@ -117,11 +133,17 @@ in {
|
||||||
useDHCP = false;
|
useDHCP = false;
|
||||||
ipv4.addresses = [ { address = "10.0.0.1"; prefixLength = 24;}];
|
ipv4.addresses = [ { address = "10.0.0.1"; prefixLength = 24;}];
|
||||||
};
|
};
|
||||||
|
nat = {
|
||||||
|
enable = true;
|
||||||
|
internalInterfaces = [ "eth1" ];
|
||||||
|
externalInterface = "eth0";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
users.users.liminix = {
|
users.users.liminix = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
uid = 1000;
|
uid = 1000;
|
||||||
extraGroups = [ "wheel"];
|
extraGroups = [ "wheel" ];
|
||||||
|
openssh.authorizedKeys.keys = cfg.keys;
|
||||||
};
|
};
|
||||||
services.getty.autologinUser = "liminix";
|
services.getty.autologinUser = "liminix";
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
{...}:
|
{ ... }:
|
||||||
{
|
{
|
||||||
bordervm = {
|
bordervm = {
|
||||||
# ethernet.pci = { id = "01:00.0"; enable = true; };
|
# ethernet.pci = { id = "01:00.0"; enable = true; };
|
||||||
ethernet.usb = { vendor = "0x0bda"; product = "0x8153"; enable = true; };
|
ethernet.usb = {
|
||||||
|
vendor = "0x0bda";
|
||||||
|
product = "0x8153";
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
l2tp = {
|
l2tp = {
|
||||||
host = "l2tp.aa.net.uk";
|
host = "l2tp.aa.net.uk";
|
||||||
};
|
};
|
||||||
|
|
60
ci.nix
60
ci.nix
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
nixpkgs
|
nixpkgs,
|
||||||
, unstable
|
unstable,
|
||||||
, liminix
|
liminix,
|
||||||
, ... }:
|
...
|
||||||
|
}:
|
||||||
let
|
let
|
||||||
inherit (builtins) map;
|
pkgs = (import nixpkgs { });
|
||||||
pkgs = (import nixpkgs {});
|
borderVmConf = ./bordervm.conf-example.nix;
|
||||||
borderVmConf = ./bordervm.conf-example.nix;
|
|
||||||
inherit (pkgs.lib.attrsets) genAttrs;
|
inherit (pkgs.lib.attrsets) genAttrs;
|
||||||
devices = [
|
devices = [
|
||||||
"gl-ar750"
|
"gl-ar750"
|
||||||
|
@ -27,33 +27,35 @@ let
|
||||||
}).outputs.default;
|
}).outputs.default;
|
||||||
tests = import ./tests/ci.nix;
|
tests = import ./tests/ci.nix;
|
||||||
jobs =
|
jobs =
|
||||||
(genAttrs devices for-device) //
|
(genAttrs devices for-device)
|
||||||
tests //
|
// tests
|
||||||
{
|
// {
|
||||||
buildEnv = (import liminix {
|
buildEnv =
|
||||||
inherit nixpkgs borderVmConf;
|
(import liminix {
|
||||||
device = import (liminix + "/devices/qemu");
|
inherit nixpkgs borderVmConf;
|
||||||
liminix-config = vanilla;
|
device = import (liminix + "/devices/qemu");
|
||||||
}).buildEnv;
|
liminix-config = vanilla;
|
||||||
|
}).buildEnv;
|
||||||
doc =
|
doc =
|
||||||
let json =
|
let
|
||||||
(import liminix {
|
json =
|
||||||
inherit nixpkgs borderVmConf;
|
(import liminix {
|
||||||
device = import (liminix + "/devices/qemu");
|
inherit nixpkgs borderVmConf;
|
||||||
liminix-config = {...} : {
|
device = import (liminix + "/devices/qemu");
|
||||||
|
liminix-config =
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
imports = [ ./modules/all-modules.nix ];
|
imports = [ ./modules/all-modules.nix ];
|
||||||
};
|
};
|
||||||
}).outputs.optionsJson;
|
}).outputs.optionsJson;
|
||||||
installers = map (f: "system.outputs.${f}") [
|
in
|
||||||
"vmroot"
|
pkgs.stdenv.mkDerivation {
|
||||||
"mtdimage"
|
|
||||||
"ubimage"
|
|
||||||
];
|
|
||||||
inherit (pkgs.lib) concatStringsSep;
|
|
||||||
in pkgs.stdenv.mkDerivation {
|
|
||||||
name = "liminix-doc";
|
name = "liminix-doc";
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
gnumake sphinx fennel luaPackages.lyaml
|
gnumake
|
||||||
|
sphinx
|
||||||
|
fennel
|
||||||
|
luaPackages.lyaml
|
||||||
];
|
];
|
||||||
src = ./.;
|
src = ./.;
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
|
|
48
default.nix
48
default.nix
|
@ -1,31 +1,39 @@
|
||||||
{
|
{
|
||||||
device
|
deviceName ? null,
|
||||||
, liminix-config ? <liminix-config>
|
device ? (import ./devices/${deviceName}),
|
||||||
, nixpkgs ? <nixpkgs>
|
liminix-config ? <liminix-config>,
|
||||||
, borderVmConf ? ./bordervm.conf.nix
|
nixpkgs ? <nixpkgs>,
|
||||||
, imageType ? "primary"
|
borderVmConf ? ./bordervm.conf.nix,
|
||||||
|
imageType ? "primary",
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
overlay = import ./overlay.nix;
|
overlay = import ./overlay.nix;
|
||||||
pkgs = import nixpkgs (device.system // {
|
pkgs = import nixpkgs (
|
||||||
overlays = [overlay];
|
device.system
|
||||||
config = {
|
// {
|
||||||
allowUnsupportedSystem = true; # mipsel
|
overlays = [ overlay ];
|
||||||
permittedInsecurePackages = [
|
config = {
|
||||||
"python-2.7.18.6" # kernel backports needs python <3
|
allowUnsupportedSystem = true; # mipsel
|
||||||
"python-2.7.18.7"
|
permittedInsecurePackages = [
|
||||||
];
|
"python-2.7.18.6" # kernel backports needs python <3
|
||||||
};
|
"python-2.7.18.7"
|
||||||
});
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
eval = pkgs.lib.evalModules {
|
eval = pkgs.lib.evalModules {
|
||||||
|
specialArgs = {
|
||||||
|
modulesPath = builtins.toString ./modules;
|
||||||
|
};
|
||||||
modules = [
|
modules = [
|
||||||
{ _module.args = { inherit pkgs; inherit (pkgs) lim; }; }
|
{ _module.args = { inherit pkgs; inherit (pkgs) lim; }; }
|
||||||
./modules/hardware.nix
|
./modules/hardware.nix
|
||||||
./modules/base.nix
|
./modules/base.nix
|
||||||
./modules/busybox.nix
|
./modules/busybox.nix
|
||||||
./modules/hostname.nix
|
./modules/hostname.nix
|
||||||
|
./modules/kernel
|
||||||
device.module
|
device.module
|
||||||
liminix-config
|
liminix-config
|
||||||
./modules/s6
|
./modules/s6
|
||||||
|
@ -41,7 +49,14 @@ let
|
||||||
borderVm = ((import <nixpkgs/nixos/lib/eval-config.nix>) {
|
borderVm = ((import <nixpkgs/nixos/lib/eval-config.nix>) {
|
||||||
system = builtins.currentSystem;
|
system = builtins.currentSystem;
|
||||||
modules = [
|
modules = [
|
||||||
({ ... } : { nixpkgs.overlays = [ overlay ]; })
|
{
|
||||||
|
nixpkgs.overlays = [
|
||||||
|
(final: prev: {
|
||||||
|
go-l2tp = final.callPackage ./pkgs/go-l2tp {};
|
||||||
|
tufted = final.callPackage ./pkgs/tufted {};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
(import ./bordervm-configuration.nix)
|
(import ./bordervm-configuration.nix)
|
||||||
borderVmConf
|
borderVmConf
|
||||||
];
|
];
|
||||||
|
@ -72,6 +87,7 @@ in {
|
||||||
min-copy-closure
|
min-copy-closure
|
||||||
fennelrepl
|
fennelrepl
|
||||||
lzma
|
lzma
|
||||||
|
lua
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@
|
||||||
MTK_INFRACFG = "y";
|
MTK_INFRACFG = "y";
|
||||||
|
|
||||||
MTK_PMIC_WRAP = "y";
|
MTK_PMIC_WRAP = "y";
|
||||||
MTK_EFUSE="y";
|
NVMEM_MTK_EFUSE="y";
|
||||||
# MTK_HSDMA="y";
|
# MTK_HSDMA="y";
|
||||||
MTK_SCPSYS="y";
|
MTK_SCPSYS="y";
|
||||||
MTK_SCPSYS_PM_DOMAINS="y";
|
MTK_SCPSYS_PM_DOMAINS="y";
|
||||||
|
@ -92,7 +92,6 @@
|
||||||
|
|
||||||
MEDIATEK_GE_PHY = "y";
|
MEDIATEK_GE_PHY = "y";
|
||||||
# MEDIATEK_MT6577_AUXADC = "y";
|
# MEDIATEK_MT6577_AUXADC = "y";
|
||||||
# MEDIATEK_WATCHDOG = "y";
|
|
||||||
NET_MEDIATEK_SOC = "y";
|
NET_MEDIATEK_SOC = "y";
|
||||||
NET_MEDIATEK_SOC_WED = "y";
|
NET_MEDIATEK_SOC_WED = "y";
|
||||||
NET_MEDIATEK_STAR_EMAC = "y"; # this enables REGMAP_MMIO
|
NET_MEDIATEK_STAR_EMAC = "y"; # this enables REGMAP_MMIO
|
||||||
|
@ -214,7 +213,6 @@
|
||||||
networkInterfaces =
|
networkInterfaces =
|
||||||
let
|
let
|
||||||
inherit (config.system.service.network) link;
|
inherit (config.system.service.network) link;
|
||||||
inherit (config.system.service) bridge;
|
|
||||||
in rec {
|
in rec {
|
||||||
wan = link.build { ifname = "wan"; };
|
wan = link.build { ifname = "wan"; };
|
||||||
lan1 = link.build { ifname = "lan1"; };
|
lan1 = link.build { ifname = "lan1"; };
|
||||||
|
|
|
@ -23,12 +23,17 @@
|
||||||
VIRTIO_BLK = "y";
|
VIRTIO_BLK = "y";
|
||||||
VIRTIO_NET = "y";
|
VIRTIO_NET = "y";
|
||||||
};
|
};
|
||||||
|
conditionalConfig = {
|
||||||
|
WLAN= {
|
||||||
|
MAC80211_HWSIM = "m";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
hardware =
|
hardware =
|
||||||
let
|
let
|
||||||
mac80211 = pkgs.mac80211.override {
|
mac80211 = pkgs.kmodloader.override {
|
||||||
drivers = ["mac80211_hwsim"];
|
inherit (config.system.outputs) kernel;
|
||||||
klibBuild = config.system.outputs.kernel.modulesupport;
|
targets = ["mac80211_hwsim"];
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
defaultOutput = "vmroot";
|
defaultOutput = "vmroot";
|
||||||
|
|
|
@ -92,7 +92,6 @@
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
inherit (pkgs.pseudofile) dir symlink;
|
inherit (pkgs.pseudofile) dir symlink;
|
||||||
inherit (pkgs.liminix.networking) interface;
|
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
../../modules/network
|
../../modules/network
|
||||||
|
@ -125,8 +124,14 @@
|
||||||
networkInterfaces =
|
networkInterfaces =
|
||||||
let inherit (config.system.service.network) link;
|
let inherit (config.system.service.network) link;
|
||||||
in {
|
in {
|
||||||
lan = link.build { ifname = "eth0"; };
|
lan = link.build {
|
||||||
wan = link.build { ifname = "eth1"; };
|
ifname = "lan";
|
||||||
|
devpath = "/devices/platform/ahb/19000000.eth";
|
||||||
|
};
|
||||||
|
wan = link.build {
|
||||||
|
ifname = "wan";
|
||||||
|
devpath = "/devices/platform/ahb/1a000000.eth";
|
||||||
|
};
|
||||||
wlan = link.build {
|
wlan = link.build {
|
||||||
ifname = "wlan0";
|
ifname = "wlan0";
|
||||||
dependencies = [ mac80211 ];
|
dependencies = [ mac80211 ];
|
||||||
|
@ -149,6 +154,7 @@
|
||||||
};
|
};
|
||||||
boot.tftp = {
|
boot.tftp = {
|
||||||
loadAddress = lim.parseInt "0x00A00000";
|
loadAddress = lim.parseInt "0x00A00000";
|
||||||
|
appendDTB = true;
|
||||||
};
|
};
|
||||||
kernel = {
|
kernel = {
|
||||||
src = pkgs.pkgsBuildBuild.fetchurl {
|
src = pkgs.pkgsBuildBuild.fetchurl {
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
|
|
||||||
module = { pkgs, config, lib, lim, ...}:
|
module = { pkgs, config, lib, lim, ...}:
|
||||||
let
|
let
|
||||||
inherit (pkgs.liminix.networking) interface;
|
|
||||||
inherit (pkgs) openwrt;
|
inherit (pkgs) openwrt;
|
||||||
mac80211 = pkgs.kmodloader.override {
|
mac80211 = pkgs.kmodloader.override {
|
||||||
targets = ["rt2800soc"];
|
targets = ["rt2800soc"];
|
||||||
|
@ -90,19 +89,6 @@
|
||||||
let
|
let
|
||||||
inherit (config.system.service.network) link;
|
inherit (config.system.service.network) link;
|
||||||
inherit (config.system.service) vlan;
|
inherit (config.system.service) vlan;
|
||||||
inherit (pkgs.liminix.services) oneshot;
|
|
||||||
swconfig = oneshot {
|
|
||||||
name = "swconfig";
|
|
||||||
up = ''
|
|
||||||
PATH=${pkgs.swconfig}/bin:$PATH
|
|
||||||
swconfig dev switch0 set reset
|
|
||||||
swconfig dev switch0 set enable_vlan 1
|
|
||||||
swconfig dev switch0 vlan 1 set ports '1 2 3 4 6t'
|
|
||||||
swconfig dev switch0 vlan 2 set ports '0 6t'
|
|
||||||
swconfig dev switch0 set apply
|
|
||||||
'';
|
|
||||||
down = "${pkgs.swconfig}/bin/swconfig dev switch0 set reset";
|
|
||||||
};
|
|
||||||
in rec {
|
in rec {
|
||||||
eth = link.build { ifname = "eth0"; };
|
eth = link.build { ifname = "eth0"; };
|
||||||
# lan and wan ports are both behind a switch on eth0
|
# lan and wan ports are both behind a switch on eth0
|
||||||
|
@ -110,13 +96,11 @@
|
||||||
ifname = "eth0.1";
|
ifname = "eth0.1";
|
||||||
primary = eth;
|
primary = eth;
|
||||||
vid = "1";
|
vid = "1";
|
||||||
dependencies = [swconfig eth];
|
|
||||||
};
|
};
|
||||||
wan = vlan.build {
|
wan = vlan.build {
|
||||||
ifname = "eth0.2";
|
ifname = "eth0.2";
|
||||||
primary = eth;
|
primary = eth;
|
||||||
vid = "2";
|
vid = "2";
|
||||||
dependencies = [swconfig eth];
|
|
||||||
};
|
};
|
||||||
wlan = link.build {
|
wlan = link.build {
|
||||||
ifname = "wlan0";
|
ifname = "wlan0";
|
||||||
|
@ -126,7 +110,8 @@
|
||||||
};
|
};
|
||||||
boot.tftp = {
|
boot.tftp = {
|
||||||
loadAddress = lim.parseInt "0x00A00000";
|
loadAddress = lim.parseInt "0x00A00000";
|
||||||
};
|
appendDTB = true;
|
||||||
|
};
|
||||||
|
|
||||||
kernel = {
|
kernel = {
|
||||||
src = pkgs.fetchurl {
|
src = pkgs.fetchurl {
|
||||||
|
@ -136,6 +121,7 @@
|
||||||
};
|
};
|
||||||
extraPatchPhase = ''
|
extraPatchPhase = ''
|
||||||
${openwrt.applyPatches.ramips}
|
${openwrt.applyPatches.ramips}
|
||||||
|
${openwrt.applyPatches.rt2x00}
|
||||||
'';
|
'';
|
||||||
config = {
|
config = {
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
|
|
||||||
module = { pkgs, config, lib, lim, ...}:
|
module = { pkgs, config, lib, lim, ...}:
|
||||||
let
|
let
|
||||||
inherit (pkgs.liminix.networking) interface;
|
|
||||||
inherit (pkgs.liminix.services) oneshot;
|
inherit (pkgs.liminix.services) oneshot;
|
||||||
inherit (pkgs.pseudofile) dir symlink;
|
inherit (pkgs.pseudofile) dir symlink;
|
||||||
inherit (pkgs) openwrt;
|
inherit (pkgs) openwrt;
|
||||||
|
@ -97,7 +96,7 @@
|
||||||
swconfig dev switch0 vlan 2 set ports '0 6t'
|
swconfig dev switch0 vlan 2 set ports '0 6t'
|
||||||
swconfig dev switch0 set apply
|
swconfig dev switch0 set apply
|
||||||
'';
|
'';
|
||||||
down = "swconfig dev switch0 set reset";
|
down = "${pkgs.swconfig}/bin/swconfig dev switch0 set reset";
|
||||||
};
|
};
|
||||||
in rec {
|
in rec {
|
||||||
eth = link.build { ifname = "eth0"; dependencies = [swconfig]; };
|
eth = link.build { ifname = "eth0"; dependencies = [swconfig]; };
|
||||||
|
@ -122,6 +121,7 @@
|
||||||
# 20MB seems to give enough room to uncompress the kernel
|
# 20MB seems to give enough room to uncompress the kernel
|
||||||
# without anything getting trodden on. 10MB was too small
|
# without anything getting trodden on. 10MB was too small
|
||||||
loadAddress = lim.parseInt "0x1400000";
|
loadAddress = lim.parseInt "0x1400000";
|
||||||
|
appendDTB = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
kernel = {
|
kernel = {
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
# this device is described by the "qemu" device
|
# this device is described by the "qemu" device
|
||||||
installer = "vmroot";
|
installer = "vmroot";
|
||||||
|
|
||||||
module = {pkgs, config, lim, ... }: {
|
module = { config, lim, ... }: {
|
||||||
imports = [
|
imports = [
|
||||||
../../modules/arch/aarch64.nix
|
../../modules/arch/aarch64.nix
|
||||||
../families/qemu.nix
|
../families/qemu.nix
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
'';
|
'';
|
||||||
installer = "vmroot";
|
installer = "vmroot";
|
||||||
|
|
||||||
module = {pkgs, config, lim, ... }: {
|
module = { config, lim, ... }: {
|
||||||
imports = [
|
imports = [
|
||||||
../../modules/arch/arm.nix
|
../../modules/arch/arm.nix
|
||||||
../families/qemu.nix
|
../families/qemu.nix
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
in the Development manual.
|
in the Development manual.
|
||||||
|
|
||||||
'';
|
'';
|
||||||
module = {pkgs, config, lib, lim, ... }: {
|
module = { config, lib, lim, ... }: {
|
||||||
imports = [
|
imports = [
|
||||||
../../modules/arch/mipseb.nix
|
../../modules/arch/mipseb.nix
|
||||||
../families/qemu.nix
|
../families/qemu.nix
|
||||||
|
|
|
@ -419,7 +419,6 @@
|
||||||
networkInterfaces =
|
networkInterfaces =
|
||||||
let
|
let
|
||||||
inherit (config.system.service.network) link;
|
inherit (config.system.service.network) link;
|
||||||
inherit (config.system.service) bridge;
|
|
||||||
in rec {
|
in rec {
|
||||||
lan1 = link.build { ifname = "lan1"; };
|
lan1 = link.build { ifname = "lan1"; };
|
||||||
lan2 = link.build { ifname = "lan2"; };
|
lan2 = link.build { ifname = "lan2"; };
|
||||||
|
|
|
@ -155,8 +155,6 @@
|
||||||
|
|
||||||
module = {pkgs, config, lib, lim, ... }:
|
module = {pkgs, config, lib, lim, ... }:
|
||||||
let
|
let
|
||||||
openwrt = pkgs.openwrt;
|
|
||||||
inherit (lib) mkOption types;
|
|
||||||
inherit (pkgs.liminix.services) oneshot;
|
inherit (pkgs.liminix.services) oneshot;
|
||||||
inherit (pkgs) liminix;
|
inherit (pkgs) liminix;
|
||||||
mtd_by_name_links = pkgs.liminix.services.oneshot rec {
|
mtd_by_name_links = pkgs.liminix.services.oneshot rec {
|
||||||
|
@ -358,7 +356,6 @@
|
||||||
networkInterfaces =
|
networkInterfaces =
|
||||||
let
|
let
|
||||||
inherit (config.system.service.network) link;
|
inherit (config.system.service.network) link;
|
||||||
inherit (config.system.service) bridge;
|
|
||||||
in rec {
|
in rec {
|
||||||
en70000 = link.build {
|
en70000 = link.build {
|
||||||
# in armada-38x.dtsi this is eth0.
|
# in armada-38x.dtsi this is eth0.
|
||||||
|
|
|
@ -103,8 +103,6 @@
|
||||||
|
|
||||||
module = { pkgs, config, lib, lim, ...}:
|
module = { pkgs, config, lib, lim, ...}:
|
||||||
let
|
let
|
||||||
inherit (pkgs.liminix.networking) interface;
|
|
||||||
inherit (pkgs.liminix.services) oneshot;
|
|
||||||
inherit (pkgs.pseudofile) dir symlink;
|
inherit (pkgs.pseudofile) dir symlink;
|
||||||
inherit (pkgs) openwrt;
|
inherit (pkgs) openwrt;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
{ eval, lib, pkgs }:
|
{ eval, lib, pkgs }:
|
||||||
let
|
let
|
||||||
inherit (lib) types;
|
|
||||||
conf = eval.config;
|
conf = eval.config;
|
||||||
rootDir = builtins.toPath ./..;
|
rootDir = builtins.toPath ./..;
|
||||||
stripAnyPrefixes = lib.flip (lib.fold lib.removePrefix)
|
stripAnyPrefixes = lib.flip (lib.fold lib.removePrefix) [ "${rootDir}/" ];
|
||||||
["${rootDir}/"];
|
optToDoc = name: opt: {
|
||||||
optToDoc = name: opt : {
|
|
||||||
inherit name;
|
inherit name;
|
||||||
description = opt.description or null;
|
description = opt.description or null;
|
||||||
default = opt.default or null;
|
default = opt.default or null;
|
||||||
|
@ -26,7 +24,6 @@ let
|
||||||
let x = lib.mapAttrsToList optToDoc sd.parameters; in x;
|
let x = lib.mapAttrsToList optToDoc sd.parameters; in x;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
item // { declarations = map stripAnyPrefixes item.declarations; };
|
item // { declarations = map stripAnyPrefixes item.declarations; };
|
||||||
in
|
in
|
||||||
builtins.map spliceServiceDefn
|
builtins.map spliceServiceDefn (pkgs.lib.optionAttrSetToDocList eval.options)
|
||||||
(pkgs.lib.optionAttrSetToDocList eval.options)
|
|
||||||
|
|
|
@ -1,24 +1,18 @@
|
||||||
with import <nixpkgs> {} ;
|
with import <nixpkgs> { };
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (builtins) stringLength readDir filter;
|
inherit (builtins) stringLength readDir filter;
|
||||||
devices = filter (n: n != "families")
|
devices = filter (n: n != "families") (lib.mapAttrsToList (n: t: n) (readDir ../devices));
|
||||||
(lib.mapAttrsToList (n: t: n) (readDir ../devices));
|
texts = map (
|
||||||
texts = map (n:
|
n:
|
||||||
let d = import ../devices/${n}/default.nix;
|
let
|
||||||
d' = {
|
d = import ../devices/${n}/default.nix;
|
||||||
description = "${n}\n${substring 0 (stringLength n) "********************************"}\n";
|
d' = {
|
||||||
} // d;
|
description = "${n}\n${substring 0 (stringLength n) "********************************"}\n";
|
||||||
installer =
|
} // d;
|
||||||
if d ? description && d ? installer
|
in
|
||||||
then ''
|
d'.description
|
||||||
|
) devices;
|
||||||
The default installation route for this device is
|
|
||||||
:ref:`system-outputs-${d.installer}`
|
|
||||||
''
|
|
||||||
else "";
|
|
||||||
in d'.description)
|
|
||||||
devices;
|
|
||||||
in
|
in
|
||||||
writeText "hwdoc" ''
|
writeText "hwdoc" ''
|
||||||
Supported hardware
|
Supported hardware
|
||||||
|
|
|
@ -11,15 +11,15 @@
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
secrets = import ./extneder-secrets.nix;
|
secrets = import ./extneder-secrets.nix;
|
||||||
inherit (pkgs.liminix.services) oneshot longrun bundle target;
|
inherit (pkgs.liminix.services) oneshot longrun target;
|
||||||
inherit (pkgs.pseudofile) dir symlink;
|
inherit (pkgs.pseudofile) dir symlink;
|
||||||
inherit (pkgs) writeText dropbear ifwait serviceFns;
|
inherit (pkgs) writeText serviceFns;
|
||||||
svc = config.system.service;
|
svc = config.system.service;
|
||||||
in rec {
|
in rec {
|
||||||
boot = {
|
boot = {
|
||||||
tftp = {
|
tftp = {
|
||||||
serverip = "192.168.8.148";
|
serverip = "10.0.0.1";
|
||||||
ipaddr = "192.168.8.251";
|
ipaddr = "10.0.0.8";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,34 +28,12 @@ in rec {
|
||||||
../modules/network
|
../modules/network
|
||||||
../modules/vlan
|
../modules/vlan
|
||||||
../modules/ssh
|
../modules/ssh
|
||||||
|
../modules/usb.nix
|
||||||
../modules/watchdog
|
../modules/watchdog
|
||||||
../modules/mount
|
../modules/mount
|
||||||
];
|
];
|
||||||
hostname = "arhcive";
|
hostname = "arhcive";
|
||||||
|
|
||||||
kernel = {
|
|
||||||
config = {
|
|
||||||
USB = "y";
|
|
||||||
USB_EHCI_HCD = "y";
|
|
||||||
USB_EHCI_HCD_PLATFORM = "y";
|
|
||||||
USB_OHCI_HCD = "y";
|
|
||||||
USB_OHCI_HCD_PLATFORM = "y";
|
|
||||||
USB_SUPPORT = "y";
|
|
||||||
USB_COMMON = "y";
|
|
||||||
USB_STORAGE = "y";
|
|
||||||
USB_STORAGE_DEBUG = "n";
|
|
||||||
USB_UAS = "y";
|
|
||||||
USB_ANNOUNCE_NEW_DEVICES = "y";
|
|
||||||
SCSI = "y";
|
|
||||||
BLK_DEV_SD = "y";
|
|
||||||
USB_PRINTER = "y";
|
|
||||||
MSDOS_PARTITION = "y";
|
|
||||||
EFI_PARTITION = "y";
|
|
||||||
EXT4_FS = "y";
|
|
||||||
EXT4_USE_FOR_EXT2 = "y";
|
|
||||||
FS_ENCRYPTION = "y";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.dhcpc =
|
services.dhcpc =
|
||||||
let iface = config.hardware.networkInterfaces.lan;
|
let iface = config.hardware.networkInterfaces.lan;
|
||||||
|
@ -105,7 +83,7 @@ in rec {
|
||||||
};
|
};
|
||||||
|
|
||||||
services.mount_external_disk = svc.mount.build {
|
services.mount_external_disk = svc.mount.build {
|
||||||
device = "LABEL=backup-disk";
|
partlabel = "backup-disk";
|
||||||
mountpoint = "/srv";
|
mountpoint = "/srv";
|
||||||
fstype = "ext4";
|
fstype = "ext4";
|
||||||
};
|
};
|
||||||
|
@ -141,23 +119,37 @@ in rec {
|
||||||
secrets_file
|
secrets_file
|
||||||
services.mount_external_disk
|
services.mount_external_disk
|
||||||
config.hardware.networkInterfaces.lan
|
config.hardware.networkInterfaces.lan
|
||||||
] ;
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
users.root = {
|
users.root = {
|
||||||
passwd = lib.mkForce secrets.root.passwd;
|
passwd = lib.mkForce secrets.root.passwd;
|
||||||
# openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = secrets.root.keys;
|
||||||
# (builtins.readFile "/home/dan/.ssh/id_rsa.pub")
|
|
||||||
# ];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
users.backup = {
|
users.backup = {
|
||||||
uid=500; gid=500; gecos="Storage owner"; dir="/srv";
|
uid = 500;
|
||||||
shell="/dev/null";
|
gid = 500;
|
||||||
|
gecos = "Storage owner";
|
||||||
|
dir = "/srv";
|
||||||
|
shell = "/dev/null";
|
||||||
};
|
};
|
||||||
groups.backup = {
|
groups.backup = {
|
||||||
gid=500; usernames = ["backup"];
|
gid = 500;
|
||||||
|
usernames = [ "backup" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
defaultProfile.packages = with pkgs; [e2fsprogs strace tcpdump ];
|
defaultProfile.packages = with pkgs; [
|
||||||
|
e2fsprogs
|
||||||
|
mtdutils
|
||||||
|
(levitate.override {
|
||||||
|
config = {
|
||||||
|
services = {
|
||||||
|
inherit (config.services) dhcpc sshd watchdog;
|
||||||
|
};
|
||||||
|
defaultProfile.packages = [ mtdutils ];
|
||||||
|
users.root.openssh.authorizedKeys.keys = secrets.root.keys;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
# wherever the text "EDIT" appears - please consult the tutorial
|
# wherever the text "EDIT" appears - please consult the tutorial
|
||||||
# documentation for details.
|
# documentation for details.
|
||||||
|
|
||||||
{ config, pkgs, lib, ... } :
|
{ config, pkgs, ... }:
|
||||||
let
|
let
|
||||||
inherit (pkgs.liminix.services) bundle oneshot longrun;
|
inherit (pkgs.liminix.services) bundle oneshot;
|
||||||
inherit (pkgs) serviceFns;
|
inherit (pkgs) serviceFns;
|
||||||
# EDIT: you can pick your preferred RFC1918 address space
|
# EDIT: you can pick your preferred RFC1918 address space
|
||||||
# for NATted connections, if you don't like this one.
|
# for NATted connections, if you don't like this one.
|
||||||
|
@ -49,31 +49,40 @@ in rec {
|
||||||
country_code = "GB";
|
country_code = "GB";
|
||||||
wpa_passphrase = "not a real wifi password";
|
wpa_passphrase = "not a real wifi password";
|
||||||
|
|
||||||
hw_mode="g";
|
hw_mode = "g";
|
||||||
ieee80211n = 1;
|
ieee80211n = 1;
|
||||||
auth_algs = 1; # 1=wpa2, 2=wep, 3=both
|
auth_algs = 1; # 1=wpa2, 2=wep, 3=both
|
||||||
wpa = 2; # 1=wpa, 2=wpa2, 3=both
|
wpa = 2; # 1=wpa, 2=wpa2, 3=both
|
||||||
wpa_key_mgmt = "WPA-PSK";
|
wpa_key_mgmt = "WPA-PSK";
|
||||||
wpa_pairwise = "TKIP CCMP"; # auth for wpa (may not need this?)
|
wpa_pairwise = "TKIP CCMP"; # auth for wpa (may not need this?)
|
||||||
rsn_pairwise = "CCMP"; # auth for wpa2
|
rsn_pairwise = "CCMP"; # auth for wpa2
|
||||||
wmm_enabled = 1;
|
wmm_enabled = 1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.int = svc.network.address.build {
|
services.int = svc.network.address.build {
|
||||||
interface = svc.bridge.primary.build { ifname = "int"; };
|
interface = svc.bridge.primary.build { ifname = "int"; };
|
||||||
family = "inet"; address = "${ipv4LocalNet}.1"; prefixLength = 16;
|
family = "inet";
|
||||||
|
address = "${ipv4LocalNet}.1";
|
||||||
|
prefixLength = 16;
|
||||||
};
|
};
|
||||||
|
|
||||||
services.bridge = svc.bridge.members.build {
|
services.bridge = svc.bridge.members.build {
|
||||||
primary = services.int;
|
primary = services.int;
|
||||||
members = with config.hardware.networkInterfaces;
|
members = with config.hardware.networkInterfaces; [
|
||||||
[ wlan lan ];
|
wlan
|
||||||
|
lan
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.ntp = svc.ntp.build {
|
services.ntp = svc.ntp.build {
|
||||||
pools = { "pool.ntp.org" = ["iburst"]; };
|
pools = {
|
||||||
makestep = { threshold = 1.0; limit = 3; };
|
"pool.ntp.org" = [ "iburst" ];
|
||||||
|
};
|
||||||
|
makestep = {
|
||||||
|
threshold = 1.0;
|
||||||
|
limit = 3;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.sshd = svc.ssh.build { };
|
services.sshd = svc.ssh.build { };
|
||||||
|
@ -157,9 +166,7 @@ in rec {
|
||||||
interface = services.wan;
|
interface = services.wan;
|
||||||
};
|
};
|
||||||
|
|
||||||
services.firewall = svc.firewall.build {
|
services.firewall = svc.firewall.build { };
|
||||||
ruleset = import ./demo-firewall.nix;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.packet_forwarding = svc.network.forward.build { };
|
services.packet_forwarding = svc.network.forward.build { };
|
||||||
|
|
||||||
|
@ -196,7 +203,5 @@ in rec {
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
defaultProfile.packages = with pkgs; [
|
defaultProfile.packages = with pkgs; [ min-collect-garbage ];
|
||||||
min-collect-garbage
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,11 @@
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
lib,
|
lib,
|
||||||
|
modulesPath,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
secrets = import ./extneder-secrets.nix;
|
secrets = import ./extneder-secrets.nix;
|
||||||
|
svc = config.system.service;
|
||||||
in rec {
|
in rec {
|
||||||
boot = {
|
boot = {
|
||||||
tftp = {
|
tftp = {
|
||||||
|
@ -20,47 +22,13 @@ in rec {
|
||||||
};
|
};
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
../modules/profiles/wap.nix
|
"${modulesPath}/profiles/wap.nix"
|
||||||
../modules/vlan
|
"${modulesPath}/vlan"
|
||||||
|
"${modulesPath}/ssh"
|
||||||
];
|
];
|
||||||
|
|
||||||
hostname = "extneder";
|
hostname = "extneder";
|
||||||
|
|
||||||
kernel = {
|
|
||||||
config = {
|
|
||||||
|
|
||||||
NETFILTER_XT_MATCH_CONNTRACK = "y";
|
|
||||||
|
|
||||||
IP6_NF_IPTABLES = "y"; # do we still need these
|
|
||||||
IP_NF_IPTABLES = "y"; # if using nftables directly
|
|
||||||
|
|
||||||
# these are copied from rotuer and need review.
|
|
||||||
# we're not running a firewall, so why do we need
|
|
||||||
# nftables config?
|
|
||||||
IP_NF_NAT = "y";
|
|
||||||
IP_NF_TARGET_MASQUERADE = "y";
|
|
||||||
NETFILTER = "y";
|
|
||||||
NETFILTER_ADVANCED = "y";
|
|
||||||
NETFILTER_XTABLES = "y";
|
|
||||||
|
|
||||||
NFT_COMPAT = "y";
|
|
||||||
NFT_CT = "y";
|
|
||||||
NFT_LOG = "y";
|
|
||||||
NFT_MASQ = "y";
|
|
||||||
NFT_NAT = "y";
|
|
||||||
NFT_REJECT = "y";
|
|
||||||
NFT_REJECT_INET = "y";
|
|
||||||
|
|
||||||
NF_CONNTRACK = "y";
|
|
||||||
NF_NAT = "y";
|
|
||||||
NF_NAT_MASQUERADE = "y";
|
|
||||||
NF_TABLES = "y";
|
|
||||||
NF_TABLES_INET = "y";
|
|
||||||
NF_TABLES_IPV4 = "y";
|
|
||||||
NF_TABLES_IPV6 = "y";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
profile.wap = {
|
profile.wap = {
|
||||||
interfaces = with config.hardware.networkInterfaces; [
|
interfaces = with config.hardware.networkInterfaces; [
|
||||||
lan
|
lan
|
||||||
|
@ -79,6 +47,7 @@ in rec {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.sshd = svc.ssh.build {};
|
||||||
users.root.passwd = lib.mkForce secrets.root.passwd;
|
users.root.passwd = lib.mkForce secrets.root.passwd;
|
||||||
defaultProfile.packages = with pkgs; [nftables strace tcpdump swconfig];
|
defaultProfile.packages = with pkgs; [nftables strace tcpdump swconfig];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
{ config, pkgs, lib, ... } :
|
{ config, pkgs, ... } :
|
||||||
let
|
let
|
||||||
inherit (pkgs) serviceFns;
|
|
||||||
svc = config.system.service;
|
svc = config.system.service;
|
||||||
|
|
||||||
in rec {
|
in rec {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
{ config, pkgs, lib, ... } :
|
{ config, pkgs, ... } :
|
||||||
let
|
let
|
||||||
inherit (pkgs) serviceFns;
|
|
||||||
svc = config.system.service;
|
svc = config.system.service;
|
||||||
|
|
||||||
in rec {
|
in rec {
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
secrets = import ./extneder-secrets.nix;
|
||||||
|
rsecrets = import ./rotuer-secrets.nix;
|
||||||
|
|
||||||
|
# https://support.aa.net.uk/Category:Incoming_L2TP says:
|
||||||
|
# "Please use the DNS name (l2tp.aa.net.uk) instead of hardcoding an
|
||||||
|
# IP address; IP addresses can and do change. If you have to use an
|
||||||
|
# IP, use 194.4.172.12, but do check the DNS for l2tp.aa.net.uk in
|
||||||
|
# case it changes."
|
||||||
|
|
||||||
|
# but (1) we don't want to use the wwan stick's dns as our main
|
||||||
|
# resolver: it's provided by some mobile ISP and they aren't
|
||||||
|
# necessarily the best at providing unfettered services without
|
||||||
|
# deciding to do something weird; (2) it's not simple to arrange
|
||||||
|
# that xl2tpd gets a different resolver than every other process;
|
||||||
|
# (3) there's no way to specify an lns address to xl2tpd at runtime
|
||||||
|
# except by rewriting its config file. So what we will do is lookup
|
||||||
|
# the lns hostname using the mobile ISP's dns server and then refuse
|
||||||
|
# to start l2tp unless the expected lns address is one of the
|
||||||
|
# addresses returned. I think this satisfies "do check the DNS"
|
||||||
|
|
||||||
|
lns = { hostname = "l2tp.aaisp.net.uk"; address = "194.4.172.12"; };
|
||||||
|
|
||||||
|
inherit (pkgs.liminix.services) oneshot target;
|
||||||
|
inherit (pkgs.pseudofile) dir symlink;
|
||||||
|
inherit (pkgs) serviceFns;
|
||||||
|
svc = config.system.service;
|
||||||
|
in rec {
|
||||||
|
boot = {
|
||||||
|
tftp = {
|
||||||
|
serverip = "10.0.0.1";
|
||||||
|
ipaddr = "10.0.0.8";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
../modules/cdc-ncm
|
||||||
|
../modules/network
|
||||||
|
../modules/vlan
|
||||||
|
../modules/ssh
|
||||||
|
../modules/usb.nix
|
||||||
|
../modules/watchdog
|
||||||
|
../modules/mount
|
||||||
|
../modules/ppp
|
||||||
|
];
|
||||||
|
hostname = "thing";
|
||||||
|
|
||||||
|
services.wwan = svc.wwan.build {
|
||||||
|
apn = "data.uk";
|
||||||
|
username = "user";
|
||||||
|
password = "one2one";
|
||||||
|
authType = "chap";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.dhcpc = svc.network.dhcp.client.build {
|
||||||
|
interface = config.services.wwan;
|
||||||
|
dependencies = [ config.services.hostname ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.sshd = svc.ssh.build { };
|
||||||
|
|
||||||
|
services.resolvconf = oneshot rec {
|
||||||
|
dependencies = [ services.l2tp ];
|
||||||
|
name = "resolvconf";
|
||||||
|
up = ''
|
||||||
|
. ${serviceFns}
|
||||||
|
( in_outputs ${name}
|
||||||
|
for i in ns1 ns2 ; do
|
||||||
|
ns=$(output ${services.l2tp} $i)
|
||||||
|
echo "nameserver $ns" >> resolv.conf
|
||||||
|
done
|
||||||
|
)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
filesystem = dir {
|
||||||
|
etc = dir {
|
||||||
|
"resolv.conf" = symlink "${services.resolvconf}/.outputs/resolv.conf";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.lns-address = let
|
||||||
|
ns = "$(output_word ${services.dhcpc} dns 1)";
|
||||||
|
route-to-bootstrap-nameserver = svc.network.route.build {
|
||||||
|
via = "$(output ${services.dhcpc} router)";
|
||||||
|
target = ns;
|
||||||
|
dependencies = [services.dhcpc];
|
||||||
|
};
|
||||||
|
in oneshot rec {
|
||||||
|
name = "resolve-l2tp-server";
|
||||||
|
dependencies = [ services.dhcpc route-to-bootstrap-nameserver ];
|
||||||
|
up = ''
|
||||||
|
(in_outputs ${name}
|
||||||
|
DNSCACHEIP="${ns}" ${pkgs.s6-dns}/bin/s6-dnsip4 ${lns.hostname} \
|
||||||
|
> addresses
|
||||||
|
)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
services.l2tp =
|
||||||
|
let
|
||||||
|
check-address = oneshot rec {
|
||||||
|
name = "check-lns-address";
|
||||||
|
up = ''
|
||||||
|
grep -Fx ${lns.address} $(output_path ${services.lns-address} addresses)
|
||||||
|
'';
|
||||||
|
dependencies = [ services.lns-address ];
|
||||||
|
};
|
||||||
|
route = svc.network.route.build {
|
||||||
|
via = "$(output ${services.dhcpc} router)";
|
||||||
|
target = lns.address;
|
||||||
|
dependencies = [services.dhcpc check-address];
|
||||||
|
};
|
||||||
|
in svc.l2tp.build {
|
||||||
|
lns = lns.address;
|
||||||
|
ppp-options = [
|
||||||
|
"debug" "+ipv6" "noauth"
|
||||||
|
"name" rsecrets.l2tp.name
|
||||||
|
"connect-delay" "5000"
|
||||||
|
"password" rsecrets.l2tp.password
|
||||||
|
];
|
||||||
|
dependencies = [config.services.lns-address route check-address];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.defaultroute4 = svc.network.route.build {
|
||||||
|
via = "$(output ${services.l2tp} peer-address)";
|
||||||
|
target = "default";
|
||||||
|
dependencies = [services.l2tp];
|
||||||
|
};
|
||||||
|
|
||||||
|
# defaultProfile.packages = [ pkgs.go-l2tp ];
|
||||||
|
|
||||||
|
users.root = {
|
||||||
|
passwd = lib.mkForce secrets.root.passwd;
|
||||||
|
openssh.authorizedKeys.keys = secrets.root.keys;
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
{ config, pkgs, ... } :
|
{ config, pkgs, ... } :
|
||||||
let
|
let
|
||||||
inherit (pkgs.liminix.services) oneshot longrun bundle target;
|
inherit (pkgs.liminix.services) target;
|
||||||
inherit (pkgs) writeText;
|
|
||||||
svc = config.system.service;
|
svc = config.system.service;
|
||||||
secrets-1 = {
|
secrets-1 = {
|
||||||
ssid = "Zyxel 2G (N)";
|
ssid = "Zyxel 2G (N)";
|
||||||
|
|
|
@ -3,8 +3,8 @@ let
|
||||||
inherit (pkgs) serviceFns;
|
inherit (pkgs) serviceFns;
|
||||||
svc = config.system.service;
|
svc = config.system.service;
|
||||||
inherit (pkgs.pseudofile) dir symlink;
|
inherit (pkgs.pseudofile) dir symlink;
|
||||||
inherit (pkgs.liminix.services) oneshot longrun bundle target;
|
inherit (pkgs.liminix.services) oneshot target;
|
||||||
some-util-linux = pkgs.runCommand "some-util-linux" {} ''
|
some-util-linux = pkgs.runCommand "some-util-linux" { } ''
|
||||||
mkdir -p $out/bin
|
mkdir -p $out/bin
|
||||||
cd ${pkgs.util-linux-small}/bin
|
cd ${pkgs.util-linux-small}/bin
|
||||||
cp fdisk sfdisk mkswap $out/bin
|
cp fdisk sfdisk mkswap $out/bin
|
||||||
|
@ -53,7 +53,7 @@ in rec {
|
||||||
services.defaultroute4 = svc.network.route.build {
|
services.defaultroute4 = svc.network.route.build {
|
||||||
via = "$(output ${services.dhcpc} router)";
|
via = "$(output ${services.dhcpc} router)";
|
||||||
target = "default";
|
target = "default";
|
||||||
dependencies = [services.dhcpc];
|
dependencies = [ services.dhcpc ];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.resolvconf = oneshot rec {
|
services.resolvconf = oneshot rec {
|
||||||
|
|
|
@ -8,12 +8,10 @@
|
||||||
root = {
|
root = {
|
||||||
# mkpasswd -m sha512crypt
|
# mkpasswd -m sha512crypt
|
||||||
passwd = "$6$6pt0mpbgcB7kC2RJ$kSBoCYGyi1.qxt7dqmexLj1l8E6oTZJZmfGyJSsMYMW.jlsETxdgQSdv6ptOYDM7DHAwf6vLG0pz3UD31XBfC1";
|
passwd = "$6$6pt0mpbgcB7kC2RJ$kSBoCYGyi1.qxt7dqmexLj1l8E6oTZJZmfGyJSsMYMW.jlsETxdgQSdv6ptOYDM7DHAwf6vLG0pz3UD31XBfC1";
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [ ];
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
lan = {
|
lan = {
|
||||||
prefix = "10.8.0";
|
prefix = "10.8.0";
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,23 +6,16 @@
|
||||||
# problems.
|
# problems.
|
||||||
|
|
||||||
|
|
||||||
{ config, pkgs, lib, ... } :
|
{ config, pkgs, lib, modulesPath, ... } :
|
||||||
let
|
let
|
||||||
secrets = {
|
secrets = {
|
||||||
domainName = "fake.liminix.org";
|
domainName = "fake.liminix.org";
|
||||||
firewallRules = {};
|
firewallRules = { };
|
||||||
} // (import ./rotuer-secrets.nix);
|
} // (import ./rotuer-secrets.nix);
|
||||||
inherit (pkgs.liminix.services) oneshot longrun bundle;
|
|
||||||
inherit (pkgs) serviceFns;
|
|
||||||
svc = config.system.service;
|
svc = config.system.service;
|
||||||
wirelessConfig = {
|
wirelessConfig = {
|
||||||
country_code = "GB";
|
country_code = "GB";
|
||||||
inherit (secrets) wpa_passphrase;
|
inherit (secrets) wpa_passphrase;
|
||||||
auth_algs = 1; # 1=wpa2, 2=wep, 3=both
|
|
||||||
wpa = 2; # 1=wpa, 2=wpa2, 3=both
|
|
||||||
wpa_key_mgmt = "WPA-PSK";
|
|
||||||
wpa_pairwise = "TKIP CCMP"; # auth for wpa (may not need this?)
|
|
||||||
rsn_pairwise = "CCMP"; # auth for wpa2
|
|
||||||
wmm_enabled = 1;
|
wmm_enabled = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,65 +29,62 @@ in rec {
|
||||||
};
|
};
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
../modules/wlan.nix
|
"${modulesPath}/profiles/gateway.nix"
|
||||||
../modules/network
|
"${modulesPath}/schnapps"
|
||||||
../modules/ppp
|
"${modulesPath}/outputs/btrfs.nix"
|
||||||
../modules/dnsmasq
|
"${modulesPath}/outputs/extlinux.nix"
|
||||||
../modules/dhcp6c
|
|
||||||
../modules/firewall
|
|
||||||
../modules/hostapd
|
|
||||||
../modules/bridge
|
|
||||||
../modules/ntp
|
|
||||||
../modules/schnapps
|
|
||||||
../modules/ssh
|
|
||||||
../modules/outputs/btrfs.nix
|
|
||||||
../modules/outputs/extlinux.nix
|
|
||||||
];
|
];
|
||||||
hostname = "rotuer";
|
hostname = "rotuer";
|
||||||
rootfsType = "btrfs";
|
rootfsType = "btrfs";
|
||||||
rootOptions = "subvol=@";
|
rootOptions = "subvol=@";
|
||||||
boot.loader.extlinux.enable = true;
|
boot.loader.extlinux.enable = true;
|
||||||
|
|
||||||
services.hostap = svc.hostapd.build {
|
profile.gateway = {
|
||||||
interface = config.hardware.networkInterfaces.wlan;
|
lan = {
|
||||||
params = {
|
interfaces = with config.hardware.networkInterfaces;
|
||||||
ssid = secrets.ssid;
|
[
|
||||||
hw_mode="g";
|
wlan wlan5
|
||||||
channel = "2";
|
lan0 lan1 lan2 lan3 lan4
|
||||||
ieee80211n = 1;
|
];
|
||||||
} // wirelessConfig;
|
inherit (secrets.lan) prefix;
|
||||||
};
|
address = {
|
||||||
|
family = "inet"; address ="${secrets.lan.prefix}.1"; prefixLength = 24;
|
||||||
services.hostap5 = svc.hostapd.build {
|
};
|
||||||
interface = config.hardware.networkInterfaces.wlan5;
|
dhcp = {
|
||||||
params = rec {
|
start = 10;
|
||||||
ssid = "${secrets.ssid}5";
|
end = 240;
|
||||||
hw_mode="a";
|
hosts = { } // lib.optionalAttrs (builtins.pathExists ./static-leases.nix) (import ./static-leases.nix);
|
||||||
channel = 36;
|
localDomain = "lan";
|
||||||
ht_capab = "[HT40+]";
|
};
|
||||||
vht_oper_chwidth = 1;
|
};
|
||||||
vht_oper_centr_freq_seg0_idx = channel + 6;
|
wan = {
|
||||||
ieee80211n = 1;
|
interface = config.hardware.networkInterfaces.wan;
|
||||||
ieee80211ac = 1;
|
username = secrets.l2tp.name;
|
||||||
} // wirelessConfig;
|
password = secrets.l2tp.password;
|
||||||
};
|
dhcp6.enable = true;
|
||||||
|
};
|
||||||
services.int = svc.network.address.build {
|
firewall = {
|
||||||
interface = svc.bridge.primary.build { ifname = "int"; };
|
enable = true;
|
||||||
family = "inet"; address ="${secrets.lan.prefix}.1"; prefixLength = 24;
|
rules = secrets.firewallRules;
|
||||||
};
|
};
|
||||||
|
wireless.networks = {
|
||||||
services.bridge = svc.bridge.members.build {
|
"${secrets.ssid}" = {
|
||||||
primary = services.int;
|
interface = config.hardware.networkInterfaces.wlan;
|
||||||
members = with config.hardware.networkInterfaces;
|
hw_mode = "g";
|
||||||
[ wlan
|
channel = "2";
|
||||||
wlan5
|
ieee80211n = 1;
|
||||||
lan0
|
} // wirelessConfig;
|
||||||
lan1
|
"${secrets.ssid}5" = rec {
|
||||||
lan2
|
interface = config.hardware.networkInterfaces.wlan5;
|
||||||
lan3
|
hw_mode = "a";
|
||||||
lan4
|
channel = 36;
|
||||||
];
|
ht_capab = "[HT40+]";
|
||||||
|
vht_oper_chwidth = 1;
|
||||||
|
vht_oper_centr_freq_seg0_idx = channel + 6;
|
||||||
|
ieee80211n = 1;
|
||||||
|
ieee80211ac = 1;
|
||||||
|
} // wirelessConfig;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.ntp = svc.ntp.build {
|
services.ntp = svc.ntp.build {
|
||||||
|
@ -106,95 +96,6 @@ in rec {
|
||||||
|
|
||||||
users.root = secrets.root;
|
users.root = secrets.root;
|
||||||
|
|
||||||
services.dns =
|
|
||||||
let interface = services.int;
|
|
||||||
in svc.dnsmasq.build {
|
|
||||||
resolvconf = services.resolvconf;
|
|
||||||
inherit interface;
|
|
||||||
ranges = [
|
|
||||||
"${secrets.lan.prefix}.10,${secrets.lan.prefix}.240"
|
|
||||||
# ra-stateless: sends router advertisements with the O and A
|
|
||||||
# bits set, and provides a stateless DHCP service. The client
|
|
||||||
# will use a SLAAC address, and use DHCP for other
|
|
||||||
# configuration information.
|
|
||||||
"::,constructor:$(output ${interface} ifname),ra-stateless"
|
|
||||||
];
|
|
||||||
|
|
||||||
# You can add static addresses for the DHCP server here. I'm
|
|
||||||
# not putting my actual MAC addresses in a public git repo ...
|
|
||||||
hosts = { } // lib.optionalAttrs (builtins.pathExists ./static-leases.nix) (import ./static-leases.nix);
|
|
||||||
upstreams = [ "/${secrets.domainName}/" ];
|
|
||||||
domain = secrets.domainName;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.wan = svc.pppoe.build {
|
|
||||||
interface = config.hardware.networkInterfaces.wan;
|
|
||||||
ppp-options = [
|
|
||||||
"debug" "+ipv6" "noauth"
|
|
||||||
"name" secrets.l2tp.name
|
|
||||||
"password" secrets.l2tp.password
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.resolvconf = oneshot rec {
|
|
||||||
dependencies = [ services.wan ];
|
|
||||||
name = "resolvconf";
|
|
||||||
up = ''
|
|
||||||
. ${serviceFns}
|
|
||||||
( in_outputs ${name}
|
|
||||||
echo "nameserver $(output ${services.wan} ns1)" > resolv.conf
|
|
||||||
echo "nameserver $(output ${services.wan} ns2)" >> resolv.conf
|
|
||||||
chmod 0444 resolv.conf
|
|
||||||
)
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
filesystem =
|
|
||||||
let inherit (pkgs.pseudofile) dir symlink;
|
|
||||||
in dir {
|
|
||||||
etc = dir {
|
|
||||||
"resolv.conf" = symlink "${services.resolvconf}/.outputs/resolv.conf";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.defaultroute4 = svc.network.route.build {
|
|
||||||
via = "$(output ${services.wan} address)";
|
|
||||||
target = "default";
|
|
||||||
dependencies = [ services.wan ];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.defaultroute6 = svc.network.route.build {
|
|
||||||
via = "$(output ${services.wan} ipv6-peer-address)";
|
|
||||||
target = "default";
|
|
||||||
interface = services.wan;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.firewall = svc.firewall.build {
|
|
||||||
ruleset =
|
|
||||||
let defaults = import ./demo-firewall.nix;
|
|
||||||
in lib.recursiveUpdate defaults secrets.firewallRules;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.packet_forwarding = svc.network.forward.build { };
|
|
||||||
|
|
||||||
services.dhcp6c =
|
|
||||||
let client = svc.dhcp6c.client.build {
|
|
||||||
interface = services.wan;
|
|
||||||
};
|
|
||||||
in bundle {
|
|
||||||
name = "dhcp6c";
|
|
||||||
contents = [
|
|
||||||
(svc.dhcp6c.prefix.build {
|
|
||||||
inherit client;
|
|
||||||
interface = services.int;
|
|
||||||
})
|
|
||||||
(svc.dhcp6c.address.build {
|
|
||||||
inherit client;
|
|
||||||
interface = services.wan;
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultProfile.packages = with pkgs; [
|
defaultProfile.packages = with pkgs; [
|
||||||
min-collect-garbage
|
min-collect-garbage
|
||||||
nftables
|
nftables
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
{ config, pkgs, lib, lim, ... } :
|
{ config, pkgs, lim, ... } :
|
||||||
let
|
let
|
||||||
inherit (pkgs) serviceFns;
|
|
||||||
svc = config.system.service;
|
svc = config.system.service;
|
||||||
|
|
||||||
in rec {
|
in rec {
|
||||||
|
|
|
@ -9,29 +9,29 @@
|
||||||
./busybox.nix
|
./busybox.nix
|
||||||
./dhcp6c
|
./dhcp6c
|
||||||
./dnsmasq
|
./dnsmasq
|
||||||
./outputs/ext4fs.nix
|
|
||||||
./firewall
|
./firewall
|
||||||
./hardware.nix
|
./hardware.nix
|
||||||
./hostapd
|
./hostapd
|
||||||
./hostname.nix
|
./hostname.nix
|
||||||
./outputs/initramfs.nix
|
|
||||||
./outputs/jffs2.nix
|
|
||||||
./kernel
|
./kernel
|
||||||
./outputs/kexecboot.nix
|
./mdevd.nix
|
||||||
./mount
|
./mount
|
||||||
./network
|
./network
|
||||||
./ntp
|
./ntp
|
||||||
./outputs.nix
|
./outputs.nix
|
||||||
./outputs/vmroot.nix
|
./outputs/ext4fs.nix
|
||||||
./outputs/ubimage.nix
|
./outputs/initramfs.nix
|
||||||
|
./outputs/jffs2.nix
|
||||||
|
./outputs/kexecboot.nix
|
||||||
./outputs/mtdimage.nix
|
./outputs/mtdimage.nix
|
||||||
|
./outputs/tftpboot.nix
|
||||||
|
./outputs/ubifs.nix
|
||||||
|
./outputs/ubimage.nix
|
||||||
|
./outputs/vmroot.nix
|
||||||
./ppp
|
./ppp
|
||||||
./ramdisk.nix
|
./ramdisk.nix
|
||||||
./squashfs.nix
|
./squashfs.nix
|
||||||
./ssh
|
./ssh
|
||||||
./outputs/tftpboot.nix
|
|
||||||
./outputs/ubifs.nix
|
|
||||||
./ubinize.nix
|
|
||||||
./users.nix
|
./users.nix
|
||||||
./vlan
|
./vlan
|
||||||
./watchdog
|
./watchdog
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ lib, lim, pkgs, config, ...}:
|
{ lim, pkgs, config, ...}:
|
||||||
{
|
{
|
||||||
config = {
|
config = {
|
||||||
kernel.config = {
|
kernel.config = {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ lib, lim, pkgs, config, ...}:
|
{ lim, pkgs, config, ...}:
|
||||||
{
|
{
|
||||||
config = {
|
config = {
|
||||||
kernel.config = {
|
kernel.config = {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ lib, pkgs, config, lim, ...}:
|
{ config, lim, ...}:
|
||||||
{
|
{
|
||||||
config = {
|
config = {
|
||||||
kernel.config = {
|
kernel.config = {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ lib, pkgs, config, ...}:
|
{ pkgs, config, ...}:
|
||||||
{
|
{
|
||||||
imports = [ ./mips.nix ];
|
imports = [ ./mips.nix ];
|
||||||
config = {
|
config = {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ lib, pkgs, config, ...}:
|
{ config, ...}:
|
||||||
{
|
{
|
||||||
imports = [ ./mips.nix ];
|
imports = [ ./mips.nix ];
|
||||||
config = {
|
config = {
|
||||||
|
|
|
@ -4,17 +4,12 @@
|
||||||
|
|
||||||
{ lib, pkgs, config, ...}:
|
{ lib, pkgs, config, ...}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkEnableOption mkOption types isDerivation hasAttr ;
|
inherit (lib) mkOption types;
|
||||||
inherit (pkgs.pseudofile) dir symlink;
|
inherit (pkgs.pseudofile) dir symlink;
|
||||||
inherit (pkgs.liminix.networking) address interface;
|
|
||||||
inherit (pkgs.liminix.services) bundle;
|
|
||||||
|
|
||||||
type_service = pkgs.liminix.lib.types.service;
|
type_service = pkgs.liminix.lib.types.service;
|
||||||
|
|
||||||
in {
|
in {
|
||||||
imports = [
|
|
||||||
./kernel # kernel is a separate module for doc purposes
|
|
||||||
];
|
|
||||||
options = {
|
options = {
|
||||||
defaultProfile = {
|
defaultProfile = {
|
||||||
packages = mkOption {
|
packages = mkOption {
|
||||||
|
@ -29,6 +24,10 @@ in {
|
||||||
services = mkOption {
|
services = mkOption {
|
||||||
type = types.attrsOf type_service;
|
type = types.attrsOf type_service;
|
||||||
};
|
};
|
||||||
|
system.callService = mkOption {
|
||||||
|
type = types.functionTo (types.functionTo types.anything);
|
||||||
|
};
|
||||||
|
|
||||||
filesystem = mkOption {
|
filesystem = mkOption {
|
||||||
type = types.anything;
|
type = types.anything;
|
||||||
description = ''
|
description = ''
|
||||||
|
@ -37,7 +36,7 @@ in {
|
||||||
'';
|
'';
|
||||||
# internal = true; # probably a good case to make this internal
|
# internal = true; # probably a good case to make this internal
|
||||||
};
|
};
|
||||||
rootfsType = mkOption {
|
rootfsType = mkOption {
|
||||||
default = "squashfs";
|
default = "squashfs";
|
||||||
type = types.enum [
|
type = types.enum [
|
||||||
"btrfs"
|
"btrfs"
|
||||||
|
@ -47,7 +46,7 @@ in {
|
||||||
"ubifs"
|
"ubifs"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
rootOptions = mkOption {
|
rootOptions = mkOption {
|
||||||
type = types.nullOr types.str;
|
type = types.nullOr types.str;
|
||||||
default = null;
|
default = null;
|
||||||
};
|
};
|
||||||
|
@ -55,20 +54,29 @@ in {
|
||||||
boot = {
|
boot = {
|
||||||
commandLine = mkOption {
|
commandLine = mkOption {
|
||||||
type = types.listOf types.nonEmptyStr;
|
type = types.listOf types.nonEmptyStr;
|
||||||
default = [];
|
default = [ ];
|
||||||
description = "Kernel command line";
|
description = "Kernel command line";
|
||||||
};
|
};
|
||||||
commandLineDtbNode = mkOption {
|
commandLineDtbNode = mkOption {
|
||||||
type = types.enum [ "bootargs" "bootargs-override" ];
|
type = types.enum [
|
||||||
|
"bootargs"
|
||||||
|
"bootargs-override"
|
||||||
|
];
|
||||||
default = "bootargs";
|
default = "bootargs";
|
||||||
description = "Kernel command line's devicetree node";
|
description = "Kernel command line's devicetree node";
|
||||||
};
|
};
|
||||||
imageType = mkOption {
|
imageType = mkOption {
|
||||||
type = types.enum [ "primary" "secondary" ];
|
type = types.enum [
|
||||||
|
"primary"
|
||||||
|
"secondary"
|
||||||
|
];
|
||||||
default = "primary";
|
default = "primary";
|
||||||
};
|
};
|
||||||
imageFormat = mkOption {
|
imageFormat = mkOption {
|
||||||
type = types.enum ["fit" "uimage"];
|
type = types.enum [
|
||||||
|
"fit"
|
||||||
|
"uimage"
|
||||||
|
];
|
||||||
default = "uimage";
|
default = "uimage";
|
||||||
};
|
};
|
||||||
tftp = {
|
tftp = {
|
||||||
|
@ -84,7 +92,7 @@ in {
|
||||||
};
|
};
|
||||||
# These names match the uboot environment variables. I reserve
|
# These names match the uboot environment variables. I reserve
|
||||||
# the right to change them if I think of better ones.
|
# the right to change them if I think of better ones.
|
||||||
ipaddr = mkOption {
|
ipaddr = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
description = ''
|
description = ''
|
||||||
Our IP address to use when creating scripts to
|
Our IP address to use when creating scripts to
|
||||||
|
@ -111,6 +119,29 @@ in {
|
||||||
"fw_devlink=off"
|
"fw_devlink=off"
|
||||||
] ++ lib.optional (config.rootOptions != null) "rootflags=${config.rootOptions}";
|
] ++ lib.optional (config.rootOptions != null) "rootflags=${config.rootOptions}";
|
||||||
|
|
||||||
|
system.callService = path : parameters :
|
||||||
|
let
|
||||||
|
typeChecked = caller: type: value:
|
||||||
|
let
|
||||||
|
inherit (lib) types mergeDefinitions;
|
||||||
|
defs = [{ file = caller; inherit value; }];
|
||||||
|
type' = types.submodule { options = type; };
|
||||||
|
in (mergeDefinitions [] type' defs).mergedValue;
|
||||||
|
cp = lib.callPackageWith(pkgs // { svc = config.system.service; });
|
||||||
|
pkg = cp path {};
|
||||||
|
checkTypes = t : p : typeChecked (builtins.toString path) t p;
|
||||||
|
in {
|
||||||
|
inherit parameters;
|
||||||
|
build = { dependencies ? [], ... } @ args :
|
||||||
|
let
|
||||||
|
s = pkg (checkTypes parameters
|
||||||
|
(builtins.removeAttrs args ["dependencies"]));
|
||||||
|
in s.overrideAttrs (o: {
|
||||||
|
dependencies = dependencies ++ o.dependencies;
|
||||||
|
buildInputs = dependencies ++ o.buildInputs;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
users.root = {
|
users.root = {
|
||||||
uid = 0; gid= 0; gecos = "Root of all evaluation";
|
uid = 0; gid= 0; gecos = "Root of all evaluation";
|
||||||
dir = "/home/root/";
|
dir = "/home/root/";
|
||||||
|
|
|
@ -10,10 +10,11 @@
|
||||||
{ lib, pkgs, config, ...}:
|
{ lib, pkgs, config, ...}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkOption types;
|
inherit (lib) mkOption types;
|
||||||
inherit (pkgs.liminix.services) oneshot;
|
|
||||||
inherit (pkgs) liminix;
|
inherit (pkgs) liminix;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
imports = [ ../ifwait ];
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
system.service.bridge = {
|
system.service.bridge = {
|
||||||
primary = mkOption { type = liminix.lib.types.serviceDefn; };
|
primary = mkOption { type = liminix.lib.types.serviceDefn; };
|
||||||
|
@ -27,7 +28,7 @@ in
|
||||||
description = "bridge interface name to create";
|
description = "bridge interface name to create";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
members = liminix.callService ./members.nix {
|
members = config.system.callService ./members.nix {
|
||||||
primary = mkOption {
|
primary = mkOption {
|
||||||
type = liminix.lib.types.interface;
|
type = liminix.lib.types.interface;
|
||||||
description = "primary bridge interface";
|
description = "primary bridge interface";
|
||||||
|
@ -47,5 +48,5 @@ in
|
||||||
# a better way to test for the existence of vlan config:
|
# a better way to test for the existence of vlan config:
|
||||||
# maybe the module should set an `enabled` attribute?
|
# maybe the module should set an `enabled` attribute?
|
||||||
BRIDGE_VLAN_FILTERING = "y";
|
BRIDGE_VLAN_FILTERING = "y";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,28 @@
|
||||||
{
|
{
|
||||||
liminix
|
liminix
|
||||||
, ifwait
|
, ifwait
|
||||||
, lib
|
, svc
|
||||||
}:
|
}:
|
||||||
{ members, primary } :
|
{ members, primary } :
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (liminix.networking) interface;
|
inherit (liminix.networking) interface;
|
||||||
inherit (liminix.services) bundle oneshot;
|
inherit (liminix.services) bundle oneshot;
|
||||||
inherit (lib) mkOption types;
|
|
||||||
addif = member :
|
addif = member :
|
||||||
oneshot {
|
# how do we get sight of services from here? maybe we need to
|
||||||
name = "${primary.name}.member.${member.name}";
|
# implement ifwait as a regualr derivation instead of a
|
||||||
up = ''
|
# servicedefinition
|
||||||
dev=$(output ${member} ifname)
|
svc.ifwait.build {
|
||||||
${ifwait}/bin/ifwait $dev running && ip link set dev $dev master $(output ${primary} ifname)
|
state = "running";
|
||||||
'';
|
interface = member;
|
||||||
down = "ip link set dev $(output ${member} ifname) nomaster";
|
|
||||||
dependencies = [ primary member ];
|
dependencies = [ primary member ];
|
||||||
|
service = oneshot {
|
||||||
|
name = "${primary.name}.member.${member.name}";
|
||||||
|
up = ''
|
||||||
|
ip link set dev $(output ${member} ifname) master $(output ${primary} ifname)
|
||||||
|
'';
|
||||||
|
down = "ip link set dev $(output ${member} ifname) nomaster";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
in bundle {
|
in bundle {
|
||||||
name = "${primary.name}.members";
|
name = "${primary.name}.members";
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
{
|
{
|
||||||
liminix
|
liminix
|
||||||
, ifwait
|
|
||||||
, lib
|
, lib
|
||||||
}:
|
}:
|
||||||
{ ifname } :
|
{ ifname } :
|
||||||
let
|
let
|
||||||
inherit (liminix.services) bundle oneshot;
|
inherit (liminix.services) oneshot;
|
||||||
inherit (lib) mkOption types;
|
|
||||||
in oneshot rec {
|
in oneshot rec {
|
||||||
name = "${ifname}.link";
|
name = "${ifname}.link";
|
||||||
up = ''
|
up = ''
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
{ lib, pkgs, config, ...}:
|
{ lib, pkgs, config, ...}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkOption mkEnableOption types mapAttrsToList;
|
inherit (lib) mkOption types mapAttrsToList;
|
||||||
inherit (pkgs.pseudofile) dir symlink;
|
inherit (pkgs.pseudofile) dir symlink;
|
||||||
inherit (lib.strings) toUpper;
|
inherit (lib.strings) toUpper;
|
||||||
|
|
||||||
|
@ -85,10 +85,13 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
filesystem = dir {
|
filesystem = dir {
|
||||||
bin = dir ({
|
bin = dir (
|
||||||
busybox = symlink "${busybox}/bin/busybox";
|
{
|
||||||
sh = symlink "${busybox}/bin/busybox";
|
busybox = symlink "${busybox}/bin/busybox";
|
||||||
} // makeLinks);
|
sh = symlink "${busybox}/bin/busybox";
|
||||||
|
}
|
||||||
|
// makeLinks
|
||||||
|
);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
let
|
||||||
|
inherit (pkgs) liminix;
|
||||||
|
inherit (lib) mkOption types;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
../service-trigger
|
||||||
|
];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
system.service.wwan = mkOption {
|
||||||
|
type = liminix.lib.types.serviceDefn;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
kernel.config = {
|
||||||
|
USB_NET_HUAWEI_CDC_NCM = "y";
|
||||||
|
USB_USBNET = "y";
|
||||||
|
USB_SERIAL = "y";
|
||||||
|
USB_SERIAL_OPTION = "y";
|
||||||
|
};
|
||||||
|
|
||||||
|
# https://www.0xf8.org/2017/01/flashing-a-huawei-e3372h-4g-lte-stick-from-hilink-to-stick-mode/
|
||||||
|
system.service.wwan = config.system.callService ./wwan.nix {
|
||||||
|
apn = mkOption { type = types.str; };
|
||||||
|
username = mkOption { type = types.str; };
|
||||||
|
password = mkOption { type = types.str; };
|
||||||
|
authType = mkOption { type = types.enum [ "pap" "chap" ]; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
{
|
||||||
|
liminix
|
||||||
|
, usb-modeswitch
|
||||||
|
, ppp
|
||||||
|
, lib
|
||||||
|
, svc
|
||||||
|
, uevent-watch
|
||||||
|
}:
|
||||||
|
{ apn, username, password, authType }:
|
||||||
|
let
|
||||||
|
inherit (liminix.services) oneshot;
|
||||||
|
authTypeNum = if authType == "pap" then "1" else "2";
|
||||||
|
chat = lib.escapeShellArgs [
|
||||||
|
# Your usb modem thing might present as a tty that you run PPP
|
||||||
|
# over, or as a network device ("ndis" or "ncm"). The latter
|
||||||
|
# kind is to be preferred, at least in principle, because it's
|
||||||
|
# faster. This initialization sequence works for the Huawei
|
||||||
|
# E3372, and took much swearing: the error messages are *awful*
|
||||||
|
"" "AT"
|
||||||
|
"OK" "ATZ"
|
||||||
|
# create PDP context
|
||||||
|
"OK" "AT+CGDCONT=1,\"IP\",\"${apn}\""
|
||||||
|
# activate PDP context
|
||||||
|
"OK" "AT+CGACT=1,1"
|
||||||
|
# setup username and password per requirements of sim provider.
|
||||||
|
# (caret is special to chat, so needs escaping in AT commands)
|
||||||
|
"OK" "AT\\^AUTHDATA=1,${authTypeNum},\"\",\"${password}\",\"${username}\""
|
||||||
|
# start the thing (I am choosing to read this as "NDIS DialUP")
|
||||||
|
"OK" "AT\\^NDISDUP=1,1"
|
||||||
|
"OK"
|
||||||
|
];
|
||||||
|
modeswitch = oneshot rec {
|
||||||
|
name = "modem-modeswitch";
|
||||||
|
controller = (svc.uevent-rule.build {
|
||||||
|
serviceName = name;
|
||||||
|
terms = { devtype = "usb_device"; product = "12d1/14fe/102"; };
|
||||||
|
});
|
||||||
|
up = ''
|
||||||
|
${usb-modeswitch}/bin/usb_modeswitch -v 12d1 -p 14fe --huawei-new-mode
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
atz = oneshot rec {
|
||||||
|
name = "modem-atz";
|
||||||
|
dependencies = [ modeswitch ];
|
||||||
|
controller = (svc.uevent-rule.build {
|
||||||
|
serviceName = name;
|
||||||
|
terms = {
|
||||||
|
subsystem = "tty";
|
||||||
|
attrs = {
|
||||||
|
idVendor = "12d1";
|
||||||
|
idProduct = "1506";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
symlink = "/dev/modem";
|
||||||
|
});
|
||||||
|
up = ''
|
||||||
|
ls -l /dev/modem
|
||||||
|
test -L /dev/modem || exit 1
|
||||||
|
${ppp}/bin/chat -s -v ${chat} 0<>/dev/modem 1>&0
|
||||||
|
'';
|
||||||
|
down = "${ppp}/bin/chat -v '' ATZ OK 0<>/dev/modem 1>&0";
|
||||||
|
};
|
||||||
|
|
||||||
|
in svc.network.link.build {
|
||||||
|
ifname = "wwan0";
|
||||||
|
dependencies = [ atz ];
|
||||||
|
}
|
|
@ -2,9 +2,9 @@
|
||||||
writeFennel
|
writeFennel
|
||||||
, linotify
|
, linotify
|
||||||
, anoia
|
, anoia
|
||||||
, lua
|
, lualinux
|
||||||
}:
|
}:
|
||||||
writeFennel "acquire-delegated-prefix" {
|
writeFennel "acquire-delegated-prefix" {
|
||||||
packages = [ linotify anoia lua.pkgs.luafilesystem ];
|
packages = [ linotify anoia lualinux ];
|
||||||
mainFunction = "run";
|
mainFunction = "run";
|
||||||
} ./acquire-delegated-prefix.fnl
|
} ./acquire-delegated-prefix.fnl
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
(local subject (require :acquire-wan-address))
|
(local subject (require :acquire-wan-address))
|
||||||
(local { : view } (require :fennel))
|
(import-macros { : expect= } :anoia.assert)
|
||||||
(local { : merge : dup } (require :anoia))
|
(local { : merge : dup } (require :anoia))
|
||||||
|
|
||||||
|
;; nix-shell --run "cd modules/dhcp6c && fennelrepl acquire-wan-address-test.fnl"
|
||||||
|
|
||||||
(local a1
|
(local a1
|
||||||
{
|
{
|
||||||
|
@ -47,19 +48,6 @@
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
(macro expect [assertion]
|
|
||||||
(let [msg (.. "expectation failed: " (view assertion))]
|
|
||||||
`(when (not ,assertion)
|
|
||||||
(assert false ,msg))))
|
|
||||||
|
|
||||||
(macro expect= [actual expected]
|
|
||||||
`(let [ve# (view ,expected)
|
|
||||||
va# (view ,actual)]
|
|
||||||
(when (not (= ve# va#))
|
|
||||||
(assert false
|
|
||||||
(.. "\nexpected " ve# "\ngot " va#)
|
|
||||||
))))
|
|
||||||
|
|
||||||
(fn first-address []
|
(fn first-address []
|
||||||
(let [deleted
|
(let [deleted
|
||||||
(subject.deletions
|
(subject.deletions
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
writeFennel
|
writeFennel
|
||||||
, linotify
|
, linotify
|
||||||
, anoia
|
, anoia
|
||||||
|
, lualinux
|
||||||
, lua
|
, lua
|
||||||
}:
|
}:
|
||||||
writeFennel "acquire-wan-address" {
|
writeFennel "acquire-wan-address" {
|
||||||
packages = [ linotify anoia lua.pkgs.luafilesystem ];
|
packages = [ linotify anoia lualinux ];
|
||||||
mainFunction = "run";
|
mainFunction = "run";
|
||||||
} ./acquire-wan-address.fnl
|
} ./acquire-wan-address.fnl
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
{
|
{
|
||||||
liminix
|
liminix
|
||||||
, lib
|
|
||||||
, callPackage
|
, callPackage
|
||||||
}:
|
}:
|
||||||
{ client, interface } :
|
{ client, interface } :
|
||||||
let
|
let
|
||||||
inherit (liminix.services) longrun;
|
inherit (liminix.services) longrun;
|
||||||
inherit (lib) mkOption types;
|
|
||||||
name = "dhcp6c.addr.${client.name}.${interface.name}";
|
name = "dhcp6c.addr.${client.name}.${interface.name}";
|
||||||
script = callPackage ./acquire-wan-address.nix { };
|
script = callPackage ./acquire-wan-address.nix { };
|
||||||
in longrun {
|
in longrun {
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
{
|
{
|
||||||
liminix
|
liminix
|
||||||
, lib
|
|
||||||
, odhcp6c
|
, odhcp6c
|
||||||
, odhcp-script
|
, odhcp-script
|
||||||
}:
|
}:
|
||||||
{ interface } :
|
{ interface } :
|
||||||
let
|
let
|
||||||
inherit (liminix.services) longrun;
|
inherit (liminix.services) longrun;
|
||||||
inherit (lib) mkOption types;
|
|
||||||
name = "dhcp6c.${interface.name}";
|
name = "dhcp6c.${interface.name}";
|
||||||
in longrun {
|
in longrun {
|
||||||
inherit name;
|
inherit name;
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
{ lib, pkgs, config, ...}:
|
{ lib, pkgs, config, ...}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkOption types;
|
inherit (lib) mkOption types;
|
||||||
inherit (pkgs.liminix.services) oneshot;
|
|
||||||
inherit (pkgs) liminix;
|
inherit (pkgs) liminix;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
{
|
{
|
||||||
liminix
|
liminix
|
||||||
, lib
|
|
||||||
, callPackage
|
, callPackage
|
||||||
}:
|
}:
|
||||||
{ client, interface } :
|
{ client, interface } :
|
||||||
let
|
let
|
||||||
inherit (liminix.services) longrun;
|
inherit (liminix.services) longrun;
|
||||||
inherit (lib) mkOption types;
|
|
||||||
name = "dhcp6c.prefix.${client.name}.${interface.name}";
|
name = "dhcp6c.prefix.${client.name}.${interface.name}";
|
||||||
script = callPackage ./acquire-delegated-prefix.nix { };
|
script = callPackage ./acquire-delegated-prefix.nix { };
|
||||||
in longrun {
|
in longrun {
|
||||||
|
|
|
@ -18,7 +18,7 @@ let
|
||||||
name = "${interface.name}.dnsmasq";
|
name = "${interface.name}.dnsmasq";
|
||||||
inherit (liminix.services) longrun;
|
inherit (liminix.services) longrun;
|
||||||
inherit (lib) concatStrings concatStringsSep mapAttrsToList;
|
inherit (lib) concatStrings concatStringsSep mapAttrsToList;
|
||||||
hostOpt = name : { mac, v4, v6, leasetime } @ attrs:
|
hostOpt = name : { mac, v4, v6, leasetime }:
|
||||||
let v6s = concatStrings (map (a : ",[${a}]") v6);
|
let v6s = concatStrings (map (a : ",[${a}]") v6);
|
||||||
in "--dhcp-host=${mac},${v4}${v6s},${name},${builtins.toString leasetime}";
|
in "--dhcp-host=${mac},${v4}${v6s},${name},${builtins.toString leasetime}";
|
||||||
in
|
in
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
let
|
let
|
||||||
inherit (lib) mkOption types;
|
inherit (lib) mkOption types;
|
||||||
inherit (pkgs) liminix;
|
inherit (pkgs) liminix;
|
||||||
inherit (pkgs.liminix.services) oneshot;
|
|
||||||
|
|
||||||
kmodules = pkgs.kmodloader.override {
|
kmodules = pkgs.kmodloader.override {
|
||||||
inherit (config.system.outputs) kernel;
|
inherit (config.system.outputs) kernel;
|
||||||
|
@ -56,8 +55,14 @@ in
|
||||||
config = {
|
config = {
|
||||||
system.service.firewall =
|
system.service.firewall =
|
||||||
let svc = liminix.callService ./service.nix {
|
let svc = liminix.callService ./service.nix {
|
||||||
ruleset = mkOption {
|
extraRules = mkOption {
|
||||||
|
type = types.attrsOf types.attrs;
|
||||||
|
description = "firewall ruleset";
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
rules = mkOption {
|
||||||
type = types.attrsOf types.attrs; # we could usefully tighten this a bit :-)
|
type = types.attrsOf types.attrs; # we could usefully tighten this a bit :-)
|
||||||
|
default = import ./default-rules.nix;
|
||||||
description = "firewall ruleset";
|
description = "firewall ruleset";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -68,13 +73,17 @@ in
|
||||||
};
|
};
|
||||||
in svc.build args' ;
|
in svc.build args' ;
|
||||||
};
|
};
|
||||||
|
programs.busybox.applets = [
|
||||||
|
"insmod" "rmmod"
|
||||||
|
];
|
||||||
kernel.config = {
|
kernel.config = {
|
||||||
NETFILTER = "y";
|
NETFILTER = "y";
|
||||||
NETFILTER_ADVANCED = "y";
|
NETFILTER_ADVANCED = "y";
|
||||||
NETFILTER_NETLINK = "m";
|
NETFILTER_NETLINK = "m";
|
||||||
NF_CONNTRACK = "m";
|
NF_CONNTRACK = "m";
|
||||||
|
|
||||||
|
NETLINK_DIAG = "y";
|
||||||
|
|
||||||
IP6_NF_IPTABLES= "m";
|
IP6_NF_IPTABLES= "m";
|
||||||
IP_NF_IPTABLES = "m";
|
IP_NF_IPTABLES = "m";
|
||||||
IP_NF_NAT = "m";
|
IP_NF_NAT = "m";
|
||||||
|
|
|
@ -4,12 +4,10 @@
|
||||||
, firewallgen
|
, firewallgen
|
||||||
, nftables
|
, nftables
|
||||||
}:
|
}:
|
||||||
{ ruleset }:
|
{ rules, extraRules }:
|
||||||
let
|
let
|
||||||
inherit (liminix.services) oneshot;
|
inherit (liminix.services) oneshot;
|
||||||
inherit (liminix.lib) typeChecked;
|
script = firewallgen "firewall.nft" (lib.recursiveUpdate rules extraRules);
|
||||||
inherit (lib) mkOption types;
|
|
||||||
script = firewallgen "firewall.nft" ruleset;
|
|
||||||
in oneshot {
|
in oneshot {
|
||||||
name = "firewall";
|
name = "firewall";
|
||||||
up = script;
|
up = script;
|
||||||
|
|
|
@ -5,14 +5,13 @@
|
||||||
## you want to run on it, and would usually be set in the "device" file:
|
## you want to run on it, and would usually be set in the "device" file:
|
||||||
## :file:`devices/manuf-model/default.nix`
|
## :file:`devices/manuf-model/default.nix`
|
||||||
|
|
||||||
|
{ lib, ... }:
|
||||||
{ lib, pkgs, config, ...}:
|
|
||||||
let
|
let
|
||||||
inherit (lib) mkEnableOption mkOption types isDerivation hasAttr ;
|
inherit (lib) mkOption types;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options = {
|
options = {
|
||||||
boot = {
|
boot = { };
|
||||||
};
|
|
||||||
hardware = {
|
hardware = {
|
||||||
dts = {
|
dts = {
|
||||||
src = mkOption {
|
src = mkOption {
|
||||||
|
@ -26,7 +25,7 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
includes = mkOption {
|
includes = mkOption {
|
||||||
default = [];
|
default = [ ];
|
||||||
description = "List of directories to search for DTS includes (.dtsi files)";
|
description = "List of directories to search for DTS includes (.dtsi files)";
|
||||||
type = types.listOf types.path;
|
type = types.listOf types.path;
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
let
|
let
|
||||||
inherit (liminix.services) longrun;
|
inherit (liminix.services) longrun;
|
||||||
inherit (lib) concatStringsSep mapAttrsToList;
|
inherit (lib) concatStringsSep mapAttrsToList;
|
||||||
inherit (liminix.lib) typeChecked;
|
|
||||||
inherit (lib) mkOption types;
|
|
||||||
|
|
||||||
# This is not a friendly interface to configuring a wireless AP: it
|
# This is not a friendly interface to configuring a wireless AP: it
|
||||||
# just passes everything straight through to the hostapd config.
|
# just passes everything straight through to the hostapd config.
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
{ config, pkgs, lib, ... } :
|
||||||
|
let
|
||||||
|
inherit (pkgs) liminix;
|
||||||
|
inherit (lib) mkOption types;
|
||||||
|
in {
|
||||||
|
options.system.service.ifwait =
|
||||||
|
mkOption { type = liminix.lib.types.serviceDefn; };
|
||||||
|
|
||||||
|
config.system.service.ifwait = config.system.callService ./ifwait.nix {
|
||||||
|
state = mkOption { type = types.str; };
|
||||||
|
interface = mkOption {
|
||||||
|
type = liminix.lib.types.interface;
|
||||||
|
};
|
||||||
|
service = mkOption {
|
||||||
|
type = liminix.lib.types.service;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
{ ifwait, liminix } :
|
||||||
|
{
|
||||||
|
state
|
||||||
|
, interface
|
||||||
|
, service
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (liminix.services) longrun;
|
||||||
|
in longrun {
|
||||||
|
name = "ifwait.${interface.name}";
|
||||||
|
buildInputs = [ service ];
|
||||||
|
restart-on-upgrade = true;
|
||||||
|
run = ''
|
||||||
|
${ifwait}/bin/ifwait -s ${service.name} $(output ${interface} ifname) ${state}
|
||||||
|
'';
|
||||||
|
}
|
|
@ -5,14 +5,9 @@
|
||||||
|
|
||||||
{ lib, pkgs, config, ...}:
|
{ lib, pkgs, config, ...}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkEnableOption mkOption types isDerivation hasAttr ;
|
inherit (lib) mkOption types ;
|
||||||
inherit (pkgs.pseudofile) dir symlink;
|
|
||||||
inherit (pkgs.liminix.networking) address interface;
|
|
||||||
inherit (pkgs.liminix.services) bundle;
|
|
||||||
inherit (pkgs) liminix;
|
inherit (pkgs) liminix;
|
||||||
|
|
||||||
type_service = pkgs.liminix.lib.types.service;
|
|
||||||
|
|
||||||
mergeConditionals = conf : conditions :
|
mergeConditionals = conf : conditions :
|
||||||
# for each key in conditions, if it is present in conf
|
# for each key in conditions, if it is present in conf
|
||||||
# then merge the associated value into conf
|
# then merge the associated value into conf
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
{ config, pkgs, ...} :
|
||||||
|
let inherit (pkgs.liminix.services) oneshot longrun;
|
||||||
|
in {
|
||||||
|
config = {
|
||||||
|
services = rec {
|
||||||
|
mdevd = longrun {
|
||||||
|
name = "mdevd";
|
||||||
|
notification-fd = 3;
|
||||||
|
run = "${pkgs.mdevd}/bin/mdevd -D 3 -b 200000 -O4";
|
||||||
|
};
|
||||||
|
devout = longrun {
|
||||||
|
name = "devout";
|
||||||
|
notification-fd = 10;
|
||||||
|
run = "exec ${pkgs.devout}/bin/devout /run/devout.sock 4";
|
||||||
|
};
|
||||||
|
coldplug = oneshot {
|
||||||
|
name = "coldplug";
|
||||||
|
# would love to know what mdevd-coldplug/udevadm trigger does
|
||||||
|
# that this doesn't
|
||||||
|
up = ''
|
||||||
|
for i in $(find /sys -name uevent); do ( echo change > $i ) ; done
|
||||||
|
'';
|
||||||
|
dependencies = [
|
||||||
|
devout
|
||||||
|
mdevd
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -7,11 +7,6 @@
|
||||||
let
|
let
|
||||||
inherit (lib) mkOption types;
|
inherit (lib) mkOption types;
|
||||||
inherit (pkgs) liminix;
|
inherit (pkgs) liminix;
|
||||||
mkBoolOption = description : mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
inherit description;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
in {
|
in {
|
||||||
options = {
|
options = {
|
||||||
|
@ -19,28 +14,39 @@ in {
|
||||||
type = liminix.lib.types.serviceDefn;
|
type = liminix.lib.types.serviceDefn;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config.system.service = {
|
imports = [ ../mdevd.nix ../service-trigger ];
|
||||||
mount = liminix.callService ./service.nix {
|
config.system.service.mount =
|
||||||
device = mkOption {
|
let svc = config.system.callService ./service.nix {
|
||||||
type = types.str;
|
partlabel = mkOption {
|
||||||
example = "/dev/sda1";
|
type = types.str;
|
||||||
};
|
example = "my-usb-stick";
|
||||||
mountpoint = mkOption {
|
};
|
||||||
type = types.str;
|
mountpoint = mkOption {
|
||||||
example = "/mnt/media";
|
type = types.str;
|
||||||
};
|
example = "/mnt/media";
|
||||||
options = mkOption {
|
};
|
||||||
type = types.listOf types.str;
|
options = mkOption {
|
||||||
default = [];
|
type = types.listOf types.str;
|
||||||
example = ["noatime" "ro" "sync"];
|
default = [];
|
||||||
};
|
example = ["noatime" "ro" "sync"];
|
||||||
fstype = mkOption {
|
};
|
||||||
type = types.str;
|
fstype = mkOption {
|
||||||
default = "auto";
|
type = types.str;
|
||||||
example = "vfat";
|
default = "auto";
|
||||||
};
|
example = "vfat";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in svc // {
|
||||||
|
build = args:
|
||||||
|
let args' = args // {
|
||||||
|
dependencies = (args.dependencies or []) ++ [
|
||||||
|
config.services.mdevd
|
||||||
|
config.services.devout
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in svc.build args' ;
|
||||||
};
|
};
|
||||||
};
|
|
||||||
config.programs.busybox = {
|
config.programs.busybox = {
|
||||||
applets = ["blkid" "findfs"];
|
applets = ["blkid" "findfs"];
|
||||||
options = {
|
options = {
|
||||||
|
|
|
@ -1,18 +1,27 @@
|
||||||
{
|
{
|
||||||
liminix
|
liminix
|
||||||
, lib
|
, lib
|
||||||
|
, svc
|
||||||
}:
|
}:
|
||||||
{ device, mountpoint, options, fstype }:
|
{ partlabel, mountpoint, options, fstype }:
|
||||||
let
|
let
|
||||||
inherit (liminix.services) oneshot;
|
inherit (liminix.services) oneshot;
|
||||||
|
device = "/dev/disk/by-partlabel/${partlabel}";
|
||||||
|
name = "mount.${lib.strings.sanitizeDerivationName (lib.escapeURL mountpoint)}";
|
||||||
|
options_string =
|
||||||
|
if options == [] then "" else "-o ${lib.concatStringsSep "," options}";
|
||||||
|
controller = svc.uevent-rule.build {
|
||||||
|
serviceName = name;
|
||||||
|
symlink = device;
|
||||||
|
terms = {
|
||||||
|
partname = partlabel;
|
||||||
|
devtype = "partition";
|
||||||
|
};
|
||||||
|
};
|
||||||
in oneshot {
|
in oneshot {
|
||||||
name = "mount.${lib.escapeURL mountpoint}";
|
inherit name;
|
||||||
up = ''
|
timeout-up = 3600;
|
||||||
while ! findfs ${device}; do
|
up = "mount -t ${fstype} ${options_string} ${device} ${mountpoint}";
|
||||||
echo waiting for device ${device}
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
mount -t ${fstype} -o ${lib.concatStringsSep "," options} ${device} ${mountpoint}
|
|
||||||
'';
|
|
||||||
down = "umount ${mountpoint}";
|
down = "umount ${mountpoint}";
|
||||||
|
inherit controller;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
{
|
{
|
||||||
liminix
|
liminix
|
||||||
, ifwait
|
|
||||||
, serviceFns
|
, serviceFns
|
||||||
, lib
|
, lib
|
||||||
}:
|
}:
|
||||||
|
|
|
@ -17,7 +17,7 @@ let
|
||||||
ip address replace $ip/$mask dev $interface
|
ip address replace $ip/$mask dev $interface
|
||||||
(in_outputs ${name}
|
(in_outputs ${name}
|
||||||
for i in lease mask ip router siaddr dns serverid subnet opt53 interface ; do
|
for i in lease mask ip router siaddr dns serverid subnet opt53 interface ; do
|
||||||
printenv $i > $i
|
(printenv $i || true) > $i
|
||||||
done)
|
done)
|
||||||
}
|
}
|
||||||
case $action in
|
case $action in
|
||||||
|
@ -40,7 +40,7 @@ let
|
||||||
'';
|
'';
|
||||||
in longrun {
|
in longrun {
|
||||||
inherit name;
|
inherit name;
|
||||||
run = "/bin/udhcpc -f -i $(output ${interface} ifname) -x hostname:$(cat /proc/sys/kernel/hostname) -s ${script}";
|
run = "exec /bin/udhcpc -f -i $(output ${interface} ifname) -x hostname:$(cat /proc/sys/kernel/hostname) -s ${script}";
|
||||||
notification-fd = 10;
|
notification-fd = 10;
|
||||||
dependencies = [ interface ];
|
dependencies = [ interface ];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
{
|
{
|
||||||
liminix
|
liminix
|
||||||
, ifwait
|
|
||||||
, serviceFns
|
|
||||||
, lib
|
, lib
|
||||||
}:
|
}:
|
||||||
{ enableIPv4, enableIPv6 }:
|
{ enableIPv4, enableIPv6 }:
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
{
|
{
|
||||||
liminix
|
liminix
|
||||||
, ifwait
|
|
||||||
, serviceFns
|
|
||||||
, lib
|
, lib
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
|
@ -11,8 +9,7 @@
|
||||||
# if devpath is supplied, we rename the interface at that
|
# if devpath is supplied, we rename the interface at that
|
||||||
# path to have the specified name.
|
# path to have the specified name.
|
||||||
let
|
let
|
||||||
inherit (liminix.services) longrun oneshot;
|
inherit (liminix.services) oneshot;
|
||||||
inherit (lib) concatStringsSep;
|
|
||||||
name = "${ifname}.link";
|
name = "${ifname}.link";
|
||||||
rename = if devpath != null
|
rename = if devpath != null
|
||||||
then ''
|
then ''
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
{
|
{
|
||||||
liminix
|
liminix
|
||||||
, ifwait
|
|
||||||
, serviceFns
|
|
||||||
, lib
|
, lib
|
||||||
}:
|
}:
|
||||||
{ target, via, interface ? null, metric }:
|
{ target, via, interface ? null, metric }:
|
||||||
let
|
let
|
||||||
inherit (liminix.services) oneshot;
|
inherit (liminix.services) oneshot;
|
||||||
with_dev = if interface != null then "dev $(output ${interface} ifname)" else "";
|
with_dev = if interface != null then "dev $(output ${interface} ifname)" else "";
|
||||||
|
target_hash = builtins.substring 0 12 (builtins.hashString "sha256" target);
|
||||||
|
via_hash = builtins.substring 0 12 (builtins.hashString "sha256" via);
|
||||||
in oneshot {
|
in oneshot {
|
||||||
name = "route-${target}-${builtins.substring 0 12 (builtins.hashString "sha256" "${via}-${if interface!=null then interface.name else ""}")}";
|
name = "route-${target_hash}-${builtins.substring 0 12 (builtins.hashString "sha256" "${via_hash}-${if interface!=null then interface.name else ""}")}";
|
||||||
up = ''
|
up = ''
|
||||||
ip route add ${target} via ${via} metric ${toString metric} ${with_dev}
|
ip route add ${target} via ${via} metric ${toString metric} ${with_dev}
|
||||||
'';
|
'';
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
liminix
|
liminix
|
||||||
, chrony
|
, chrony
|
||||||
, serviceFns
|
|
||||||
, lib
|
, lib
|
||||||
, writeText
|
, writeText
|
||||||
}:
|
}:
|
||||||
|
@ -9,10 +8,6 @@ params:
|
||||||
let
|
let
|
||||||
inherit (liminix.services) longrun;
|
inherit (liminix.services) longrun;
|
||||||
inherit (lib) concatStringsSep mapAttrsToList;
|
inherit (lib) concatStringsSep mapAttrsToList;
|
||||||
inherit (liminix.lib) typeChecked;
|
|
||||||
inherit (lib) mkOption types;
|
|
||||||
|
|
||||||
serverOpts = types.listOf types.str;
|
|
||||||
configFile = p:
|
configFile = p:
|
||||||
(mapAttrsToList (name: opts: "server ${name} ${concatStringsSep "" opts}")
|
(mapAttrsToList (name: opts: "server ${name} ${concatStringsSep "" opts}")
|
||||||
p.servers)
|
p.servers)
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
config
|
config,
|
||||||
, pkgs
|
pkgs,
|
||||||
, lib
|
lib,
|
||||||
, ...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkOption types concatStringsSep;
|
inherit (lib) mkOption types concatStringsSep;
|
||||||
inherit (pkgs) liminix callPackage writeText;
|
inherit (pkgs) liminix writeText;
|
||||||
o = config.system.outputs;
|
o = config.system.outputs;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,7 @@ in
|
||||||
# but only part of one.
|
# but only part of one.
|
||||||
kernel = mkOption {
|
kernel = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
internal = true;
|
internal = true;
|
||||||
description = ''
|
description = ''
|
||||||
kernel
|
kernel
|
||||||
******
|
******
|
||||||
|
@ -42,7 +42,7 @@ in
|
||||||
};
|
};
|
||||||
dtb = mkOption {
|
dtb = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
internal = true;
|
internal = true;
|
||||||
description = ''
|
description = ''
|
||||||
dtb
|
dtb
|
||||||
***
|
***
|
||||||
|
@ -52,7 +52,7 @@ in
|
||||||
};
|
};
|
||||||
uimage = mkOption {
|
uimage = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
internal = true;
|
internal = true;
|
||||||
description = ''
|
description = ''
|
||||||
uimage
|
uimage
|
||||||
******
|
******
|
||||||
|
@ -68,7 +68,7 @@ in
|
||||||
};
|
};
|
||||||
manifest = mkOption {
|
manifest = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
internal = true;
|
internal = true;
|
||||||
description = ''
|
description = ''
|
||||||
Debugging aid. JSON rendition of config.filesystem, on
|
Debugging aid. JSON rendition of config.filesystem, on
|
||||||
which can run "nix-store -q --tree" on it and find
|
which can run "nix-store -q --tree" on it and find
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
, ...
|
, ...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkIf mkOption types;
|
inherit (lib) mkIf;
|
||||||
o = config.system.outputs;
|
o = config.system.outputs;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
, ...
|
, ...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkIf mkOption types;
|
inherit (lib) mkIf;
|
||||||
o = config.system.outputs;
|
o = config.system.outputs;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkEnableOption mkOption mkIf types;
|
inherit (lib) mkEnableOption mkOption mkIf types;
|
||||||
inherit (pkgs) runCommand callPackage writeText;
|
inherit (pkgs) runCommand;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
, ...
|
, ...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkIf mkOption types;
|
inherit (lib) mkIf;
|
||||||
o = config.system.outputs;
|
o = config.system.outputs;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
, ...
|
, ...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkOption mkForce types concatStringsSep;
|
inherit (lib) mkOption types concatStringsSep;
|
||||||
in {
|
in {
|
||||||
imports = [ ../ramdisk.nix ];
|
imports = [ ../ramdisk.nix ];
|
||||||
options.system.outputs = {
|
options.system.outputs = {
|
||||||
|
@ -42,8 +42,7 @@ in {
|
||||||
|
|
||||||
boot-sh =
|
boot-sh =
|
||||||
let
|
let
|
||||||
inherit (pkgs.lib.trivial) toHexString;
|
inherit (config.system.outputs) rootfs;
|
||||||
inherit (config.system.outputs) rootfs kernel;
|
|
||||||
cmdline = concatStringsSep " " config.boot.commandLine;
|
cmdline = concatStringsSep " " config.boot.commandLine;
|
||||||
in
|
in
|
||||||
pkgs.buildPackages.runCommand "boot.sh.sh" {
|
pkgs.buildPackages.runCommand "boot.sh.sh" {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
, ...
|
, ...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkOption types concatStringsSep;
|
inherit (lib) mkOption types;
|
||||||
o = config.system.outputs;
|
o = config.system.outputs;
|
||||||
phram_address = lib.toHexString (config.hardware.ram.startAddress + 256 * 1024 * 1024);
|
phram_address = lib.toHexString (config.hardware.ram.startAddress + 256 * 1024 * 1024);
|
||||||
in {
|
in {
|
||||||
|
|
|
@ -58,7 +58,6 @@ in {
|
||||||
system.outputs = rec {
|
system.outputs = rec {
|
||||||
tftpboot =
|
tftpboot =
|
||||||
let
|
let
|
||||||
inherit (pkgs.lib.trivial) toHexString;
|
|
||||||
o = config.system.outputs;
|
o = config.system.outputs;
|
||||||
image = let choices = {
|
image = let choices = {
|
||||||
uimage = o.uimage;
|
uimage = o.uimage;
|
||||||
|
@ -122,7 +121,7 @@ in {
|
||||||
fdtput -p -t lx dtb /reserved-memory/$node reg $ac_prefix $(hex $rootfsStart) $sz_prefix $(hex $rootfsSize)
|
fdtput -p -t lx dtb /reserved-memory/$node reg $ac_prefix $(hex $rootfsStart) $sz_prefix $(hex $rootfsSize)
|
||||||
|
|
||||||
cmd="liminix ${cmdline} mtdparts=phram0:''${rootfsSize}(rootfs) phram.phram=phram0,''${rootfsStart},''${rootfsSize},${toString config.hardware.flash.eraseBlockSize} root=/dev/mtdblock0";
|
cmd="liminix ${cmdline} mtdparts=phram0:''${rootfsSize}(rootfs) phram.phram=phram0,''${rootfsStart},''${rootfsSize},${toString config.hardware.flash.eraseBlockSize} root=/dev/mtdblock0";
|
||||||
fdtput -t s dtb /chosen bootargs "$cmd"
|
fdtput -t s dtb /chosen ${config.boot.commandLineDtbNode} "$cmd"
|
||||||
|
|
||||||
dtbSize=$(binsize ./dtb )
|
dtbSize=$(binsize ./dtb )
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
, ...
|
, ...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkOption types concatStringsSep;
|
inherit (lib) mkOption types;
|
||||||
o = config.system.outputs;
|
o = config.system.outputs;
|
||||||
cfg = config.tplink-safeloader;
|
cfg = config.tplink-safeloader;
|
||||||
in {
|
in {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
, ...
|
, ...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkIf mkEnableOption mkOption types concatStringsSep;
|
inherit (lib) mkIf mkOption types;
|
||||||
cfg = config.boot.tftp;
|
cfg = config.boot.tftp;
|
||||||
instructions = pkgs.writeText "env.scr" ''
|
instructions = pkgs.writeText "env.scr" ''
|
||||||
setenv serverip ${cfg.serverip}
|
setenv serverip ${cfg.serverip}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
, ...
|
, ...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (pkgs) liminix;
|
|
||||||
inherit (lib) mkIf mkOption types concatStringsSep optionalString;
|
inherit (lib) mkIf mkOption types concatStringsSep optionalString;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
, ...
|
, ...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkIf mkEnableOption mkOption types concatStringsSep;
|
inherit (lib) mkIf mkOption types;
|
||||||
models = "6b e1 6f e1 ff ff ff ff ff ff";
|
models = "6b e1 6f e1 ff ff ff ff ff ff";
|
||||||
in {
|
in {
|
||||||
options.system.outputs = {
|
options.system.outputs = {
|
||||||
|
|
|
@ -17,6 +17,9 @@ in {
|
||||||
system.service.pppoe = mkOption {
|
system.service.pppoe = mkOption {
|
||||||
type = liminix.lib.types.serviceDefn;
|
type = liminix.lib.types.serviceDefn;
|
||||||
};
|
};
|
||||||
|
system.service.l2tp = mkOption {
|
||||||
|
type = liminix.lib.types.serviceDefn;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
system.service.pppoe = pkgs.liminix.callService ./pppoe.nix {
|
system.service.pppoe = pkgs.liminix.callService ./pppoe.nix {
|
||||||
|
@ -29,6 +32,16 @@ in {
|
||||||
description = "options supplied on ppp command line";
|
description = "options supplied on ppp command line";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
system.service.l2tp = pkgs.liminix.callService ./l2tp.nix {
|
||||||
|
lns = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "hostname or address of the L2TP network server";
|
||||||
|
};
|
||||||
|
ppp-options = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = "options supplied on ppp command line";
|
||||||
|
};
|
||||||
|
};
|
||||||
kernel = {
|
kernel = {
|
||||||
config = {
|
config = {
|
||||||
PPP = "y";
|
PPP = "y";
|
||||||
|
@ -36,6 +49,8 @@ in {
|
||||||
PPP_DEFLATE = "y";
|
PPP_DEFLATE = "y";
|
||||||
PPP_ASYNC = "y";
|
PPP_ASYNC = "y";
|
||||||
PPP_SYNC_TTY = "y";
|
PPP_SYNC_TTY = "y";
|
||||||
|
PPPOL2TP = "y";
|
||||||
|
L2TP = "y";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
{
|
||||||
|
liminix
|
||||||
|
, writeAshScript
|
||||||
|
, writeText
|
||||||
|
, serviceFns
|
||||||
|
, xl2tpd
|
||||||
|
} :
|
||||||
|
{ lns, ppp-options }:
|
||||||
|
let
|
||||||
|
inherit (liminix.services) longrun;
|
||||||
|
name = "${lns}.l2tp";
|
||||||
|
ip-up = writeAshScript "ip-up" {} ''
|
||||||
|
. ${serviceFns}
|
||||||
|
(in_outputs ${name}
|
||||||
|
echo $1 > ifname
|
||||||
|
echo $2 > tty
|
||||||
|
echo $3 > speed
|
||||||
|
echo $4 > address
|
||||||
|
echo $5 > peer-address
|
||||||
|
echo $DNS1 > ns1
|
||||||
|
echo $DNS2 > ns2
|
||||||
|
)
|
||||||
|
echo >/proc/self/fd/10
|
||||||
|
'';
|
||||||
|
ip6-up = writeAshScript "ip6-up" {} ''
|
||||||
|
. ${serviceFns}
|
||||||
|
(in_outputs ${name}
|
||||||
|
echo $4 > ipv6-address
|
||||||
|
echo $5 > ipv6-peer-address
|
||||||
|
)
|
||||||
|
echo >/proc/self/fd/10
|
||||||
|
'';
|
||||||
|
ppp-options' = ppp-options ++ [
|
||||||
|
"ip-up-script" ip-up
|
||||||
|
"ipv6-up-script" ip6-up
|
||||||
|
"ipparam" name
|
||||||
|
"nodetach"
|
||||||
|
"usepeerdns"
|
||||||
|
"logfd" "2"
|
||||||
|
];
|
||||||
|
conf = writeText "xl2tpd.conf" ''
|
||||||
|
[lac upstream]
|
||||||
|
lns = ${lns}
|
||||||
|
require authentication = no
|
||||||
|
pppoptfile = ${writeText "ppp-options" ppp-options'}
|
||||||
|
autodial = yes
|
||||||
|
redial = yes
|
||||||
|
'';
|
||||||
|
control = "/run/xl2tpd/control-${name}";
|
||||||
|
in
|
||||||
|
longrun {
|
||||||
|
inherit name;
|
||||||
|
run = ''
|
||||||
|
mkdir -p /run/xl2tpd
|
||||||
|
touch ${control}
|
||||||
|
exec ${xl2tpd}/bin/xl2tpd -D -p /run/xl2tpd/${name}.pid -c ${conf} -C ${control}
|
||||||
|
'';
|
||||||
|
notification-fd = 10;
|
||||||
|
}
|
|
@ -0,0 +1,178 @@
|
||||||
|
{ config, pkgs, lib, ... } :
|
||||||
|
let
|
||||||
|
svc = config.system.service;
|
||||||
|
cfg = config.profile.gateway;
|
||||||
|
inherit (lib) mkOption mkEnableOption mkIf types;
|
||||||
|
inherit (pkgs) liminix serviceFns;
|
||||||
|
inherit (liminix.services) bundle oneshot;
|
||||||
|
hostaps =
|
||||||
|
let
|
||||||
|
defaults = {
|
||||||
|
auth_algs = 1; # 1=wpa2, 2=wep, 3=both
|
||||||
|
wpa = 2; # 1=wpa, 2=wpa2, 3=both
|
||||||
|
wpa_key_mgmt = "WPA-PSK";
|
||||||
|
wpa_pairwise = "TKIP CCMP"; # auth for wpa (may not need this?)
|
||||||
|
rsn_pairwise = "CCMP"; # auth for wpa2
|
||||||
|
};
|
||||||
|
in lib.mapAttrs'
|
||||||
|
(name : value :
|
||||||
|
let
|
||||||
|
attrs = defaults // { ssid = name; } // value;
|
||||||
|
in lib.nameValuePair
|
||||||
|
"hostap-${name}"
|
||||||
|
(svc.hostapd.build {
|
||||||
|
interface = attrs.interface;
|
||||||
|
params = lib.filterAttrs (k: v: k != "interface") attrs;
|
||||||
|
}))
|
||||||
|
cfg.wireless.networks;
|
||||||
|
in {
|
||||||
|
|
||||||
|
options.profile.gateway = {
|
||||||
|
lan = {
|
||||||
|
interfaces = mkOption {
|
||||||
|
type = types.listOf liminix.lib.types.interface;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
address = mkOption {
|
||||||
|
type = types.attrs;
|
||||||
|
};
|
||||||
|
prefix = mkOption { type = types.str; };
|
||||||
|
dhcp = {
|
||||||
|
start = mkOption { type = types.int; };
|
||||||
|
end = mkOption { type = types.int; };
|
||||||
|
hosts = mkOption { type = types.attrs; };
|
||||||
|
localDomain = mkOption { type = types.str; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
firewall = {
|
||||||
|
enable = mkEnableOption "firewall";
|
||||||
|
rules = mkOption { type = types.attrsOf types.attrs; };
|
||||||
|
};
|
||||||
|
|
||||||
|
wan = {
|
||||||
|
interface = mkOption { type = liminix.lib.types.interface; };
|
||||||
|
username = mkOption { type = types.str; };
|
||||||
|
password = mkOption { type = types.str; };
|
||||||
|
dhcp6.enable = mkOption { type = types.bool; };
|
||||||
|
};
|
||||||
|
|
||||||
|
wireless = mkOption {
|
||||||
|
type = types.attrsOf types.anything;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
../wlan.nix
|
||||||
|
../network
|
||||||
|
../ppp
|
||||||
|
../dnsmasq
|
||||||
|
../dhcp6c
|
||||||
|
../firewall
|
||||||
|
../hostapd
|
||||||
|
../bridge
|
||||||
|
../ntp
|
||||||
|
../ssh
|
||||||
|
{ config.services = hostaps; }
|
||||||
|
];
|
||||||
|
|
||||||
|
config = {
|
||||||
|
services.int = svc.network.address.build ({
|
||||||
|
interface = svc.bridge.primary.build { ifname = "int"; };
|
||||||
|
} // cfg.lan.address);
|
||||||
|
|
||||||
|
services.bridge = svc.bridge.members.build {
|
||||||
|
primary = config.services.int;
|
||||||
|
members = cfg.lan.interfaces;
|
||||||
|
};
|
||||||
|
|
||||||
|
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.dhcp6c =
|
||||||
|
let
|
||||||
|
client = svc.dhcp6c.client.build {
|
||||||
|
interface = config.services.wan;
|
||||||
|
};
|
||||||
|
bundl = bundle {
|
||||||
|
name = "dhcp6c";
|
||||||
|
contents = [
|
||||||
|
(svc.dhcp6c.prefix.build {
|
||||||
|
inherit client;
|
||||||
|
interface = config.services.int;
|
||||||
|
})
|
||||||
|
(svc.dhcp6c.address.build {
|
||||||
|
inherit client;
|
||||||
|
interface = config.services.wan;
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in mkIf cfg.wan.dhcp6.enable bundl;
|
||||||
|
|
||||||
|
services.dns =
|
||||||
|
let interface = config.services.int;
|
||||||
|
dcfg = cfg.lan.dhcp;
|
||||||
|
in svc.dnsmasq.build {
|
||||||
|
resolvconf = config.services.resolvconf;
|
||||||
|
inherit interface;
|
||||||
|
ranges = [
|
||||||
|
"${cfg.lan.prefix}.${toString dcfg.start},${cfg.lan.prefix}.${toString dcfg.end}"
|
||||||
|
# ra-stateless: sends router advertisements with the O and A
|
||||||
|
# bits set, and provides a stateless DHCP service. The client
|
||||||
|
# will use a SLAAC address, and use DHCP for other
|
||||||
|
# configuration information.
|
||||||
|
"::,constructor:$(output ${interface} ifname),ra-stateless"
|
||||||
|
];
|
||||||
|
|
||||||
|
hosts = dcfg.hosts;
|
||||||
|
upstreams = [ "/${dcfg.localDomain}/" ];
|
||||||
|
domain = dcfg.localDomain;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.defaultroute4 = svc.network.route.build {
|
||||||
|
via = "$(output ${config.services.wan} address)";
|
||||||
|
target = "default";
|
||||||
|
dependencies = [ config.services.wan ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.defaultroute6 = svc.network.route.build {
|
||||||
|
via = "$(output ${config.services.wan} ipv6-peer-address)";
|
||||||
|
target = "default";
|
||||||
|
interface = config.services.wan;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.firewall = mkIf cfg.firewall.enable
|
||||||
|
(svc.firewall.build {
|
||||||
|
extraRules = cfg.firewall.rules;
|
||||||
|
});
|
||||||
|
|
||||||
|
services.resolvconf = oneshot rec {
|
||||||
|
dependencies = [ config.services.wan ];
|
||||||
|
name = "resolvconf";
|
||||||
|
up = ''
|
||||||
|
. ${serviceFns}
|
||||||
|
( in_outputs ${name}
|
||||||
|
echo "nameserver $(output ${config.services.wan} ns1)" > resolv.conf
|
||||||
|
echo "nameserver $(output ${config.services.wan} ns2)" >> resolv.conf
|
||||||
|
chmod 0444 resolv.conf
|
||||||
|
)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
filesystem =
|
||||||
|
let inherit (pkgs.pseudofile) dir symlink;
|
||||||
|
in dir {
|
||||||
|
etc = dir {
|
||||||
|
"resolv.conf" = symlink "${config.services.resolvconf}/.outputs/resolv.conf";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -5,9 +5,9 @@
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (pkgs) liminix;
|
inherit (pkgs) liminix;
|
||||||
inherit (lib) mkEnableOption mkOption types isDerivation hasAttr ;
|
inherit (lib) mkOption types ;
|
||||||
|
|
||||||
inherit (pkgs.liminix.services) oneshot longrun bundle target;
|
inherit (pkgs.liminix.services) oneshot target;
|
||||||
inherit (pkgs.pseudofile) dir symlink;
|
inherit (pkgs.pseudofile) dir symlink;
|
||||||
inherit (pkgs) serviceFns;
|
inherit (pkgs) serviceFns;
|
||||||
svc = config.system.service;
|
svc = config.system.service;
|
||||||
|
@ -40,7 +40,6 @@ in {
|
||||||
../network
|
../network
|
||||||
../hostapd
|
../hostapd
|
||||||
../bridge
|
../bridge
|
||||||
../ssh
|
|
||||||
{ config.services = hostaps; }
|
{ config.services = hostaps; }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -54,7 +53,6 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
services.sshd = svc.ssh.build {};
|
|
||||||
|
|
||||||
services.int = svc.bridge.primary.build {
|
services.int = svc.bridge.primary.build {
|
||||||
ifname = "int";
|
ifname = "int";
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
{
|
{ config, lib, ... }:
|
||||||
config
|
|
||||||
, pkgs
|
|
||||||
, lib
|
|
||||||
, ...
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
inherit (lib) mkIf mkEnableOption mkOption; # types concatStringsSep;
|
inherit (lib) mkIf mkEnableOption; # types concatStringsSep;
|
||||||
in {
|
in {
|
||||||
options = {
|
options = {
|
||||||
boot = {
|
boot = {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
let
|
let
|
||||||
inherit (pkgs)
|
inherit (pkgs)
|
||||||
execline
|
execline
|
||||||
|
@ -6,14 +6,50 @@ let
|
||||||
s6-init-bin
|
s6-init-bin
|
||||||
s6-linux-init
|
s6-linux-init
|
||||||
stdenvNoCC;
|
stdenvNoCC;
|
||||||
|
inherit (lib.lists) unique concatMap;
|
||||||
inherit (pkgs.pseudofile) dir symlink;
|
inherit (pkgs.pseudofile) dir symlink;
|
||||||
inherit (pkgs.liminix.services) bundle;
|
inherit (pkgs.liminix.services) oneshot bundle;
|
||||||
|
|
||||||
s6-rc-db =
|
s6-rc-db =
|
||||||
let
|
let
|
||||||
|
# In the default bundle we need to have all the services
|
||||||
|
# in config.services except for controlled services and
|
||||||
|
# anything that depends on one. But we do need the controllers
|
||||||
|
# themselves.
|
||||||
|
|
||||||
|
# So, find all required services and their transitive
|
||||||
|
# dependencies and their controllers. remove all controlled
|
||||||
|
# services and all services that have a controlled service as
|
||||||
|
# dependency
|
||||||
|
|
||||||
|
isControlled = s : s ? controller && s.controller != null;
|
||||||
|
deps = s : s.dependencies ++
|
||||||
|
lib.optional (isControlled s) s.controller;
|
||||||
|
flatDeps = s : [s] ++ concatMap flatDeps (deps s);
|
||||||
|
allServices = unique (concatMap flatDeps (builtins.attrValues config.services));
|
||||||
|
isDependentOnControlled = s :
|
||||||
|
isControlled s ||
|
||||||
|
(lib.lists.any isDependentOnControlled s.dependencies);
|
||||||
|
|
||||||
|
# all controlled services depend on this oneshot, which
|
||||||
|
# makes a list of them so we can identify them at runtime
|
||||||
|
controlled = oneshot {
|
||||||
|
name = "controlled";
|
||||||
|
up = ''
|
||||||
|
mkdir -p /run/services/controlled
|
||||||
|
for s in $(s6-rc-db -d dependencies controlled); do
|
||||||
|
touch /run/services/controlled/$s
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
down = "rm -r /run/services/controlled";
|
||||||
|
};
|
||||||
|
|
||||||
|
defaultStart =
|
||||||
|
builtins.filter
|
||||||
|
(s: !(isDependentOnControlled s)) allServices;
|
||||||
defaultDefaultTarget = bundle {
|
defaultDefaultTarget = bundle {
|
||||||
name = "default";
|
name = "default";
|
||||||
contents = builtins.attrValues config.services;
|
contents = defaultStart ++ [controlled];
|
||||||
};
|
};
|
||||||
servicesAttrs = {
|
servicesAttrs = {
|
||||||
default = defaultDefaultTarget;
|
default = defaultDefaultTarget;
|
||||||
|
|
|
@ -34,7 +34,7 @@ fi
|
||||||
|
|
||||||
### If your services are managed by s6-rc:
|
### If your services are managed by s6-rc:
|
||||||
### (replace /run/service with your scandir)
|
### (replace /run/service with your scandir)
|
||||||
s6-rc-init /run/service -d -c /etc/s6-rc/compiled
|
s6-rc-init -d -c /etc/s6-rc/compiled /run/service
|
||||||
|
|
||||||
|
|
||||||
### 2. Starting the wanted set of services
|
### 2. Starting the wanted set of services
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, pkgs, lib, ... } :
|
{ config, pkgs, ... } :
|
||||||
{
|
{
|
||||||
config = {
|
config = {
|
||||||
programs.busybox = {
|
programs.busybox = {
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
# this is unlikely to be the final form or location of this code, it's
|
||||||
|
# an interim module which wraps the uevent-watch command
|
||||||
|
|
||||||
|
{ lib, pkgs, config, ... }:
|
||||||
|
let
|
||||||
|
inherit (lib) mkOption types;
|
||||||
|
inherit (pkgs) liminix;
|
||||||
|
# inherit (pkgs.liminix.services) bundle;
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
system.service.uevent-rule = mkOption {
|
||||||
|
description = "a service which starts other services based on device state (sysfs)";
|
||||||
|
type = liminix.lib.types.serviceDefn;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
system.service.uevent-rule = liminix.callService ./rule.nix {
|
||||||
|
serviceName = mkOption {
|
||||||
|
description = "name of the service to run when the rule matches";
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
terms = mkOption {
|
||||||
|
type = types.attrs;
|
||||||
|
example = {
|
||||||
|
devtype = "usb_device";
|
||||||
|
attrs.idVendor = "8086";
|
||||||
|
};
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
symlink = mkOption {
|
||||||
|
description = "create symlink targeted on devpath";
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
liminix
|
||||||
|
, uevent-watch
|
||||||
|
, lib }:
|
||||||
|
{
|
||||||
|
serviceName, terms, symlink
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (liminix.services) longrun;
|
||||||
|
inherit (lib.attrsets) collect mapAttrsRecursive;
|
||||||
|
inherit (lib.strings) concatStringsSep;
|
||||||
|
stringify = attrs :
|
||||||
|
concatStringsSep " "
|
||||||
|
(collect lib.isString
|
||||||
|
(mapAttrsRecursive
|
||||||
|
(path : value : "${concatStringsSep "." path}=${value}")
|
||||||
|
attrs));
|
||||||
|
termsString = stringify terms;
|
||||||
|
in longrun {
|
||||||
|
name = "watch-for-${serviceName}";
|
||||||
|
restart-on-upgrade = true;
|
||||||
|
run = "${uevent-watch}/bin/uevent-watch ${if symlink != null then "-n ${symlink}" else ""} -s ${serviceName} ${termsString}";
|
||||||
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
config
|
config,
|
||||||
, pkgs
|
pkgs,
|
||||||
, lib
|
lib,
|
||||||
, ...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (pkgs) liminix;
|
inherit (pkgs) liminix;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
liminix
|
liminix
|
||||||
, dropbear
|
, dropbear
|
||||||
, serviceFns
|
|
||||||
, lib
|
, lib
|
||||||
}:
|
}:
|
||||||
p :
|
p :
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# support for USB block devices and the common filesystems
|
# support for USB block devices and the common filesystems
|
||||||
# they're likely to provide
|
# they're likely to provide
|
||||||
|
|
||||||
{lib, config, ... }:
|
{ config, ... }:
|
||||||
{
|
{
|
||||||
kernel = {
|
kernel = {
|
||||||
config = {
|
config = {
|
||||||
|
@ -24,8 +24,6 @@
|
||||||
EXT4_FS = "y";
|
EXT4_FS = "y";
|
||||||
EXT4_USE_FOR_EXT2 = "y";
|
EXT4_USE_FOR_EXT2 = "y";
|
||||||
FS_ENCRYPTION = "y";
|
FS_ENCRYPTION = "y";
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,17 @@ let
|
||||||
inherit (lib)
|
inherit (lib)
|
||||||
concatStrings concatStringsSep mapAttrsToList mkOption types;
|
concatStrings concatStringsSep mapAttrsToList mkOption types;
|
||||||
inherit (builtins) toString;
|
inherit (builtins) toString;
|
||||||
inherit (pkgs.pseudofile) dir symlink;
|
inherit (pkgs.pseudofile) dir;
|
||||||
passwd-file =
|
passwd-file =
|
||||||
let lines = mapAttrsToList (name: u: "${name}:${if u ? passwd then u.passwd else "!!"}:${toString u.uid}:${toString u.gid}:${u.gecos}:${u.dir}:${u.shell}\n" )
|
let
|
||||||
config.users;
|
lines = mapAttrsToList (
|
||||||
in concatStrings lines;
|
name: u:
|
||||||
|
"${name}:${
|
||||||
|
if u ? passwd then u.passwd else "!!"
|
||||||
|
}:${toString u.uid}:${toString u.gid}:${u.gecos}:${u.dir}:${u.shell}\n"
|
||||||
|
) config.users;
|
||||||
|
in
|
||||||
|
concatStrings lines;
|
||||||
group-file =
|
group-file =
|
||||||
let lines = mapAttrsToList
|
let lines = mapAttrsToList
|
||||||
(name: {gid, usernames ? []}:
|
(name: {gid, usernames ? []}:
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
{ lib, pkgs, config, ...}:
|
{ lib, pkgs, config, ...}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkOption types;
|
inherit (lib) mkOption types;
|
||||||
inherit (pkgs.liminix.services) oneshot;
|
|
||||||
inherit (pkgs) liminix;
|
inherit (pkgs) liminix;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,4 +15,5 @@ in oneshot rec {
|
||||||
)
|
)
|
||||||
'';
|
'';
|
||||||
down = "ip link set down dev ${ifname}";
|
down = "ip link set down dev ${ifname}";
|
||||||
|
dependencies = [ primary ];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
liminix
|
liminix
|
||||||
, lib
|
, lib
|
||||||
|
, s6
|
||||||
}:
|
}:
|
||||||
{ watched, headStart } :
|
{ watched, headStart } :
|
||||||
let
|
let
|
||||||
|
@ -8,5 +9,5 @@ let
|
||||||
in longrun {
|
in longrun {
|
||||||
name = "watchdog";
|
name = "watchdog";
|
||||||
run =
|
run =
|
||||||
"HEADSTART=${toString headStart} ${./gaspode.sh} ${lib.concatStringsSep " " (builtins.map (s: s.name) watched)}";
|
"PATH=${s6}/bin:$PATH HEADSTART=${toString headStart} ${./gaspode.sh} ${lib.concatStringsSep " " (builtins.map (s: s.name) watched)}";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
{ lib, pkgs, config, ...}:
|
{ lib, pkgs, config, ...}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkEnableOption mkOption types isDerivation hasAttr ;
|
|
||||||
inherit (pkgs.pseudofile) dir symlink;
|
inherit (pkgs.pseudofile) dir symlink;
|
||||||
inherit (pkgs) stdenv wireless-regdb;
|
inherit (pkgs) stdenv wireless-regdb;
|
||||||
regulatory = stdenv.mkDerivation {
|
regulatory = stdenv.mkDerivation {
|
||||||
name = "regulatory.db";
|
name = "regulatory.db";
|
||||||
phases = ["installPhase"];
|
phases = [ "installPhase" ];
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
cp ${wireless-regdb}/lib/firmware/regulatory.db $out/
|
cp ${wireless-regdb}/lib/firmware/regulatory.db $out/
|
||||||
|
|
67
overlay.nix
67
overlay.nix
|
@ -46,7 +46,7 @@ in
|
||||||
extraPkgs // {
|
extraPkgs // {
|
||||||
# liminix library functions
|
# liminix library functions
|
||||||
lim = {
|
lim = {
|
||||||
parseInt = s : (builtins.fromTOML "r=${s}").r;
|
parseInt = s: (builtins.fromTOML "r=${s}").r;
|
||||||
};
|
};
|
||||||
|
|
||||||
# keep these alphabetical
|
# keep these alphabetical
|
||||||
|
@ -74,9 +74,24 @@ extraPkgs // {
|
||||||
# should texinfo be in nativeBuildInputs instead of
|
# should texinfo be in nativeBuildInputs instead of
|
||||||
# buildInputs?
|
# buildInputs?
|
||||||
texinfo = null;
|
texinfo = null;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# luarocks wants a cross-compiled cmake (which seems like a bug,
|
||||||
|
# we're never going to run luarocks on the device, but ...)
|
||||||
|
# but https://github.com/NixOS/nixpkgs/issues/284734
|
||||||
|
# so we do surgery on the cmake derivation until that's fixed
|
||||||
|
|
||||||
|
cmake = prev.cmake.overrideAttrs(o:
|
||||||
|
# don't override the build cmake or we'll have to rebuild
|
||||||
|
# half the known universe to no useful benefit
|
||||||
|
if final.stdenv.buildPlatform != final.stdenv.hostPlatform
|
||||||
|
then {
|
||||||
|
preConfigure =
|
||||||
|
builtins.replaceStrings
|
||||||
|
["$configureFlags"] ["$configureFlags $cmakeFlags"] o.preConfigure;
|
||||||
|
}
|
||||||
|
else {}
|
||||||
|
);
|
||||||
|
|
||||||
dnsmasq =
|
dnsmasq =
|
||||||
let d = prev.dnsmasq.overrideAttrs(o: {
|
let d = prev.dnsmasq.overrideAttrs(o: {
|
||||||
|
@ -170,9 +185,12 @@ extraPkgs // {
|
||||||
# done. Do it the ugly way..
|
# done. Do it the ugly way..
|
||||||
postPatch =
|
postPatch =
|
||||||
o.postPatch
|
o.postPatch
|
||||||
+ (with final;
|
+ (
|
||||||
lib.optionalString (stdenv.buildPlatform != stdenv.hostPlatform)
|
with final;
|
||||||
"\nsed -i.bak 's/linux.*-mips/linux-mops/' Configure\n");
|
lib.optionalString (
|
||||||
|
stdenv.buildPlatform != stdenv.hostPlatform
|
||||||
|
) "\nsed -i.bak 's/linux.*-mips/linux-mops/' Configure\n"
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
pppBuild = prev.ppp;
|
pppBuild = prev.ppp;
|
||||||
|
@ -184,13 +202,12 @@ extraPkgs // {
|
||||||
}); in q.override { nixosTestRunner = true; sdlSupport = false; };
|
}); in q.override { nixosTestRunner = true; sdlSupport = false; };
|
||||||
|
|
||||||
rsyncSmall =
|
rsyncSmall =
|
||||||
let r = prev.rsync.overrideAttrs(o: {
|
let
|
||||||
configureFlags = o.configureFlags ++ [
|
r = prev.rsync.overrideAttrs (o: {
|
||||||
"--disable-openssl"
|
configureFlags = o.configureFlags ++ [ "--disable-openssl" ];
|
||||||
];
|
});
|
||||||
});
|
in
|
||||||
in r.override { openssl = null; };
|
r.override { openssl = null; };
|
||||||
|
|
||||||
|
|
||||||
inherit s6;
|
inherit s6;
|
||||||
s6-linux-init = prev.s6-linux-init.override {
|
s6-linux-init = prev.s6-linux-init.override {
|
||||||
|
@ -208,14 +225,14 @@ extraPkgs // {
|
||||||
|
|
||||||
ubootQemuAarch64 = final.buildUBoot {
|
ubootQemuAarch64 = final.buildUBoot {
|
||||||
defconfig = "qemu_arm64_defconfig";
|
defconfig = "qemu_arm64_defconfig";
|
||||||
extraMeta.platforms = ["aarch64-linux"];
|
extraMeta.platforms = [ "aarch64-linux" ];
|
||||||
filesToInstall = ["u-boot.bin"];
|
filesToInstall = [ "u-boot.bin" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
ubootQemuArm = final.buildUBoot {
|
ubootQemuArm = final.buildUBoot {
|
||||||
defconfig = "qemu_arm_defconfig";
|
defconfig = "qemu_arm_defconfig";
|
||||||
extraMeta.platforms = ["armv7l-linux"];
|
extraMeta.platforms = [ "armv7l-linux" ];
|
||||||
filesToInstall = ["u-boot.bin"];
|
filesToInstall = [ "u-boot.bin" ];
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
CONFIG_CMD_UBI=y
|
CONFIG_CMD_UBI=y
|
||||||
CONFIG_CMD_UBIFS=y
|
CONFIG_CMD_UBIFS=y
|
||||||
|
@ -229,8 +246,8 @@ extraPkgs // {
|
||||||
|
|
||||||
ubootQemuMips = final.buildUBoot {
|
ubootQemuMips = final.buildUBoot {
|
||||||
defconfig = "malta_defconfig";
|
defconfig = "malta_defconfig";
|
||||||
extraMeta.platforms = ["mips-linux"];
|
extraMeta.platforms = [ "mips-linux" ];
|
||||||
filesToInstall = ["u-boot.bin"];
|
filesToInstall = [ "u-boot.bin" ];
|
||||||
# define the prompt to be the same as arm{32,64} so
|
# define the prompt to be the same as arm{32,64} so
|
||||||
# we can use the same expect script for both
|
# we can use the same expect script for both
|
||||||
extraPatches = [ ./pkgs/u-boot/0002-virtio-init-for-malta.patch ];
|
extraPatches = [ ./pkgs/u-boot/0002-virtio-init-for-malta.patch ];
|
||||||
|
@ -252,9 +269,20 @@ extraPkgs // {
|
||||||
CONFIG_MIPS_BOOT_FDT=y
|
CONFIG_MIPS_BOOT_FDT=y
|
||||||
CONFIG_OF_LIBFDT=y
|
CONFIG_OF_LIBFDT=y
|
||||||
CONFIG_OF_STDOUT_VIA_ALIAS=y
|
CONFIG_OF_STDOUT_VIA_ALIAS=y
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
libusb1 =
|
||||||
|
let u = prev.libusb1.overrideAttrs(o: {
|
||||||
|
# don't use gcc libatomic because it vastly increases the
|
||||||
|
# closure size
|
||||||
|
preConfigure = "sed -i.bak /__atomic_fetch_add_4/c\: configure.ac";
|
||||||
|
});
|
||||||
|
in u.override {
|
||||||
|
enableUdev = final.stdenv.buildPlatform == final.stdenv.hostPlatform;
|
||||||
|
withDocs = false;
|
||||||
|
};
|
||||||
|
|
||||||
util-linux-small = prev.util-linux.override {
|
util-linux-small = prev.util-linux.override {
|
||||||
ncursesSupport = false;
|
ncursesSupport = false;
|
||||||
pamSupport = false;
|
pamSupport = false;
|
||||||
|
@ -263,5 +291,4 @@ extraPkgs // {
|
||||||
translateManpages = false;
|
translateManpages = false;
|
||||||
capabilitiesSupport = false;
|
capabilitiesSupport = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue