this is the dhcp6c service we want

hark-how-all-the-belkin-rings
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

@ -7,7 +7,7 @@
{ config, pkgs, lib, ... } : { config, pkgs, lib, ... } :
let let
inherit (pkgs.liminix.services) oneshot longrun; inherit (pkgs.liminix.services) bundle oneshot longrun;
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.
@ -25,6 +25,7 @@ in rec {
imports = [ imports = [
../modules/bridge ../modules/bridge
../modules/dhcp6c
../modules/dnsmasq ../modules/dnsmasq
../modules/firewall ../modules/firewall
../modules/hostapd ../modules/hostapd
@ -95,11 +96,16 @@ in rec {
resolvconf = services.resolvconf; resolvconf = services.resolvconf;
inherit interface; inherit interface;
ranges = [ ranges = [
"${ipv4LocalNet}.10,${ipv4LocalNet}.240" "${ipv4LocalNet}.10,${ipv4LocalNet}.249"
# ra-stateless: sends router advertisements with the O and A # 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 # bits set, and provides a stateless DHCP service. The client
# will use a SLAAC address, and use DHCP for other # will use a SLAAC address, and use DHCP for other
# configuration information. # 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" "::,constructor:$(output ${interface} ifname),ra-stateless"
]; ];
# EDIT: choose a domain name for the DNS names issued for your # 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.packet_forwarding = svc.network.forward.build { };
services.dhcp6 = # We expect the ISP uses DHCP6 to issue IPv6 addresses. There is a
let # service to request address information in the form of a DHCP
name = "dhcp6c.wan"; # lease, and two dependent services that listen for updates to the
in longrun { # DHCP address information and update the addresses of the WAN and
inherit name; # LAN interfaces respectively.
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 = services.dhcp6c =
let script = pkgs.callPackage ./acquire-delegated-prefix.nix { }; let client = svc.dhcp6c.client.build {
in longrun { interface = services.wan;
name = "acquire-lan-prefix"; };
run = "${script} /run/service-state/dhcp6c.wan $(output ${services.int} ifname)"; in bundle {
dependencies = [ services.dhcp6 ]; name = "dhcp6c";
}; contents = [
(svc.dhcp6c.prefix.build {
services.acquire-wan-address = # if your ISP provides you a real IPv6 prefix for your local
let script = pkgs.callPackage ./acquire-wan-address.nix { }; # network (usually a /64 or /48 or something in between the
in longrun { # two), this service subscribes to that "prefix delegation"
name = "acquire-wan-address"; # information, and uses it to assign an address to the LAN
run = "${script} /run/service-state/dhcp6c.wan $(output ${services.wan} ifname)"; # device. dnsmasq will notice this address and use it to
dependencies = [ services.dhcp6 ]; # 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; [ defaultProfile.packages = with pkgs; [

View File

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

View File

@ -0,0 +1,16 @@
{
liminix
, lib
, callPackage
}:
{ client, interface } :
let
inherit (liminix.services) longrun;
inherit (lib) mkOption types;
name = "dhcp6c.addr.${client.name}.${interface.name}";
script = callPackage ./acquire-wan-address.nix { };
in longrun {
inherit name;
run = "${script} /run/service-state/${client.name} $(output ${interface} ifname)";
dependencies = [ client interface ];
}

21
modules/dhcp6c/client.nix Normal file
View File

@ -0,0 +1,21 @@
{
liminix
, lib
, odhcp6c
, odhcp-script
}:
{ interface } :
let
inherit (liminix.services) longrun;
inherit (lib) mkOption types;
name = "dhcp6c.${interface.name}";
in longrun {
inherit name;
notification-fd = 10;
run = ''
export SERVICE_STATE=/run/service-state/${name}
${odhcp6c}/bin/odhcp6c -s ${odhcp-script} -e -v -p /run/${name}.pid -P0 $(output ${interface} ifname)
)
'';
dependencies = [ interface ];
}

View File

@ -0,0 +1,52 @@
## DHCP6 client module
## ===================
##
## This is for use if you have an IPv6-capable upstream that provides
## address information and/or prefix delegation using DHCP6. It
## provides 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 can be used to update
## addresses of network interfaces that you want to assign those
## prefixes to
{ lib, pkgs, config, ...}:
let
inherit (lib) mkOption types;
inherit (pkgs.liminix.services) oneshot;
inherit (pkgs) liminix;
in
{
options = {
system.service.dhcp6c = {
client = mkOption { type = liminix.lib.types.serviceDefn; };
prefix = mkOption { type = liminix.lib.types.serviceDefn; };
address = mkOption { type = liminix.lib.types.serviceDefn; };
};
};
config.system.service.dhcp6c = {
client = liminix.callService ./client.nix {
interface = mkOption {
type = liminix.lib.types.interface;
description = "interface (usually WAN) to query for DHCP6";
};
};
address = liminix.callService ./address.nix {
client = mkOption {
type = types.anything; # liminix.lib.types.service;
};
interface = mkOption {
type = liminix.lib.types.interface;
description = "interface to assign the address to";
};
};
prefix = liminix.callService ./prefix.nix {
client = mkOption {
type = types.anything; # liminix.lib.types.service;
};
interface = mkOption {
type = liminix.lib.types.interface;
description = "interface to assign <prefix>::1 to";
};
};
};
}

16
modules/dhcp6c/prefix.nix Normal file
View File

@ -0,0 +1,16 @@
{
liminix
, lib
, callPackage
}:
{ client, interface } :
let
inherit (liminix.services) longrun;
inherit (lib) mkOption types;
name = "dhcp6c.prefix.${client.name}.${interface.name}";
script = callPackage ./acquire-delegated-prefix.nix { };
in longrun {
inherit name;
run = "${script} /run/service-state/${client.name} $(output ${interface} ifname)";
dependencies = [ client interface ];
}