From 333327be759c30552ef2cc090c17df9fe16b9d28 Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Wed, 30 Aug 2023 23:26:44 +0100 Subject: [PATCH] make a module for vlan Acked-by: Daniel Barlow <> --- devices/gl-mt300a/default.nix | 9 +--- devices/gl-mt300n-v2/default.nix | 75 ++++++++++++++------------------ examples/arhcive.nix | 1 + modules/vlan/default.nix | 41 +++++++++++++++++ modules/vlan/service.nix | 15 +++++++ 5 files changed, 90 insertions(+), 51 deletions(-) create mode 100644 modules/vlan/default.nix create mode 100644 modules/vlan/service.nix diff --git a/devices/gl-mt300a/default.nix b/devices/gl-mt300a/default.nix index 9fe80efb..cb0fd1a2 100644 --- a/devices/gl-mt300a/default.nix +++ b/devices/gl-mt300a/default.nix @@ -115,6 +115,7 @@ NET_RALINK_MDIO = "y"; NET_RALINK_MDIO_MT7620 = "y"; NET_RALINK_MT7620 = "y"; + SWPHY = "y"; SPI = "y"; MTD_SPI_NOR = "y"; @@ -123,14 +124,6 @@ SPI_MASTER= "y"; SPI_MEM= "y"; - # both the ethernet ports on this device (lan and wan) - # are behind a switch, so we need VLANs to do anything - # useful with them - - VLAN_8021Q = "y"; - SWCONFIG = "y"; - SWPHY = "y"; - MTD = "y"; MTD_CMDLINE_PARTS = "y"; MTD_BLOCK = "y"; # fix undefined ref to register_mtd_blktrans_devs diff --git a/devices/gl-mt300n-v2/default.nix b/devices/gl-mt300n-v2/default.nix index 576cc16c..dca648ad 100644 --- a/devices/gl-mt300n-v2/default.nix +++ b/devices/gl-mt300n-v2/default.nix @@ -52,44 +52,40 @@ "${openwrt.src}/target/linux/ramips/dts" ]; }; - networkInterfaces = rec { - # lan and wan ports are both behind a switch on eth0 - eth = - let swconfig = oneshot { - name = "swconfig"; - up = '' - PATH=${pkgs.swconfig}/bin:$PATH - swconfig dev switch0 set reset - swconfig dev switch0 set enable_vlan 1 - swconfig dev switch0 vlan 1 set ports '1 2 3 4 6t' - swconfig dev switch0 vlan 2 set ports '0 6t' - swconfig dev switch0 set apply - ''; - down = "swconfig dev switch0 set reset"; - }; - in interface { - device = "eth0"; - dependencies = [swconfig]; + networkInterfaces = + let + inherit (config.system.service.network) link; + inherit (config.system.service) vlan; + swconfig = oneshot { + name = "swconfig"; + up = '' + PATH=${pkgs.swconfig}/bin:$PATH + swconfig dev switch0 set reset + swconfig dev switch0 set enable_vlan 1 + swconfig dev switch0 vlan 1 set ports '1 2 3 4 6t' + swconfig dev switch0 vlan 2 set ports '0 6t' + swconfig dev switch0 set apply + ''; + down = "swconfig dev switch0 set reset"; + }; + in rec { + eth = link.build { ifname = "eth0"; dependencies = [swconfig]; }; + # lan and wan ports are both behind a switch on eth0 + lan = vlan.build { + ifname = "eth0.1"; + primary = eth; + vid = "1"; + }; + wan = vlan.build { + ifname = "eth0.2"; + primary = eth; + vid = "2"; + }; + wlan = link.build { + ifname = "wlan0"; + dependencies = [ mac80211 ]; }; - lan = interface { - type = "vlan"; - device = "eth0.1"; - link = "eth0"; - id = "1"; - dependencies = [eth]; }; - wan = interface { - type = "vlan"; - device = "eth0.2"; - id = "2"; - link = "eth0"; - dependencies = [eth]; - }; - wlan = interface { - device = "wlan0"; - dependencies = [ mac80211 ]; - }; - }; }; boot.tftp = { # 20MB seems to give enough room to uncompress the kernel @@ -148,13 +144,6 @@ NET_VENDOR_RALINK = "y"; NET_RALINK_RT3050 = "y"; NET_RALINK_SOC="y"; - - # both the ethernet ports on this device (lan and wan) - # are behind a switch, so we need VLANs to do anything - # useful with them - - VLAN_8021Q = "y"; - SWCONFIG = "y"; SWPHY = "y"; WATCHDOG = "y"; diff --git a/examples/arhcive.nix b/examples/arhcive.nix index bd4bfd52..dbb4774e 100644 --- a/examples/arhcive.nix +++ b/examples/arhcive.nix @@ -31,6 +31,7 @@ in rec { ../modules/standard.nix ../modules/wlan.nix ../modules/network + ../modules/vlan ]; hostname = "arhcive"; diff --git a/modules/vlan/default.nix b/modules/vlan/default.nix new file mode 100644 index 00000000..2d747ecf --- /dev/null +++ b/modules/vlan/default.nix @@ -0,0 +1,41 @@ +## VLAN +## ==== +## +## Virtual LANs give you the ability to sub-divide a LAN. Linux can +## accept VLAN tagged traffic and presents each VLAN ID as a +## different network interface (eg: eth0.100 for VLAN ID 100) +## +## Some Liminix devices with multiple ethernet ports are implemented +## using a network switch connecting the physical ports to the CPU, +## and require using VLAN in order to send different traffic to +## different ports (e.g. LAN vs WAN) + +{ lib, pkgs, config, ...}: +let + inherit (lib) mkOption types; + inherit (pkgs.liminix.services) oneshot; + inherit (pkgs) liminix; +in +{ + options = { + system.service.vlan = mkOption { type = liminix.lib.types.serviceDefn; }; + }; + config.system.service.vlan = liminix.callService ./service.nix { + ifname = mkOption { + type = types.str; + description = "interface name to create"; + }; + primary = mkOption { + description = "existing physical interface"; + type = liminix.lib.types.interface; + }; + vid = mkOption { + description = "VLAN identifier (VID) in range 1-4094"; + type = types.str; + }; + }; + config.kernel.config = { + VLAN_8021Q = "y"; + SWCONFIG = "y"; # not always appropriate, some devices will use DSA + }; +} diff --git a/modules/vlan/service.nix b/modules/vlan/service.nix new file mode 100644 index 00000000..4b30cd9a --- /dev/null +++ b/modules/vlan/service.nix @@ -0,0 +1,15 @@ +{ + liminix +, lib +}: +{ ifname, primary, vid } : +let + inherit (liminix.services) oneshot; +in oneshot rec { + name = "${ifname}.link"; + up = '' + ip link add link $(output ${primary} ifname) name ${ifname} type vlan id ${vid} + ${liminix.networking.ifup name ifname} + ''; + down = "ip link set down dev ${ifname}"; +}