From b6215ba95899328bd13fabbf6488b602763b9352 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Thu, 11 Nov 2021 14:44:26 +0100 Subject: add global-functions.d/bridge-port-vlan --- README.md | 5 ++ doc/bridge-port.md | 5 ++ doc/global-functions.d/bridge-port-vlan.md | 83 ++++++++++++++++++++++++++++++ global-config | 2 +- global-config-overlay | 2 +- global-config.changes | 1 + global-functions | 2 +- global-functions.d/bridge-port-vlan | 62 ++++++++++++++++++++++ 8 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 doc/global-functions.d/bridge-port-vlan.md create mode 100644 global-functions.d/bridge-port-vlan diff --git a/README.md b/README.md index ca3554f..1787ab5 100644 --- a/README.md +++ b/README.md @@ -201,6 +201,11 @@ Available Scripts [comment]: # (* learn-mac-based-vlan) [comment]: # (* manage-umts) +Available modules +----------------- + +* [Manage VLANs on bridge ports](doc/global-functions.d/bridge-port-vlan.md) + Contact ------- diff --git a/doc/bridge-port.md b/doc/bridge-port.md index d5435b4..924bd6a 100644 --- a/doc/bridge-port.md +++ b/doc/bridge-port.md @@ -76,6 +76,11 @@ More configuration can be loaded by setting `BridgePortTo`: * Interfaces `en1` and `en2` are unchanged. * Interface `en3` is put in bridge `br-intern`. +See also +-------- + +* [Manage VLANs on bridge ports](global-functions.d/bridge-port-vlan.md) + --- [◀ Go back to main README](../README.md) [▲ Go back to top](#top) diff --git a/doc/global-functions.d/bridge-port-vlan.md b/doc/global-functions.d/bridge-port-vlan.md new file mode 100644 index 0000000..f59cb83 --- /dev/null +++ b/doc/global-functions.d/bridge-port-vlan.md @@ -0,0 +1,83 @@ +Manage VLANs on bridge ports +============================ + +[◀ Go back to main README](../../README.md) + +🛈 This module can not be used on its own but requires the base installation. +See [main README](../../README.md) for details. + +Description +----------- + +This module and its function are supposed to handle VLANs on bridge ports. + +Requirements and installation +----------------------------- + +Just install the module: + + $ScriptInstallUpdate global-functions.d/bridge-port-vlan; + +Configuration +------------- + +Using named VLANs you have to add comments in bridge vlan menu: + + / interface bridge vlan add bridge=bridge comment=intern tagged=br-local vlan-ids=10; + / interface bridge vlan add bridge=bridge comment=geust tagged=br-local vlan-ids=20; + / interface bridge vlan add bridge=bridge comment=extra tagged=br-local vlan-ids=30; + +The configuration goes to ports' comments (`/ interface bridge port`). + + / interface bridge port add bridge=bridge comment="default=dhcp-client, alt=guest" disabled=yes interface=en1; + / interface bridge port add bridge=bridge comment="default=intern, alt=guest, extra=30" interface=en2; + / interface bridge port add bridge=bridge comment="default=guest, extra=extra" interface=en3; + +Also dhcp client can be handled: + + / ip dhcp-client add comment="toggle with bridge port" disabled=no interface=en1; + +Add a scheduler to start with default setup on system startup: + + / system scheduler add name=bridge-port-vlan on-event=":global GlobalFunctionsReady; :while (\$GlobalFunctionsReady != true) do={ :delay 500ms; }; :global BridgePortVlan; \$BridgePortVlan default;" start-time=startup; + +Usage and invocation +-------------------- + +The usage examples show what happens with the configuration from above. + +Running the function `$BridgePortVlan` with parameter `default` applies all +configuration given with `default=`: + + $BridgePortVlan default; + +For the three interfaces we get this configuration: + +* The special value `dhcp-client` enables the dhcp client for interface `en1`. The bridge port entry is disabled. +* Primary VLAN `intern` (ID `10`) is configured on `en2`. +* Primary VLAN `guest` (ID `20`) is configured on `en3`. + +Running the function `$BridgePortVlan` with parameter `alt` applies all +configuration given with `alt=`: + + $BridgePortVlan alt; + +* Primary VLAN `guest` (ID `20`) is configured on `en1`, dhcp client for the interface is disabled. +* Primary VLAN `guest` (ID `20`) is configured on `en2`. +* Interface `en3` is unchanged, primary VLAN `guest` (ID `20`) is unchanged. + +Running the function `$BridgePortVlan` with parameter `extra` applies another +configuration: + +* Interface `en1` is unchanged. +* Primary VLAN `extra` (via its ID `30`) is configured on `en2`. +* Primary VLAN `extra` (ID `30`) is configured on `en3`. + +See also +-------- + +* [Manage ports in bridge](../bridge-port.md) + +--- +[◀ Go back to main README](../../README.md) +[▲ Go back to top](#top) diff --git a/global-config b/global-config index bf3b0e4..5dc9a20 100644 --- a/global-config +++ b/global-config @@ -8,7 +8,7 @@ # Make sure all configuration properties are up to date and this # value is in sync with value in script 'global-functions'! -:global GlobalConfigVersion 64; +:global GlobalConfigVersion 65; # This is used for DNS and backup file. :global Domain "example.com"; diff --git a/global-config-overlay b/global-config-overlay index 78d34b0..7bdc516 100644 --- a/global-config-overlay +++ b/global-config-overlay @@ -8,7 +8,7 @@ # Make sure all configuration properties are up to date and this # value is in sync with value in script 'global-functions'! # Comment or remove to disable news and change notifications. -:global GlobalConfigVersion 64; +:global GlobalConfigVersion 65; # Copy configuration from global-config here and modify it. diff --git a/global-config.changes b/global-config.changes index 1ef2792..6a8b145 100644 --- a/global-config.changes +++ b/global-config.changes @@ -68,6 +68,7 @@ 62="Added '\$ScriptRunOnce' to run a script from URL once without installation, intended to aid configuration management and the like."; 63="Moved optional functions '\$IPCalc' and '\$ScriptRunOnce' to modules."; 64="Implemented '\$InspectVar' in module to inspect variables."; + 65="Added module to manage VLANs on bridge ports."; }; # Migration steps to be applied on script updates diff --git a/global-functions b/global-functions index 80d6e6a..dbfeaa1 100644 --- a/global-functions +++ b/global-functions @@ -8,7 +8,7 @@ # https://git.eworm.de/cgit/routeros-scripts/about/ # expected configuration version -:global ExpectedConfigVersion 64; +:global ExpectedConfigVersion 65; # global variables not to be changed by user :global GlobalFunctionsReady false; diff --git a/global-functions.d/bridge-port-vlan b/global-functions.d/bridge-port-vlan new file mode 100644 index 0000000..754579a --- /dev/null +++ b/global-functions.d/bridge-port-vlan @@ -0,0 +1,62 @@ +#!rsc by RouterOS +# RouterOS script: global-functions.d/bridge-port-vlan +# Copyright (c) 2013-2021 Christian Hesse +# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md +# +# manage VLANs on bridge ports +# https://git.eworm.de/cgit/routeros-scripts/about/doc/global-functions.d/bridge-port-vlan.md + +:global BridgePortVlan; + +# TODO +:global BridgePortVlan do={ + :local ConfigTo [ :tostr $1 ]; + + :global IfThenElse; + :global LogPrintExit2; + :global ParseKeyValueStore; + + :foreach BridgePort in=[ / interface bridge port find where !(comment=[]) ] do={ + :local BridgePortVal [ / interface bridge port get $BridgePort ]; + :foreach Config,Vlan in=[ $ParseKeyValueStore ($BridgePortVal->"comment") ] do={ + :if ($Config = $ConfigTo) do={ + :local DHCPClient [ / ip dhcp-client find where interface=$BridgePortVal->"interface" comment="toggle with bridge port" ]; + + :if ($Vlan = "dhcp-client") do={ + :if ([ :len $DHCPClient ] != 1) do={ + $LogPrintExit2 warning $0 ([ $IfThenElse ([ :len $DHCPClient ] = 0) "Missing" "Duplicate" ] . \ + " dhcp client configuration for interface " . $BridgePortVal->"interface" . "!") true; + } + :local DHCPClientDisabled [ / ip dhcp-client get $DHCPClient disabled ]; + + :if ($BridgePortVal->"disabled" = false || $DHCPClientDisabled = true) do={ + $LogPrintExit2 info $0 ("Disabling bridge port for interface " . $BridgePortVal->"interface" . ", enabling dhcp client.") false; + / interface bridge port disable $BridgePort; + :delay 200ms; + / ip dhcp-client enable $DHCPClient; + } + } else={ + :if ($Vlan != [ :tostr [ :tonum $Vlan ] ]) do={ + :do { + :set $Vlan ([ / interface bridge vlan get [ find where comment=$Vlan ] vlan-ids ]->0); + } on-error={ + $LogPrintExit2 warning $0 ("Could not find VLAN '" . $Vlan . "' for interface " . $BridgePortVal->"interface" . "!") true; + } + } + :if ($BridgePortVal->"disabled" = true || $Vlan != $BridgePortVal->"pvid") do={ + $LogPrintExit2 info $0 ("Enabling bridge port for interface " . $BridgePortVal->"interface" . ", changing to " . $ConfigTo . \ + " vlan " . $Vlan . ", disabling dhcp client.") false; + :if ([ :len $DHCPClient ] = 1) do={ + / ip dhcp-client disable $DHCPClient; + :delay 200ms; + } + / interface bridge port set disabled=no pvid=$Vlan $BridgePort; + } else={ + $LogPrintExit2 debug $0 ("Interface " . $BridgePortVal->"interface" . " already connected to " . $ConfigTo . \ + " vlan " . $Vlan . ".") false; + } + } + } + } + } +} -- cgit v1.2.3-70-g09d2