2424
2525LOGGER = logging .getLogger (__name__ )
2626
27- CUDN_EVPN_SUBNET_IPV4 : str = f"{ random_ipv4_address (net_seed = 5 , host_address = 0 )} /24"
28- CUDN_EVPN_SUBNET_IPV6 : str = f"{ random_ipv6_address (net_seed = 5 , host_address = 0 )} /64"
27+ EVPN_CUDN_NET_SEED : int = 5
28+ CUDN_EVPN_SUBNET_IPV4 : str = f"{ random_ipv4_address (net_seed = EVPN_CUDN_NET_SEED , host_address = 0 )} /24"
29+ CUDN_EVPN_SUBNET_IPV6 : str = f"{ random_ipv6_address (net_seed = EVPN_CUDN_NET_SEED , host_address = 0 )} /64"
2930
3031_BRIDGE_NAME : str = "br0"
3132_VXLAN_NAME : str = "vxlan0"
@@ -51,6 +52,7 @@ class EvpnEndpoint:
5152 pod : Pod
5253 ip_addresses : list [str ]
5354 netns_name : str
55+ mac_address : str | None = None
5456
5557
5658class EndpointTcpClient (PodTcpClient ):
@@ -143,6 +145,7 @@ def deploy_evpn_l2_endpoint(
143145 pod : Pod ,
144146 vni : int ,
145147 endpoint_ips : list [str ],
148+ mac_address : str | None = None ,
146149) -> EvpnEndpoint :
147150 """Creates a stretched L2 endpoint on the shared SVD bridge.
148151
@@ -155,32 +158,46 @@ def deploy_evpn_l2_endpoint(
155158 pod: The FRR pod hosting the endpoint.
156159 vni: MAC-VRF VNI (must match CUDN's macVRF VNI).
157160 endpoint_ips: IPs with prefix length (e.g. ["10.0.5.250/24", "fd00::fa/64"]).
161+ mac_address: Explicit MAC for the endpoint interface (locally-administered).
158162
159163 Returns:
160164 EvpnEndpoint.
161165 """
162- commands = _build_l2_endpoint_commands (vni = vni , endpoint_ips = endpoint_ips )
166+ commands = _build_l2_endpoint_commands (vni = vni , endpoint_ips = endpoint_ips , mac_address = mac_address )
163167 for command in commands :
164168 pod .execute (command = shlex .split (command ), container = NET_TOOLS_CONTAINER_NAME )
165169
166170 bare_ips = [ip .split ("/" )[0 ] for ip in endpoint_ips ]
167171 LOGGER .info (f"EVPN L2 endpoint deployed: { bare_ips } in namespace { _L2_ENDPOINT_NETNS } " )
168172
169- return EvpnEndpoint (pod = pod , ip_addresses = bare_ips , netns_name = _L2_ENDPOINT_NETNS )
173+ return EvpnEndpoint (pod = pod , ip_addresses = bare_ips , netns_name = _L2_ENDPOINT_NETNS , mac_address = mac_address )
170174
171175
172- def teardown_evpn_l2_endpoint (pod : Pod ) -> None :
173- """Removes the EVPN L2 endpoint (netns, veth) from the FRR pod."""
176+ def teardown_evpn_l2_endpoint (pod : Pod , vni : int ) -> None :
177+ """Removes the EVPN L2 endpoint (netns, veth, VLAN/VNI mappings) from the FRR pod.
178+
179+ Args:
180+ pod: The FRR pod hosting the endpoint.
181+ vni: MAC-VRF VNI used during deployment.
182+ """
174183 for cmd in [
175184 f"ip netns delete { _L2_ENDPOINT_NETNS } " ,
176185 f"ip link delete { _L2_VETH_POD_SIDE } " ,
186+ f"bridge vlan del dev { _VXLAN_NAME } vid { _L2_VID } tunnel_info id { vni } " ,
187+ f"bridge vni del dev { _VXLAN_NAME } vni { vni } " ,
188+ f"bridge vlan del dev { _VXLAN_NAME } vid { _L2_VID } " ,
189+ f"bridge vlan del dev { _BRIDGE_NAME } vid { _L2_VID } self" ,
177190 ]:
178191 pod .execute (command = shlex .split (cmd ), container = NET_TOOLS_CONTAINER_NAME , ignore_rc = True )
179192
180193 LOGGER .info (f"EVPN L2 endpoint removed: namespace={ _L2_ENDPOINT_NETNS } " )
181194
182195
183- def _build_l2_endpoint_commands (vni : int , endpoint_ips : list [str ]) -> list [str ]:
196+ def _build_l2_endpoint_commands (
197+ vni : int ,
198+ endpoint_ips : list [str ],
199+ mac_address : str | None = None ,
200+ ) -> list [str ]:
184201 return [
185202 f"bridge vlan add dev { _BRIDGE_NAME } vid { _L2_VID } self" ,
186203 f"bridge vlan add dev { _VXLAN_NAME } vid { _L2_VID } " ,
@@ -193,6 +210,11 @@ def _build_l2_endpoint_commands(vni: int, endpoint_ips: list[str]) -> list[str]:
193210 f"ip netns add { _L2_ENDPOINT_NETNS } " ,
194211 f"ip link set { _L2_VETH_EP_SIDE } netns { _L2_ENDPOINT_NETNS } " ,
195212 * (f"ip netns exec { _L2_ENDPOINT_NETNS } ip addr add { ip } dev { _L2_VETH_EP_SIDE } " for ip in endpoint_ips ),
213+ * (
214+ [f"ip netns exec { _L2_ENDPOINT_NETNS } ip link set dev { _L2_VETH_EP_SIDE } address { mac_address } " ]
215+ if mac_address
216+ else []
217+ ),
196218 f"ip netns exec { _L2_ENDPOINT_NETNS } ip link set { _L2_VETH_EP_SIDE } up" ,
197219 f"ip netns exec { _L2_ENDPOINT_NETNS } ip link set lo up" ,
198220 ]
0 commit comments