1
0
forked from dan/liminix

Compare commits

..

10 Commits

Author SHA1 Message Date
dan 3792ec1f39 allow lan dns queries (ipv6) 2024-02-11 23:31:15 +00:00
dan f71e8d5710 rotuer: network debugging tools 2024-02-11 23:30:46 +00:00
dan d3bde4533b rotuer: don't forward queries for local domain 2024-02-11 23:30:12 +00:00
dan 0e941a8686 deep thoughts 2024-02-11 15:46:18 +00:00
dan f023f7a0de deep thoughts 2024-02-11 15:46:18 +00:00
dan 6c61d88a3a deep thoughts 2024-02-11 15:46:18 +00:00
dan bbce605a14 WIP-but-works: mainline kernel for Turris Omnia 2024-02-11 15:46:18 +00:00
dan e6705c4d06 rotuer: make domainName configurable 2024-02-11 15:40:28 +00:00
dan 6684d34a43 add wifi ssid to secrets 2024-02-11 15:40:17 +00:00
dan a8c6d5d8a4 remove root_password secret, is dup of root.passwd 2024-02-11 15:40:11 +00:00
37 changed files with 331 additions and 575 deletions
-47
View File
@@ -31,52 +31,5 @@ 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. This may be a regression on some devices that depend on
OpenWrt patches for wireless functionality: if you have a device that
used to work and now doesn't, refer to OpenWrt
package/kernel/mac80211/patches/ to see if there's something in there
that needs to be applied.
* 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.
2024-02-16
New (or at least, previously unreported) port! Liminix now runs on the
Turris Omnia and has been serving my family's internet needs for most
of this week. Thanks to NGI0 Entrust and the NLnet Foundation for
sponsoring this development (and funding the hardware)
+30 -128
View File
@@ -3953,6 +3953,31 @@ 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 12:41:12 GMT 2024
s6-linux-init version 1.1.2.0
nfnetlink: module verification failed: signature and/or required key missing - tainting kernel
------------[ cut here ]------------
kernel BUG at net/wireless/core.h:125!
Internal error: Oops - BUG: 0 [#1] SMP ARM
Modules linked in: cfg80211(E+) nfnetlink(E)
CPU: 0 PID: 197 Comm: insmod Tainted: G E 6.7.4 #1
Hardware name: Marvell Armada 380/385 (Device Tree)
PC is at cfg80211_netdev_notifier_call+0x2cc/0x3e0 [cfg80211]
LR is at call_netdevice_register_net_notifiers+0x4c/0xec
pc : [<bf010024>] lr : [<c0672e30>] psr: 60000013
sp : f0ba5c10 ip : fffffffb fp : c328df00
r10: c15c4170 r9 : c328df00 r8 : 00000000
r7 : 00000000 r6 : bf04c620 r5 : c10c9000 r4 : c11ff414
r3 : 00000000 r2 : f0ba5df4 r1 : 00000005 r0 : bf04c620
Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
Control: 10c5387d Table: 0320804a DAC: 00000051
R
cfg80211_netdev_notifier_call [cfg80211] from call_netdevice_register_net_notifiers+0x4c/0xec
setenv omnia_reset 1; run bootcmd_rescue
Sat Feb 10 18:23:54 GMT 2024
ARGH KERNEL
@@ -3976,138 +4001,15 @@ 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,
- support kernel version as parameter to builder pkgs/kernel/default.nix
- 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
- wlan module to take 'backported' as a parameter
half of the omnia conditionalConfig can go into the module
- [done] upgrade omnia to kernel v6
- 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?
- turn rotuer,extneder examples into "profiles" that don't embed
hardware specifics
Thu Feb 15 11:50:56 GMT 2024
1) to make tftpboot work with old bootm implementations we need
- compressed root
- uncompressed root
- kernel with dtb
dtb needs to know where uncompressed rootfs is and how big
2) if the image is a zImage (arm32) or an Image (arm64) we have to stick
with the three-arg bootz, and the dtb has to be lower in ram than the kernel
Fri Feb 16 15:43:32 GMT 2024
DHCP6c refresh is still wrong. We get updates for an address that
hasn't changed prefix or length, when the expiry times have changed,
and we can't action that by remove;add because remove will wipe out
any routes through the interface but add won't put them back
We can use "change" for both adds and changes, but we need to know that
a change is not a delete
The "identity" of an address is the address itself: kernel won't
let you add the same address with two different prefixes.
Keeping it simple, we could call "change" on every address in the
new-addresses list and "del" on every address in old-addresses
that is no longer in new-addresses
If the upstream has changed length, "ip addr change" is ignored,
so it needs to be in deleted as well as added/changed
- forward some port to loaclhost 22 for inbound ipv4 ssh
+6 -10
View File
@@ -149,13 +149,6 @@
WATCHDOG = "y";
MEDIATEK_WATCHDOG = "y";
};
conditionalConfig = {
WLAN= {
MT7615E = "m";
MT7622_WMAC = "y";
MT7915E = "m";
};
};
};
boot = {
commandLine = [ "console=ttyS0,115200" ];
@@ -176,9 +169,12 @@
hardware =
let
openwrt = pkgs.openwrt;
mac80211 = pkgs.kmodloader.override {
targets = ["mt7615e" "mt7915e"];
inherit (config.system.outputs) kernel;
mac80211 = pkgs.mac80211.override {
drivers = [
"mt7615e"
"mt7915e"
];
klibBuild = config.system.outputs.kernel.modulesupport;
};
in {
ubi = {
+8 -18
View File
@@ -71,10 +71,9 @@
cp $blobdir/board.bin $out/ath10k/QCA9887/hw1.0/
'';
};
mac80211 = pkgs.kmodloader.override {
targets = ["ath9k" "ath10k_pci"];
inherit (config.system.outputs) kernel;
dependencies = [ ath10k_cal_data ];
mac80211 = pkgs.mac80211.override {
drivers = ["ath9k" "ath10k_pci"];
klibBuild = config.system.outputs.kernel.modulesupport;
};
ath10k_cal_data =
let
@@ -133,7 +132,7 @@
};
wlan5 = link.build {
ifname = "wlan1";
dependencies = [ ath10k_cal_data mac80211 ];
dependencies = [ mac80211 ath10k_cal_data ];
};
};
};
@@ -162,8 +161,6 @@
# OpenWrt kernel patches
extraPatchPhase = ''
${openwrt.applyPatches.ath79}
sed -i.bak -e '\,include <linux/hw_random.h>,a #include <linux/gpio/driver.h>' drivers/net/wireless/ath/ath9k/ath9k.h # context reqd for next patch
patch -p1 < ${openwrt.src}/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch
'';
config = {
@@ -214,21 +211,14 @@
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";
};
};
};
};
}
+3 -11
View File
@@ -47,9 +47,9 @@
let
inherit (pkgs.liminix.networking) interface;
inherit (pkgs) openwrt;
mac80211 = pkgs.kmodloader.override {
targets = ["rt2800soc"];
inherit (config.system.outputs) kernel;
mac80211 = pkgs.mac80211.override {
drivers = ["rt2800soc"];
klibBuild = config.system.outputs.kernel.modulesupport;
};
in {
imports = [
@@ -178,14 +178,6 @@
} // lib.optionalAttrs (config.system.service ? vlan) {
SWCONFIG = "y";
};
conditionalConfig = {
WLAN = {
WLAN_VENDOR_RALINK = "y";
RT2800SOC = "m";
RT2X00 = "m";
};
};
};
};
}
+3 -12
View File
@@ -43,9 +43,9 @@
inherit (pkgs.pseudofile) dir symlink;
inherit (pkgs) openwrt;
mac80211 = pkgs.kmodloader.override {
targets = ["mt7603e"];
inherit (config.system.outputs) kernel;
mac80211 = pkgs.mac80211.override {
drivers = ["mt7603e"];
klibBuild = config.system.outputs.kernel.modulesupport;
};
wlan_firmware = pkgs.fetchurl {
url = "https://github.com/openwrt/mt76/raw/f24b56f935392ca1d35fae5fd6e56ef9deda4aad/firmware/mt7628_e2.bin";
@@ -185,15 +185,6 @@
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";
};
};
};
};
}
+6 -11
View File
@@ -322,14 +322,9 @@
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
};
conditionalConfig = {
WLAN = {
MT7915E = "m";
};
};
RALINK_WDT = "y"; # watchdog
MT7621_WDT = "y"; # or it might be this one
};
};
tplink-safeloader.board = "ARCHER-AX23-V1";
boot = {
@@ -358,11 +353,11 @@
hardware =
let
openwrt = pkgs.openwrt;
mac80211 = pkgs.kmodloader.override {
targets = [
mac80211 = pkgs.mac80211.override {
drivers = [
"mt7915e"
];
inherit (config.system.outputs) kernel;
klibBuild = config.system.outputs.kernel.modulesupport;
};
in {
# from OEM bootlog (openwrt wiki):
+43 -4
View File
@@ -289,6 +289,14 @@
USB_XHCI_HCD = "y";
};
WLAN = {
CFG80211 = "m";
MAC80211 = "m";
CFG80211_CERTIFICATION_ONUS = "y";
CFG80211_REQUIRE_SIGNED_REGDB = "n"; # depends on ONUS
CFG80211_CRDA_SUPPORT = "n";
WLAN_VENDOR_ATH = "y";
ATH_COMMON = "m";
ATH9K = "m";
@@ -338,10 +346,41 @@
};
hardware = let
mac80211 = pkgs.kmodloader.override {
inherit (config.system.outputs) kernel;
targets = ["ath9k" "ath10k_pci"];
};
mac80211 =
let
targets = [
"ath9k"
"ath10k_pci"
];
kmodules = pkgs.runCommand "modules" {
nativeBuildInputs = with pkgs.pkgsBuildBuild ;[
kmod cpio gawk
];
} ''
kernel=${config.system.outputs.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 = "mac80211-modules";
up = "sh ${kmodules}/load.sh";
down = "sh ${kmodules}/unload.sh";
};
in {
defaultOutput = "mtdimage";
loadAddress = lim.parseInt "0x00800000"; # "0x00008000";
+3 -5
View File
@@ -233,11 +233,9 @@ in {
type = "filter";
family = "ip";
rules = [
# 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).
# 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
];
};
+6 -10
View File
@@ -26,6 +26,7 @@ let
wmm_enabled = 1;
};
in rec {
boot = {
tftp = {
@@ -87,7 +88,8 @@ in rec {
services.bridge = svc.bridge.members.build {
primary = services.int;
members = with config.hardware.networkInterfaces;
[ wlan
[
wlan
wlan5
lan0
lan1
@@ -200,15 +202,9 @@ in rec {
nftables
strace
tcpdump
s6
];
programs.busybox = {
applets = [
"fdisk" "sfdisk"
];
options = {
FEATURE_FANCY_TAIL = "y";
};
};
programs.busybox.applets = [
"fdisk" "sfdisk"
];
}
+1 -1
View File
@@ -16,7 +16,7 @@
./hostname.nix
./outputs/initramfs.nix
./outputs/jffs2.nix
./kernel
./kernel.nix
./outputs/kexecboot.nix
./mount
./network
+1 -1
View File
@@ -13,7 +13,7 @@ let
in {
imports = [
./kernel # kernel is a separate module for doc purposes
./kernel.nix # kernel is a separate module for doc purposes
];
options = {
defaultProfile = {
+18 -19
View File
@@ -1,32 +1,31 @@
(local { : system } (require :anoia))
(local svc (require :anoia.svc))
(fn deletions [old-addresses new-addresses]
(let [deleted {}]
(fn changes [old-addresses new-addresses]
(let [added {}
deleted {}]
(each [n address (pairs new-addresses)]
(if (not (. old-addresses n))
(table.insert added address)))
(each [n address (pairs old-addresses)]
(let [now (. new-addresses n)]
(if (or (not now) (not (= now.len address.len)))
(table.insert deleted address))))
deleted))
(if (not (. new-addresses n))
(table.insert deleted address)))
(values added deleted)))
(fn update-prefixes [wan-device addresses new-addresses exec]
(each [_ p (ipairs (deletions addresses new-addresses))]
(exec
(.. "ip address del " p.address "1/" p.len " dev " wan-device)))
(each [_ p (pairs new-addresses)]
(exec
(.. "ip address change " p.address "1/" p.len
" dev " wan-device
" valid_lft " p.valid
" preferred_lft " p.preferred
)))
new-addresses)
(fn update-prefixes [device prefixes new-prefixes]
(let [(added deleted) (changes prefixes new-prefixes)]
(each [_ p (ipairs added)]
(system
(.. "ip address add " p.address "1/" p.len " dev " device)))
(each [_ p (ipairs deleted)]
(system
(.. "ip address del " p.address "1/" p.len " dev " device)))))
(fn run []
(let [[state-directory lan-device] arg
dir (svc.open state-directory)]
(accumulate [addresses []
v (dir:events)]
(update-prefixes lan-device addresses (v:output "prefix") system))))
(update-prefixes lan-device addresses (v:output "prefix")))))
{ : changes : run }
+30 -98
View File
@@ -5,45 +5,23 @@
(local a1
{
"2001-ab-cd-ef" {
:address "2001:ab:cd:ef"
:len "64"
:preferred "3600"
:valid "7200"
}
}
)
(local a156
{
"2001-ab-cd-ef" {
:address "2001:ab:cd:ef"
:len "56"
:preferred "3600"
:valid "7200"
}
"2001-ab-cd-ef_hjgKHGhKJH" {
:address "2001:ab:cd:ef"
:len "64"
:preferred "200"
:valid "200"
}
}
)
(local a2
{
"2001-0-1-2-3" {
:address "2001:0:1:2:3"
:len "64"
:preferred "3600"
:valid "7200"
}
}
)
(local a21
{
"2001-0-1-2-3" {
:address "2001:0:1:2:3"
:len "64"
:preferred "1800"
:valid "5400"
}
"2001-0-1-2-3_aNteBnb" {
:address "2001:0:1:2:3"
:len "64"
:preferred "200"
:valid "200"
}
}
)
@@ -52,85 +30,39 @@
`(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 []
(let [deleted
(subject.deletions
(let [(add del)
(subject.changes
{ }
a1
)]
(expect= deleted [])))
(expect (= (# del) 0))
(expect (= (# add) 1))
(let [[first] add]
(expect (= first.address "2001:ab:cd:ef")))))
(fn second-address []
(let [del
(subject.deletions
(let [(add del)
(subject.changes
a1
(merge (dup a1) a2)
)]
(expect= del [])))
(expect (= (# del) 0))
(expect (= (# add) 1))
(let [[first] add] (expect (= first.address "2001:0:1:2:3")))))
(fn old-address-is-deleted []
(let [del
(subject.deletions
(fn less-address []1
(let [(add del)
(subject.changes
(merge (dup a1) a2)
a1
)]
(expect= (. del 1) (. a2 "2001-0-1-2-3"))
))
(expect (= (# add) 0))
(expect (= (# del) 1))
(fn changed-lifetime-not-deleted []
(let [del
(subject.deletions
(merge (dup a1) a2)
(merge (dup a1) a21)
)]
;; when an address lifetime changes, "ip address change"
;; will update that so it need not (should not) be deleted
(expect= del [])))
(let [[first] del] (expect (= first.address "2001:0:1:2:3")))))
(fn changed-prefix-is-deleted []
(let [del
(subject.deletions a1 a156)]
;; when an address prefix changes, "ip address change"
;; ignores that cjhange, so we have to remove the
;; address before reinstating it
(expect= del [(. a1 "2001-ab-cd-ef")])))
(first-address)
(second-address)
(old-address-is-deleted)
(changed-lifetime-not-deleted)
(changed-prefix-is-deleted)
(let [cmds []]
(subject.update-addresses
"ppp0" a1 (merge (dup a1) a2)
(fn [a] (table.insert cmds a)))
(expect=
(doto cmds table.sort)
[
;; order of changes is unimportant
"ip address change 2001:0:1:2:3/64 dev ppp0 valid_lft 7200 preferred_lft 3600"
"ip address change 2001:ab:cd:ef/64 dev ppp0 valid_lft 7200 preferred_lft 3600"
]))
(let [cmds []]
(subject.update-addresses
"ppp0" (merge (dup a1) a2) a1
(fn [a] (table.insert cmds a)))
(expect=
cmds
[
;; deletes are executed before changes
"ip address del 2001:0:1:2:3/64 dev ppp0"
"ip address change 2001:ab:cd:ef/64 dev ppp0 valid_lft 7200 preferred_lft 3600"
]))
(print "OK")
(less-address)
+24 -21
View File
@@ -1,32 +1,35 @@
(local { : system } (require :anoia))
(local svc (require :anoia.svc))
(fn deletions [old-addresses new-addresses]
(let [deleted {}]
(each [n address (pairs old-addresses)]
(let [now (. new-addresses n)]
(if (or (not now) (not (= now.len address.len)))
(table.insert deleted address))))
deleted))
;; acquire-delegated-prefix has very similar code: we'd like to move
;; this to anoia.svc when we see what the general form would look like
(fn update-addresses [wan-device addresses new-addresses exec]
(each [_ p (ipairs (deletions addresses new-addresses))]
(exec
(.. "ip address del " p.address "/" p.len " dev " wan-device)))
(each [_ p (pairs new-addresses)]
(exec
(.. "ip address change " p.address "/" p.len
" dev " wan-device
" valid_lft " p.valid
" preferred_lft " p.preferred
)))
new-addresses)
(fn changes [old-addresses new-addresses]
(let [added {}
deleted {}]
(each [n address (pairs new-addresses)]
(if (not (. old-addresses n))
(table.insert added address)))
(each [n address (pairs old-addresses)]
(if (not (. new-addresses n))
(table.insert deleted address)))
(values added deleted)))
(fn update-addresses [wan-device addresses new-addresses]
(let [(added deleted) (changes addresses new-addresses)]
(each [_ p (ipairs added)]
(system
(.. "ip address add " p.address "/" p.len " dev " wan-device)))
(each [_ p (ipairs deleted)]
(system
(.. "ip address del " p.address "/" p.len " dev " wan-device)))
new-addresses))
(fn run []
(let [[state-directory wan-device] arg
dir (svc.open state-directory)]
(accumulate [addresses []
v (dir:events)]
(update-addresses wan-device addresses (v:output "address") system))))
(update-addresses wan-device addresses (v:output "address")))))
{ : update-addresses : deletions : run }
{ : update-addresses : changes : run }
+1 -1
View File
@@ -11,6 +11,6 @@ let
script = callPackage ./acquire-wan-address.nix { };
in longrun {
inherit name;
run = "${script} $SERVICE_OUTPUTS/${client.name} $(output ${interface} ifname)";
run = "${script} /run/service-state/${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=$SERVICE_OUTPUTS/${name}
export SERVICE_STATE=/run/service-state/${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} $SERVICE_OUTPUTS/${client.name} $(output ${interface} ifname)";
run = "${script} /run/service-state/${client.name} $(output ${interface} ifname)";
dependencies = [ client interface ];
}
+3 -4
View File
@@ -41,11 +41,10 @@ longrun {
--no-hosts \
--log-dhcp \
--enable-ra \
--log-debug \
--log-queries \
--log-facility=- \
--dhcp-leasefile=$(mkstate ${name})/leases \
--dhcp-leasefile=/run/${name}.leases \
--pid-file=/run/${name}.pid
'';
# --log-debug \
# --log-queries \
}
+47 -34
View File
@@ -10,8 +10,45 @@ let
inherit (pkgs) liminix;
inherit (pkgs.liminix.services) oneshot;
kmodules = pkgs.kmodloader.override {
inherit (config.system.outputs) kernel;
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;
targets = [
"nft_fib_ipv4"
"nft_fib_ipv6"
@@ -45,6 +82,12 @@ let
"xt_nat"
"xt_tcpudp"
];
kconfig = kconf true;
};
loadModules = oneshot {
name = "firewall-modules";
up = "sh ${kmodules}/load.sh";
down = "sh ${kmodules}/unload.sh";
};
in
{
@@ -64,41 +107,11 @@ in
in svc // {
build = args :
let args' = args // {
dependencies = (args.dependencies or []) ++ [kmodules];
dependencies = (args.dependencies or []) ++ [loadModules];
};
in svc.build args' ;
};
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";
};
kernel.config = kconf true;
};
}
@@ -80,7 +80,8 @@ in {
config.kernel.conditionalConfig;
k = liminix.builders.kernel.override {
config = mergedConfig;
inherit (config.kernel) version src extraPatchPhase;
version = builtins.trace config.kernel.version config.kernel.version;
inherit (config.kernel) src extraPatchPhase;
targets = config.kernel.makeTargets;
};
in {
+13 -47
View File
@@ -7,8 +7,6 @@
let
inherit (lib) mkOption types concatStringsSep;
cfg = config.boot.tftp;
hw = config.hardware;
arch = pkgs.stdenv.hostPlatform.linuxArch;
in {
imports = [ ../ramdisk.nix ];
options.boot.tftp = {
@@ -24,10 +22,6 @@ in {
type = types.bool;
default = false;
};
appendDTB = mkOption {
type = types.bool;
default = false;
};
};
options.system.outputs = {
tftpboot = mkOption {
@@ -68,46 +62,32 @@ 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.stdenv.cc ubootTools ]; } ''
pkgs.runCommand "tftpboot" { nativeBuildInputs = with pkgs.pkgsBuildBuild; [ lzma dtc ]; } ''
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=$dtbStart
rootfsLzStart=$(($imageStart + $imageSize))
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')
@@ -121,40 +101,26 @@ 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"
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}
mkimage -A ${arch} -O linux -T kernel -C lzma -a $(hex ${toString hw.loadAddress}) -e $(hex ${toString hw.entryPoint}) -n '${lib.toUpper arch} Liminix Linux tftpboot' -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)"
''}
# dtc -I dtb -O dts -o /dev/stdout dtb | grep -A10 chosen ; exit 1
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"
}; $tftpcmd
}; tftpboot $(hex $dtbStart) result/dtb
${if cfg.compressRoot
then "lzmadec $(hex $rootfsLzStart) $(hex $rootfsStart); "
else ""
} $bootcmd
} ${bootCommand} $(hex $imageStart) - $(hex $dtbStart)
EOF
'';
+2 -9
View File
@@ -22,15 +22,8 @@ mount -t tmpfs none /tmp
mkdir /dev/pts
mount -t devpts none /dev/pts
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
mkdir -m 0751 /run/service-state
chgrp system /run/service-state
### If your services are managed by s6-rc:
### (replace /run/service with your scandir)
+6 -3
View File
@@ -29,12 +29,15 @@ 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 = ''
ln -s $(mkstate dropbear) /run
if test -d /persist; then
mkdir -p /persist/secrets/dropbear
ln -s /persist/secrets/dropbear /run
else
mkdir -p /run/dropbear
fi
. /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}
'';
+2 -6
View File
@@ -47,13 +47,9 @@ in {
ENCRYPTED_KEYS = "y";
KEYS = "y";
# see note in include/linux/netdevice.h re LL_MAX_HEADER
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
View File
@@ -104,7 +104,6 @@ extraPkgs // {
"CONFIG_DRIVER_NL80211=y"
"CONFIG_IAPP=y"
"CONFIG_IEEE80211AC=y"
"CONFIG_IEEE80211AX=y"
"CONFIG_IEEE80211N=y"
"CONFIG_IEEE80211W=y"
"CONFIG_INTERNAL_LIBTOMMATH=y"
+1 -1
View File
@@ -66,7 +66,7 @@ in {
ifwait = callPackage ./ifwait {};
initramfs-peek = callPackage ./initramfs-peek {};
kernel-backport = callPackage ./kernel-backport {};
kmodloader = callPackage ./kmodloader {};
kernel-modules = callPackage ./kernel-modules {};
levitate = callPackage ./levitate {};
libubootenv = callPackage ./libubootenv {};
linotify = callPackage ./linotify {};
+3
View File
@@ -0,0 +1,3 @@
# obj-m += net/ipv4/netfilter/nft_fib_ipv4.o
+50
View File
@@ -0,0 +1,50 @@
{
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 -2
View File
@@ -6,7 +6,7 @@
, config
, src
, version ? "0"
, version ? "1"
, extraPatchPhase ? "echo"
, targets ? ["vmlinux"]
} :
@@ -24,6 +24,7 @@ stdenv.mkDerivation rec {
(with buildPackages.pkgs; [
rsync bc bison flex pkg-config
openssl ncurses.all perl
cpio
]);
CC = "${stdenv.cc.bintools.targetPrefix}gcc";
HOSTCC = with buildPackages.pkgs;
@@ -53,7 +54,7 @@ stdenv.mkDerivation rec {
patches = [
./cmdline-cookie.patch
./mips-malta-fdt-from-bootloader.patch
] ++ lib.optional (lib.versionOlder version "5.18.0")
] ++ lib.optional (lib.versionOlder version "6.0")
./phram-allow-cached-mappings.patch;
# this is here to work around what I think is a bug in nixpkgs
@@ -104,6 +105,7 @@ stdenv.mkDerivation rec {
mkdir -p $headers
cp -a include .config $headers/
mkdir -p $modulesupport
cp modules.* vmlinux.o $modulesupport
make modules
cp -a . $modulesupport
'';
-43
View File
@@ -1,43 +0,0 @@
{
liminix
, lib
, targets ? []
, kernel ? null
, runCommand
, pkgsBuildBuild
, dependencies ? []
} :
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";
inherit dependencies;
}
+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/services/outputs/${name} ./.outputs )
( cd $out && ln -s /run/service-state/${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/services/outputs";
prefix = "/run/service-state";
output = service: name: "${prefix}/${service.name}/${name}";
serviceScript = commands : ''
#!/bin/sh
+1 -1
View File
@@ -20,7 +20,7 @@ if toplevel=$(nix-build "$@" -A outputs.systemConfiguration --no-out-link); then
echo systemConfiguration $toplevel
min-copy-closure $target_host $toplevel
$ssh_command $target_host $toplevel/bin/install
$ssh_command $target_host "sync; source /etc/profile; reboot -f"
$ssh_command $target_host "sync; source /etc/profile; reboot"
else
echo Rebuild failed
fi
+8 -6
View File
@@ -20,21 +20,23 @@
out))
(let [(address len preferred valid extra)
(string.match str "(.-)/(%d+),(%d+),(%d+)(.*)$")]
(merge {: address : len
:preferred (or preferred "forever")
:valid (or valid "forever")
}
(parse-extra extra))))
(merge {: address : len : preferred : valid} (parse-extra extra))))
(fn write-addresses [prefix addresses]
(each [_ a (ipairs (split " " addresses))]
(let [address (parse-address a)
suffix (base64url (string.pack "n" (hash a)))
;; keydir should be a function of all the address
;; attributes: we want it to change whenever anything changes
;; so that clients can see which addresses are new without
;; deep table comparisons
keydir (..
prefix
(-> address.address
(: :gsub "::$" "")
(: :gsub ":" "-")))]
(: :gsub ":" "-"))
"_"
suffix)]
(mktree (.. state-directory "/" keydir))
(each [k v (pairs address)]
(write-value (.. keydir "/" k) v)))))
+1 -8
View File
@@ -2,15 +2,8 @@
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=$SERVICE_OUTPUTS/$1
mkdir -m 2751 -p $d && chown root:system $d
echo $d
}
mkstate() {
d=$SERVICE_STATE/$1
d=/run/service-state/$1
mkdir -m 2751 -p $d && chown root:system $d
echo $d
}
+1 -8
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-${deviceName}" {
in pkgsBuild.runCommand "check" {
nativeBuildInputs = with pkgsBuild; [
expect
socat
@@ -44,11 +44,4 @@ in {
mipsLz = check "qemu" {
boot.tftp.compressRoot = true;
};
# this works on real hardware but I haven't figured out how
# to make it work on qemu: it says
# "OF: fdt: No chosen node found, continuing without"
# mipsOldUboot = check "qemu" {
# boot.tftp.appendDTB = true;
# };
}