From 7230c3532a56999ef34209cf08dbe552a9b9aaa9 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Wed, 6 Mar 2024 18:10:22 +0100 Subject: [PATCH] confd: improve bridge port validation for VLAN filtering bridges This patch adds validation of bridge port VLAN memberships and IP addressing for VLAN filtering bridges: 1. Ports must be a member of this bridge 2. Ports cannot be tagged and untagged member at the same time 3. A VLAN filtering bridge does not support IP addressing A VLAN filtering bridge can only be a tagged member of a VLAN. Any IP addressing needs to be done using an upper VLAN interface. NOTE: while technically possible break up these long must expressions into multiple must expressions per node (split at 'and'), it will break libyang in interesting ways that in turn make the confd inference functionality stop working. E.g., creating VETH pairs. Signed-off-by: Joachim Wiberg --- .../yang/infix-if-bridge@2024-03-06.yang | 49 ++++++++++++++++--- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/src/confd/yang/infix-if-bridge@2024-03-06.yang b/src/confd/yang/infix-if-bridge@2024-03-06.yang index efc122c8..a0168321 100644 --- a/src/confd/yang/infix-if-bridge@2024-03-06.yang +++ b/src/confd/yang/infix-if-bridge@2024-03-06.yang @@ -16,6 +16,9 @@ submodule infix-if-bridge { import ietf-inet-types { prefix inet; } + import ietf-ip { + prefix ip; + } import ieee802-dot1q-types { prefix dot1q-types; } @@ -25,8 +28,17 @@ submodule infix-if-bridge { description "Linux bridge extension for ietf-interfaces."; revision 2024-03-06 { - description "Drop default value for bridge-port PVID. - Should be possible to drop untagged frames."; + description "Drop default value for bridge-port PVID. Should be possible + to drop untagged frames. + + Add must() expression for VLAN memberships. Listed ports must + belong to this bridge and cannot be untagged and tagged at the + same time. + + Also, add must() expression to ensure VLAN filtering bridges + do not have any IP address set since the bridge is always only + a tagged member of VLANs. Use a VLAN interfaces on top of the + bridge for IP addressing."; reference "internal"; } revision 2024-02-19 { @@ -302,20 +314,43 @@ submodule infix-if-bridge { leaf-list untagged { type if:interface-ref; description "The set of ports in the untagged set for VLAN."; - } + must "current() = ../../../../if:name + or (/if:interfaces/if:interface[if:name = current()]/bridge-port/bridge = ../../../../if:name + and not(../tagged[contains(., current())]))" { + error-message "Port is not a member of this bridge or already set as tagged member in the same VLAN."; + } + } leaf-list tagged { - type if:interface-ref; - must "not(../untagged[contains(., current())])" { - error-message "Cannot be an untagged port at the same time."; - } description "The set of ports in the tagged set for VLAN."; + type if:interface-ref; + must "current() = ../../../../if:name + or (/if:interfaces/if:interface[if:name = current()]/bridge-port/bridge = ../../../../if:name + and not(../untagged[contains(., current())]))" { + error-message "Port is not a member of bridge or already untagged in the same VLAN."; + } } } } } } + deviation "/if:interfaces/if:interface/ip:ipv4/ip:enabled" { + deviate add { + must "not(.) or count(../../infix-if:bridge/infix-if:vlans/infix-if:vlan) = 0" { + error-message "IPv4 address is not supported on VLAN filtering bridges."; + } + } + } + + deviation "/if:interfaces/if:interface/ip:ipv6/ip:enabled" { + deviate add { + must "not(.) or count(../../infix-if:bridge/infix-if:vlans/infix-if:vlan) = 0" { + error-message "IPv6 address is not supported on VLAN filtering bridges."; + } + } + } + augment "/if:interfaces/if:interface/infix-if:port" { when "derived-from-or-self(if:type,'ianaift:bridge') or "+ "derived-from-or-self(if:type,'ianaift:ethernetCsmacd') or "+