diff options
-rw-r--r-- | internal/pkg/table/path.go | 30 | ||||
-rw-r--r-- | pkg/server/server.go | 6 | ||||
-rw-r--r-- | pkg/server/zclient.go | 66 |
3 files changed, 51 insertions, 51 deletions
diff --git a/internal/pkg/table/path.go b/internal/pkg/table/path.go index bdeb6ff2..b6080ffa 100644 --- a/internal/pkg/table/path.go +++ b/internal/pkg/table/path.go @@ -133,14 +133,13 @@ type Validation struct { } type Path struct { - info *originInfo - parent *Path - pathAttrs []bgp.PathAttributeInterface - dels []bgp.BGPAttrType - attrsHash uint32 - aslooped bool - reason BestPathReason - receiveVrfId uint32 //VRF in which the path was received. + info *originInfo + parent *Path + pathAttrs []bgp.PathAttributeInterface + dels []bgp.BGPAttrType + attrsHash uint32 + aslooped bool + reason BestPathReason // For BGP Nexthop Tracking, this field shows if nexthop is invalidated by IGP. IsNexthopInvalid bool @@ -168,9 +167,8 @@ func NewPath(source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, pa timestamp: timestamp.Unix(), noImplicitWithdraw: noImplicitWithdraw, }, - IsWithdraw: isWithdraw, - pathAttrs: pattrs, - receiveVrfId: 0, + IsWithdraw: isWithdraw, + pathAttrs: pattrs, } } @@ -334,13 +332,6 @@ func (path *Path) IsIBGP() bool { return (as == path.GetSource().LocalAS) && as != 0 } -func (path *Path) ReceiveVrfId() uint32 { - return path.receiveVrfId -} -func (path *Path) SetReceiveVrfId(vrfId uint32) { - path.receiveVrfId = vrfId -} - // create new PathAttributes func (path *Path) Clone(isWithdraw bool) *Path { return &Path{ @@ -348,7 +339,6 @@ func (path *Path) Clone(isWithdraw bool) *Path { IsWithdraw: isWithdraw, IsNexthopInvalid: path.IsNexthopInvalid, attrsHash: path.attrsHash, - receiveVrfId: path.receiveVrfId, } } @@ -590,7 +580,6 @@ func (path *Path) String() string { if path.IsWithdraw { s.WriteString(", withdraw") } - s.WriteString(fmt.Sprintf(", receiveVrfId: %d", path.receiveVrfId)) s.WriteString(" }") return s.String() } @@ -1149,7 +1138,6 @@ func (p *Path) ToGlobal(vrf *Vrf) *Path { path.delPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP) path.setPathAttr(bgp.NewPathAttributeMpReachNLRI(nh.String(), []bgp.AddrPrefixInterface{nlri})) path.IsNexthopInvalid = p.IsNexthopInvalid - path.receiveVrfId = p.receiveVrfId return path } diff --git a/pkg/server/server.go b/pkg/server/server.go index 71508666..414e5dbf 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -958,8 +958,10 @@ func (s *BgpServer) propagateUpdate(peer *peer, pathList []*table.Path) { peer.fsm.lock.RLock() peerVrf := peer.fsm.pConf.Config.Vrf peer.fsm.lock.RUnlock() - path.SetReceiveVrfId(rib.Vrfs[peerVrf].Id) path = path.ToGlobal(rib.Vrfs[peerVrf]) + if s.zclient != nil { + s.zclient.pathVrf[path] = rib.Vrfs[peerVrf].Id + } } policyOptions := &table.PolicyOptions{} @@ -2086,7 +2088,7 @@ func (s *BgpServer) AddVrf(ctx context.Context, r *api.AddVrfRequest) error { s.propagateUpdate(nil, pathList) } if vrf, ok := s.globalRib.Vrfs[name]; ok { - if s.bgpConfig.Zebra.Config.MplsLabelRangeSize > 0 { + if s.zclient != nil && s.zclient.mplsLabelRangeSize > 0 { go assignMplsLabel(s, vrf) } } diff --git a/pkg/server/zclient.go b/pkg/server/zclient.go index f4276e5b..3a650cfe 100644 --- a/pkg/server/zclient.go +++ b/pkg/server/zclient.go @@ -35,6 +35,9 @@ import ( // the metric value of math.MaxUint32 means the nexthop is unreachable. type nexthopStateCache map[string]uint32 +// pathVrfMap stores nexthop vpn id of VPN paths in global rib +type pathVrfMap map[*table.Path]uint32 + func (m nexthopStateCache) applyToPathList(paths []*table.Path) []*table.Path { updated := make([]*table.Path, 0, len(paths)) for _, path := range paths { @@ -116,13 +119,26 @@ func filterOutExternalPath(paths []*table.Path) []*table.Path { return filteredPaths } -func newIPRouteBody(dst []*table.Path, vrfId uint32, version uint8) (body *zebra.IPRouteBody, isWithdraw bool) { +func addMessageLabelToIPRouteBody(path *table.Path, vrfId uint32, z *zebraClient, msgFlags *zebra.MESSAGE_FLAG, nexthop *zebra.Nexthop) { + v := z.client.Version + nhVrfId := z.pathVrf[path] + rf := path.GetRouteFamily() + if v > 4 && (rf == bgp.RF_IPv4_VPN || rf == bgp.RF_IPv6_VPN) && nhVrfId != vrfId { + *msgFlags |= zebra.FRR_ZAPI5_MESSAGE_LABEL + for _, label := range path.GetNlri().(*bgp.LabeledVPNIPAddrPrefix).Labels.Labels { + nexthop.LabelNum++ + nexthop.MplsLabels = append(nexthop.MplsLabels, label) + } + } +} + +func newIPRouteBody(dst []*table.Path, vrfId uint32, z *zebraClient) (body *zebra.IPRouteBody, isWithdraw bool) { + version := z.client.Version paths := filterOutExternalPath(dst) if len(paths) == 0 { return nil, false } path := paths[0] - receiveVrfId := path.ReceiveVrfId() l := strings.SplitN(path.GetNlri().String(), "/", 2) var prefix net.IP @@ -136,39 +152,31 @@ func newIPRouteBody(dst []*table.Path, vrfId uint32, version uint8) (body *zebra } else { prefix = path.GetNlri().(*bgp.LabeledVPNIPAddrPrefix).IPAddrPrefixDefault.Prefix.To4() } - for _, p := range paths { - nexthop.Gate = p.GetNexthop().To4() - nexthop.VrfId = receiveVrfId - if version > 4 && path.GetRouteFamily() == bgp.RF_IPv4_VPN && receiveVrfId != vrfId { - msgFlags |= zebra.FRR_ZAPI5_MESSAGE_LABEL - for _, label := range path.GetNlri().(*bgp.LabeledVPNIPAddrPrefix).Labels.Labels { - nexthop.LabelNum++ - nexthop.MplsLabels = append(nexthop.MplsLabels, label) - } - } - nexthops = append(nexthops, nexthop) - } case bgp.RF_IPv6_UC, bgp.RF_IPv6_VPN: if path.GetRouteFamily() == bgp.RF_IPv6_UC { prefix = path.GetNlri().(*bgp.IPv6AddrPrefix).IPAddrPrefixDefault.Prefix.To16() } else { prefix = path.GetNlri().(*bgp.LabeledVPNIPv6AddrPrefix).IPAddrPrefixDefault.Prefix.To16() } - for _, p := range paths { - nexthop.Gate = p.GetNexthop().To16() - nexthop.VrfId = receiveVrfId - if version > 4 && path.GetRouteFamily() == bgp.RF_IPv6_VPN && receiveVrfId != vrfId { - msgFlags |= zebra.FRR_ZAPI5_MESSAGE_LABEL - for _, label := range path.GetNlri().(*bgp.LabeledVPNIPAddrPrefix).Labels.Labels { - nexthop.LabelNum++ - nexthop.MplsLabels = append(nexthop.MplsLabels, label) - } - } - nexthops = append(nexthops, nexthop) - } default: return nil, false } + var nhVrfId uint32 + if nhvrfid, ok := z.pathVrf[path]; ok { + // if the path is withdraw, delete path from Map pathVrf after refer the path + nhVrfId = nhvrfid + if isWithdraw { + delete(z.pathVrf, path) + } + } else { + nhVrfId = zebra.VRF_DEFAULT + } + for _, p := range paths { + nexthop.Gate = p.GetNexthop() + nexthop.VrfId = nhVrfId + addMessageLabelToIPRouteBody(path, vrfId, z, &msgFlags, &nexthop) + nexthops = append(nexthops, nexthop) + } plen, _ := strconv.ParseUint(l[1], 10, 8) med, err := path.GetMed() if err == nil { @@ -305,6 +313,7 @@ type zebraClient struct { client *zebra.Client server *BgpServer nexthopCache nexthopStateCache + pathVrf pathVrfMap mplsLabelRangeCh chan [2]uint32 // {start, end} mplsLabelRangeSize uint32 dead chan struct{} @@ -402,7 +411,7 @@ func (z *zebraClient) loop() { if table.UseMultiplePaths.Enabled { for _, paths := range msg.MultiPathList { z.updatePathByNexthopCache(paths) - if body, isWithdraw := newIPRouteBody(paths, 0, z.client.Version); body != nil { + if body, isWithdraw := newIPRouteBody(paths, 0, z); body != nil { z.client.SendIPRoute(0, body, isWithdraw) } if body := newNexthopRegisterBody(paths, z.nexthopCache); body != nil { @@ -423,7 +432,7 @@ func (z *zebraClient) loop() { if i == zebra.VRF_DEFAULT && (routeFamily == bgp.RF_IPv4_VPN || routeFamily == bgp.RF_IPv6_VPN) { continue } - if body, isWithdraw := newIPRouteBody([]*table.Path{path}, i, z.client.Version); body != nil { + if body, isWithdraw := newIPRouteBody([]*table.Path{path}, i, z); body != nil { err := z.client.SendIPRoute(i, body, isWithdraw) if err != nil { continue @@ -506,6 +515,7 @@ func newZebraClient(s *BgpServer, url string, protos []string, version uint8, nh client: cli, server: s, nexthopCache: make(nexthopStateCache), + pathVrf: make(pathVrfMap), mplsLabelRangeSize: mplsLabelRangeSize, dead: make(chan struct{}), mplsLabelRangeCh: make(chan [2]uint32), |