@@ -278,7 +278,7 @@ def generate_sonic_config(device, hwsku, device_as_mapping=None, config_version=
278278 _add_portchannel_configuration (config , portchannel_info , evpn_system_mac )
279279
280280 # Add VRF configuration
281- _add_vrf_configuration (config , vrf_info , netbox_interfaces )
281+ _add_vrf_configuration (config , vrf_info , vlan_info , netbox_interfaces )
282282
283283 # Set DATABASE VERSION from config_version parameter or default
284284 if "VERSIONS" not in config :
@@ -1927,12 +1927,13 @@ def _get_vrf_info(device):
19271927 return vrf_info
19281928
19291929
1930- def _add_vrf_configuration (config , vrf_info , netbox_interfaces ):
1930+ def _add_vrf_configuration (config , vrf_info , vlan_info , netbox_interfaces ):
19311931 """Add VRF configuration to config.
19321932
19331933 Args:
19341934 config: Configuration dictionary to update
19351935 vrf_info: VRF information dictionary from _get_vrf_info()
1936+ vlan_info: VLAN information dictionary from get_device_vlans()
19361937 netbox_interfaces: Dict mapping SONiC names to NetBox interface info
19371938 """
19381939 # Track VRFs with VNI for VXLAN configuration
@@ -2019,8 +2020,11 @@ def _add_vrf_configuration(config, vrf_info, netbox_interfaces):
20192020 config ["BGP_GLOBALS" ][vrf_name ] = copy .deepcopy (default_bgp )
20202021 logger .info (f"Added BGP_GLOBALS for VRF { vrf_name } " )
20212022
2022- # Add VXLAN configuration if there are VRFs with VNI
2023- if vrfs_with_vni :
2023+ # Collect L2 VNI VLANs (tagged evpn-l2vni in NetBox, VNI == VID)
2024+ l2vni_vlans = vlan_info .get ("l2vni_vlans" , {})
2025+
2026+ # Add VXLAN configuration if there are VRFs with VNI or L2 VNI VLANs
2027+ if vrfs_with_vni or l2vni_vlans :
20242028 # Get source IP from BGP_GLOBALS default router_id
20252029 src_ip = config .get ("BGP_GLOBALS" , {}).get ("default" , {}).get ("router_id" , "" )
20262030
@@ -2039,7 +2043,7 @@ def _add_vrf_configuration(config, vrf_info, netbox_interfaces):
20392043 }
20402044 logger .info (f"Added VXLAN_EVPN_NVO nvo1 with source_vtep { VXLAN_VTEP_NAME } " )
20412045
2042- # Add VXLAN_TUNNEL_MAP for each VRF with VNI
2046+ # Add VXLAN_TUNNEL_MAP for each VRF with VNI (L3 / IRB)
20432047 for vrf_entry in vrfs_with_vni :
20442048 vni = vrf_entry ["vni" ]
20452049 vlan_name = f"Vlan{ vni } "
@@ -2050,6 +2054,22 @@ def _add_vrf_configuration(config, vrf_info, netbox_interfaces):
20502054 }
20512055 logger .info (f"Added VXLAN_TUNNEL_MAP { map_key } " )
20522056
2057+ # Add VXLAN_TUNNEL_MAP for each L2 VNI VLAN (pure L2, no VRF assignment)
2058+ vrf_vnis = {entry ["vni" ] for entry in vrfs_with_vni }
2059+ for vid , vni in l2vni_vlans .items ():
2060+ if vni in vrf_vnis :
2061+ logger .debug (
2062+ f"Skipping L2 VNI { vni } for Vlan{ vid } : already covered by VRF tunnel map"
2063+ )
2064+ continue
2065+ vlan_name = f"Vlan{ vid } "
2066+ map_key = f"{ VXLAN_VTEP_NAME } |map_{ vni } _{ vlan_name } "
2067+ config ["VXLAN_TUNNEL_MAP" ][map_key ] = {
2068+ "vlan" : vlan_name ,
2069+ "vni" : str (vni ),
2070+ }
2071+ logger .info (f"Added L2 VXLAN_TUNNEL_MAP { map_key } " )
2072+
20532073 # Add VRF assignments to interfaces
20542074 for sonic_interface , vrf_name in vrf_info ["interface_vrf_mapping" ].items ():
20552075 # Check if this is a regular interface
0 commit comments