From 3d0f595e1941a9d3611ceec103a3da96a94052ff Mon Sep 17 00:00:00 2001 From: Sergei Lukianov Date: Mon, 13 Nov 2023 19:46:47 -0800 Subject: [PATCH] Complete spine-leaf underlay --- pkg/agent/dozer/bcm/plan.go | 42 +++++++++++++++++++++++++++++-- pkg/agent/dozer/bcm/spec_vxlan.go | 3 +++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/pkg/agent/dozer/bcm/plan.go b/pkg/agent/dozer/bcm/plan.go index 1293a400..4e0e523c 100644 --- a/pkg/agent/dozer/bcm/plan.go +++ b/pkg/agent/dozer/bcm/plan.go @@ -37,6 +37,9 @@ const ( LO_PROTO = "Loopback1" LO_VTEP = "Loopback2" VRF_DEFAULT = "default" + VTEP_FABRIC = "vtepfabric" + EVPN_NVO = "nvo1" + ANYCAST_MAC = "00:00:00:11:11:11" ) func (p *broadcomProcessor) PlanDesiredState(ctx context.Context, agent *agentapi.Agent) (*dozer.Spec, error) { @@ -95,7 +98,7 @@ func (p *broadcomProcessor) PlanDesiredState(ctx context.Context, agent *agentap return nil, errors.Wrap(err, "failed to plan switch IP loopbacks") } - err = planBGP(agent, spec) + err = planDefaultVRFWithBGP(agent, spec) if err != nil { return nil, errors.Wrap(err, "failed to plan basic BGP") } @@ -111,6 +114,13 @@ func (p *broadcomProcessor) PlanDesiredState(ctx context.Context, agent *agentap return nil, errors.Wrap(err, "failed to plan server connections") } + if agent.Spec.Role.IsLeaf() { + err = planVXLAN(agent, spec) + if err != nil { + return nil, errors.Wrap(err, "failed to plan VXLAN") + } + } + first, err := planMCLAGDomain(agent, spec) if err != nil { return nil, errors.Wrap(err, "failed to plan mclag domain") @@ -338,6 +348,7 @@ func planFabricConnections(agent *agentapi.Agent, spec *dozer.Spec) error { Description: stringPtr(fmt.Sprintf("Fabric %s // %s", remote, conn.Name)), RemoteAS: uint32Ptr(peerSw.ASN), IPv4Unicast: boolPtr(true), + L2VPNEVPN: boolPtr(true), } } } @@ -425,7 +436,7 @@ func planServerConnections(agent *agentapi.Agent, spec *dozer.Spec) error { return nil } -func planBGP(agent *agentapi.Agent, spec *dozer.Spec) error { +func planDefaultVRFWithBGP(agent *agentapi.Agent, spec *dozer.Spec) error { ip, _, err := net.ParseCIDR(agent.Spec.Switch.ProtocolIP) if err != nil { return errors.Wrapf(err, "failed to parse protocol ip %s", agent.Spec.Switch.ProtocolIP) @@ -434,6 +445,7 @@ func planBGP(agent *agentapi.Agent, spec *dozer.Spec) error { spec.VRFs[VRF_DEFAULT] = &dozer.SpecVRF{ Enabled: boolPtr(true), Interfaces: map[string]*dozer.SpecVRFInterface{}, + AnycastMAC: stringPtr(ANYCAST_MAC), BGP: &dozer.SpecVRFBGP{ AS: uint32Ptr(agent.Spec.Switch.ASN), RouterID: stringPtr(ip.String()), @@ -443,6 +455,10 @@ func planBGP(agent *agentapi.Agent, spec *dozer.Spec) error { Enabled: true, MaxPaths: uint32Ptr(64), }, + L2VPNEVPN: dozer.SpecVRFBGPL2VPNEVPN{ + Enabled: true, + AdvertiseAllVNI: boolPtr(true), + }, }, TableConnections: map[string]*dozer.SpecVRFTableConnection{ dozer.SpecVRFBGPTableConnectionConnected: {}, @@ -453,6 +469,28 @@ func planBGP(agent *agentapi.Agent, spec *dozer.Spec) error { return nil } +func planVXLAN(agent *agentapi.Agent, spec *dozer.Spec) error { + ip, _, err := net.ParseCIDR(agent.Spec.Switch.VTEPIP) + if err != nil { + return errors.Wrapf(err, "failed to parse vtep ip %s", agent.Spec.Switch.VTEPIP) + } + + spec.VXLANTunnels = map[string]*dozer.SpecVXLANTunnel{ + VTEP_FABRIC: { + SourceIP: stringPtr(ip.String()), + SourceInterface: stringPtr(LO_VTEP), + }, + } + + spec.VXLANEVPNNVOs = map[string]*dozer.SpecVXLANEVPNNVO{ + EVPN_NVO: { + SourceVTEP: stringPtr(VTEP_FABRIC), + }, + } + + return nil +} + func planMCLAGDomain(agent *agentapi.Agent, spec *dozer.Spec) (bool, error) { ok := false mclagPeerLinks := []string{} diff --git a/pkg/agent/dozer/bcm/spec_vxlan.go b/pkg/agent/dozer/bcm/spec_vxlan.go index 9a64b8c5..748b0c90 100644 --- a/pkg/agent/dozer/bcm/spec_vxlan.go +++ b/pkg/agent/dozer/bcm/spec_vxlan.go @@ -20,6 +20,7 @@ var specVXLANTunnelsEnforcer = &DefaultMapEnforcer[string, *dozer.SpecVXLANTunne var specVXLANTunnelEnforcer = &DefaultValueEnforcer[string, *dozer.SpecVXLANTunnel]{ Summary: "VXLAN tunnel %s", + CreatePath: "/sonic-vxlan/VXLAN_TUNNEL/VXLAN_TUNNEL_LIST", Path: "/sonic-vxlan/VXLAN_TUNNEL/VXLAN_TUNNEL_LIST[name=%s]", UpdateWeight: ActionWeightVXLANTunnelUpdate, DeleteWeight: ActionWeightVXLANTunnelDelete, @@ -43,6 +44,7 @@ var specVXLANEVPNNVOsEnforcer = &DefaultMapEnforcer[string, *dozer.SpecVXLANEVPN var specVXLANEVPNNVOEnforcer = &DefaultValueEnforcer[string, *dozer.SpecVXLANEVPNNVO]{ Summary: "VXLAN EVPN NVO %s", + CreatePath: "/sonic-vxlan/VXLAN_EVPN_NVO/VXLAN_EVPN_NVO_LIST", Path: "/sonic-vxlan/VXLAN_EVPN_NVO/VXLAN_EVPN_NVO_LIST[name=%s]", UpdateWeight: ActionWeightVXLANEVPNNVOUpdate, DeleteWeight: ActionWeightVXLANEVPNNVODelete, @@ -65,6 +67,7 @@ var specVXLANTunnelMapsEnforcer = &DefaultMapEnforcer[string, *dozer.SpecVXLANTu var specVXLANTunnelMapEnforcer = &DefaultValueEnforcer[string, *dozer.SpecVXLANTunnelMap]{ Summary: "VXLAN tunnel map %s", + CreatePath: "/sonic-vxlan/VXLAN_TUNNEL_MAP/VXLAN_TUNNEL_MAP_LIST", Path: "/sonic-vxlan/VXLAN_TUNNEL_MAP/VXLAN_TUNNEL_MAP_LIST[name=vtepfabric][mapname=%s]", // TODO unhardcode vtepfabric, but it's always only single vtep configured UpdateWeight: ActionWeightVXLANTunnelMapUpdate, DeleteWeight: ActionWeightVXLANTunnelMapDelete,