2
0

24 Commits

Author SHA1 Message Date
dan e8e0de0284 make tftpboot work on devices with old u-boot
Some devices have a U-boot variant that does not accept a third
parameter on the "bootm" command, meaning we can't override the dtb
in the bootloader so have to smush it back into the kernel image

This is WIP because
- still hardcodes MIPS
- doesn't work in QEMU

Based on
https://gti.telent.net/raboof/liminix/src/branch/tftp-old-uboot

Co-authored-by:  Arnout Engelen <arnout@bzzt.net>
2024-02-15 20:12:03 +00:00
dan 6920ee765d deep thoughts 2024-02-15 09:11:54 +00:00
dan 71a1ef286e deep thoughts 2024-02-13 22:32:57 +00:00
dan ffe0e9d26b use mkstate for dropbear keys 2024-02-13 22:12:26 +00:00
dan 2b22c7aa91 dnsmasq: store dhcp lease file on /persist 2024-02-13 21:54:45 +00:00
dan 3c950704e1 rename /run/service-state to /run/services/outputs 2024-02-13 21:41:43 +00:00
dan 8578a554c7 deep thoughts 2024-02-13 21:11:30 +00:00
dan 3851698d35 fix tftpboot compressed rootfs 2024-02-13 18:16:17 +00:00
dan f69ebbb6f5 fix doc CI target 2024-02-13 15:41:45 +00:00
dan 16e4b05653 dhcp6c: set preferred and valid address lifetimes
also workaround a bug in rebinding/updates where we get an error
from "ip addr add" trying to add an address that's already present
2024-02-13 13:49:12 +00:00
dan 8ac848b1e6 ath10k_pci: wifi modules must be modules 2024-02-13 12:56:03 +00:00
dan b7efbd3e21 update NEWS file 2024-02-12 21:10:52 +00:00
dan a654577ac2 improve port-forwarding comment 2024-02-12 21:05:01 +00:00
dan c50423f689 turris omnia: upgrade to mainline 6.7.4 kernel
On this device we don't need the openwrt kernel or patches. The
newer kernel also fixes the weird one minute pause at boot when
it was doing something with either mmc or switch.
2024-02-12 20:43:01 +00:00
dan 65479e206b use regular kernel not backports for mac80211
the kernel on most devices is now newer than the version that the
backported drivers were backported from
2024-02-12 20:41:10 +00:00
dan 79926c6fe7 remove call to deleted package 2024-02-12 14:56:12 +00:00
dan ae4856ea7c improve firewall comment 2024-02-12 13:56:56 +00:00
dan b9c0d93670 build modules at same time as main kernel vmlinux
This changes the practice for building kernel modules: now we expect
that the appropriate Kconfig symbols are set to =m in
config.kernel.config, and then use pkgs.kmodloader to create
a service that loads and unloads all the modules depended on by
a particular requirement.

Note that modules won't be installed on the target device just by
virue of having been built: only the modules that are referenced by a
kmodloader package will be in the closure.

An example may make this clearer: see modules/firewall/default.nix
in this commit.

Why?

If you have a compiled Linux kernel source tree and you change some
symbol from "is not set" to m and then run make modules, you cannot in
general expect that newly compiled module to work. This is because
there are places in the build of the main kernel where it looks to see
which modules _may_ be defined and uses that information to
accommodate them.

For example in an in-kernel build of

  https://github.com/torvalds/linux/blob/master/net/netfilter/core.c#L689

some symbols are defined only if CONFIG_NF_CONNTRACK is set, meaning
this code won't work if we have it unset initially then try later to
enable it and build modules only. Or see

  https://github.com/torvalds/linux/blob/master/include/linux/netdevice.h#L160
