diff --git a/modules/bridge/default.nix b/modules/bridge/default.nix index 3a24d7c..df7bce1 100644 --- a/modules/bridge/default.nix +++ b/modules/bridge/default.nix @@ -9,8 +9,7 @@ { lib, pkgs, config, ...}: let - inherit (lib) mkOption types; - inherit (pkgs.liminix.services) oneshot; + inherit (lib) mkOption types mkEnableOption; inherit (pkgs) liminix; in { @@ -35,6 +34,20 @@ in default = null; 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 { primary = mkOption { diff --git a/modules/bridge/primary.nix b/modules/bridge/primary.nix index f5e1219..35140dd 100644 --- a/modules/bridge/primary.nix +++ b/modules/bridge/primary.nix @@ -3,17 +3,22 @@ , ifwait , lib }: -{ ifname, macAddressFromInterface ? null } : +{ ifname, macAddressFromInterface ? null, untagged } : let - inherit (liminix.services) bundle oneshot; - inherit (lib) mkOption types optional; + inherit (liminix.services) oneshot; + 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 { name = "${ifname}.link"; up = '' ${if macAddressFromInterface == null then - "ip link add name ${ifname} type bridge" + "ip link add name ${ifname} type bridge${extra}" 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} echo ${ifname} > ifname diff --git a/modules/vlan/default.nix b/modules/vlan/default.nix index 6698630..2a6bed9 100644 --- a/modules/vlan/default.nix +++ b/modules/vlan/default.nix @@ -33,6 +33,11 @@ in description = "VLAN identifier (VID) in range 1-4094"; type = types.str; }; + untagged.egress = mkOption { + description = "Whether packets from this interface will go out *untagged*"; + type = types.bool; + default = false; + }; }; config.kernel.config = { VLAN_8021Q = "y"; diff --git a/modules/vlan/service.nix b/modules/vlan/service.nix index 1311545..3fa4ea2 100644 --- a/modules/vlan/service.nix +++ b/modules/vlan/service.nix @@ -2,13 +2,15 @@ liminix , lib }: -{ ifname, primary, vid } : +{ ifname, primary, vid, untagged } : let + inherit (lib) optionalString; inherit (liminix.services) oneshot; in oneshot rec { name = "${ifname}.link"; up = '' 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} (in_outputs ${name} echo ${ifname} > ifname