this is the dhcp6c service we want

This commit is contained in:
Daniel Barlow 2023-09-24 23:29:30 +01:00
parent 1673a71831
commit c59a228955
11 changed files with 163 additions and 60 deletions

View file

@ -1,31 +0,0 @@
(local { : system } (require :anoia))
(local svc (require :anoia.svc))
(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-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")))))
{ : changes : run }

View file

@ -1,10 +0,0 @@
{
writeFennel
, linotify
, anoia
, lua
}:
writeFennel "acquire-delegated-prefix" {
packages = [ linotify anoia lua.pkgs.luafilesystem ];
mainFunction = "run";
} ./acquire-delegated-prefix.fnl

View file

@ -1,68 +0,0 @@
(local subject (require :acquire-wan-address))
(local { : view } (require :fennel))
(local { : merge : dup } (require :anoia))
(local a1
{
"2001-ab-cd-ef_hjgKHGhKJH" {
:address "2001:ab:cd:ef"
:len "64"
:preferred "200"
:valid "200"
}
}
)
(local a2
{
"2001-0-1-2-3_aNteBnb" {
:address "2001:0:1:2:3"
:len "64"
:preferred "200"
:valid "200"
}
}
)
(macro expect [assertion]
(let [msg (.. "expectation failed: " (view assertion))]
`(when (not ,assertion)
(assert false ,msg))))
(fn first-address []
(let [(add del)
(subject.changes
{ }
a1
)]
(expect (= (# del) 0))
(expect (= (# add) 1))
(let [[first] add]
(expect (= first.address "2001:ab:cd:ef")))))
(fn second-address []
(let [(add del)
(subject.changes
a1
(merge (dup a1) a2)
)]
(expect (= (# del) 0))
(expect (= (# add) 1))
(let [[first] add] (expect (= first.address "2001:0:1:2:3")))))
(fn less-address []1
(let [(add del)
(subject.changes
(merge (dup a1) a2)
a1
)]
(expect (= (# add) 0))
(expect (= (# del) 1))
(let [[first] del] (expect (= first.address "2001:0:1:2:3")))))
(first-address)
(second-address)
(less-address)

View file

@ -1,35 +0,0 @@
(local { : system } (require :anoia))
(local svc (require :anoia.svc))
;; 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 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")))))
{ : update-addresses : changes : run }

View file

@ -1,10 +0,0 @@
{
writeFennel
, linotify
, anoia
, lua
}:
writeFennel "acquire-wan-address" {
packages = [ linotify anoia lua.pkgs.luafilesystem ];
mainFunction = "run";
} ./acquire-wan-address.fnl

View file

@ -7,7 +7,7 @@
{ config, pkgs, lib, ... } :
let
inherit (pkgs.liminix.services) oneshot longrun;
inherit (pkgs.liminix.services) bundle oneshot longrun;
inherit (pkgs) serviceFns;
# EDIT: you can pick your preferred RFC1918 address space
# for NATted connections, if you don't like this one.
@ -25,6 +25,7 @@ in rec {
imports = [
../modules/bridge
../modules/dhcp6c
../modules/dnsmasq
../modules/firewall
../modules/hostapd
@ -95,11 +96,16 @@ in rec {
resolvconf = services.resolvconf;
inherit interface;
ranges = [
"${ipv4LocalNet}.10,${ipv4LocalNet}.240"
# ra-stateless: sends router advertisements with the O and A
"${ipv4LocalNet}.10,${ipv4LocalNet}.249"
# EDIT: ... maybe. In this example we use "ra-stateless",
# meaning dnsmasq 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.
# If you didn't understand the preceding sentence then
# the default is _probably_ fine, but if you need
# a DHCP-only IPv6 network or some other different
# configuration, this is the place to change it.
"::,constructor:$(output ${interface} ifname),ra-stateless"
];
# EDIT: choose a domain name for the DNS names issued for your
@ -158,34 +164,37 @@ in rec {
services.packet_forwarding = svc.network.forward.build { };
services.dhcp6 =
let
name = "dhcp6c.wan";
in longrun {
inherit name;
notification-fd = 10;
run = ''
export SERVICE_STATE=/run/service-state/${name}
${pkgs.odhcp6c}/bin/odhcp6c -s ${pkgs.odhcp-script} -e -v -p /run/${name}.pid -P 48 $(output ${services.wan} ifname)
)
'';
dependencies = [ services.wan ];
};
# We expect the ISP uses DHCP6 to issue IPv6 addresses. There is a
# service to request address information in the form of a DHCP
# lease, and two dependent services that listen for updates to the
# DHCP address information and update the addresses of the WAN and
# LAN interfaces respectively.
services.acquire-lan-prefix =
let script = pkgs.callPackage ./acquire-delegated-prefix.nix { };
in longrun {
name = "acquire-lan-prefix";
run = "${script} /run/service-state/dhcp6c.wan $(output ${services.int} ifname)";
dependencies = [ services.dhcp6 ];
};
services.acquire-wan-address =
let script = pkgs.callPackage ./acquire-wan-address.nix { };
in longrun {
name = "acquire-wan-address";
run = "${script} /run/service-state/dhcp6c.wan $(output ${services.wan} ifname)";
dependencies = [ services.dhcp6 ];
services.dhcp6c =
let client = svc.dhcp6c.client.build {
interface = services.wan;
};
in bundle {
name = "dhcp6c";
contents = [
(svc.dhcp6c.prefix.build {
# if your ISP provides you a real IPv6 prefix for your local
# network (usually a /64 or /48 or something in between the
# two), this service subscribes to that "prefix delegation"
# information, and uses it to assign an address to the LAN
# device. dnsmasq will notice this address and use it to
# form the addresses it hands out to devices on the lan
inherit client;
interface = services.int;
})
(svc.dhcp6c.address.build {
# if your ISP provides you a regular global IPv6 address,
# this service subscribes to that information and assigns
# the address to the WAN device.
inherit client;
interface = services.wan;
})
];
};
defaultProfile.packages = with pkgs; [

View file

@ -9,7 +9,7 @@
{ config, pkgs, lib, ... } :
let
secrets = import ./rotuer-secrets.nix;
inherit (pkgs.liminix.services) oneshot longrun;
inherit (pkgs.liminix.services) oneshot longrun bundle;
inherit (pkgs) serviceFns;
svc = config.system.service;
wirelessConfig = {
@ -38,6 +38,7 @@ in rec {
../modules/network
../modules/ppp
../modules/dnsmasq
../modules/dhcp6c
../modules/firewall
../modules/hostapd
../modules/bridge
@ -154,39 +155,27 @@ in rec {
};
services.firewall = svc.firewall.build {
ruleset = import ./rotuer-firewall.nix;
ruleset = import ./demo-firewall.nix;
};
services.packet_forwarding = svc.network.forward.build { };
services.dhcp6 =
let
name = "dhcp6c.wan";
in longrun {
inherit name;
notification-fd = 10;
run = ''
export SERVICE_STATE=/run/service-state/${name}
${pkgs.odhcp6c}/bin/odhcp6c -s ${pkgs.odhcp-script} -e -v -p /run/${name}.pid -P 48 $(output ${services.wan} ifname)
)
'';
dependencies = [ services.wan ];
};
services.acquire-lan-prefix =
let script = pkgs.callPackage ./acquire-delegated-prefix.nix { };
in longrun {
name = "acquire-lan-prefix";
run = "${script} /run/service-state/dhcp6c.wan $(output ${services.int} ifname)";
dependencies = [ services.dhcp6 ];
};
services.acquire-wan-address =
let script = pkgs.callPackage ./acquire-wan-address.nix { };
in longrun {
name = "acquire-wan-address";
run = "${script} /run/service-state/dhcp6c.wan $(output ${services.wan} ifname)";
dependencies = [ services.dhcp6 ];
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; [