2024-02-11 23:47:11 +00:00
dan 11287a8436 allow lan dns queries (ipv6) 2024-02-11 23:32:46 +00:00
dan 57aece0709 rotuer: don't forward queries for local domain 2024-02-11 23:32:46 +00:00
dan c1d285a220 rotuer: network debugging tools 2024-02-11 23:32:46 +00:00
dan dce983ec79 move kernel module to its own subdir 2024-02-11 18:15:55 +00:00
dan 812f497660 add kernel.version param to allow for version-specific patches
default to 5.15.137 to avoid breaking the devices that don't declare it
2024-02-11 16:19:52 +00:00
dan 1206d02200 rotuer-secrets: remove root_password, add wifi ssid and domainName
this is step one towards getting rid of rotuer-secrets completely and
turning rotuer into a "profile" module that can be less hackily
customised for other people's networks
2024-02-11 15:56:14 +00:00
37 changed files with 456 additions and 193 deletions
+35
View File
@@ -31,5 +31,40 @@ Upstream changes that have led to incompatible Liminix changes are:
* newer U-Boot version
* util-linux can now be built (previously depended on systemd)
2024-01-30
New port! Thanks to Arnout Engelen <arnout@bzzt.net>, Liminix
now runs on the TP-Link Archer AX23
2024-02-12
* we now build wifi drivers (mac80211) from the same kernel source as
the running kernel, instead of using drivers from the linux-backports
project.
* in general, we build kernel modules (e.g. for nftables) at the same
time as the kernel itself instead of expecting to be able to build
them afterwards as though they were "out of tree". Refer to commit
b9c0d93670275e69df24902b05bf4aa4f0fcbe96 for a fuller explanation
of how this simplifies things.
2024-02-13
So that we can be more consistent about services that would like their
state to be preserved across boots (assuming a writable filesystem)
these changes have been made
* /run/service-state has been moved to /run/services/outputs
to better reflect what it's used for
* /run/services/state is either a symlink to /persist/services/state
(if there's a writeable fs on /persist) or a directory (if there
isn't)
The change will lose your ssh host key(s) unless you copy them from
the old location to the new one before rebooting into the new system
mkdir -m 02751 -p /run/services/state/dropbear
cp /persist/secrets/dropbear/* /run/services/state/dropbear
The `output`, `mkoutputs` functions defined by ${serviceFns}
have been updated for the new location.
+125
View File
@@ -3952,3 +3952,128 @@ I can actually use it as a CPE. This means
- would be quite cool to run sniproxy instead of forwarding to
loaclhost (extra credit)
Sat Feb 10 18:23:54 GMT 2024
ARGH KERNEL
You can't define CONFIG_NETFILTER=y in a monolithic kernel and expect
later to separately build some modules that use it, because there are
a bunch of symbols that only get defined if certain other CONFIG
options are set at the time that the monolithic kernel is built.
https://github.com/torvalds/linux/blob/master/net/netfilter/core.c#L689
Another example is
https://github.com/torvalds/linux/blob/master/include/linux/netdevice.h#L160
- if you decide after building the kernel that you're going to build
some wireless modules, you can't do that without rebuilding the kernel
so that it knows to expect them
The moral of the story seems to be: if you have a compiled Linux kernel source tree and you change some symbol from "is not set" to m and then run make modules, you cannot in general expect that newly compiled module to work.
AP advertised VHT without HT, disabling HT/VHT/HE
TODO
- [done] support kernel version as parameter to builder pkgs/kernel/default.nix
- [done] extract the change in how module loading works from omnia device config,
and fix the other thing that uses it
- [axed] wlan module to take 'backported' as a parameter
half of the omnia conditionalConfig can go into the module
- [done] upgrade omnia to kernel v6
- figure out what mdns we need for local hostname resolution
(maybe bridging lan/wlan)?
- [DONE] slow wifi because "AP advertised VHT without HT, disabling HT/VHT/HE"
- [DONE] add local domain to secrets
- run sniproxy instead of forwarding
- [test] forward some port to loaclhost 22 for inbound ipv4 ssh
Mon Feb 12 21:50:35 GMT 2024
# find /run/service-state/dhcp6c.wan.link.pppoe/address/
/run/service-state/dhcp6c.wan.link.pppoe/address/
/run/service-state/dhcp6c.wan.link.pppoe/address/2001-8b0-1111-1111-0-ffff-51bb-4cf2_LFoo015bSsM
/run/service-state/dhcp6c.wan.link.pppoe/address/2001-8b0-1111-1111-0-ffff-51bb-4cf2_LFoo015bSsM/valid
/run/service-state/dhcp6c.wan.link.pppoe/address/2001-8b0-1111-1111-0-ffff-51bb-4cf2_LFoo015bSsM/preferred
/run/service-state/dhcp6c.wan.link.pppoe/address/2001-8b0-1111-1111-0-ffff-51bb-4cf2_LFoo015bSsM/len
/run/service-state/dhcp6c.wan.link.pppoe/address/2001-8b0-1111-1111-0-ffff-51bb-4cf2_LFoo015bSsM/address
#
valid 7199 preferred 3599
Tue Feb 13 19:44:57 GMT 2024
Before we put this back live, would be good to
[done] 1) move the leases file into /persist
I think we'll do /persist/service/<name>/ and change ssh to use the same
scheme.
we could put mkpersist() in serviceFns which would check for /persist
and return a directory in /persist/service/ or /run/service-state
(will something bad happen if we use /run/service-state? it will also
expose the thingy as an output, but whether it's accessible that way
will depend on whether there's a writable fs or not, which is unexpected)
: rename service-state to /run/services/outputs
: on boot
: if /persist
: create /persist/services/state and symlink /run/services/state to it
: else create /run/services/state
[done] 2) maybe change the local domain back to .lan? setting up
systemd-networkd with search domains is an awful faff
[done] 3) work out what to do with incoming ssh from wan
- For noetbook and thinkpad we have a vpn anyway so can expect to
reach loaclhost directly using ipv6
- stop ssh from ever trying to get to our ipv4 address.
- we could get rid of A record for loaclhost.telent.net but
there are a bunch of CNAMES pointing at it for web servers.
- we could reject incoming connections to tcp4 port 22 in firewall
and then there is a clear signal to Dont Do That Then
- for emergency use, dnat ipv4 2200 and 2201 to rotuer and loaclhost
Tue Feb 13 22:31:03 GMT 2024
* the reason we can't reboot is that there is a service to add each
lan device to the bridge which does ifwait $dev running, which doesn't
return until there's something plugged in. So s6-rc hangs indefinitely
until the lan switch is fully populated. This is definitely a "next
milestone" thing.
* another example of "thing that depends on other thing but which it
is actually OK if neither of them happen" might be "mount a
filesystem if there is a usb mass storage device attached"
* I don't know if failover also fits into the model we don't quite
have. LTE route depends on pppoe not being healthy
we can have services (or bundles) that aren't part of the default target,
and plumb them into events of some kind (netlink?) to bring them up/down?
we can use s6-rc instanced services:
https://skarnet.org/software/s6/instances.html
"s6-instance-create and s6-instance-delete are relatively expensive operations, because they have to recursively copy or delete directories and use the synchronization mechanism with the instance supervisor, compared to s6-instance-control which only has to send commands to already existing supervisors. If you are going to turn instances on and off on a regular basis, it is more efficient to keep the instance existing and control it with s6-instance-control than it is to repeatedly create and delete it. "
Probably we need something that reads netlink messages and converts
them to a format that we can use to control services. Is there a
benefit to using services here and not just running commands? it means
the system state change we desire will stay changed.
TODO items not to lose track of
- speed testing (iperf)
- make gl-ar750 tftpboot build again
- finish belkin
- install sniproxy
- is there something simple we can do to make it reboot again?
+10 -6
View File
@@ -149,6 +149,13 @@
WATCHDOG = "y";
MEDIATEK_WATCHDOG = "y";
};
conditionalConfig = {
WLAN= {
MT7615E = "m";
MT7622_WMAC = "y";
MT7915E = "m";
};
};
};
boot = {
commandLine = [ "console=ttyS0,115200" ];
@@ -169,12 +176,9 @@
hardware =
let
openwrt = pkgs.openwrt;
mac80211 = pkgs.mac80211.override {
drivers = [
"mt7615e"
"mt7915e"
];
klibBuild = config.system.outputs.kernel.modulesupport;
mac80211 = pkgs.kmodloader.override {
targets = ["mt7615e" "mt7915e"];
inherit (config.system.outputs) kernel;
};
in {
ubi = {
+14 -7
View File
@@ -71,9 +71,9 @@
cp $blobdir/board.bin $out/ath10k/QCA9887/hw1.0/
'';
};
mac80211 = pkgs.mac80211.override {
drivers = ["ath9k" "ath10k_pci"];
klibBuild = config.system.outputs.kernel.modulesupport;
mac80211 = pkgs.kmodloader.override {
targets = ["ath9k" "ath10k_pci"];
inherit (config.system.outputs) kernel;
};
ath10k_cal_data =
let
@@ -211,14 +211,21 @@
WATCHDOG = "y";
ATH79_WDT = "y"; # watchdog timer
# this is all copied from nixwrt ath79 config. Clearly not all
# of it is device config, some of it is wifi config or
# installation method config or ...
EARLY_PRINTK = "y";
PRINTK_TIME = "y";
};
conditionalConfig = {
WLAN = {
WLAN_VENDOR_ATH = "y";
ATH_COMMON = "m";
ATH9K = "m";
ATH9K_AHB = "y";
ATH10K = "m";
ATH10K_PCI = "m";
ATH10K_DEBUG = "y";
};
};
};
};
}
+11 -3
View File
@@ -47,9 +47,9 @@
let
inherit (pkgs.liminix.networking) interface;
inherit (pkgs) openwrt;
mac80211 = pkgs.mac80211.override {
drivers = ["rt2800soc"];
klibBuild = config.system.outputs.kernel.modulesupport;
mac80211 = pkgs.kmodloader.override {
targets = ["rt2800soc"];
inherit (config.system.outputs) kernel;
};
in {
imports = [
@@ -178,6 +178,14 @@
} // lib.optionalAttrs (config.system.service ? vlan) {
SWCONFIG = "y";
};
conditionalConfig = {
WLAN = {
WLAN_VENDOR_RALINK = "y";
RT2800SOC = "m";
RT2X00 = "m";
};
};
};
};
}
+12 -3
View File
@@ -43,9 +43,9 @@
inherit (pkgs.pseudofile) dir symlink;
inherit (pkgs) openwrt;
mac80211 = pkgs.mac80211.override {
drivers = ["mt7603e"];
klibBuild = config.system.outputs.kernel.modulesupport;
mac80211 = pkgs.kmodloader.override {
targets = ["mt7603e"];
inherit (config.system.outputs) kernel;
};
wlan_firmware = pkgs.fetchurl {
url = "https://github.com/openwrt/mt76/raw/f24b56f935392ca1d35fae5fd6e56ef9deda4aad/firmware/mt7628_e2.bin";
@@ -185,6 +185,15 @@
RALINK_WDT = "y"; # watchdog
MT7621_WDT = "y"; # or it might be this one
};
conditionalConfig = {
WLAN = {
WLAN_VENDOR_RALINK = "y";
WLAN_VENDOR_MEDIATEK = "y";
MT7603E = "m";
};
};
};
};
}
+11 -6
View File
@@ -322,9 +322,14 @@
ZSTD_COMPRESS="y";
ZSTD_DECOMPRESS="y";
} // lib.optionalAttrs (config.system.service ? watchdog) {
RALINK_WDT = "y"; # watchdog
MT7621_WDT = "y"; # or it might be this one
};
RALINK_WDT = "y"; # watchdog
MT7621_WDT = "y"; # or it might be this one
};
conditionalConfig = {
WLAN = {
MT7915E = "m";
};
};
};
tplink-safeloader.board = "ARCHER-AX23-V1";
boot = {
@@ -353,11 +358,11 @@
hardware =
let
openwrt = pkgs.openwrt;
mac80211 = pkgs.mac80211.override {
drivers = [
mac80211 = pkgs.kmodloader.override {
targets = [
"mt7915e"
];
klibBuild = config.system.outputs.kernel.modulesupport;
inherit (config.system.outputs) kernel;
};
in {
# from OEM bootlog (openwrt wiki):
+25 -15
View File
@@ -182,12 +182,10 @@
kernel = {
src = pkgs.pkgsBuildBuild.fetchurl {
name = "linux.tar.gz";
url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz";
hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ=";
url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.7.4.tar.gz";
hash = "sha256-wIrmL0BS63nRwWfm4nw+dRNVPUzGh9M4X7LaHzAn5tU=";
};
extraPatchPhase = ''
${pkgs.openwrt.applyPatches.mvebu}
'';
version = "6.7.4";
config = {
PCI = "y";
OF = "y";
@@ -203,6 +201,10 @@
RTC_CLASS = "y";
RTC_DRV_ARMADA38X = "y"; # this may be useful anyway?
EXPERT = "y";
ALLOW_DEV_COREDUMP = "n";
# dts has a compatible for this but dmesg is not
# showing it
EEPROM_AT24 = "y"; # atmel,24c64
@@ -213,9 +215,9 @@
MACH_ARMADA_38X = "y";
SMP = "y";
# this is disabled for the moment because it relies on a GCC
# plugin that requires gmp.h to build, and I can't see right now
# how to confgure it to find gmp
# this is disabled for the moment because it relies on a
# GCC plugin that requires gmp.h to build, and I can't see
# right now how to confgure it to find gmp
STACKPROTECTOR_PER_TASK = "n";
NR_CPUS = "4";
VFP = "y";
@@ -227,7 +229,7 @@
PSTORE = "y";
PSTORE_RAM = "y";
PSTORE_CONSOLE = "y";
PSTORE_DEFLATE_COMPRESS = "n";
# PSTORE_DEFLATE_COMPRESS = "n";
BLOCK = "y";
MMC="y";
@@ -286,9 +288,17 @@
USB_XHCI_MVEBU = "y";
USB_XHCI_HCD = "y";
};
WLAN = {
WLAN_VENDOR_ATH = "y";
ATH_COMMON = "m";
ATH9K = "m";
ATH9K_PCI = "y";
ATH10K = "m";
ATH10K_PCI = "m";
ATH10K_DEBUG = "y";
};
};
};
boot = {
commandLine = [
"console=ttyS0,115200"
@@ -328,9 +338,9 @@
};
hardware = let
mac80211 = pkgs.mac80211.override {
drivers = ["ath9k_pci" "ath10k_pci"];
klibBuild = config.system.outputs.kernel.modulesupport;
mac80211 = pkgs.kmodloader.override {
inherit (config.system.outputs) kernel;
targets = ["ath9k" "ath10k_pci"];
};
in {
defaultOutput = "mtdimage";
@@ -339,9 +349,9 @@
rootDevice = "/dev/mmcblk0p1";
dts = {
src = "${config.system.outputs.kernel.modulesupport}/arch/arm/boot/dts/armada-385-turris-omnia.dts";
src = "${config.system.outputs.kernel.modulesupport}/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts";
includes = [
"${config.system.outputs.kernel.modulesupport}/arch/arm/boot/dts/"
"${config.system.outputs.kernel.modulesupport}/arch/arm/boot/dts/marvell/"
];
};
flash.eraseBlockSize = 65536; # only used for tftpboot
+1 -1
View File
@@ -145,7 +145,7 @@ in rec {
};
users.root = {
passwd = lib.mkForce secrets.root_password;
passwd = lib.mkForce secrets.root.passwd;
# openssh.authorizedKeys.keys = [
# (builtins.readFile "/home/dan/.ssh/id_rsa.pub")
# ];
+6 -3
View File
@@ -107,6 +107,7 @@ in {
rules = [
(accept "udp dport 547") # dhcp, could restrict to daddr ff02::1:2
(accept "udp dport 53") # dns
(accept "tcp dport 22")
];
};
@@ -232,9 +233,11 @@ in {
type = "filter";
family = "ip";
rules = [
# this is where you put permitted incoming
# connections. Practically there's not a lot of use for this
# chain unless you have routable ipv4 addresses
# This is where you put permitted incoming connections. If
# you're using NAT and want to forward a port from outside to
# devices on the LAN, then you need a DNAT rule in nat-rx chain
# *and* to accept the packet in this chain (specifying the
# internal (RFC1918) address).
];
};
+1 -1
View File
@@ -131,6 +131,6 @@ in rec {
dependencies = [services.dhcpc];
};
users.root.passwd = lib.mkForce secrets.root_password;
users.root.passwd = lib.mkForce secrets.root.passwd;
defaultProfile.packages = with pkgs; [nftables strace tcpdump swconfig];
}
+4 -3
View File
@@ -1,5 +1,6 @@
rec {
{
wpa_passphrase = "you bring light in";
ssid = "liminix";
l2tp = {
name = "abcde@a.1";
password = "NotMyIspPassword";
@@ -10,9 +11,9 @@ rec {
openssh.authorizedKeys.keys = [
];
};
root_password = root.passwd;
lan = {
prefix = "10.8.0"; # "192.168.8";
prefix = "10.8.0";
};
}
+11 -5
View File
@@ -8,7 +8,10 @@
{ config, pkgs, lib, ... } :
let
secrets = import ./rotuer-secrets.nix;
secrets = {
domainName = "fake.liminix.org";
firewallRules = {};
} // (import ./rotuer-secrets.nix);
inherit (pkgs.liminix.services) oneshot longrun bundle;
inherit (pkgs) serviceFns;
svc = config.system.service;
@@ -55,7 +58,7 @@ in rec {
services.hostap = svc.hostapd.build {
interface = config.hardware.networkInterfaces.wlan;
params = {
ssid = "liminix";
ssid = secrets.ssid;
hw_mode="g";
channel = "2";
ieee80211n = 1;
@@ -65,7 +68,7 @@ in rec {
services.hostap5 = svc.hostapd.build {
interface = config.hardware.networkInterfaces.wlan5;
params = rec {
ssid = "liminix_5";
ssid = "${secrets.ssid}5";
hw_mode="a";
channel = 36;
ht_capab = "[HT40+]";
@@ -120,8 +123,8 @@ in rec {
# 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);
domain = "fake.liminix.org";
upstreams = [ "/${secrets.domainName}/" ];
domain = secrets.domainName;
};
services.wan = svc.pppoe.build {
@@ -194,6 +197,9 @@ in rec {
defaultProfile.packages = with pkgs; [
min-collect-garbage
nftables
strace
tcpdump
];
programs.busybox.applets = [
+1 -1
View File
@@ -16,7 +16,7 @@
./hostname.nix
./outputs/initramfs.nix
./outputs/jffs2.nix
./kernel.nix
./kernel
./outputs/kexecboot.nix
./mount
./network
+1 -1
View File
@@ -13,7 +13,7 @@ let
in {
imports = [
./kernel.nix # kernel is a separate module for doc purposes
./kernel # kernel is a separate module for doc purposes
];
options = {
defaultProfile = {
+10 -1
View File
@@ -14,9 +14,18 @@
(fn update-prefixes [device prefixes new-prefixes]
(let [(added deleted) (changes prefixes new-prefixes)]
;; if some address has changed (e.g. preferred/valid lifetime)
;; then we don't want to delete it before re-adding it because
;; the kernel will drop any routes that go through it. On the
;; other hand, we can't add it _before_ deleting it as we'll
;; get an error that it already exists. Therefore, use "change"
;; instead of "add", it works a bit more like an upsert
(each [_ p (ipairs added)]
(system
(.. "ip address add " p.address "1/" p.len " dev " device)))
(.. "ip address change " p.address "1/" p.len " dev " device
" valid_lft " p.valid
" preferred_lft " p.preferred
)))
(each [_ p (ipairs deleted)]
(system
(.. "ip address del " p.address "1/" p.len " dev " device)))))
+6 -1
View File
@@ -17,9 +17,14 @@
(fn update-addresses [wan-device addresses new-addresses]
(let [(added deleted) (changes addresses new-addresses)]
;; see comment in acquire-delegated-prefix.fnl
(each [_ p (ipairs added)]
(system
(.. "ip address add " p.address "/" p.len " dev " wan-device)))
(.. "ip address change " p.address "/" p.len
" dev " wan-device
" valid_lft " p.valid
" preferred_lft " p.preferred
)))
(each [_ p (ipairs deleted)]
(system
(.. "ip address del " p.address "/" p.len " dev " wan-device)))
+1 -1
View File
@@ -11,6 +11,6 @@ let
script = callPackage ./acquire-wan-address.nix { };
in longrun {
inherit name;
run = "${script} /run/service-state/${client.name} $(output ${interface} ifname)";
run = "${script} $SERVICE_OUTPUTS/${client.name} $(output ${interface} ifname)";
dependencies = [ client interface ];
}
+1 -1
View File
@@ -13,7 +13,7 @@ in longrun {
inherit name;
notification-fd = 10;
run = ''
export SERVICE_STATE=/run/service-state/${name}
export SERVICE_STATE=$SERVICE_OUTPUTS/${name}
${odhcp6c}/bin/odhcp6c -s ${odhcp-script} -e -v -p /run/${name}.pid -P0 $(output ${interface} ifname)
)
'';
+1 -1
View File
@@ -11,6 +11,6 @@ let
script = callPackage ./acquire-delegated-prefix.nix { };
in longrun {
inherit name;
run = "${script} /run/service-state/${client.name} $(output ${interface} ifname)";
run = "${script} $SERVICE_OUTPUTS/${client.name} $(output ${interface} ifname)";
dependencies = [ client interface ];
}
+1 -1
View File
@@ -44,7 +44,7 @@ longrun {
--log-debug \
--log-queries \
--log-facility=- \
--dhcp-leasefile=/run/${name}.leases \
--dhcp-leasefile=$(mkstate ${name})/leases \
--pid-file=/run/${name}.pid
'';
}
+34 -47
View File
@@ -10,45 +10,8 @@ let
inherit (pkgs) liminix;
inherit (pkgs.liminix.services) oneshot;
kconf = isModule :
# setting isModule false is utterly untested and mostly
# unimplemented: I say this to preempt any "how on earth is this
# even supposed to work?" questions
let yes = if isModule then "m" else "y";
in {
NETFILTER = "y";
NETFILTER_ADVANCED = "y";
NETFILTER_NETLINK = yes;
NF_CONNTRACK = yes;
IP6_NF_IPTABLES= yes;
IP_NF_IPTABLES = yes;
IP_NF_NAT = yes;
IP_NF_TARGET_MASQUERADE = yes;
NFT_CT = yes;
NFT_FIB_IPV4 = yes;
NFT_FIB_IPV6 = yes;
NFT_LOG = yes;
NFT_MASQ = yes;
NFT_NAT = yes;
NFT_REJECT = yes;
NFT_REJECT_INET = yes;
NF_CT_PROTO_DCCP = "y";
NF_CT_PROTO_SCTP = "y";
NF_CT_PROTO_UDPLITE = "y";
NF_LOG_SYSLOG = yes;
NF_NAT = yes;
NF_NAT_MASQUERADE = "y";
NF_TABLES = yes;
NF_TABLES_INET = "y";
NF_TABLES_IPV4 = "y";
NF_TABLES_IPV6 = "y";
};
kmodules = pkgs.kernel-modules.override {
kernelSrc = config.system.outputs.kernel.src;
modulesupport = config.system.outputs.kernel.modulesupport;
kmodules = pkgs.kmodloader.override {
inherit (config.system.outputs) kernel;
targets = [
"nft_fib_ipv4"
"nft_fib_ipv6"
@@ -82,12 +45,6 @@ let
"xt_nat"
"xt_tcpudp"
];
kconfig = kconf true;
};
loadModules = oneshot {
name = "firewall-modules";
up = "sh ${kmodules}/load.sh";
down = "sh ${kmodules}/unload.sh";
};
in
{
@@ -107,11 +64,41 @@ in
in svc // {
build = args :
let args' = args // {
dependencies = (args.dependencies or []) ++ [loadModules];
dependencies = (args.dependencies or []) ++ [kmodules];
};
in svc.build args' ;
};
kernel.config = kconf true;
kernel.config = {
NETFILTER = "y";
NETFILTER_ADVANCED = "y";
NETFILTER_NETLINK = "m";
NF_CONNTRACK = "m";
IP6_NF_IPTABLES= "m";
IP_NF_IPTABLES = "m";
IP_NF_NAT = "m";
IP_NF_TARGET_MASQUERADE = "m";
NFT_CT = "m";
NFT_FIB_IPV4 = "m";
NFT_FIB_IPV6 = "m";
NFT_LOG = "m";
NFT_MASQ = "m";
NFT_NAT = "m";
NFT_REJECT = "m";
NFT_REJECT_INET = "m";
NF_CT_PROTO_DCCP = "y";
NF_CT_PROTO_SCTP = "y";
NF_CT_PROTO_UDPLITE = "y";
NF_LOG_SYSLOG = "m";
NF_NAT = "m";
NF_NAT_MASQUERADE = "y";
NF_TABLES = "m";
NF_TABLES_INET = "y";
NF_TABLES_IPV4 = "y";
NF_TABLES_IPV6 = "y";
};
};
}
@@ -27,6 +27,7 @@ in {
options = {
kernel = {
src = mkOption { type = types.path; } ;
version = mkOption { type = types.str; default = "5.15.137";} ;
modular = mkOption {
type = types.bool;
default = true;
@@ -79,7 +80,7 @@ in {
config.kernel.conditionalConfig;
k = liminix.builders.kernel.override {
config = mergedConfig;
inherit (config.kernel) src extraPatchPhase;
inherit (config.kernel) version src extraPatchPhase;
targets = config.kernel.makeTargets;
};
in {
+47 -13
View File
@@ -7,6 +7,7 @@
let
inherit (lib) mkOption types concatStringsSep;
cfg = config.boot.tftp;
hw = config.hardware;
in {
imports = [ ../ramdisk.nix ];
options.boot.tftp = {
@@ -22,6 +23,10 @@ in {
type = types.bool;
default = false;
};
appendDTB = mkOption {
type = types.bool;
default = false;
};
};
options.system.outputs = {
tftpboot = mkOption {
@@ -62,32 +67,46 @@ in {
uimage = "bootm";
zimage = "bootz";
}; in choices.${cfg.kernelFormat};
cmdline = concatStringsSep " " config.boot.commandLine;
objcopy = "${pkgs.stdenv.cc.bintools.targetPrefix}objcopy";
stripAndZip = ''
${objcopy} -O binary -R .reginfo -R .notes -R .note -R .comment -R .mdebug -R .note.gnu.build-id -S vmlinux.elf vmlinux.bin
rm -f vmlinux.bin.lzma ; lzma -k -z vmlinux.bin
'';
in
pkgs.runCommand "tftpboot" { nativeBuildInputs = with pkgs.pkgsBuildBuild; [ lzma dtc ]; } ''
pkgs.runCommand "tftpboot" { nativeBuildInputs = with pkgs.pkgsBuildBuild; [ lzma dtc pkgs.stdenv.cc ubootTools ]; } ''
mkdir $out
cd $out
binsize() { local s=$(stat -L -c %s $1); echo $(($s + 0x1000 &(~0xfff))); }
binsize64k() { local s=$(stat -L -c %s $1); echo $(($s + 0x10000 &(~0xffff))); }
hex() { printf "0x%x" $1; }
rootfsStart=${toString cfg.loadAddress}
rootfsSize=$(binsize64k ${o.rootfs} )
rootfsSize=$(($rootfsSize + ${toString cfg.freeSpaceBytes} ))
dtbStart=$(($rootfsStart + $rootfsSize))
imageSize=$(binsize ${image})
ln -s ${o.manifest} manifest
ln -s ${image} image
ln -s ${o.kernel} vmlinux # handy for gdb
# if we are transferring kernel and dtb separately, the
# dtb has to precede the kernel in ram, because zimage
# decompression code will assume that any memory after the
# end of the kernel is free
dtbStart=$(($rootfsStart + $rootfsSize))
${if cfg.compressRoot
then ''
lzma -z9cv ${o.rootfs} > rootfs.lz
rootfsLzStart=$(($imageStart + $imageSize))
rootfsLzStart=$dtbStart
rootfsLzSize=$(binsize rootfs.lz)
dtbStart=$(($dtbStart + $rootfsLzSize))
''
else ''
ln -s ${o.rootfs} rootfs
''
else "ln -s ${o.rootfs} rootfs"
}
cat ${o.dtb} > dtb
address_cells=$(fdtget dtb / '#address-cells')
size_cells=$(fdtget dtb / '#size-cells')
@@ -101,26 +120,41 @@ in {
fdtput -p -t s dtb /reserved-memory/$node compatible phram
fdtput -p -t lx dtb /reserved-memory/$node reg $ac_prefix $(hex $rootfsStart) $sz_prefix $(hex $rootfsSize)
dtbSize=$(binsize ./dtb )
imageStart=$(($dtbStart + $dtbSize))
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"
# dtc -I dtb -O dts -o /dev/stdout dtb | grep -A10 chosen ; exit 1
dtbSize=$(binsize ./dtb )
${if cfg.appendDTB then ''
imageStart=$dtbStart
# re-package image with updated dtb
cat ${o.kernel} > vmlinux.elf
${objcopy} --update-section .appended_dtb=dtb vmlinux.elf
${stripAndZip}
# TODO don't hardcode mips, entryPoint, loadAddress, name
mkimage -A mips -O linux -T kernel -C lzma -a $(hex ${toString hw.loadAddress}) -e $(hex ${toString hw.entryPoint}) -n 'MIPS Liminix Linux' -d vmlinux.bin.lzma image
# dtc -I dtb -O dts -o /dev/stdout dtb | grep -A10 chosen ; exit 1
tftpcmd="tftpboot $(hex $imageStart) result/image "
bootcmd="bootm $(hex $imageStart)"
'' else ''
imageStart=$(($dtbStart + $dtbSize))
tftpcmd="tftpboot $(hex $imageStart) result/image; tftpboot $(hex $dtbStart) result/dtb "
ln -s ${image} image
bootcmd="${bootCommand} $(hex $imageStart) - $(hex $dtbStart)"
''}
cat > boot.scr << EOF
setenv serverip ${cfg.serverip}
setenv ipaddr ${cfg.ipaddr}
tftpboot $(hex $imageStart) result/image ; ${
${
if cfg.compressRoot
then "tftpboot $(hex $rootfsLzStart) result/rootfs.lz"
else "tftpboot $(hex $rootfsStart) result/rootfs"
}; tftpboot $(hex $dtbStart) result/dtb
}; $tftpcmd
${if cfg.compressRoot
then "lzmadec $(hex $rootfsLzStart) $(hex $rootfsStart); "
else ""
} ${bootCommand} $(hex $imageStart) - $(hex $dtbStart)
} $bootcmd
EOF
'';
+9 -2
View File
@@ -22,8 +22,15 @@ mount -t tmpfs none /tmp
mkdir /dev/pts
mount -t devpts none /dev/pts
mkdir -m 0751 /run/service-state
chgrp system /run/service-state
mkdir -m 0751 -p /run/services/outputs
chgrp system /run/services/outputs
if test -d /persist; then
mkdir -m 0751 -p /persist/services/state
(cd /run/services && ln -s ../../persist/services/state .)
else
mkdir -m 0751 -p /run/services/state
fi
### If your services are managed by s6-rc:
### (replace /run/service with your scandir)
+3 -6
View File
@@ -29,15 +29,12 @@ let
in
longrun {
name = "sshd";
# we need /run/dropbear to point to hostkey storage, as that
# pathname is hardcoded into the binary.
# env -i clears the environment so we don't pass anything weird to
# ssh sessions
run = ''
if test -d /persist; then
mkdir -p /persist/secrets/dropbear
ln -s /persist/secrets/dropbear /run
else
mkdir -p /run/dropbear
fi
ln -s $(mkstate dropbear) /run
. /etc/profile # sets PATH but do we need this? it's the same file as ashrc
exec env -i ENV=/etc/ashrc PATH=$PATH ${dropbear}/bin/dropbear ${concatStringsSep " " options}
'';
+8
View File
@@ -46,6 +46,14 @@ in {
CRYPTO_SHA1 = "y";
ENCRYPTED_KEYS = "y";
KEYS = "y";
WLAN = "y";
CFG80211 = "m";
MAC80211 = "m";
EXPERT = "y";
CFG80211_CERTIFICATION_ONUS = "y";
CFG80211_REQUIRE_SIGNED_REGDB = "n"; # depends on ONUS
CFG80211_CRDA_SUPPORT = "n";
};
};
};
+1 -1
View File
@@ -66,7 +66,7 @@ in {
ifwait = callPackage ./ifwait {};
initramfs-peek = callPackage ./initramfs-peek {};
kernel-backport = callPackage ./kernel-backport {};
kernel-modules = callPackage ./kernel-modules {};
kmodloader = callPackage ./kmodloader {};
levitate = callPackage ./levitate {};
libubootenv = callPackage ./libubootenv {};
linotify = callPackage ./linotify {};
-3
View File
@@ -1,3 +0,0 @@
# obj-m += net/ipv4/netfilter/nft_fib_ipv4.o
-50
View File
@@ -1,50 +0,0 @@
{
stdenv
, buildPackages
, kernelSrc ? null
, modulesupport ? null
, targets ? []
, kconfig ? {}
, openssl
, writeText
, lib
}:
let
writeConfig = import ../kernel/write-kconfig.nix { inherit lib writeText; };
arch = stdenv.hostPlatform.linuxArch;
in stdenv.mkDerivation {
name = "kernel-modules";
nativeBuildInputs = [buildPackages.stdenv.cc] ++
(with buildPackages.pkgs; [
bc bison flex
openssl
cpio
kmod
]);
CC = "${stdenv.cc.bintools.targetPrefix}gcc";
HOST_EXTRACFLAGS = with buildPackages.pkgs;
"-I${buildPackages.openssl.dev}/include -L${buildPackages.openssl.out}/lib";
CROSS_COMPILE = stdenv.cc.bintools.targetPrefix;
ARCH = arch;
KBUILD_BUILD_HOST = "liminix.builder";
buildPhase = ''
cat ${writeConfig "kconfig" kconfig} > .more-config
cat .more-config >> .config
make olddefconfig
for v in $(cat .more-config) ; do grep $v .config || (echo Missing $v && exit 1);done
make modules
'';
src = modulesupport;
installPhase = ''
mkdir -p $out/lib/modules/0.0
find . -name \*.ko | cpio --verbose --make-directories -p $out/lib/modules/0.0
depmod -b $out -v 0.0
touch $out/load.sh
for i in ${lib.concatStringsSep " " targets}; do
modprobe -S 0.0 -d $out --show-depends $i >> $out/load.sh
done
tac < $out/load.sh | sed 's/^insmod/rmmod/g' > $out/unload.sh
'';
}
+4 -4
View File
@@ -6,6 +6,7 @@
, config
, src
, version ? "0"
, extraPatchPhase ? "echo"
, targets ? ["vmlinux"]
} :
@@ -51,9 +52,9 @@ stdenv.mkDerivation rec {
patches = [
./cmdline-cookie.patch
./phram-allow-cached-mappings.patch
./mips-malta-fdt-from-bootloader.patch
];
] ++ lib.optional (lib.versionOlder version "5.18.0")
./phram-allow-cached-mappings.patch;
# this is here to work around what I think is a bug in nixpkgs
# packaging of ncurses: it installs pkg-config data files which
@@ -103,8 +104,7 @@ stdenv.mkDerivation rec {
mkdir -p $headers
cp -a include .config $headers/
mkdir -p $modulesupport
cp modules.* $modulesupport
make clean modules_prepare
make modules
cp -a . $modulesupport
'';
}
+41
View File
@@ -0,0 +1,41 @@
{
liminix
, lib
, targets ? []
, kernel ? null
, runCommand
, pkgsBuildBuild
} :
let
inherit (liminix.services) oneshot;
inherit (lib) concatStringsSep;
loader = runCommand "modules" {
nativeBuildInputs = with pkgsBuildBuild ;[
kmod cpio gawk
];
} ''
kernel=${kernel.modulesupport}
mkdir -p lib/modules/0.0
(cd $kernel && find . -name \*.ko | cpio --verbose --make-directories -p $NIX_BUILD_TOP/lib/modules/0.0)
cp $kernel/modules.* lib/modules/0.0
depmod -b . 0.0
(for i in ${lib.concatStringsSep " " targets}; do
modprobe -S 0.0 -d $NIX_BUILD_TOP --show-depends $i | sed "s,^insmod $NIX_BUILD_TOP/lib/modules/0.0/,,g"
done) | awk '!a[$0]++' > load-order
mkdir $out
for i in $(cat load-order); do
install -v $NIX_BUILD_TOP/lib/modules/0.0/$i -D $out/$i
done
echo "O=$out" > $out/load.sh
sed "s,^,insmod \$O/,g" < load-order >> $out/load.sh
echo "O=$out" > $out/unload.sh
tac load-order | sed "s,^,rmmod \$O/,g" > $out/unload.sh
'';
in oneshot {
name = "kmodloader-" + (concatStringsSep "-" targets);
up = "sh ${loader}/load.sh";
down = "sh ${loader}/unload.sh";
}
+1 -1
View File
@@ -15,6 +15,6 @@ for i in run notification-fd up down consumer-for producer-for pipeline-name ; d
test -n "$(printenv $i)" && (echo "$(printenv $i)" > $out/${name}/$i)
done
( cd $out && ln -s /run/service-state/${name} ./.outputs )
( cd $out && ln -s /run/services/outputs/${name} ./.outputs )
for i in $out/${name}/{down,up,run} ; do test -f $i && chmod +x $i; done
true
+1 -1
View File
@@ -9,7 +9,7 @@
}:
let
inherit (builtins) concatStringsSep;
prefix = "/run/service-state";
prefix = "/run/services/outputs";
output = service: name: "${prefix}/${service.name}/${name}";
serviceScript = commands : ''
#!/bin/sh
+5 -1
View File
@@ -20,7 +20,11 @@
out))
(let [(address len preferred valid extra)
(string.match str "(.-)/(%d+),(%d+),(%d+)(.*)$")]
(merge {: address : len : preferred : valid} (parse-extra extra))))
(merge {: address : len
:preferred (or preferred "forever")
:valid (or valid "forever")
}
(parse-extra extra))))
(fn write-addresses [prefix addresses]
(each [_ a (ipairs (split " " addresses))]
+8 -1
View File
@@ -2,8 +2,15 @@
writeText "service-fns.sh" ''
output() { cat $1/.outputs/$2; }
output_path() { echo $(realpath $1/.outputs)/$2; }
SERVICE_OUTPUTS=/run/services/outputs
SERVICE_STATE=/run/services/state
mkoutputs() {
d=/run/service-state/$1
d=$SERVICE_OUTPUTS/$1
mkdir -m 2751 -p $d && chown root:system $d
echo $d
}
mkstate() {
d=$SERVICE_STATE/$1
mkdir -m 2751 -p $d && chown root:system $d
echo $d
}
+4 -1
View File
@@ -12,7 +12,7 @@ let derivation = (import liminix {
img = derivation.outputs.tftpboot;
uboot = derivation.outputs.u-boot;
pkgsBuild = derivation.pkgs.pkgsBuildBuild;
in pkgsBuild.runCommand "check" {
in pkgsBuild.runCommand "check-${deviceName}" {
nativeBuildInputs = with pkgsBuild; [
expect
socat
@@ -44,4 +44,7 @@ in {
mipsLz = check "qemu" {
boot.tftp.compressRoot = true;
};
mipsOldUboot = check "qemu" {
boot.tftp.appendDTB = true;
};
}