feat: add support for untagged frames

Should cover egress & ingress.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
This commit is contained in:
Raito Bezarius 2024-12-09 01:01:15 +01:00
parent 9490822c1a
commit 1322de1ee0
4 changed files with 33 additions and 8 deletions

View file

@ -9,8 +9,7 @@
{ lib, pkgs, config, ...}: { lib, pkgs, config, ...}:
let let
inherit (lib) mkOption types; inherit (lib) mkOption types mkEnableOption;
inherit (pkgs.liminix.services) oneshot;
inherit (pkgs) liminix; inherit (pkgs) liminix;
in in
{ {
@ -35,6 +34,20 @@ in
default = null; default = null;
description = "reuse mac address from an existing interface service"; description = "reuse mac address from an existing interface service";
}; };
untagged = {
enable = mkEnableOption "untagged frames on port VID";
pvid = mkOption {
type = types.nullOr types.int;
default = null;
description = "Port VLAN ID for egress untagged frames";
};
default-pvid = mkOption {
type = types.int;
default = 0;
description = "Default PVID for ingress untagged frames, defaults to 0, which disable untagged frames for ingress";
};
};
}; };
members = config.system.callService ./members.nix { members = config.system.callService ./members.nix {
primary = mkOption { primary = mkOption {

View file

@ -3,17 +3,22 @@
, ifwait , ifwait
, lib , lib
}: }:
{ ifname, macAddressFromInterface ? null } : { ifname, macAddressFromInterface ? null, untagged } :
let let
inherit (liminix.services) bundle oneshot; inherit (liminix.services) oneshot;
inherit (lib) mkOption types optional; inherit (lib) optional optionalString;
# This enables vlan_filtering if we do make use of it.
extra = if untagged.enable then " vlan_filtering 1 vlan_default_pvid ${toString untagged.default-pvid}" else "";
in oneshot rec { in oneshot rec {
name = "${ifname}.link"; name = "${ifname}.link";
up = '' up = ''
${if macAddressFromInterface == null then ${if macAddressFromInterface == null then
"ip link add name ${ifname} type bridge" "ip link add name ${ifname} type bridge${extra}"
else else
"ip link add name ${ifname} address $(output ${macAddressFromInterface} ether) type bridge"} "ip link add name ${ifname} address $(output ${macAddressFromInterface} ether) type bridge${extra}"}
${optionalString untagged.enable
"bridge vlan add vid ${toString untagged.pvid} dev ${ifname} pvid untagged self"}
(in_outputs ${name} (in_outputs ${name}
echo ${ifname} > ifname echo ${ifname} > ifname

View file

@ -33,6 +33,11 @@ in
description = "VLAN identifier (VID) in range 1-4094"; description = "VLAN identifier (VID) in range 1-4094";
type = types.str; type = types.str;
}; };
untagged.egress = mkOption {
description = "Whether packets from this interface will go out *untagged*";
type = types.bool;
default = false;
};
}; };
config.kernel.config = { config.kernel.config = {
VLAN_8021Q = "y"; VLAN_8021Q = "y";

View file

@ -2,13 +2,15 @@
liminix liminix
, lib , lib
}: }:
{ ifname, primary, vid } : { ifname, primary, vid, untagged } :
let let
inherit (lib) optionalString;
inherit (liminix.services) oneshot; inherit (liminix.services) oneshot;
in oneshot rec { in oneshot rec {
name = "${ifname}.link"; name = "${ifname}.link";
up = '' up = ''
ip link add link $(output ${primary} ifname) name ${ifname} type vlan id ${vid} ip link add link $(output ${primary} ifname) name ${ifname} type vlan id ${vid}
${optionalString untagged.egress "bridge vlan add dev ${ifname} vid ${toString untagged.vid} pvid untagged master"}
${liminix.networking.ifup name ifname} ${liminix.networking.ifup name ifname}
(in_outputs ${name} (in_outputs ${name}
echo ${ifname} > ifname echo ${ifname} > ifname