github.com/osrg/gobgp@v2.0.0+incompatible/pkg/server/server.go (about) 1 // Copyright (C) 2014-2016 Nippon Telegraph and Telephone Corporation. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 // implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package server 17 18 import ( 19 "bytes" 20 "context" 21 "fmt" 22 "net" 23 "strconv" 24 "sync" 25 "time" 26 27 "github.com/eapache/channels" 28 uuid "github.com/satori/go.uuid" 29 log "github.com/sirupsen/logrus" 30 "google.golang.org/grpc" 31 32 api "github.com/osrg/gobgp/api" 33 "github.com/osrg/gobgp/internal/pkg/apiutil" 34 "github.com/osrg/gobgp/internal/pkg/config" 35 "github.com/osrg/gobgp/internal/pkg/table" 36 "github.com/osrg/gobgp/internal/pkg/zebra" 37 "github.com/osrg/gobgp/pkg/packet/bgp" 38 ) 39 40 type tcpListener struct { 41 l *net.TCPListener 42 ch chan struct{} 43 } 44 45 func (l *tcpListener) Close() error { 46 if err := l.l.Close(); err != nil { 47 return err 48 } 49 <-l.ch 50 return nil 51 } 52 53 // avoid mapped IPv6 address 54 func newTCPListener(address string, port uint32, ch chan *net.TCPConn) (*tcpListener, error) { 55 proto := "tcp4" 56 if ip := net.ParseIP(address); ip == nil { 57 return nil, fmt.Errorf("can't listen on %s", address) 58 } else if ip.To4() == nil { 59 proto = "tcp6" 60 } 61 addr, err := net.ResolveTCPAddr(proto, net.JoinHostPort(address, strconv.Itoa(int(port)))) 62 if err != nil { 63 return nil, err 64 } 65 66 l, err := net.ListenTCP(proto, addr) 67 if err != nil { 68 return nil, err 69 } 70 // Note: Set TTL=255 for incoming connection listener in order to accept 71 // connection in case for the neighbor has TTL Security settings. 72 if err := setListenTCPTTLSockopt(l, 255); err != nil { 73 log.WithFields(log.Fields{ 74 "Topic": "Peer", 75 "Key": addr, 76 }).Warnf("cannot set TTL(=%d) for TCPListener: %s", 255, err) 77 } 78 79 closeCh := make(chan struct{}) 80 go func() error { 81 for { 82 conn, err := l.AcceptTCP() 83 if err != nil { 84 close(closeCh) 85 log.WithFields(log.Fields{ 86 "Topic": "Peer", 87 "Error": err, 88 }).Warn("Failed to AcceptTCP") 89 return err 90 } 91 ch <- conn 92 } 93 }() 94 return &tcpListener{ 95 l: l, 96 ch: closeCh, 97 }, nil 98 } 99 100 type options struct { 101 grpcAddress string 102 grpcOption []grpc.ServerOption 103 } 104 105 type ServerOption func(*options) 106 107 func GrpcListenAddress(addr string) ServerOption { 108 return func(o *options) { 109 o.grpcAddress = addr 110 } 111 } 112 113 func GrpcOption(opt []grpc.ServerOption) ServerOption { 114 return func(o *options) { 115 o.grpcOption = opt 116 } 117 } 118 119 type BgpServer struct { 120 bgpConfig config.Bgp 121 fsmincomingCh *channels.InfiniteChannel 122 fsmStateCh chan *fsmMsg 123 acceptCh chan *net.TCPConn 124 125 mgmtCh chan *mgmtOp 126 policy *table.RoutingPolicy 127 listeners []*tcpListener 128 neighborMap map[string]*peer 129 peerGroupMap map[string]*peerGroup 130 globalRib *table.TableManager 131 rsRib *table.TableManager 132 roaManager *roaManager 133 shutdownWG *sync.WaitGroup 134 watcherMap map[watchEventType][]*watcher 135 zclient *zebraClient 136 bmpManager *bmpClientManager 137 mrtManager *mrtManager 138 uuidMap map[uuid.UUID]string 139 } 140 141 func NewBgpServer(opt ...ServerOption) *BgpServer { 142 opts := options{} 143 for _, o := range opt { 144 o(&opts) 145 } 146 147 roaManager, _ := newROAManager(0) 148 s := &BgpServer{ 149 neighborMap: make(map[string]*peer), 150 peerGroupMap: make(map[string]*peerGroup), 151 policy: table.NewRoutingPolicy(), 152 roaManager: roaManager, 153 mgmtCh: make(chan *mgmtOp, 1), 154 watcherMap: make(map[watchEventType][]*watcher), 155 uuidMap: make(map[uuid.UUID]string), 156 } 157 s.bmpManager = newBmpClientManager(s) 158 s.mrtManager = newMrtManager(s) 159 if len(opts.grpcAddress) != 0 { 160 grpc.EnableTracing = false 161 api := newAPIserver(s, grpc.NewServer(opts.grpcOption...), opts.grpcAddress) 162 go func() { 163 if err := api.serve(); err != nil { 164 log.Fatalf("failed to listen grpc port: %s", err) 165 } 166 }() 167 168 } 169 return s 170 } 171 172 func (s *BgpServer) listListeners(addr string) []*net.TCPListener { 173 list := make([]*net.TCPListener, 0, len(s.listeners)) 174 rhs := net.ParseIP(addr).To4() != nil 175 for _, l := range s.listeners { 176 host, _, _ := net.SplitHostPort(l.l.Addr().String()) 177 lhs := net.ParseIP(host).To4() != nil 178 if lhs == rhs { 179 list = append(list, l.l) 180 } 181 } 182 return list 183 } 184 185 func (s *BgpServer) active() error { 186 if s.bgpConfig.Global.Config.As == 0 { 187 return fmt.Errorf("bgp server hasn't started yet") 188 } 189 return nil 190 } 191 192 type mgmtOp struct { 193 f func() error 194 errCh chan error 195 checkActive bool // check BGP global setting is configured before calling f() 196 } 197 198 func (s *BgpServer) handleMGMTOp(op *mgmtOp) { 199 if op.checkActive { 200 if err := s.active(); err != nil { 201 op.errCh <- err 202 return 203 } 204 } 205 op.errCh <- op.f() 206 } 207 208 func (s *BgpServer) mgmtOperation(f func() error, checkActive bool) (err error) { 209 ch := make(chan error) 210 defer func() { err = <-ch }() 211 s.mgmtCh <- &mgmtOp{ 212 f: f, 213 errCh: ch, 214 checkActive: checkActive, 215 } 216 return 217 } 218 219 func (s *BgpServer) Serve() { 220 s.listeners = make([]*tcpListener, 0, 2) 221 s.fsmincomingCh = channels.NewInfiniteChannel() 222 s.fsmStateCh = make(chan *fsmMsg, 4096) 223 224 handlefsmMsg := func(e *fsmMsg) { 225 peer, found := s.neighborMap[e.MsgSrc] 226 if !found { 227 log.WithFields(log.Fields{ 228 "Topic": "Peer", 229 }).Warnf("Can't find the neighbor %s", e.MsgSrc) 230 return 231 } 232 peer.fsm.lock.RLock() 233 versionMismatch := e.Version != peer.fsm.version 234 peer.fsm.lock.RUnlock() 235 if versionMismatch { 236 log.WithFields(log.Fields{ 237 "Topic": "Peer", 238 }).Debug("FSM version inconsistent") 239 return 240 } 241 s.handleFSMMessage(peer, e) 242 } 243 244 for { 245 passConn := func(conn *net.TCPConn) { 246 host, _, _ := net.SplitHostPort(conn.RemoteAddr().String()) 247 ipaddr, _ := net.ResolveIPAddr("ip", host) 248 remoteAddr := ipaddr.String() 249 peer, found := s.neighborMap[remoteAddr] 250 if found { 251 peer.fsm.lock.RLock() 252 adminStateNotUp := peer.fsm.adminState != adminStateUp 253 peer.fsm.lock.RUnlock() 254 if adminStateNotUp { 255 peer.fsm.lock.RLock() 256 log.WithFields(log.Fields{ 257 "Topic": "Peer", 258 "Remote Addr": remoteAddr, 259 "Admin State": peer.fsm.adminState, 260 }).Debug("New connection for non admin-state-up peer") 261 peer.fsm.lock.RUnlock() 262 conn.Close() 263 return 264 } 265 peer.fsm.lock.RLock() 266 localAddr := peer.fsm.pConf.Transport.Config.LocalAddress 267 peer.fsm.lock.RUnlock() 268 localAddrValid := func(laddr string) bool { 269 if laddr == "0.0.0.0" || laddr == "::" { 270 return true 271 } 272 l := conn.LocalAddr() 273 if l == nil { 274 // already closed 275 return false 276 } 277 278 host, _, _ := net.SplitHostPort(l.String()) 279 if host != laddr { 280 log.WithFields(log.Fields{ 281 "Topic": "Peer", 282 "Key": remoteAddr, 283 "Configured addr": laddr, 284 "Addr": host, 285 }).Info("Mismatched local address") 286 return false 287 } 288 return true 289 }(localAddr) 290 291 if !localAddrValid { 292 conn.Close() 293 return 294 } 295 296 log.WithFields(log.Fields{ 297 "Topic": "Peer", 298 }).Debugf("Accepted a new passive connection from:%s", remoteAddr) 299 peer.PassConn(conn) 300 } else if pg := s.matchLongestDynamicNeighborPrefix(remoteAddr); pg != nil { 301 log.WithFields(log.Fields{ 302 "Topic": "Peer", 303 }).Debugf("Accepted a new dynamic neighbor from:%s", remoteAddr) 304 rib := s.globalRib 305 if pg.Conf.RouteServer.Config.RouteServerClient { 306 rib = s.rsRib 307 } 308 peer := newDynamicPeer(&s.bgpConfig.Global, remoteAddr, pg.Conf, rib, s.policy) 309 if peer == nil { 310 log.WithFields(log.Fields{ 311 "Topic": "Peer", 312 "Key": remoteAddr, 313 }).Infof("Can't create new Dynamic Peer") 314 conn.Close() 315 return 316 } 317 peer.fsm.lock.RLock() 318 policy := peer.fsm.pConf.ApplyPolicy 319 peer.fsm.lock.RUnlock() 320 s.policy.Reset(nil, map[string]config.ApplyPolicy{peer.ID(): policy}) 321 s.neighborMap[remoteAddr] = peer 322 peer.startFSMHandler(s.fsmincomingCh, s.fsmStateCh) 323 s.broadcastPeerState(peer, bgp.BGP_FSM_ACTIVE, nil) 324 peer.PassConn(conn) 325 } else { 326 log.WithFields(log.Fields{ 327 "Topic": "Peer", 328 }).Infof("Can't find configuration for a new passive connection from:%s", remoteAddr) 329 conn.Close() 330 } 331 } 332 333 select { 334 case op := <-s.mgmtCh: 335 s.handleMGMTOp(op) 336 case conn := <-s.acceptCh: 337 passConn(conn) 338 default: 339 } 340 341 for { 342 select { 343 case e := <-s.fsmStateCh: 344 handlefsmMsg(e) 345 default: 346 goto CONT 347 } 348 } 349 CONT: 350 351 select { 352 case op := <-s.mgmtCh: 353 s.handleMGMTOp(op) 354 case rmsg := <-s.roaManager.ReceiveROA(): 355 s.roaManager.HandleROAEvent(rmsg) 356 case conn := <-s.acceptCh: 357 passConn(conn) 358 case e, ok := <-s.fsmincomingCh.Out(): 359 if !ok { 360 continue 361 } 362 handlefsmMsg(e.(*fsmMsg)) 363 case e := <-s.fsmStateCh: 364 handlefsmMsg(e) 365 } 366 } 367 } 368 369 func (s *BgpServer) matchLongestDynamicNeighborPrefix(a string) *peerGroup { 370 ipAddr := net.ParseIP(a) 371 longestMask := net.CIDRMask(0, 32).String() 372 var longestPG *peerGroup 373 for _, pg := range s.peerGroupMap { 374 for _, d := range pg.dynamicNeighbors { 375 _, netAddr, _ := net.ParseCIDR(d.Config.Prefix) 376 if netAddr.Contains(ipAddr) { 377 if netAddr.Mask.String() > longestMask { 378 longestMask = netAddr.Mask.String() 379 longestPG = pg 380 } 381 } 382 } 383 } 384 return longestPG 385 } 386 387 func sendfsmOutgoingMsg(peer *peer, paths []*table.Path, notification *bgp.BGPMessage, stayIdle bool) { 388 peer.outgoing.In() <- &fsmOutgoingMsg{ 389 Paths: paths, 390 Notification: notification, 391 StayIdle: stayIdle, 392 } 393 } 394 395 func isASLoop(peer *peer, path *table.Path) bool { 396 for _, as := range path.GetAsList() { 397 if as == peer.AS() { 398 return true 399 } 400 } 401 return false 402 } 403 404 func filterpath(peer *peer, path, old *table.Path) *table.Path { 405 if path == nil { 406 return nil 407 } 408 409 peer.fsm.lock.RLock() 410 _, ok := peer.fsm.rfMap[path.GetRouteFamily()] 411 peer.fsm.lock.RUnlock() 412 if !ok { 413 return nil 414 } 415 416 //RFC4684 Constrained Route Distribution 417 peer.fsm.lock.RLock() 418 _, y := peer.fsm.rfMap[bgp.RF_RTC_UC] 419 peer.fsm.lock.RUnlock() 420 if y && path.GetRouteFamily() != bgp.RF_RTC_UC { 421 ignore := true 422 for _, ext := range path.GetExtCommunities() { 423 for _, p := range peer.adjRibIn.PathList([]bgp.RouteFamily{bgp.RF_RTC_UC}, true) { 424 rt := p.GetNlri().(*bgp.RouteTargetMembershipNLRI).RouteTarget 425 // Note: nil RT means the default route target 426 if rt == nil || ext.String() == rt.String() { 427 ignore = false 428 break 429 } 430 } 431 if !ignore { 432 break 433 } 434 } 435 if ignore { 436 log.WithFields(log.Fields{ 437 "Topic": "Peer", 438 "Key": peer.ID(), 439 "Data": path, 440 }).Debug("Filtered by Route Target Constraint, ignore") 441 return nil 442 } 443 } 444 445 //iBGP handling 446 if peer.isIBGPPeer() { 447 ignore := false 448 if !path.IsLocal() { 449 ignore = true 450 info := path.GetSource() 451 //if the path comes from eBGP peer 452 if info.AS != peer.AS() { 453 ignore = false 454 } 455 if info.RouteReflectorClient { 456 ignore = false 457 } 458 if peer.isRouteReflectorClient() { 459 // RFC4456 8. Avoiding Routing Information Loops 460 // If the local CLUSTER_ID is found in the CLUSTER_LIST, 461 // the advertisement received SHOULD be ignored. 462 for _, clusterID := range path.GetClusterList() { 463 peer.fsm.lock.RLock() 464 rrClusterID := peer.fsm.peerInfo.RouteReflectorClusterID 465 peer.fsm.lock.RUnlock() 466 if clusterID.Equal(rrClusterID) { 467 log.WithFields(log.Fields{ 468 "Topic": "Peer", 469 "Key": peer.ID(), 470 "ClusterID": clusterID, 471 "Data": path, 472 }).Debug("cluster list path attribute has local cluster id, ignore") 473 return nil 474 } 475 } 476 ignore = false 477 } 478 } 479 480 if ignore { 481 if !path.IsWithdraw && old != nil { 482 oldSource := old.GetSource() 483 if old.IsLocal() || oldSource.Address.String() != peer.ID() && oldSource.AS != peer.AS() { 484 // In this case, we suppose this peer has the same prefix 485 // received from another iBGP peer. 486 // So we withdraw the old best which was injected locally 487 // (from CLI or gRPC for example) in order to avoid the 488 // old best left on peers. 489 // Also, we withdraw the eBGP route which is the old best. 490 // When we got the new best from iBGP, we don't advertise 491 // the new best and need to withdraw the old best. 492 return old.Clone(true) 493 } 494 } 495 log.WithFields(log.Fields{ 496 "Topic": "Peer", 497 "Key": peer.ID(), 498 "Data": path, 499 }).Debug("From same AS, ignore.") 500 return nil 501 } 502 } 503 504 if path = peer.filterPathFromSourcePeer(path, old); path == nil { 505 return nil 506 } 507 508 if !peer.isRouteServerClient() && isASLoop(peer, path) { 509 return nil 510 } 511 return path 512 } 513 514 func (s *BgpServer) filterpath(peer *peer, path, old *table.Path) *table.Path { 515 // Special handling for RTM NLRI. 516 if path != nil && path.GetRouteFamily() == bgp.RF_RTC_UC && !path.IsWithdraw { 517 // If the given "path" is locally generated and the same with "old", we 518 // assumes "path" was already sent before. This assumption avoids the 519 // infinite UPDATE loop between Route Reflector and its clients. 520 if path.IsLocal() && path.Equal(old) { 521 peer.fsm.lock.RLock() 522 log.WithFields(log.Fields{ 523 "Topic": "Peer", 524 "Key": peer.fsm.pConf.State.NeighborAddress, 525 "Path": path, 526 }).Debug("given rtm nlri is already sent, skipping to advertise") 527 peer.fsm.lock.RUnlock() 528 return nil 529 } 530 531 if old != nil && old.IsLocal() { 532 // We assumes VRF with the specific RT is deleted. 533 path = old.Clone(true) 534 } else if peer.isRouteReflectorClient() { 535 // We need to send the path even if the peer is originator of the 536 // path in order to signal that the client should distribute route 537 // with the given RT. 538 } else { 539 // We send a path even if it is not the best path. See comments in 540 // (*Destination) GetChanges(). 541 dst := peer.localRib.GetDestination(path) 542 path = nil 543 for _, p := range dst.GetKnownPathList(peer.TableID(), peer.AS()) { 544 srcPeer := p.GetSource() 545 if peer.ID() != srcPeer.Address.String() { 546 if srcPeer.RouteReflectorClient { 547 // The path from a RR client is preferred than others 548 // for the case that RR and non RR client peering 549 // (e.g., peering of different RR clusters). 550 path = p 551 break 552 } else if path == nil { 553 path = p 554 } 555 } 556 } 557 } 558 } 559 560 // only allow vpnv4 and vpnv6 paths to be advertised to VRFed neighbors. 561 // also check we can import this path using table.CanImportToVrf() 562 // if we can, make it local path by calling (*Path).ToLocal() 563 peer.fsm.lock.RLock() 564 peerVrf := peer.fsm.pConf.Config.Vrf 565 peer.fsm.lock.RUnlock() 566 if path != nil && peerVrf != "" { 567 if f := path.GetRouteFamily(); f != bgp.RF_IPv4_VPN && f != bgp.RF_IPv6_VPN { 568 return nil 569 } 570 vrf := peer.localRib.Vrfs[peerVrf] 571 if table.CanImportToVrf(vrf, path) { 572 path = path.ToLocal() 573 } else { 574 return nil 575 } 576 } 577 578 // replace-peer-as handling 579 peer.fsm.lock.RLock() 580 if path != nil && !path.IsWithdraw && peer.fsm.pConf.AsPathOptions.State.ReplacePeerAs { 581 path = path.ReplaceAS(peer.fsm.pConf.Config.LocalAs, peer.fsm.pConf.Config.PeerAs) 582 } 583 peer.fsm.lock.RUnlock() 584 585 if path = filterpath(peer, path, old); path == nil { 586 return nil 587 } 588 589 peer.fsm.lock.RLock() 590 options := &table.PolicyOptions{ 591 Info: peer.fsm.peerInfo, 592 OldNextHop: path.GetNexthop(), 593 } 594 path = table.UpdatePathAttrs(peer.fsm.gConf, peer.fsm.pConf, peer.fsm.peerInfo, path) 595 596 if v := s.roaManager.validate(path); v != nil { 597 options.ValidationResult = v 598 } 599 peer.fsm.lock.RUnlock() 600 601 path = peer.policy.ApplyPolicy(peer.TableID(), table.POLICY_DIRECTION_EXPORT, path, options) 602 // When 'path' is filtered (path == nil), check 'old' has been sent to this peer. 603 // If it has, send withdrawal to the peer. 604 if path == nil && old != nil { 605 o := peer.policy.ApplyPolicy(peer.TableID(), table.POLICY_DIRECTION_EXPORT, old, options) 606 if o != nil { 607 path = old.Clone(true) 608 } 609 } 610 611 // draft-uttaro-idr-bgp-persistence-02 612 // 4.3. Processing LLGR_STALE Routes 613 // 614 // The route SHOULD NOT be advertised to any neighbor from which the 615 // Long-lived Graceful Restart Capability has not been received. The 616 // exception is described in the Optional Partial Deployment 617 // Procedure section (Section 4.7). Note that this requirement 618 // implies that such routes should be withdrawn from any such neighbor. 619 if path != nil && !path.IsWithdraw && !peer.isLLGREnabledFamily(path.GetRouteFamily()) && path.IsLLGRStale() { 620 // we send unnecessary withdrawn even if we didn't 621 // sent the route. 622 path = path.Clone(true) 623 } 624 625 // remove local-pref attribute 626 // we should do this after applying export policy since policy may 627 // set local-preference 628 if path != nil && !peer.isIBGPPeer() && !peer.isRouteServerClient() { 629 path.RemoveLocalPref() 630 } 631 return path 632 } 633 634 func clonePathList(pathList []*table.Path) []*table.Path { 635 l := make([]*table.Path, 0, len(pathList)) 636 for _, p := range pathList { 637 if p != nil { 638 l = append(l, p.Clone(p.IsWithdraw)) 639 } 640 } 641 return l 642 } 643 644 func (s *BgpServer) notifyBestWatcher(best []*table.Path, multipath [][]*table.Path) { 645 if table.SelectionOptions.DisableBestPathSelection { 646 // Note: If best path selection disabled, no best path to notify. 647 return 648 } 649 clonedM := make([][]*table.Path, len(multipath)) 650 for i, pathList := range multipath { 651 clonedM[i] = clonePathList(pathList) 652 } 653 clonedB := clonePathList(best) 654 m := make(map[string]uint32) 655 for _, p := range clonedB { 656 switch p.GetRouteFamily() { 657 case bgp.RF_IPv4_VPN, bgp.RF_IPv6_VPN: 658 for _, vrf := range s.globalRib.Vrfs { 659 if vrf.Id != 0 && table.CanImportToVrf(vrf, p) { 660 m[p.GetNlri().String()] = uint32(vrf.Id) 661 } 662 } 663 } 664 } 665 w := &watchEventBestPath{PathList: clonedB, MultiPathList: clonedM} 666 if len(m) > 0 { 667 w.Vrf = m 668 } 669 s.notifyWatcher(watchEventTypeBestPath, w) 670 } 671 672 func (s *BgpServer) toConfig(peer *peer, getAdvertised bool) *config.Neighbor { 673 // create copy which can be access to without mutex 674 peer.fsm.lock.RLock() 675 conf := *peer.fsm.pConf 676 peerAfiSafis := peer.fsm.pConf.AfiSafis 677 peerCapMap := peer.fsm.capMap 678 peer.fsm.lock.RUnlock() 679 680 conf.AfiSafis = make([]config.AfiSafi, len(peerAfiSafis)) 681 for i, af := range peerAfiSafis { 682 conf.AfiSafis[i] = af 683 conf.AfiSafis[i].AddPaths.State.Receive = peer.isAddPathReceiveEnabled(af.State.Family) 684 if peer.isAddPathSendEnabled(af.State.Family) { 685 conf.AfiSafis[i].AddPaths.State.SendMax = af.AddPaths.State.SendMax 686 } else { 687 conf.AfiSafis[i].AddPaths.State.SendMax = 0 688 } 689 } 690 691 remoteCap := make([]bgp.ParameterCapabilityInterface, 0, len(peerCapMap)) 692 for _, caps := range peerCapMap { 693 for _, m := range caps { 694 // need to copy all values here 695 buf, _ := m.Serialize() 696 c, _ := bgp.DecodeCapability(buf) 697 remoteCap = append(remoteCap, c) 698 } 699 } 700 701 conf.State.RemoteCapabilityList = remoteCap 702 703 peer.fsm.lock.RLock() 704 conf.State.LocalCapabilityList = capabilitiesFromConfig(peer.fsm.pConf) 705 conf.State.SessionState = config.IntToSessionStateMap[int(peer.fsm.state)] 706 conf.State.AdminState = config.IntToAdminStateMap[int(peer.fsm.adminState)] 707 state := peer.fsm.state 708 peer.fsm.lock.RUnlock() 709 710 if state == bgp.BGP_FSM_ESTABLISHED { 711 peer.fsm.lock.RLock() 712 conf.Transport.State.LocalAddress, conf.Transport.State.LocalPort = peer.fsm.LocalHostPort() 713 _, conf.Transport.State.RemotePort = peer.fsm.RemoteHostPort() 714 buf, _ := peer.fsm.recvOpen.Serialize() 715 // need to copy all values here 716 conf.State.ReceivedOpenMessage, _ = bgp.ParseBGPMessage(buf) 717 conf.State.RemoteRouterId = peer.fsm.peerInfo.ID.To4().String() 718 peer.fsm.lock.RUnlock() 719 } 720 return &conf 721 } 722 723 func (s *BgpServer) notifyPrePolicyUpdateWatcher(peer *peer, pathList []*table.Path, msg *bgp.BGPMessage, timestamp time.Time, payload []byte) { 724 if !s.isWatched(watchEventTypePreUpdate) || peer == nil { 725 return 726 } 727 728 cloned := clonePathList(pathList) 729 if len(cloned) == 0 { 730 return 731 } 732 n := s.toConfig(peer, false) 733 peer.fsm.lock.RLock() 734 _, y := peer.fsm.capMap[bgp.BGP_CAP_FOUR_OCTET_AS_NUMBER] 735 l, _ := peer.fsm.LocalHostPort() 736 ev := &watchEventUpdate{ 737 Message: msg, 738 PeerAS: peer.fsm.peerInfo.AS, 739 LocalAS: peer.fsm.peerInfo.LocalAS, 740 PeerAddress: peer.fsm.peerInfo.Address, 741 LocalAddress: net.ParseIP(l), 742 PeerID: peer.fsm.peerInfo.ID, 743 FourBytesAs: y, 744 Timestamp: timestamp, 745 Payload: payload, 746 PostPolicy: false, 747 PathList: cloned, 748 Neighbor: n, 749 } 750 peer.fsm.lock.RUnlock() 751 s.notifyWatcher(watchEventTypePreUpdate, ev) 752 } 753 754 func (s *BgpServer) notifyPostPolicyUpdateWatcher(peer *peer, pathList []*table.Path) { 755 if !s.isWatched(watchEventTypePostUpdate) || peer == nil { 756 return 757 } 758 759 cloned := clonePathList(pathList) 760 if len(cloned) == 0 { 761 return 762 } 763 n := s.toConfig(peer, false) 764 peer.fsm.lock.RLock() 765 _, y := peer.fsm.capMap[bgp.BGP_CAP_FOUR_OCTET_AS_NUMBER] 766 l, _ := peer.fsm.LocalHostPort() 767 ev := &watchEventUpdate{ 768 PeerAS: peer.fsm.peerInfo.AS, 769 LocalAS: peer.fsm.peerInfo.LocalAS, 770 PeerAddress: peer.fsm.peerInfo.Address, 771 LocalAddress: net.ParseIP(l), 772 PeerID: peer.fsm.peerInfo.ID, 773 FourBytesAs: y, 774 Timestamp: cloned[0].GetTimestamp(), 775 PostPolicy: true, 776 PathList: cloned, 777 Neighbor: n, 778 } 779 peer.fsm.lock.RUnlock() 780 s.notifyWatcher(watchEventTypePostUpdate, ev) 781 } 782 783 func newWatchEventPeerState(peer *peer, m *fsmMsg) *watchEventPeerState { 784 _, rport := peer.fsm.RemoteHostPort() 785 laddr, lport := peer.fsm.LocalHostPort() 786 sentOpen := buildopen(peer.fsm.gConf, peer.fsm.pConf) 787 peer.fsm.lock.RLock() 788 recvOpen := peer.fsm.recvOpen 789 e := &watchEventPeerState{ 790 PeerAS: peer.fsm.peerInfo.AS, 791 LocalAS: peer.fsm.peerInfo.LocalAS, 792 PeerAddress: peer.fsm.peerInfo.Address, 793 LocalAddress: net.ParseIP(laddr), 794 PeerPort: rport, 795 LocalPort: lport, 796 PeerID: peer.fsm.peerInfo.ID, 797 SentOpen: sentOpen, 798 RecvOpen: recvOpen, 799 State: peer.fsm.state, 800 AdminState: peer.fsm.adminState, 801 Timestamp: time.Now(), 802 PeerInterface: peer.fsm.pConf.Config.NeighborInterface, 803 } 804 peer.fsm.lock.RUnlock() 805 806 if m != nil { 807 e.StateReason = m.StateReason 808 } 809 return e 810 } 811 812 func (s *BgpServer) broadcastPeerState(peer *peer, oldState bgp.FSMState, e *fsmMsg) { 813 peer.fsm.lock.RLock() 814 newState := peer.fsm.state 815 peer.fsm.lock.RUnlock() 816 if oldState == bgp.BGP_FSM_ESTABLISHED || newState == bgp.BGP_FSM_ESTABLISHED { 817 s.notifyWatcher(watchEventTypePeerState, newWatchEventPeerState(peer, e)) 818 } 819 } 820 821 func (s *BgpServer) notifyMessageWatcher(peer *peer, timestamp time.Time, msg *bgp.BGPMessage, isSent bool) { 822 // validation should be done in the caller of this function 823 peer.fsm.lock.RLock() 824 _, y := peer.fsm.capMap[bgp.BGP_CAP_FOUR_OCTET_AS_NUMBER] 825 l, _ := peer.fsm.LocalHostPort() 826 ev := &watchEventMessage{ 827 Message: msg, 828 PeerAS: peer.fsm.peerInfo.AS, 829 LocalAS: peer.fsm.peerInfo.LocalAS, 830 PeerAddress: peer.fsm.peerInfo.Address, 831 LocalAddress: net.ParseIP(l), 832 PeerID: peer.fsm.peerInfo.ID, 833 FourBytesAs: y, 834 Timestamp: timestamp, 835 IsSent: isSent, 836 } 837 peer.fsm.lock.RUnlock() 838 if !isSent { 839 s.notifyWatcher(watchEventTypeRecvMsg, ev) 840 } 841 } 842 843 func (s *BgpServer) notifyRecvMessageWatcher(peer *peer, timestamp time.Time, msg *bgp.BGPMessage) { 844 if peer == nil || !s.isWatched(watchEventTypeRecvMsg) { 845 return 846 } 847 s.notifyMessageWatcher(peer, timestamp, msg, false) 848 } 849 850 func (s *BgpServer) getBestFromLocal(peer *peer, rfList []bgp.RouteFamily) ([]*table.Path, []*table.Path) { 851 pathList := []*table.Path{} 852 filtered := []*table.Path{} 853 for _, family := range peer.toGlobalFamilies(rfList) { 854 pl := func() []*table.Path { 855 if peer.isAddPathSendEnabled(family) { 856 return peer.localRib.GetPathList(peer.TableID(), peer.AS(), []bgp.RouteFamily{family}) 857 } 858 return peer.localRib.GetBestPathList(peer.TableID(), peer.AS(), []bgp.RouteFamily{family}) 859 }() 860 for _, path := range pl { 861 if p := s.filterpath(peer, path, nil); p != nil { 862 pathList = append(pathList, p) 863 } else { 864 filtered = append(filtered, path) 865 } 866 } 867 } 868 if peer.isGracefulRestartEnabled() { 869 for _, family := range rfList { 870 pathList = append(pathList, table.NewEOR(family)) 871 } 872 } 873 return pathList, filtered 874 } 875 876 func (s *BgpServer) processOutgoingPaths(peer *peer, paths, olds []*table.Path) []*table.Path { 877 peer.fsm.lock.RLock() 878 notEstablished := peer.fsm.state != bgp.BGP_FSM_ESTABLISHED 879 localRestarting := peer.fsm.pConf.GracefulRestart.State.LocalRestarting 880 peer.fsm.lock.RUnlock() 881 if notEstablished { 882 return nil 883 } 884 if localRestarting { 885 peer.fsm.lock.RLock() 886 log.WithFields(log.Fields{ 887 "Topic": "Peer", 888 "Key": peer.fsm.pConf.State.NeighborAddress, 889 }).Debug("now syncing, suppress sending updates") 890 peer.fsm.lock.RUnlock() 891 return nil 892 } 893 894 outgoing := make([]*table.Path, 0, len(paths)) 895 896 for idx, path := range paths { 897 var old *table.Path 898 if olds != nil { 899 old = olds[idx] 900 } 901 if p := s.filterpath(peer, path, old); p != nil { 902 outgoing = append(outgoing, p) 903 } 904 } 905 return outgoing 906 } 907 908 func (s *BgpServer) handleRouteRefresh(peer *peer, e *fsmMsg) []*table.Path { 909 m := e.MsgData.(*bgp.BGPMessage) 910 rr := m.Body.(*bgp.BGPRouteRefresh) 911 rf := bgp.AfiSafiToRouteFamily(rr.AFI, rr.SAFI) 912 913 peer.fsm.lock.RLock() 914 _, ok := peer.fsm.rfMap[rf] 915 peer.fsm.lock.RUnlock() 916 if !ok { 917 log.WithFields(log.Fields{ 918 "Topic": "Peer", 919 "Key": peer.ID(), 920 "Data": rf, 921 }).Warn("Route family isn't supported") 922 return nil 923 } 924 925 peer.fsm.lock.RLock() 926 _, ok = peer.fsm.capMap[bgp.BGP_CAP_ROUTE_REFRESH] 927 peer.fsm.lock.RUnlock() 928 if !ok { 929 log.WithFields(log.Fields{ 930 "Topic": "Peer", 931 "Key": peer.ID(), 932 }).Warn("ROUTE_REFRESH received but the capability wasn't advertised") 933 return nil 934 } 935 rfList := []bgp.RouteFamily{rf} 936 accepted, _ := s.getBestFromLocal(peer, rfList) 937 return accepted 938 } 939 940 func (s *BgpServer) propagateUpdate(peer *peer, pathList []*table.Path) { 941 rs := peer != nil && peer.isRouteServerClient() 942 vrf := false 943 if peer != nil { 944 peer.fsm.lock.RLock() 945 vrf = !rs && peer.fsm.pConf.Config.Vrf != "" 946 peer.fsm.lock.RUnlock() 947 } 948 949 tableId := table.GLOBAL_RIB_NAME 950 rib := s.globalRib 951 if rs { 952 tableId = peer.TableID() 953 rib = s.rsRib 954 } 955 956 for _, path := range pathList { 957 if vrf { 958 peer.fsm.lock.RLock() 959 peerVrf := peer.fsm.pConf.Config.Vrf 960 peer.fsm.lock.RUnlock() 961 path = path.ToGlobal(rib.Vrfs[peerVrf]) 962 } 963 964 policyOptions := &table.PolicyOptions{} 965 966 if !rs && peer != nil { 967 peer.fsm.lock.RLock() 968 policyOptions.Info = peer.fsm.peerInfo 969 peer.fsm.lock.RUnlock() 970 } 971 if v := s.roaManager.validate(path); v != nil { 972 policyOptions.ValidationResult = v 973 } 974 975 if p := s.policy.ApplyPolicy(tableId, table.POLICY_DIRECTION_IMPORT, path, policyOptions); p != nil { 976 path = p 977 } else { 978 path = path.Clone(true) 979 } 980 981 if !rs { 982 s.notifyPostPolicyUpdateWatcher(peer, []*table.Path{path}) 983 984 // RFC4684 Constrained Route Distribution 6. Operation 985 // 986 // When a BGP speaker receives a BGP UPDATE that advertises or withdraws 987 // a given Route Target membership NLRI, it should examine the RIB-OUTs 988 // of VPN NLRIs and re-evaluate the advertisement status of routes that 989 // match the Route Target in question. 990 // 991 // A BGP speaker should generate the minimum set of BGP VPN route 992 // updates (advertisements and/or withdraws) necessary to transition 993 // between the previous and current state of the route distribution 994 // graph that is derived from Route Target membership information. 995 if peer != nil && path != nil && path.GetRouteFamily() == bgp.RF_RTC_UC { 996 rt := path.GetNlri().(*bgp.RouteTargetMembershipNLRI).RouteTarget 997 fs := make([]bgp.RouteFamily, 0, len(peer.negotiatedRFList())) 998 for _, f := range peer.negotiatedRFList() { 999 if f != bgp.RF_RTC_UC { 1000 fs = append(fs, f) 1001 } 1002 } 1003 var candidates []*table.Path 1004 if path.IsWithdraw { 1005 // Note: The paths to be withdrawn are filtered because the 1006 // given RT on RTM NLRI is already removed from adj-RIB-in. 1007 _, candidates = s.getBestFromLocal(peer, fs) 1008 } else { 1009 // https://github.com/osrg/gobgp/issues/1777 1010 // Ignore duplicate Membership announcements 1011 membershipsForSource := s.globalRib.GetPathListWithSource(table.GLOBAL_RIB_NAME, []bgp.RouteFamily{bgp.RF_RTC_UC}, path.GetSource()) 1012 found := false 1013 for _, membership := range membershipsForSource { 1014 if membership.GetNlri().(*bgp.RouteTargetMembershipNLRI).RouteTarget.String() == rt.String() { 1015 found = true 1016 break 1017 } 1018 } 1019 if !found { 1020 candidates = s.globalRib.GetBestPathList(peer.TableID(), 0, fs) 1021 } 1022 } 1023 paths := make([]*table.Path, 0, len(candidates)) 1024 for _, p := range candidates { 1025 for _, ext := range p.GetExtCommunities() { 1026 if rt == nil || ext.String() == rt.String() { 1027 if path.IsWithdraw { 1028 p = p.Clone(true) 1029 } 1030 paths = append(paths, p) 1031 break 1032 } 1033 } 1034 } 1035 if path.IsWithdraw { 1036 // Skips filtering because the paths are already filtered 1037 // and the withdrawal does not need the path attributes. 1038 } else { 1039 paths = s.processOutgoingPaths(peer, paths, nil) 1040 } 1041 sendfsmOutgoingMsg(peer, paths, nil, false) 1042 } 1043 } 1044 1045 if dsts := rib.Update(path); len(dsts) > 0 { 1046 s.propagateUpdateToNeighbors(peer, path, dsts, true) 1047 } 1048 } 1049 } 1050 1051 func (s *BgpServer) dropPeerAllRoutes(peer *peer, families []bgp.RouteFamily) { 1052 peer.fsm.lock.RLock() 1053 peerInfo := peer.fsm.peerInfo 1054 peer.fsm.lock.RUnlock() 1055 1056 rib := s.globalRib 1057 if peer.isRouteServerClient() { 1058 rib = s.rsRib 1059 } 1060 for _, family := range peer.toGlobalFamilies(families) { 1061 for _, path := range rib.GetPathListByPeer(peerInfo, family) { 1062 p := path.Clone(true) 1063 if dsts := rib.Update(p); len(dsts) > 0 { 1064 s.propagateUpdateToNeighbors(peer, p, dsts, false) 1065 } 1066 } 1067 } 1068 } 1069 1070 func dstsToPaths(id string, as uint32, dsts []*table.Update) ([]*table.Path, []*table.Path, [][]*table.Path) { 1071 bestList := make([]*table.Path, 0, len(dsts)) 1072 oldList := make([]*table.Path, 0, len(dsts)) 1073 mpathList := make([][]*table.Path, 0, len(dsts)) 1074 1075 for _, dst := range dsts { 1076 best, old, mpath := dst.GetChanges(id, as, false) 1077 bestList = append(bestList, best) 1078 oldList = append(oldList, old) 1079 if mpath != nil { 1080 mpathList = append(mpathList, mpath) 1081 } 1082 } 1083 return bestList, oldList, mpathList 1084 } 1085 1086 func (s *BgpServer) propagateUpdateToNeighbors(source *peer, newPath *table.Path, dsts []*table.Update, needOld bool) { 1087 if table.SelectionOptions.DisableBestPathSelection { 1088 return 1089 } 1090 var gBestList, gOldList, bestList, oldList []*table.Path 1091 var mpathList [][]*table.Path 1092 if source == nil || !source.isRouteServerClient() { 1093 gBestList, gOldList, mpathList = dstsToPaths(table.GLOBAL_RIB_NAME, 0, dsts) 1094 s.notifyBestWatcher(gBestList, mpathList) 1095 } 1096 family := newPath.GetRouteFamily() 1097 for _, targetPeer := range s.neighborMap { 1098 if (source == nil && targetPeer.isRouteServerClient()) || (source != nil && source.isRouteServerClient() != targetPeer.isRouteServerClient()) { 1099 continue 1100 } 1101 f := func() bgp.RouteFamily { 1102 targetPeer.fsm.lock.RLock() 1103 peerVrf := targetPeer.fsm.pConf.Config.Vrf 1104 targetPeer.fsm.lock.RUnlock() 1105 if peerVrf != "" { 1106 switch family { 1107 case bgp.RF_IPv4_VPN: 1108 return bgp.RF_IPv4_UC 1109 case bgp.RF_IPv6_VPN: 1110 return bgp.RF_IPv6_UC 1111 } 1112 } 1113 return family 1114 }() 1115 if targetPeer.isAddPathSendEnabled(f) { 1116 if newPath.IsWithdraw { 1117 bestList = func() []*table.Path { 1118 l := make([]*table.Path, 0, len(dsts)) 1119 for _, d := range dsts { 1120 l = append(l, d.GetWithdrawnPath()...) 1121 } 1122 return l 1123 }() 1124 } else { 1125 bestList = []*table.Path{newPath} 1126 if newPath.GetRouteFamily() == bgp.RF_RTC_UC { 1127 // we assumes that new "path" nlri was already sent before. This assumption avoids the 1128 // infinite UPDATE loop between Route Reflector and its clients. 1129 for _, old := range dsts[0].OldKnownPathList { 1130 if old.IsLocal() { 1131 bestList = []*table.Path{} 1132 break 1133 } 1134 } 1135 } 1136 } 1137 oldList = nil 1138 } else if targetPeer.isRouteServerClient() { 1139 bestList, oldList, _ = dstsToPaths(targetPeer.TableID(), targetPeer.AS(), dsts) 1140 } else { 1141 bestList = gBestList 1142 oldList = gOldList 1143 } 1144 if !needOld { 1145 oldList = nil 1146 } 1147 if paths := s.processOutgoingPaths(targetPeer, bestList, oldList); len(paths) > 0 { 1148 sendfsmOutgoingMsg(targetPeer, paths, nil, false) 1149 } 1150 } 1151 } 1152 1153 func (s *BgpServer) handleFSMMessage(peer *peer, e *fsmMsg) { 1154 switch e.MsgType { 1155 case fsmMsgStateChange: 1156 nextState := e.MsgData.(bgp.FSMState) 1157 peer.fsm.lock.Lock() 1158 oldState := bgp.FSMState(peer.fsm.pConf.State.SessionState.ToInt()) 1159 peer.fsm.pConf.State.SessionState = config.IntToSessionStateMap[int(nextState)] 1160 peer.fsm.lock.Unlock() 1161 1162 peer.fsm.StateChange(nextState) 1163 1164 peer.fsm.lock.RLock() 1165 nextStateIdle := peer.fsm.pConf.GracefulRestart.State.PeerRestarting && nextState == bgp.BGP_FSM_IDLE 1166 peer.fsm.lock.RUnlock() 1167 1168 // PeerDown 1169 if oldState == bgp.BGP_FSM_ESTABLISHED { 1170 t := time.Now() 1171 peer.fsm.lock.Lock() 1172 if t.Sub(time.Unix(peer.fsm.pConf.Timers.State.Uptime, 0)) < flopThreshold { 1173 peer.fsm.pConf.State.Flops++ 1174 } 1175 graceful := peer.fsm.reason.Type == fsmGracefulRestart 1176 peer.fsm.lock.Unlock() 1177 var drop []bgp.RouteFamily 1178 if graceful { 1179 peer.fsm.lock.Lock() 1180 peer.fsm.pConf.GracefulRestart.State.PeerRestarting = true 1181 peer.fsm.lock.Unlock() 1182 var p []bgp.RouteFamily 1183 p, drop = peer.forwardingPreservedFamilies() 1184 s.propagateUpdate(peer, peer.StaleAll(p)) 1185 } else { 1186 drop = peer.configuredRFlist() 1187 } 1188 peer.prefixLimitWarned = make(map[bgp.RouteFamily]bool) 1189 peer.DropAll(drop) 1190 s.dropPeerAllRoutes(peer, drop) 1191 1192 peer.fsm.lock.Lock() 1193 if peer.fsm.pConf.Config.PeerAs == 0 { 1194 peer.fsm.pConf.State.PeerAs = 0 1195 peer.fsm.peerInfo.AS = 0 1196 } 1197 peer.fsm.lock.Unlock() 1198 1199 if peer.isDynamicNeighbor() { 1200 peer.stopPeerRestarting() 1201 go peer.stopFSM() 1202 peer.fsm.lock.RLock() 1203 delete(s.neighborMap, peer.fsm.pConf.State.NeighborAddress) 1204 peer.fsm.lock.RUnlock() 1205 s.broadcastPeerState(peer, oldState, e) 1206 return 1207 } 1208 } else if nextStateIdle { 1209 peer.fsm.lock.RLock() 1210 longLivedEnabled := peer.fsm.pConf.GracefulRestart.State.LongLivedEnabled 1211 peer.fsm.lock.RUnlock() 1212 if longLivedEnabled { 1213 llgr, no_llgr := peer.llgrFamilies() 1214 1215 peer.DropAll(no_llgr) 1216 s.dropPeerAllRoutes(peer, no_llgr) 1217 1218 // attach LLGR_STALE community to paths in peer's adj-rib-in 1219 // paths with NO_LLGR are deleted 1220 pathList := peer.markLLGRStale(llgr) 1221 1222 // calculate again 1223 // wheh path with LLGR_STALE chosen as best, 1224 // peer which doesn't support LLGR will drop the path 1225 // if it is in adj-rib-out, do withdrawal 1226 s.propagateUpdate(peer, pathList) 1227 1228 for _, f := range llgr { 1229 endCh := make(chan struct{}) 1230 peer.llgrEndChs = append(peer.llgrEndChs, endCh) 1231 go func(family bgp.RouteFamily, endCh chan struct{}) { 1232 t := peer.llgrRestartTime(family) 1233 timer := time.NewTimer(time.Second * time.Duration(t)) 1234 1235 log.WithFields(log.Fields{ 1236 "Topic": "Peer", 1237 "Key": peer.ID(), 1238 "Family": family, 1239 }).Debugf("start LLGR restart timer (%d sec) for %s", t, family) 1240 1241 select { 1242 case <-timer.C: 1243 s.mgmtOperation(func() error { 1244 log.WithFields(log.Fields{ 1245 "Topic": "Peer", 1246 "Key": peer.ID(), 1247 "Family": family, 1248 }).Debugf("LLGR restart timer (%d sec) for %s expired", t, family) 1249 peer.DropAll([]bgp.RouteFamily{family}) 1250 s.dropPeerAllRoutes(peer, []bgp.RouteFamily{family}) 1251 1252 // when all llgr restart timer expired, stop PeerRestarting 1253 if peer.llgrRestartTimerExpired(family) { 1254 peer.stopPeerRestarting() 1255 } 1256 return nil 1257 }, false) 1258 case <-endCh: 1259 log.WithFields(log.Fields{ 1260 "Topic": "Peer", 1261 "Key": peer.ID(), 1262 "Family": family, 1263 }).Debugf("stop LLGR restart timer (%d sec) for %s", t, family) 1264 } 1265 }(f, endCh) 1266 } 1267 } else { 1268 // RFC 4724 4.2 1269 // If the session does not get re-established within the "Restart Time" 1270 // that the peer advertised previously, the Receiving Speaker MUST 1271 // delete all the stale routes from the peer that it is retaining. 1272 peer.fsm.lock.Lock() 1273 peer.fsm.pConf.GracefulRestart.State.PeerRestarting = false 1274 peer.fsm.lock.Unlock() 1275 peer.DropAll(peer.configuredRFlist()) 1276 s.dropPeerAllRoutes(peer, peer.configuredRFlist()) 1277 } 1278 } 1279 1280 cleanInfiniteChannel(peer.outgoing) 1281 peer.outgoing = channels.NewInfiniteChannel() 1282 if nextState == bgp.BGP_FSM_ESTABLISHED { 1283 // update for export policy 1284 laddr, _ := peer.fsm.LocalHostPort() 1285 // may include zone info 1286 peer.fsm.lock.Lock() 1287 peer.fsm.pConf.Transport.State.LocalAddress = laddr 1288 // exclude zone info 1289 ipaddr, _ := net.ResolveIPAddr("ip", laddr) 1290 peer.fsm.peerInfo.LocalAddress = ipaddr.IP 1291 neighborAddress := peer.fsm.pConf.State.NeighborAddress 1292 peer.fsm.lock.Unlock() 1293 deferralExpiredFunc := func(family bgp.RouteFamily) func() { 1294 return func() { 1295 s.mgmtOperation(func() error { 1296 s.softResetOut(neighborAddress, family, true) 1297 return nil 1298 }, false) 1299 } 1300 } 1301 peer.fsm.lock.RLock() 1302 notLocalRestarting := !peer.fsm.pConf.GracefulRestart.State.LocalRestarting 1303 peer.fsm.lock.RUnlock() 1304 if notLocalRestarting { 1305 // When graceful-restart cap (which means intention 1306 // of sending EOR) and route-target address family are negotiated, 1307 // send route-target NLRIs first, and wait to send others 1308 // till receiving EOR of route-target address family. 1309 // This prevents sending uninterested routes to peers. 1310 // 1311 // However, when the peer is graceful restarting, give up 1312 // waiting sending non-route-target NLRIs since the peer won't send 1313 // any routes (and EORs) before we send ours (or deferral-timer expires). 1314 var pathList []*table.Path 1315 peer.fsm.lock.RLock() 1316 _, y := peer.fsm.rfMap[bgp.RF_RTC_UC] 1317 c := peer.fsm.pConf.GetAfiSafi(bgp.RF_RTC_UC) 1318 notPeerRestarting := !peer.fsm.pConf.GracefulRestart.State.PeerRestarting 1319 peer.fsm.lock.RUnlock() 1320 if y && notPeerRestarting && c.RouteTargetMembership.Config.DeferralTime > 0 { 1321 pathList, _ = s.getBestFromLocal(peer, []bgp.RouteFamily{bgp.RF_RTC_UC}) 1322 t := c.RouteTargetMembership.Config.DeferralTime 1323 for _, f := range peer.negotiatedRFList() { 1324 if f != bgp.RF_RTC_UC { 1325 time.AfterFunc(time.Second*time.Duration(t), deferralExpiredFunc(f)) 1326 } 1327 } 1328 } else { 1329 pathList, _ = s.getBestFromLocal(peer, peer.negotiatedRFList()) 1330 } 1331 1332 if len(pathList) > 0 { 1333 sendfsmOutgoingMsg(peer, pathList, nil, false) 1334 } 1335 } else { 1336 // RFC 4724 4.1 1337 // Once the session between the Restarting Speaker and the Receiving 1338 // Speaker is re-established, ...snip... it MUST defer route 1339 // selection for an address family until it either (a) receives the 1340 // End-of-RIB marker from all its peers (excluding the ones with the 1341 // "Restart State" bit set in the received capability and excluding the 1342 // ones that do not advertise the graceful restart capability) or (b) 1343 // the Selection_Deferral_Timer referred to below has expired. 1344 allEnd := func() bool { 1345 for _, p := range s.neighborMap { 1346 if !p.recvedAllEOR() { 1347 return false 1348 } 1349 } 1350 return true 1351 }() 1352 if allEnd { 1353 for _, p := range s.neighborMap { 1354 p.fsm.lock.Lock() 1355 p.fsm.pConf.GracefulRestart.State.LocalRestarting = false 1356 p.fsm.lock.Unlock() 1357 if !p.isGracefulRestartEnabled() { 1358 continue 1359 } 1360 paths, _ := s.getBestFromLocal(p, p.configuredRFlist()) 1361 if len(paths) > 0 { 1362 sendfsmOutgoingMsg(p, paths, nil, false) 1363 } 1364 } 1365 log.WithFields(log.Fields{ 1366 "Topic": "Server", 1367 }).Info("sync finished") 1368 } else { 1369 peer.fsm.lock.RLock() 1370 deferral := peer.fsm.pConf.GracefulRestart.Config.DeferralTime 1371 peer.fsm.lock.RUnlock() 1372 log.WithFields(log.Fields{ 1373 "Topic": "Peer", 1374 "Key": peer.ID(), 1375 }).Debugf("Now syncing, suppress sending updates. start deferral timer(%d)", deferral) 1376 time.AfterFunc(time.Second*time.Duration(deferral), deferralExpiredFunc(bgp.RouteFamily(0))) 1377 } 1378 } 1379 } else { 1380 if s.shutdownWG != nil && nextState == bgp.BGP_FSM_IDLE { 1381 die := true 1382 for _, p := range s.neighborMap { 1383 p.fsm.lock.RLock() 1384 stateNotIdle := p.fsm.state != bgp.BGP_FSM_IDLE 1385 p.fsm.lock.RUnlock() 1386 if stateNotIdle { 1387 die = false 1388 break 1389 } 1390 } 1391 if die { 1392 s.shutdownWG.Done() 1393 } 1394 } 1395 peer.fsm.lock.Lock() 1396 peer.fsm.pConf.Timers.State.Downtime = time.Now().Unix() 1397 peer.fsm.lock.Unlock() 1398 } 1399 // clear counter 1400 peer.fsm.lock.RLock() 1401 adminStateDown := peer.fsm.adminState == adminStateDown 1402 peer.fsm.lock.RUnlock() 1403 if adminStateDown { 1404 peer.fsm.lock.Lock() 1405 peer.fsm.pConf.State = config.NeighborState{} 1406 peer.fsm.pConf.State.NeighborAddress = peer.fsm.pConf.Config.NeighborAddress 1407 peer.fsm.pConf.State.PeerAs = peer.fsm.pConf.Config.PeerAs 1408 peer.fsm.pConf.Timers.State = config.TimersState{} 1409 peer.fsm.lock.Unlock() 1410 } 1411 peer.startFSMHandler(s.fsmincomingCh, s.fsmStateCh) 1412 s.broadcastPeerState(peer, oldState, e) 1413 case fsmMsgRouteRefresh: 1414 peer.fsm.lock.RLock() 1415 notEstablished := peer.fsm.state != bgp.BGP_FSM_ESTABLISHED 1416 beforeUptime := e.timestamp.Unix() < peer.fsm.pConf.Timers.State.Uptime 1417 peer.fsm.lock.RUnlock() 1418 if notEstablished || beforeUptime { 1419 return 1420 } 1421 if paths := s.handleRouteRefresh(peer, e); len(paths) > 0 { 1422 sendfsmOutgoingMsg(peer, paths, nil, false) 1423 return 1424 } 1425 case fsmMsgBGPMessage: 1426 switch m := e.MsgData.(type) { 1427 case *bgp.MessageError: 1428 sendfsmOutgoingMsg(peer, nil, bgp.NewBGPNotificationMessage(m.TypeCode, m.SubTypeCode, m.Data), false) 1429 return 1430 case *bgp.BGPMessage: 1431 s.notifyRecvMessageWatcher(peer, e.timestamp, m) 1432 peer.fsm.lock.RLock() 1433 notEstablished := peer.fsm.state != bgp.BGP_FSM_ESTABLISHED 1434 beforeUptime := e.timestamp.Unix() < peer.fsm.pConf.Timers.State.Uptime 1435 peer.fsm.lock.RUnlock() 1436 if notEstablished || beforeUptime { 1437 return 1438 } 1439 pathList, eor, notification := peer.handleUpdate(e) 1440 if notification != nil { 1441 sendfsmOutgoingMsg(peer, nil, notification, true) 1442 return 1443 } 1444 if m.Header.Type == bgp.BGP_MSG_UPDATE { 1445 s.notifyPrePolicyUpdateWatcher(peer, pathList, m, e.timestamp, e.payload) 1446 } 1447 1448 if len(pathList) > 0 { 1449 s.propagateUpdate(peer, pathList) 1450 } 1451 1452 peer.fsm.lock.RLock() 1453 peerAfiSafis := peer.fsm.pConf.AfiSafis 1454 peer.fsm.lock.RUnlock() 1455 if len(eor) > 0 { 1456 rtc := false 1457 for _, f := range eor { 1458 if f == bgp.RF_RTC_UC { 1459 rtc = true 1460 } 1461 for i, a := range peerAfiSafis { 1462 if a.State.Family == f { 1463 peer.fsm.lock.Lock() 1464 peer.fsm.pConf.AfiSafis[i].MpGracefulRestart.State.EndOfRibReceived = true 1465 peer.fsm.lock.Unlock() 1466 } 1467 } 1468 } 1469 1470 // RFC 4724 4.1 1471 // Once the session between the Restarting Speaker and the Receiving 1472 // Speaker is re-established, ...snip... it MUST defer route 1473 // selection for an address family until it either (a) receives the 1474 // End-of-RIB marker from all its peers (excluding the ones with the 1475 // "Restart State" bit set in the received capability and excluding the 1476 // ones that do not advertise the graceful restart capability) or ...snip... 1477 1478 peer.fsm.lock.RLock() 1479 localRestarting := peer.fsm.pConf.GracefulRestart.State.LocalRestarting 1480 peer.fsm.lock.RUnlock() 1481 if localRestarting { 1482 allEnd := func() bool { 1483 for _, p := range s.neighborMap { 1484 if !p.recvedAllEOR() { 1485 return false 1486 } 1487 } 1488 return true 1489 }() 1490 if allEnd { 1491 for _, p := range s.neighborMap { 1492 p.fsm.lock.Lock() 1493 p.fsm.pConf.GracefulRestart.State.LocalRestarting = false 1494 p.fsm.lock.Unlock() 1495 if !p.isGracefulRestartEnabled() { 1496 continue 1497 } 1498 paths, _ := s.getBestFromLocal(p, p.negotiatedRFList()) 1499 if len(paths) > 0 { 1500 sendfsmOutgoingMsg(p, paths, nil, false) 1501 } 1502 } 1503 log.WithFields(log.Fields{ 1504 "Topic": "Server", 1505 }).Info("sync finished") 1506 1507 } 1508 1509 // we don't delay non-route-target NLRIs when local-restarting 1510 rtc = false 1511 } 1512 peer.fsm.lock.RLock() 1513 peerRestarting := peer.fsm.pConf.GracefulRestart.State.PeerRestarting 1514 peer.fsm.lock.RUnlock() 1515 if peerRestarting { 1516 if peer.recvedAllEOR() { 1517 peer.stopPeerRestarting() 1518 pathList := peer.adjRibIn.DropStale(peer.configuredRFlist()) 1519 peer.fsm.lock.RLock() 1520 log.WithFields(log.Fields{ 1521 "Topic": "Peer", 1522 "Key": peer.fsm.pConf.State.NeighborAddress, 1523 }).Debugf("withdraw %d stale routes", len(pathList)) 1524 peer.fsm.lock.RUnlock() 1525 s.propagateUpdate(peer, pathList) 1526 } 1527 1528 // we don't delay non-route-target NLRIs when peer is restarting 1529 rtc = false 1530 } 1531 1532 // received EOR of route-target address family 1533 // outbound filter is now ready, let's flash non-route-target NLRIs 1534 peer.fsm.lock.RLock() 1535 c := peer.fsm.pConf.GetAfiSafi(bgp.RF_RTC_UC) 1536 peer.fsm.lock.RUnlock() 1537 if rtc && c != nil && c.RouteTargetMembership.Config.DeferralTime > 0 { 1538 log.WithFields(log.Fields{ 1539 "Topic": "Peer", 1540 "Key": peer.ID(), 1541 }).Debug("received route-target eor. flash non-route-target NLRIs") 1542 families := make([]bgp.RouteFamily, 0, len(peer.negotiatedRFList())) 1543 for _, f := range peer.negotiatedRFList() { 1544 if f != bgp.RF_RTC_UC { 1545 families = append(families, f) 1546 } 1547 } 1548 if paths, _ := s.getBestFromLocal(peer, families); len(paths) > 0 { 1549 sendfsmOutgoingMsg(peer, paths, nil, false) 1550 } 1551 } 1552 } 1553 default: 1554 log.WithFields(log.Fields{ 1555 "Topic": "Peer", 1556 "Key": peer.fsm.pConf.State.NeighborAddress, 1557 "Data": e.MsgData, 1558 }).Panic("unknown msg type") 1559 } 1560 } 1561 } 1562 1563 func (s *BgpServer) EnableZebra(ctx context.Context, r *api.EnableZebraRequest) error { 1564 return s.mgmtOperation(func() error { 1565 if s.zclient != nil { 1566 return fmt.Errorf("already connected to Zebra") 1567 } 1568 1569 for _, p := range r.RouteTypes { 1570 if _, err := zebra.RouteTypeFromString(p, uint8(r.Version)); err != nil { 1571 return err 1572 } 1573 } 1574 1575 protos := make([]string, 0, len(r.RouteTypes)) 1576 for _, p := range r.RouteTypes { 1577 protos = append(protos, string(p)) 1578 } 1579 var err error 1580 s.zclient, err = newZebraClient(s, r.Url, protos, uint8(r.Version), r.NexthopTriggerEnable, uint8(r.NexthopTriggerDelay)) 1581 return err 1582 }, false) 1583 } 1584 1585 func (s *BgpServer) AddBmp(ctx context.Context, r *api.AddBmpRequest) error { 1586 return s.mgmtOperation(func() error { 1587 _, ok := api.AddBmpRequest_MonitoringPolicy_name[int32(r.Policy)] 1588 if !ok { 1589 return fmt.Errorf("invalid bmp route monitoring policy: %v", r.Policy) 1590 } 1591 return s.bmpManager.addServer(&config.BmpServerConfig{ 1592 Address: r.Address, 1593 Port: r.Port, 1594 RouteMonitoringPolicy: config.IntToBmpRouteMonitoringPolicyTypeMap[int(r.Policy)], 1595 StatisticsTimeout: uint16(r.StatisticsTimeout), 1596 }) 1597 }, true) 1598 } 1599 1600 func (s *BgpServer) DeleteBmp(ctx context.Context, r *api.DeleteBmpRequest) error { 1601 return s.mgmtOperation(func() error { 1602 return s.bmpManager.deleteServer(&config.BmpServerConfig{ 1603 Address: r.Address, 1604 Port: r.Port, 1605 }) 1606 }, true) 1607 } 1608 1609 func (s *BgpServer) StopBgp(ctx context.Context, r *api.StopBgpRequest) error { 1610 s.mgmtOperation(func() error { 1611 s.shutdownWG = new(sync.WaitGroup) 1612 s.shutdownWG.Add(1) 1613 1614 for k := range s.neighborMap { 1615 if err := s.deleteNeighbor(&config.Neighbor{Config: config.NeighborConfig{ 1616 NeighborAddress: k}}, bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_PEER_DECONFIGURED); err != nil { 1617 return err 1618 } 1619 } 1620 for _, l := range s.listeners { 1621 l.Close() 1622 } 1623 s.bgpConfig.Global = config.Global{} 1624 return nil 1625 }, false) 1626 1627 // Waits for all goroutines per peer to stop. 1628 // Note: This should not be wrapped with s.mgmtOperation() in order to 1629 // avoid the deadlock in the main goroutine of BgpServer. 1630 // if s.shutdownWG != nil { 1631 // s.shutdownWG.Wait() 1632 // s.shutdownWG = nil 1633 // } 1634 return nil 1635 } 1636 1637 func (s *BgpServer) SetPolicies(ctx context.Context, r *api.SetPoliciesRequest) error { 1638 rp, err := newRoutingPolicyFromApiStruct(r) 1639 if err != nil { 1640 return err 1641 } 1642 1643 getConfig := func(id string) (*config.ApplyPolicy, error) { 1644 f := func(id string, dir table.PolicyDirection) (config.DefaultPolicyType, []string, error) { 1645 rt, policies, err := s.policy.GetPolicyAssignment(id, dir) 1646 if err != nil { 1647 return config.DEFAULT_POLICY_TYPE_REJECT_ROUTE, nil, err 1648 } 1649 names := make([]string, 0, len(policies)) 1650 for _, p := range policies { 1651 names = append(names, p.Name) 1652 } 1653 t := config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE 1654 if rt == table.ROUTE_TYPE_REJECT { 1655 t = config.DEFAULT_POLICY_TYPE_REJECT_ROUTE 1656 } 1657 return t, names, nil 1658 } 1659 1660 c := &config.ApplyPolicy{} 1661 rt, policies, err := f(id, table.POLICY_DIRECTION_IMPORT) 1662 if err != nil { 1663 return nil, err 1664 } 1665 c.Config.ImportPolicyList = policies 1666 c.Config.DefaultImportPolicy = rt 1667 rt, policies, err = f(id, table.POLICY_DIRECTION_EXPORT) 1668 if err != nil { 1669 return nil, err 1670 } 1671 c.Config.ExportPolicyList = policies 1672 c.Config.DefaultExportPolicy = rt 1673 return c, nil 1674 } 1675 1676 return s.mgmtOperation(func() error { 1677 ap := make(map[string]config.ApplyPolicy, len(s.neighborMap)+1) 1678 a, err := getConfig(table.GLOBAL_RIB_NAME) 1679 if err != nil { 1680 return err 1681 } 1682 ap[table.GLOBAL_RIB_NAME] = *a 1683 for _, peer := range s.neighborMap { 1684 peer.fsm.lock.RLock() 1685 log.WithFields(log.Fields{ 1686 "Topic": "Peer", 1687 "Key": peer.fsm.pConf.State.NeighborAddress, 1688 }).Info("call set policy") 1689 peer.fsm.lock.RUnlock() 1690 a, err := getConfig(peer.ID()) 1691 if err != nil { 1692 return err 1693 } 1694 ap[peer.ID()] = *a 1695 } 1696 return s.policy.Reset(rp, ap) 1697 }, false) 1698 } 1699 1700 // EVPN MAC MOBILITY HANDLING 1701 // 1702 // We don't have multihoming function now, so ignore 1703 // ESI comparison. 1704 // 1705 // RFC7432 15. MAC Mobility 1706 // 1707 // A PE detecting a locally attached MAC address for which it had 1708 // previously received a MAC/IP Advertisement route with the same zero 1709 // Ethernet segment identifier (single-homed scenarios) advertises it 1710 // with a MAC Mobility extended community attribute with the sequence 1711 // number set properly. In the case of single-homed scenarios, there 1712 // is no need for ESI comparison. 1713 1714 func getMacMobilityExtendedCommunity(etag uint32, mac net.HardwareAddr, evpnPaths []*table.Path) *bgp.MacMobilityExtended { 1715 seqs := make([]struct { 1716 seq int 1717 isLocal bool 1718 }, 0) 1719 1720 for _, path := range evpnPaths { 1721 nlri := path.GetNlri().(*bgp.EVPNNLRI) 1722 target, ok := nlri.RouteTypeData.(*bgp.EVPNMacIPAdvertisementRoute) 1723 if !ok { 1724 continue 1725 } 1726 if target.ETag == etag && bytes.Equal(target.MacAddress, mac) { 1727 found := false 1728 for _, ec := range path.GetExtCommunities() { 1729 if t, st := ec.GetTypes(); t == bgp.EC_TYPE_EVPN && st == bgp.EC_SUBTYPE_MAC_MOBILITY { 1730 seqs = append(seqs, struct { 1731 seq int 1732 isLocal bool 1733 }{int(ec.(*bgp.MacMobilityExtended).Sequence), path.IsLocal()}) 1734 found = true 1735 break 1736 } 1737 } 1738 1739 if !found { 1740 seqs = append(seqs, struct { 1741 seq int 1742 isLocal bool 1743 }{-1, path.IsLocal()}) 1744 } 1745 } 1746 } 1747 1748 if len(seqs) > 0 { 1749 newSeq := -2 1750 var isLocal bool 1751 for _, seq := range seqs { 1752 if seq.seq > newSeq { 1753 newSeq = seq.seq 1754 isLocal = seq.isLocal 1755 } 1756 } 1757 1758 if !isLocal { 1759 newSeq += 1 1760 } 1761 1762 if newSeq != -1 { 1763 return &bgp.MacMobilityExtended{ 1764 Sequence: uint32(newSeq), 1765 } 1766 } 1767 } 1768 return nil 1769 } 1770 1771 func (s *BgpServer) fixupApiPath(vrfId string, pathList []*table.Path) error { 1772 for _, path := range pathList { 1773 if !path.IsWithdraw { 1774 if _, err := path.GetOrigin(); err != nil { 1775 return err 1776 } 1777 } 1778 1779 if vrfId != "" { 1780 vrf := s.globalRib.Vrfs[vrfId] 1781 if vrf == nil { 1782 return fmt.Errorf("vrf %s not found", vrfId) 1783 } 1784 if err := vrf.ToGlobalPath(path); err != nil { 1785 return err 1786 } 1787 } 1788 1789 // Address Family specific Handling 1790 switch nlri := path.GetNlri().(type) { 1791 case *bgp.EVPNNLRI: 1792 switch r := nlri.RouteTypeData.(type) { 1793 case *bgp.EVPNMacIPAdvertisementRoute: 1794 // MAC Mobility Extended Community 1795 paths := s.globalRib.GetBestPathList(table.GLOBAL_RIB_NAME, 0, []bgp.RouteFamily{bgp.RF_EVPN}) 1796 if m := getMacMobilityExtendedCommunity(r.ETag, r.MacAddress, paths); m != nil { 1797 pm := getMacMobilityExtendedCommunity(r.ETag, r.MacAddress, []*table.Path{path}) 1798 if pm == nil { 1799 path.SetExtCommunities([]bgp.ExtendedCommunityInterface{m}, false) 1800 } else if pm != nil && pm.Sequence < m.Sequence { 1801 return fmt.Errorf("Invalid MAC mobility sequence number") 1802 } 1803 } 1804 case *bgp.EVPNEthernetSegmentRoute: 1805 // RFC7432: BGP MPLS-Based Ethernet VPN 1806 // 7.6. ES-Import Route Target 1807 // The value is derived automatically for the ESI Types 1, 2, 1808 // and 3, by encoding the high-order 6-octet portion of the 9-octet ESI 1809 // Value, which corresponds to a MAC address, in the ES-Import Route 1810 // Target. 1811 // Note: If the given path already has the ES-Import Route Target, 1812 // skips deriving a new one. 1813 found := false 1814 for _, extComm := range path.GetExtCommunities() { 1815 if _, found = extComm.(*bgp.ESImportRouteTarget); found { 1816 break 1817 } 1818 } 1819 if !found { 1820 switch r.ESI.Type { 1821 case bgp.ESI_LACP, bgp.ESI_MSTP, bgp.ESI_MAC: 1822 mac := net.HardwareAddr(r.ESI.Value[0:6]) 1823 rt := &bgp.ESImportRouteTarget{ESImport: mac} 1824 path.SetExtCommunities([]bgp.ExtendedCommunityInterface{rt}, false) 1825 } 1826 } 1827 } 1828 } 1829 } 1830 return nil 1831 } 1832 1833 func pathTokey(path *table.Path) string { 1834 return fmt.Sprintf("%d:%s", path.GetNlri().PathIdentifier(), path.GetNlri().String()) 1835 } 1836 1837 func (s *BgpServer) addPathList(vrfId string, pathList []*table.Path) error { 1838 err := s.fixupApiPath(vrfId, pathList) 1839 if err == nil { 1840 s.propagateUpdate(nil, pathList) 1841 } 1842 return err 1843 } 1844 1845 func (s *BgpServer) AddPath(ctx context.Context, r *api.AddPathRequest) (*api.AddPathResponse, error) { 1846 var uuidBytes []byte 1847 err := s.mgmtOperation(func() error { 1848 path, err := api2Path(r.TableType, r.Path, false) 1849 if err != nil { 1850 return err 1851 } 1852 err = s.addPathList(r.VrfId, []*table.Path{path}) 1853 if err != nil { 1854 return err 1855 } 1856 id, _ := uuid.NewV4() 1857 s.uuidMap[id] = pathTokey(path) 1858 uuidBytes = id.Bytes() 1859 return nil 1860 }, true) 1861 return &api.AddPathResponse{Uuid: uuidBytes}, err 1862 } 1863 1864 func (s *BgpServer) DeletePath(ctx context.Context, r *api.DeletePathRequest) error { 1865 return s.mgmtOperation(func() error { 1866 deletePathList := make([]*table.Path, 0) 1867 1868 pathList, err := func() ([]*table.Path, error) { 1869 if r.Path != nil { 1870 path, err := api2Path(r.TableType, r.Path, true) 1871 return []*table.Path{path}, err 1872 } 1873 return []*table.Path{}, nil 1874 }() 1875 if err != nil { 1876 return err 1877 } 1878 1879 if len(r.Uuid) > 0 { 1880 // Delete locally generated path which has the given UUID 1881 path := func() *table.Path { 1882 id, _ := uuid.FromBytes(r.Uuid) 1883 if key, ok := s.uuidMap[id]; !ok { 1884 return nil 1885 } else { 1886 for _, path := range s.globalRib.GetPathList(table.GLOBAL_RIB_NAME, 0, s.globalRib.GetRFlist()) { 1887 if path.IsLocal() && key == pathTokey(path) { 1888 delete(s.uuidMap, id) 1889 return path 1890 } 1891 } 1892 } 1893 return nil 1894 }() 1895 if path == nil { 1896 return fmt.Errorf("Can't find a specified path") 1897 } 1898 deletePathList = append(deletePathList, path.Clone(true)) 1899 } else if len(pathList) == 0 { 1900 // Delete all locally generated paths 1901 families := s.globalRib.GetRFlist() 1902 if r.Family != nil { 1903 families = []bgp.RouteFamily{bgp.AfiSafiToRouteFamily(uint16(r.Family.Afi), uint8(r.Family.Safi))} 1904 1905 } 1906 for _, path := range s.globalRib.GetPathList(table.GLOBAL_RIB_NAME, 0, families) { 1907 if path.IsLocal() { 1908 deletePathList = append(deletePathList, path.Clone(true)) 1909 } 1910 } 1911 s.uuidMap = make(map[uuid.UUID]string) 1912 } else { 1913 if err := s.fixupApiPath(r.VrfId, pathList); err != nil { 1914 return err 1915 } 1916 deletePathList = pathList 1917 } 1918 s.propagateUpdate(nil, deletePathList) 1919 return nil 1920 }, true) 1921 } 1922 1923 func (s *BgpServer) updatePath(vrfId string, pathList []*table.Path) error { 1924 err := s.mgmtOperation(func() error { 1925 if err := s.fixupApiPath(vrfId, pathList); err != nil { 1926 return err 1927 } 1928 s.propagateUpdate(nil, pathList) 1929 return nil 1930 }, true) 1931 return err 1932 } 1933 1934 func (s *BgpServer) StartBgp(ctx context.Context, r *api.StartBgpRequest) error { 1935 return s.mgmtOperation(func() error { 1936 if r == nil || r.Global == nil { 1937 return fmt.Errorf("invalid request") 1938 } 1939 g := r.Global 1940 if net.ParseIP(g.RouterId) == nil { 1941 return fmt.Errorf("invalid router-id format: %s", g.RouterId) 1942 } 1943 1944 c := newGlobalFromAPIStruct(g) 1945 if err := config.SetDefaultGlobalConfigValues(c); err != nil { 1946 return err 1947 } 1948 1949 if c.Config.Port > 0 { 1950 acceptCh := make(chan *net.TCPConn, 4096) 1951 for _, addr := range c.Config.LocalAddressList { 1952 l, err := newTCPListener(addr, uint32(c.Config.Port), acceptCh) 1953 if err != nil { 1954 return err 1955 } 1956 s.listeners = append(s.listeners, l) 1957 } 1958 s.acceptCh = acceptCh 1959 } 1960 1961 rfs, _ := config.AfiSafis(c.AfiSafis).ToRfList() 1962 s.globalRib = table.NewTableManager(rfs) 1963 s.rsRib = table.NewTableManager(rfs) 1964 1965 if err := s.policy.Reset(&config.RoutingPolicy{}, map[string]config.ApplyPolicy{}); err != nil { 1966 return err 1967 } 1968 s.bgpConfig.Global = *c 1969 // update route selection options 1970 table.SelectionOptions = c.RouteSelectionOptions.Config 1971 table.UseMultiplePaths = c.UseMultiplePaths.Config 1972 1973 s.roaManager.SetAS(s.bgpConfig.Global.Config.As) 1974 return nil 1975 }, false) 1976 } 1977 1978 // TODO: delete this function 1979 func (s *BgpServer) listVrf() (l []*table.Vrf) { 1980 s.mgmtOperation(func() error { 1981 l = make([]*table.Vrf, 0, len(s.globalRib.Vrfs)) 1982 for _, vrf := range s.globalRib.Vrfs { 1983 l = append(l, vrf.Clone()) 1984 } 1985 return nil 1986 }, true) 1987 return l 1988 } 1989 1990 func (s *BgpServer) ListVrf(ctx context.Context, _ *api.ListVrfRequest, fn func(*api.Vrf)) error { 1991 toApi := func(v *table.Vrf) *api.Vrf { 1992 return &api.Vrf{ 1993 Name: v.Name, 1994 Rd: apiutil.MarshalRD(v.Rd), 1995 Id: v.Id, 1996 ImportRt: apiutil.MarshalRTs(v.ImportRt), 1997 ExportRt: apiutil.MarshalRTs(v.ExportRt), 1998 } 1999 } 2000 var l []*api.Vrf 2001 s.mgmtOperation(func() error { 2002 l = make([]*api.Vrf, 0, len(s.globalRib.Vrfs)) 2003 for _, vrf := range s.globalRib.Vrfs { 2004 l = append(l, toApi(vrf.Clone())) 2005 } 2006 return nil 2007 }, true) 2008 for _, v := range l { 2009 select { 2010 case <-ctx.Done(): 2011 return nil 2012 default: 2013 fn(v) 2014 } 2015 } 2016 return nil 2017 } 2018 2019 func (s *BgpServer) AddVrf(ctx context.Context, r *api.AddVrfRequest) error { 2020 return s.mgmtOperation(func() error { 2021 if r == nil || r.Vrf == nil { 2022 return fmt.Errorf("invalid request") 2023 } 2024 2025 name := r.Vrf.Name 2026 id := r.Vrf.Id 2027 2028 rd, err := apiutil.UnmarshalRD(r.Vrf.Rd) 2029 if err != nil { 2030 return err 2031 } 2032 im, err := apiutil.UnmarshalRTs(r.Vrf.ImportRt) 2033 if err != nil { 2034 return err 2035 } 2036 ex, err := apiutil.UnmarshalRTs(r.Vrf.ExportRt) 2037 if err != nil { 2038 return err 2039 } 2040 2041 pi := &table.PeerInfo{ 2042 AS: s.bgpConfig.Global.Config.As, 2043 LocalID: net.ParseIP(s.bgpConfig.Global.Config.RouterId).To4(), 2044 } 2045 if pathList, err := s.globalRib.AddVrf(name, id, rd, im, ex, pi); err != nil { 2046 return err 2047 } else if len(pathList) > 0 { 2048 s.propagateUpdate(nil, pathList) 2049 } 2050 return nil 2051 }, true) 2052 } 2053 2054 func (s *BgpServer) DeleteVrf(ctx context.Context, r *api.DeleteVrfRequest) error { 2055 return s.mgmtOperation(func() error { 2056 if r == nil || r.Name == "" { 2057 return fmt.Errorf("invalid request") 2058 } 2059 name := r.Name 2060 for _, n := range s.neighborMap { 2061 n.fsm.lock.RLock() 2062 peerVrf := n.fsm.pConf.Config.Vrf 2063 n.fsm.lock.RUnlock() 2064 if peerVrf == name { 2065 return fmt.Errorf("failed to delete VRF %s: neighbor %s is in use", name, n.ID()) 2066 } 2067 } 2068 pathList, err := s.globalRib.DeleteVrf(name) 2069 if err != nil { 2070 return err 2071 } 2072 if len(pathList) > 0 { 2073 s.propagateUpdate(nil, pathList) 2074 } 2075 return nil 2076 }, true) 2077 } 2078 2079 func familiesForSoftreset(peer *peer, family bgp.RouteFamily) []bgp.RouteFamily { 2080 if family == bgp.RouteFamily(0) { 2081 configured := peer.configuredRFlist() 2082 families := make([]bgp.RouteFamily, 0, len(configured)) 2083 for _, f := range configured { 2084 if f != bgp.RF_RTC_UC { 2085 families = append(families, f) 2086 } 2087 } 2088 return families 2089 } 2090 return []bgp.RouteFamily{family} 2091 } 2092 2093 func (s *BgpServer) softResetIn(addr string, family bgp.RouteFamily) error { 2094 peers, err := s.addrToPeers(addr) 2095 if err != nil { 2096 return err 2097 } 2098 for _, peer := range peers { 2099 families := familiesForSoftreset(peer, family) 2100 2101 pathList := make([]*table.Path, 0, peer.adjRibIn.Count(families)) 2102 for _, path := range peer.adjRibIn.PathList(families, false) { 2103 // RFC4271 9.1.2 Phase 2: Route Selection 2104 // 2105 // If the AS_PATH attribute of a BGP route contains an AS loop, the BGP 2106 // route should be excluded from the Phase 2 decision function. 2107 isLooped := false 2108 if aspath := path.GetAsPath(); aspath != nil { 2109 peer.fsm.lock.RLock() 2110 localAS := peer.fsm.peerInfo.LocalAS 2111 allowOwnAS := int(peer.fsm.pConf.AsPathOptions.Config.AllowOwnAs) 2112 peer.fsm.lock.RUnlock() 2113 isLooped = hasOwnASLoop(localAS, allowOwnAS, aspath) 2114 } 2115 if path.IsAsLooped() != isLooped { 2116 // can't modify the existing one. needs to create one 2117 path = path.Clone(false) 2118 path.SetAsLooped(isLooped) 2119 // update accepted counter 2120 peer.adjRibIn.Update([]*table.Path{path}) 2121 } 2122 if !path.IsAsLooped() { 2123 pathList = append(pathList, path) 2124 } 2125 } 2126 s.propagateUpdate(peer, pathList) 2127 } 2128 return err 2129 } 2130 2131 func (s *BgpServer) softResetOut(addr string, family bgp.RouteFamily, deferral bool) error { 2132 peers, err := s.addrToPeers(addr) 2133 if err != nil { 2134 return err 2135 } 2136 for _, peer := range peers { 2137 peer.fsm.lock.RLock() 2138 notEstablished := peer.fsm.state != bgp.BGP_FSM_ESTABLISHED 2139 peer.fsm.lock.RUnlock() 2140 if notEstablished { 2141 continue 2142 } 2143 families := familiesForSoftreset(peer, family) 2144 2145 if deferral { 2146 if family == bgp.RouteFamily(0) { 2147 families = peer.configuredRFlist() 2148 } 2149 peer.fsm.lock.RLock() 2150 _, y := peer.fsm.rfMap[bgp.RF_RTC_UC] 2151 c := peer.fsm.pConf.GetAfiSafi(bgp.RF_RTC_UC) 2152 restarting := peer.fsm.pConf.GracefulRestart.State.LocalRestarting 2153 peer.fsm.lock.RUnlock() 2154 if restarting { 2155 peer.fsm.lock.Lock() 2156 peer.fsm.pConf.GracefulRestart.State.LocalRestarting = false 2157 peer.fsm.lock.Unlock() 2158 log.WithFields(log.Fields{ 2159 "Topic": "Peer", 2160 "Key": peer.ID(), 2161 "Families": families, 2162 }).Debug("deferral timer expired") 2163 } else if y && !c.MpGracefulRestart.State.EndOfRibReceived { 2164 log.WithFields(log.Fields{ 2165 "Topic": "Peer", 2166 "Key": peer.ID(), 2167 "Families": families, 2168 }).Debug("route-target deferral timer expired") 2169 } else { 2170 continue 2171 } 2172 } 2173 2174 pathList, _ := s.getBestFromLocal(peer, families) 2175 if len(pathList) > 0 { 2176 if deferral { 2177 pathList = func() []*table.Path { 2178 l := make([]*table.Path, 0, len(pathList)) 2179 for _, p := range pathList { 2180 if !p.IsWithdraw { 2181 l = append(l, p) 2182 } 2183 } 2184 return l 2185 }() 2186 } 2187 sendfsmOutgoingMsg(peer, pathList, nil, false) 2188 } 2189 } 2190 return nil 2191 } 2192 2193 func (s *BgpServer) sResetIn(addr string, family bgp.RouteFamily) error { 2194 log.WithFields(log.Fields{ 2195 "Topic": "Operation", 2196 "Key": addr, 2197 }).Info("Neighbor soft reset in") 2198 return s.softResetIn(addr, family) 2199 } 2200 2201 func (s *BgpServer) sResetOut(addr string, family bgp.RouteFamily) error { 2202 log.WithFields(log.Fields{ 2203 "Topic": "Operation", 2204 "Key": addr, 2205 }).Info("Neighbor soft reset out") 2206 return s.softResetOut(addr, family, false) 2207 } 2208 2209 func (s *BgpServer) sReset(addr string, family bgp.RouteFamily) error { 2210 log.WithFields(log.Fields{ 2211 "Topic": "Operation", 2212 "Key": addr, 2213 }).Info("Neighbor soft reset") 2214 err := s.softResetIn(addr, family) 2215 if err != nil { 2216 return err 2217 } 2218 return s.softResetOut(addr, family, false) 2219 } 2220 2221 func (s *BgpServer) validateTable(r *table.Table) (v []*table.Validation) { 2222 if s.roaManager.enabled() { 2223 v = make([]*table.Validation, 0, len(r.GetDestinations())) 2224 for _, d := range r.GetDestinations() { 2225 for _, p := range d.GetAllKnownPathList() { 2226 v = append(v, s.roaManager.validate(p)) 2227 } 2228 } 2229 } 2230 return 2231 } 2232 2233 func (s *BgpServer) getRib(addr string, family bgp.RouteFamily, prefixes []*table.LookupPrefix) (rib *table.Table, v []*table.Validation, err error) { 2234 err = s.mgmtOperation(func() error { 2235 m := s.globalRib 2236 id := table.GLOBAL_RIB_NAME 2237 as := uint32(0) 2238 if len(addr) > 0 { 2239 peer, ok := s.neighborMap[addr] 2240 if !ok { 2241 return fmt.Errorf("Neighbor that has %v doesn't exist.", addr) 2242 } 2243 if !peer.isRouteServerClient() { 2244 return fmt.Errorf("Neighbor %v doesn't have local rib", addr) 2245 } 2246 id = peer.ID() 2247 as = peer.AS() 2248 m = s.rsRib 2249 } 2250 af := bgp.RouteFamily(family) 2251 tbl, ok := m.Tables[af] 2252 if !ok { 2253 return fmt.Errorf("address family: %s not supported", af) 2254 } 2255 rib, err = tbl.Select(table.TableSelectOption{ID: id, AS: as, LookupPrefixes: prefixes}) 2256 v = s.validateTable(rib) 2257 return err 2258 }, true) 2259 return 2260 } 2261 2262 func (s *BgpServer) getVrfRib(name string, family bgp.RouteFamily, prefixes []*table.LookupPrefix) (rib *table.Table, err error) { 2263 err = s.mgmtOperation(func() error { 2264 m := s.globalRib 2265 vrfs := m.Vrfs 2266 if _, ok := vrfs[name]; !ok { 2267 return fmt.Errorf("vrf %s not found", name) 2268 } 2269 var af bgp.RouteFamily 2270 switch family { 2271 case bgp.RF_IPv4_UC: 2272 af = bgp.RF_IPv4_VPN 2273 case bgp.RF_IPv6_UC: 2274 af = bgp.RF_IPv6_VPN 2275 case bgp.RF_EVPN: 2276 af = bgp.RF_EVPN 2277 } 2278 tbl, ok := m.Tables[af] 2279 if !ok { 2280 return fmt.Errorf("address family: %s not supported", af) 2281 } 2282 rib, err = tbl.Select(table.TableSelectOption{VRF: vrfs[name], LookupPrefixes: prefixes}) 2283 return err 2284 }, true) 2285 return 2286 } 2287 2288 func (s *BgpServer) getAdjRib(addr string, family bgp.RouteFamily, in bool, prefixes []*table.LookupPrefix) (rib *table.Table, v []*table.Validation, err error) { 2289 err = s.mgmtOperation(func() error { 2290 peer, ok := s.neighborMap[addr] 2291 if !ok { 2292 return fmt.Errorf("Neighbor that has %v doesn't exist.", addr) 2293 } 2294 id := peer.ID() 2295 as := peer.AS() 2296 2297 var adjRib *table.AdjRib 2298 if in { 2299 adjRib = peer.adjRibIn 2300 } else { 2301 adjRib = table.NewAdjRib(peer.configuredRFlist()) 2302 accepted, _ := s.getBestFromLocal(peer, peer.configuredRFlist()) 2303 adjRib.Update(accepted) 2304 } 2305 rib, err = adjRib.Select(family, false, table.TableSelectOption{ID: id, AS: as, LookupPrefixes: prefixes}) 2306 v = s.validateTable(rib) 2307 return err 2308 }, true) 2309 return 2310 } 2311 2312 func (s *BgpServer) ListPath(ctx context.Context, r *api.ListPathRequest, fn func(*api.Destination)) error { 2313 var tbl *table.Table 2314 var v []*table.Validation 2315 2316 f := func() []*table.LookupPrefix { 2317 l := make([]*table.LookupPrefix, 0, len(r.Prefixes)) 2318 for _, p := range r.Prefixes { 2319 l = append(l, &table.LookupPrefix{ 2320 Prefix: p.Prefix, 2321 LookupOption: table.LookupOption(p.LookupOption), 2322 }) 2323 } 2324 return l 2325 } 2326 2327 in := false 2328 family := bgp.RouteFamily(0) 2329 if r.Family != nil { 2330 family = bgp.AfiSafiToRouteFamily(uint16(r.Family.Afi), uint8(r.Family.Safi)) 2331 } 2332 var err error 2333 switch r.TableType { 2334 case api.TableType_LOCAL, api.TableType_GLOBAL: 2335 tbl, v, err = s.getRib(r.Name, family, f()) 2336 case api.TableType_ADJ_IN: 2337 in = true 2338 fallthrough 2339 case api.TableType_ADJ_OUT: 2340 tbl, v, err = s.getAdjRib(r.Name, family, in, f()) 2341 case api.TableType_VRF: 2342 tbl, err = s.getVrfRib(r.Name, family, []*table.LookupPrefix{}) 2343 default: 2344 return fmt.Errorf("unsupported resource type: %v", r.TableType) 2345 } 2346 2347 if err != nil { 2348 return err 2349 } 2350 2351 idx := 0 2352 err = func() error { 2353 for _, dst := range tbl.GetDestinations() { 2354 d := api.Destination{ 2355 Prefix: dst.GetNlri().String(), 2356 Paths: make([]*api.Path, 0, len(dst.GetAllKnownPathList())), 2357 } 2358 for i, path := range dst.GetAllKnownPathList() { 2359 p := toPathApi(path, getValidation(v, idx)) 2360 idx++ 2361 if i == 0 && !table.SelectionOptions.DisableBestPathSelection { 2362 switch r.TableType { 2363 case api.TableType_LOCAL, api.TableType_GLOBAL: 2364 p.Best = true 2365 } 2366 } 2367 d.Paths = append(d.Paths, p) 2368 } 2369 select { 2370 case <-ctx.Done(): 2371 return nil 2372 default: 2373 fn(&d) 2374 } 2375 } 2376 return nil 2377 }() 2378 return err 2379 } 2380 2381 func (s *BgpServer) getRibInfo(addr string, family bgp.RouteFamily) (info *table.TableInfo, err error) { 2382 err = s.mgmtOperation(func() error { 2383 m := s.globalRib 2384 id := table.GLOBAL_RIB_NAME 2385 as := uint32(0) 2386 if len(addr) > 0 { 2387 peer, ok := s.neighborMap[addr] 2388 if !ok { 2389 return fmt.Errorf("Neighbor that has %v doesn't exist.", addr) 2390 } 2391 if !peer.isRouteServerClient() { 2392 return fmt.Errorf("Neighbor %v doesn't have local rib", addr) 2393 } 2394 id = peer.ID() 2395 as = peer.AS() 2396 m = s.rsRib 2397 } 2398 info, err = m.TableInfo(id, as, family) 2399 return err 2400 }, true) 2401 return 2402 } 2403 2404 func (s *BgpServer) getAdjRibInfo(addr string, family bgp.RouteFamily, in bool) (info *table.TableInfo, err error) { 2405 err = s.mgmtOperation(func() error { 2406 peer, ok := s.neighborMap[addr] 2407 if !ok { 2408 return fmt.Errorf("Neighbor that has %v doesn't exist.", addr) 2409 } 2410 2411 var adjRib *table.AdjRib 2412 if in { 2413 adjRib = peer.adjRibIn 2414 } else { 2415 adjRib = table.NewAdjRib(peer.configuredRFlist()) 2416 accepted, _ := s.getBestFromLocal(peer, peer.configuredRFlist()) 2417 adjRib.Update(accepted) 2418 } 2419 info, err = adjRib.TableInfo(family) 2420 return err 2421 }, true) 2422 return 2423 } 2424 2425 func (s *BgpServer) GetTable(ctx context.Context, r *api.GetTableRequest) (*api.GetTableResponse, error) { 2426 if r == nil || r.Name == "" { 2427 return nil, fmt.Errorf("invalid request") 2428 } 2429 family := bgp.RouteFamily(0) 2430 if r.Family != nil { 2431 family = bgp.AfiSafiToRouteFamily(uint16(r.Family.Afi), uint8(r.Family.Safi)) 2432 } 2433 var in bool 2434 var err error 2435 var info *table.TableInfo 2436 switch r.TableType { 2437 case api.TableType_GLOBAL, api.TableType_LOCAL: 2438 info, err = s.getRibInfo(r.Name, family) 2439 case api.TableType_ADJ_IN: 2440 in = true 2441 fallthrough 2442 case api.TableType_ADJ_OUT: 2443 info, err = s.getAdjRibInfo(r.Name, family, in) 2444 default: 2445 return nil, fmt.Errorf("unsupported resource type: %s", r.TableType) 2446 } 2447 2448 if err != nil { 2449 return nil, err 2450 } 2451 2452 return &api.GetTableResponse{ 2453 NumDestination: uint64(info.NumDestination), 2454 NumPath: uint64(info.NumPath), 2455 NumAccepted: uint64(info.NumAccepted), 2456 }, nil 2457 } 2458 2459 func (s *BgpServer) GetBgp(ctx context.Context, r *api.GetBgpRequest) (*api.GetBgpResponse, error) { 2460 var rsp *api.GetBgpResponse 2461 s.mgmtOperation(func() error { 2462 g := s.bgpConfig.Global 2463 rsp = &api.GetBgpResponse{ 2464 Global: &api.Global{ 2465 As: g.Config.As, 2466 RouterId: g.Config.RouterId, 2467 ListenPort: g.Config.Port, 2468 ListenAddresses: g.Config.LocalAddressList, 2469 UseMultiplePaths: g.UseMultiplePaths.Config.Enabled, 2470 }, 2471 } 2472 return nil 2473 }, false) 2474 return rsp, nil 2475 } 2476 2477 func (s *BgpServer) ListPeer(ctx context.Context, r *api.ListPeerRequest, fn func(*api.Peer)) error { 2478 var l []*api.Peer 2479 s.mgmtOperation(func() error { 2480 address := r.Address 2481 getAdvertised := r.EnableAdvertised 2482 l = make([]*api.Peer, 0, len(s.neighborMap)) 2483 for k, peer := range s.neighborMap { 2484 peer.fsm.lock.RLock() 2485 neighborIface := peer.fsm.pConf.Config.NeighborInterface 2486 peer.fsm.lock.RUnlock() 2487 if address != "" && address != k && address != neighborIface { 2488 continue 2489 } 2490 // FIXME: should remove toConfig() conversion 2491 p := config.NewPeerFromConfigStruct(s.toConfig(peer, getAdvertised)) 2492 for _, family := range peer.configuredRFlist() { 2493 for i, afisafi := range p.AfiSafis { 2494 if !afisafi.Config.Enabled { 2495 continue 2496 } 2497 afi, safi := bgp.RouteFamilyToAfiSafi(family) 2498 c := afisafi.Config 2499 if c.Family != nil && c.Family.Afi == api.Family_Afi(afi) && c.Family.Safi == api.Family_Safi(safi) { 2500 flist := []bgp.RouteFamily{family} 2501 received := uint64(peer.adjRibIn.Count(flist)) 2502 accepted := uint64(peer.adjRibIn.Accepted(flist)) 2503 advertised := uint64(0) 2504 if getAdvertised { 2505 pathList, _ := s.getBestFromLocal(peer, flist) 2506 advertised = uint64(len(pathList)) 2507 } 2508 p.AfiSafis[i].State = &api.AfiSafiState{ 2509 Family: c.Family, 2510 Enabled: true, 2511 Received: received, 2512 Accepted: accepted, 2513 Advertised: advertised, 2514 } 2515 } 2516 } 2517 } 2518 l = append(l, p) 2519 } 2520 return nil 2521 }, false) 2522 for _, p := range l { 2523 select { 2524 case <-ctx.Done(): 2525 return nil 2526 default: 2527 fn(p) 2528 } 2529 } 2530 return nil 2531 } 2532 2533 func (s *BgpServer) addPeerGroup(c *config.PeerGroup) error { 2534 name := c.Config.PeerGroupName 2535 if _, y := s.peerGroupMap[name]; y { 2536 return fmt.Errorf("Can't overwrite the existing peer-group: %s", name) 2537 } 2538 2539 log.WithFields(log.Fields{ 2540 "Topic": "Peer", 2541 "Name": name, 2542 }).Info("Add a peer group configuration") 2543 2544 s.peerGroupMap[c.Config.PeerGroupName] = newPeerGroup(c) 2545 2546 return nil 2547 } 2548 2549 func (s *BgpServer) addNeighbor(c *config.Neighbor) error { 2550 addr, err := c.ExtractNeighborAddress() 2551 if err != nil { 2552 return err 2553 } 2554 2555 if _, y := s.neighborMap[addr]; y { 2556 return fmt.Errorf("Can't overwrite the existing peer: %s", addr) 2557 } 2558 2559 var pgConf *config.PeerGroup 2560 if c.Config.PeerGroup != "" { 2561 pg, ok := s.peerGroupMap[c.Config.PeerGroup] 2562 if !ok { 2563 return fmt.Errorf("no such peer-group: %s", c.Config.PeerGroup) 2564 } 2565 pgConf = pg.Conf 2566 } 2567 2568 if err := config.SetDefaultNeighborConfigValues(c, pgConf, &s.bgpConfig.Global); err != nil { 2569 return err 2570 } 2571 2572 if vrf := c.Config.Vrf; vrf != "" { 2573 if c.RouteServer.Config.RouteServerClient { 2574 return fmt.Errorf("route server client can't be enslaved to VRF") 2575 } 2576 families, _ := config.AfiSafis(c.AfiSafis).ToRfList() 2577 for _, f := range families { 2578 if f != bgp.RF_IPv4_UC && f != bgp.RF_IPv6_UC { 2579 return fmt.Errorf("%s is not supported for VRF enslaved neighbor", f) 2580 } 2581 } 2582 _, y := s.globalRib.Vrfs[vrf] 2583 if !y { 2584 return fmt.Errorf("VRF not found: %s", vrf) 2585 } 2586 } 2587 2588 if c.RouteServer.Config.RouteServerClient && c.RouteReflector.Config.RouteReflectorClient { 2589 return fmt.Errorf("can't be both route-server-client and route-reflector-client") 2590 } 2591 2592 if s.bgpConfig.Global.Config.Port > 0 { 2593 for _, l := range s.listListeners(addr) { 2594 if c.Config.AuthPassword != "" { 2595 if err := setTCPMD5SigSockopt(l, addr, c.Config.AuthPassword); err != nil { 2596 log.WithFields(log.Fields{ 2597 "Topic": "Peer", 2598 "Key": addr, 2599 }).Warnf("failed to set md5: %s", err) 2600 } 2601 } 2602 } 2603 } 2604 log.WithFields(log.Fields{ 2605 "Topic": "Peer", 2606 }).Infof("Add a peer configuration for:%s", addr) 2607 2608 rib := s.globalRib 2609 if c.RouteServer.Config.RouteServerClient { 2610 rib = s.rsRib 2611 } 2612 peer := newPeer(&s.bgpConfig.Global, c, rib, s.policy) 2613 s.policy.Reset(nil, map[string]config.ApplyPolicy{peer.ID(): c.ApplyPolicy}) 2614 s.neighborMap[addr] = peer 2615 if name := c.Config.PeerGroup; name != "" { 2616 s.peerGroupMap[name].AddMember(*c) 2617 } 2618 peer.startFSMHandler(s.fsmincomingCh, s.fsmStateCh) 2619 s.broadcastPeerState(peer, bgp.BGP_FSM_IDLE, nil) 2620 return nil 2621 } 2622 2623 func (s *BgpServer) AddPeerGroup(ctx context.Context, r *api.AddPeerGroupRequest) error { 2624 return s.mgmtOperation(func() error { 2625 c, err := newPeerGroupFromAPIStruct(r.PeerGroup) 2626 if err != nil { 2627 return err 2628 } 2629 return s.addPeerGroup(c) 2630 }, true) 2631 } 2632 2633 func (s *BgpServer) AddPeer(ctx context.Context, r *api.AddPeerRequest) error { 2634 return s.mgmtOperation(func() error { 2635 c, err := newNeighborFromAPIStruct(r.Peer) 2636 if err != nil { 2637 return err 2638 } 2639 return s.addNeighbor(c) 2640 }, true) 2641 } 2642 2643 func (s *BgpServer) AddDynamicNeighbor(ctx context.Context, r *api.AddDynamicNeighborRequest) error { 2644 return s.mgmtOperation(func() error { 2645 c := &config.DynamicNeighbor{Config: config.DynamicNeighborConfig{ 2646 Prefix: r.DynamicNeighbor.Prefix, 2647 PeerGroup: r.DynamicNeighbor.PeerGroup}, 2648 } 2649 s.peerGroupMap[c.Config.PeerGroup].AddDynamicNeighbor(c) 2650 return nil 2651 }, true) 2652 } 2653 2654 func (s *BgpServer) deletePeerGroup(name string) error { 2655 if _, y := s.peerGroupMap[name]; !y { 2656 return fmt.Errorf("Can't delete a peer-group %s which does not exist", name) 2657 } 2658 2659 log.WithFields(log.Fields{ 2660 "Topic": "Peer", 2661 "Name": name, 2662 }).Info("Delete a peer group configuration") 2663 2664 delete(s.peerGroupMap, name) 2665 return nil 2666 } 2667 2668 func (s *BgpServer) deleteNeighbor(c *config.Neighbor, code, subcode uint8) error { 2669 if c.Config.PeerGroup != "" { 2670 _, y := s.peerGroupMap[c.Config.PeerGroup] 2671 if y { 2672 s.peerGroupMap[c.Config.PeerGroup].DeleteMember(*c) 2673 } 2674 } 2675 2676 addr, err := c.ExtractNeighborAddress() 2677 if err != nil { 2678 return err 2679 } 2680 2681 if intf := c.Config.NeighborInterface; intf != "" { 2682 var err error 2683 addr, err = config.GetIPv6LinkLocalNeighborAddress(intf) 2684 if err != nil { 2685 return err 2686 } 2687 } 2688 n, y := s.neighborMap[addr] 2689 if !y { 2690 return fmt.Errorf("Can't delete a peer configuration for %s", addr) 2691 } 2692 for _, l := range s.listListeners(addr) { 2693 if err := setTCPMD5SigSockopt(l, addr, ""); err != nil { 2694 log.WithFields(log.Fields{ 2695 "Topic": "Peer", 2696 "Key": addr, 2697 }).Warnf("failed to unset md5: %s", err) 2698 } 2699 } 2700 log.WithFields(log.Fields{ 2701 "Topic": "Peer", 2702 }).Infof("Delete a peer configuration for:%s", addr) 2703 2704 n.fsm.sendNotification(code, subcode, nil, "") 2705 n.stopPeerRestarting() 2706 2707 go n.stopFSM() 2708 delete(s.neighborMap, addr) 2709 s.dropPeerAllRoutes(n, n.configuredRFlist()) 2710 return nil 2711 } 2712 2713 func (s *BgpServer) DeletePeerGroup(ctx context.Context, r *api.DeletePeerGroupRequest) error { 2714 return s.mgmtOperation(func() error { 2715 name := r.Name 2716 for _, n := range s.neighborMap { 2717 n.fsm.lock.RLock() 2718 peerGroup := n.fsm.pConf.Config.PeerGroup 2719 n.fsm.lock.RUnlock() 2720 if peerGroup == name { 2721 return fmt.Errorf("failed to delete peer-group %s: neighbor %s is in use", name, n.ID()) 2722 } 2723 } 2724 return s.deletePeerGroup(name) 2725 }, true) 2726 } 2727 2728 func (s *BgpServer) DeletePeer(ctx context.Context, r *api.DeletePeerRequest) error { 2729 return s.mgmtOperation(func() error { 2730 c := &config.Neighbor{Config: config.NeighborConfig{ 2731 NeighborAddress: r.Address, 2732 NeighborInterface: r.Interface, 2733 }} 2734 return s.deleteNeighbor(c, bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_PEER_DECONFIGURED) 2735 }, true) 2736 } 2737 2738 func (s *BgpServer) updatePeerGroup(pg *config.PeerGroup) (needsSoftResetIn bool, err error) { 2739 name := pg.Config.PeerGroupName 2740 2741 _, ok := s.peerGroupMap[name] 2742 if !ok { 2743 return false, fmt.Errorf("Peer-group %s doesn't exist.", name) 2744 } 2745 s.peerGroupMap[name].Conf = pg 2746 2747 for _, n := range s.peerGroupMap[name].members { 2748 c := n 2749 u, err := s.updateNeighbor(&c) 2750 if err != nil { 2751 return needsSoftResetIn, err 2752 } 2753 needsSoftResetIn = needsSoftResetIn || u 2754 } 2755 return needsSoftResetIn, nil 2756 } 2757 2758 func (s *BgpServer) UpdatePeerGroup(ctx context.Context, r *api.UpdatePeerGroupRequest) (rsp *api.UpdatePeerGroupResponse, err error) { 2759 doSoftreset := false 2760 err = s.mgmtOperation(func() error { 2761 pg, err := newPeerGroupFromAPIStruct(r.PeerGroup) 2762 if err != nil { 2763 return err 2764 } 2765 doSoftreset, err = s.updatePeerGroup(pg) 2766 return err 2767 }, true) 2768 return &api.UpdatePeerGroupResponse{NeedsSoftResetIn: doSoftreset}, err 2769 } 2770 2771 func (s *BgpServer) updateNeighbor(c *config.Neighbor) (needsSoftResetIn bool, err error) { 2772 if c.Config.PeerGroup != "" { 2773 if pg, ok := s.peerGroupMap[c.Config.PeerGroup]; ok { 2774 if err := config.SetDefaultNeighborConfigValues(c, pg.Conf, &s.bgpConfig.Global); err != nil { 2775 return needsSoftResetIn, err 2776 } 2777 } else { 2778 return needsSoftResetIn, fmt.Errorf("no such peer-group: %s", c.Config.PeerGroup) 2779 } 2780 } 2781 2782 addr, err := c.ExtractNeighborAddress() 2783 if err != nil { 2784 return needsSoftResetIn, err 2785 } 2786 2787 peer, ok := s.neighborMap[addr] 2788 if !ok { 2789 return needsSoftResetIn, fmt.Errorf("Neighbor that has %v doesn't exist.", addr) 2790 } 2791 2792 if !peer.fsm.pConf.ApplyPolicy.Equal(&c.ApplyPolicy) { 2793 log.WithFields(log.Fields{ 2794 "Topic": "Peer", 2795 "Key": addr, 2796 }).Info("Update ApplyPolicy") 2797 s.policy.Reset(nil, map[string]config.ApplyPolicy{peer.ID(): c.ApplyPolicy}) 2798 peer.fsm.pConf.ApplyPolicy = c.ApplyPolicy 2799 needsSoftResetIn = true 2800 } 2801 original := peer.fsm.pConf 2802 2803 if !original.AsPathOptions.Config.Equal(&c.AsPathOptions.Config) { 2804 log.WithFields(log.Fields{ 2805 "Topic": "Peer", 2806 "Key": peer.ID(), 2807 }).Info("Update aspath options") 2808 peer.fsm.pConf.AsPathOptions = c.AsPathOptions 2809 needsSoftResetIn = true 2810 } 2811 2812 if original.NeedsResendOpenMessage(c) { 2813 sub := uint8(bgp.BGP_ERROR_SUB_OTHER_CONFIGURATION_CHANGE) 2814 if original.Config.AdminDown != c.Config.AdminDown { 2815 sub = bgp.BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN 2816 state := "Admin Down" 2817 2818 if !c.Config.AdminDown { 2819 state = "Admin Up" 2820 } 2821 log.WithFields(log.Fields{ 2822 "Topic": "Peer", 2823 "Key": peer.ID(), 2824 "State": state, 2825 }).Info("Update admin-state configuration") 2826 } else if original.Config.PeerAs != c.Config.PeerAs { 2827 sub = bgp.BGP_ERROR_SUB_PEER_DECONFIGURED 2828 } 2829 if err = s.deleteNeighbor(peer.fsm.pConf, bgp.BGP_ERROR_CEASE, sub); err != nil { 2830 log.WithFields(log.Fields{ 2831 "Topic": "Peer", 2832 "Key": addr, 2833 }).Error(err) 2834 return needsSoftResetIn, err 2835 } 2836 err = s.addNeighbor(c) 2837 if err != nil { 2838 log.WithFields(log.Fields{ 2839 "Topic": "Peer", 2840 "Key": addr, 2841 }).Error(err) 2842 } 2843 return needsSoftResetIn, err 2844 } 2845 2846 if !original.Timers.Config.Equal(&c.Timers.Config) { 2847 log.WithFields(log.Fields{ 2848 "Topic": "Peer", 2849 "Key": peer.ID(), 2850 }).Info("Update timer configuration") 2851 peer.fsm.pConf.Timers.Config = c.Timers.Config 2852 } 2853 2854 err = peer.updatePrefixLimitConfig(c.AfiSafis) 2855 if err != nil { 2856 log.WithFields(log.Fields{ 2857 "Topic": "Peer", 2858 "Key": addr, 2859 }).Error(err) 2860 // rollback to original state 2861 peer.fsm.pConf = original 2862 } 2863 return needsSoftResetIn, err 2864 } 2865 2866 func (s *BgpServer) UpdatePeer(ctx context.Context, r *api.UpdatePeerRequest) (rsp *api.UpdatePeerResponse, err error) { 2867 doSoftReset := false 2868 err = s.mgmtOperation(func() error { 2869 c, err := newNeighborFromAPIStruct(r.Peer) 2870 if err != nil { 2871 return err 2872 } 2873 doSoftReset, err = s.updateNeighbor(c) 2874 return err 2875 }, true) 2876 return &api.UpdatePeerResponse{NeedsSoftResetIn: doSoftReset}, err 2877 } 2878 2879 func (s *BgpServer) addrToPeers(addr string) (l []*peer, err error) { 2880 if len(addr) == 0 { 2881 for _, p := range s.neighborMap { 2882 l = append(l, p) 2883 } 2884 return l, nil 2885 } 2886 p, found := s.neighborMap[addr] 2887 if !found { 2888 return l, fmt.Errorf("Neighbor that has %v doesn't exist.", addr) 2889 } 2890 return []*peer{p}, nil 2891 } 2892 2893 func (s *BgpServer) sendNotification(op, addr string, subcode uint8, data []byte) error { 2894 log.WithFields(log.Fields{ 2895 "Topic": "Operation", 2896 "Key": addr, 2897 }).Info(op) 2898 2899 peers, err := s.addrToPeers(addr) 2900 if err == nil { 2901 m := bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_CEASE, subcode, data) 2902 for _, peer := range peers { 2903 sendfsmOutgoingMsg(peer, nil, m, false) 2904 } 2905 } 2906 return err 2907 } 2908 2909 func (s *BgpServer) ShutdownPeer(ctx context.Context, r *api.ShutdownPeerRequest) error { 2910 return s.mgmtOperation(func() error { 2911 return s.sendNotification("Neighbor shutdown", r.Address, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN, newAdministrativeCommunication(r.Communication)) 2912 }, true) 2913 } 2914 2915 func (s *BgpServer) ResetPeer(ctx context.Context, r *api.ResetPeerRequest) error { 2916 return s.mgmtOperation(func() error { 2917 addr := r.Address 2918 comm := r.Communication 2919 if r.Soft { 2920 var err error 2921 if addr == "all" { 2922 addr = "" 2923 } 2924 family := bgp.RouteFamily(0) 2925 switch r.Direction { 2926 case api.ResetPeerRequest_IN: 2927 err = s.sResetIn(addr, family) 2928 case api.ResetPeerRequest_OUT: 2929 err = s.sResetOut(addr, family) 2930 case api.ResetPeerRequest_BOTH: 2931 err = s.sReset(addr, family) 2932 default: 2933 err = fmt.Errorf("unknown direction") 2934 } 2935 return err 2936 } 2937 2938 err := s.sendNotification("Neighbor reset", addr, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_RESET, newAdministrativeCommunication(comm)) 2939 if err != nil { 2940 return err 2941 } 2942 peers, _ := s.addrToPeers(addr) 2943 for _, peer := range peers { 2944 peer.fsm.lock.Lock() 2945 peer.fsm.idleHoldTime = peer.fsm.pConf.Timers.Config.IdleHoldTimeAfterReset 2946 peer.fsm.lock.Unlock() 2947 } 2948 return nil 2949 }, true) 2950 } 2951 2952 func (s *BgpServer) setAdminState(addr, communication string, enable bool) error { 2953 peers, err := s.addrToPeers(addr) 2954 if err != nil { 2955 return err 2956 } 2957 for _, peer := range peers { 2958 f := func(stateOp *adminStateOperation, message string) { 2959 select { 2960 case peer.fsm.adminStateCh <- *stateOp: 2961 peer.fsm.lock.RLock() 2962 log.WithFields(log.Fields{ 2963 "Topic": "Peer", 2964 "Key": peer.fsm.pConf.State.NeighborAddress, 2965 }).Debug(message) 2966 peer.fsm.lock.RUnlock() 2967 default: 2968 peer.fsm.lock.RLock() 2969 log.Warning("previous request is still remaining. : ", peer.fsm.pConf.State.NeighborAddress) 2970 peer.fsm.lock.RUnlock() 2971 } 2972 } 2973 if enable { 2974 f(&adminStateOperation{adminStateUp, nil}, "adminStateUp requested") 2975 } else { 2976 f(&adminStateOperation{adminStateDown, newAdministrativeCommunication(communication)}, "adminStateDown requested") 2977 } 2978 } 2979 return nil 2980 } 2981 2982 func (s *BgpServer) EnablePeer(ctx context.Context, r *api.EnablePeerRequest) error { 2983 return s.mgmtOperation(func() error { 2984 return s.setAdminState(r.Address, "", true) 2985 }, true) 2986 } 2987 2988 func (s *BgpServer) DisablePeer(ctx context.Context, r *api.DisablePeerRequest) error { 2989 return s.mgmtOperation(func() error { 2990 return s.setAdminState(r.Address, r.Communication, false) 2991 }, true) 2992 } 2993 2994 func (s *BgpServer) ListDefinedSet(ctx context.Context, r *api.ListDefinedSetRequest, fn func(*api.DefinedSet)) error { 2995 var cd *config.DefinedSets 2996 var err error 2997 err = s.mgmtOperation(func() error { 2998 cd, err = s.policy.GetDefinedSet(table.DefinedType(r.DefinedType), r.Name) 2999 return err 3000 }, false) 3001 3002 if err != nil { 3003 return err 3004 } 3005 exec := func(d *api.DefinedSet) bool { 3006 select { 3007 case <-ctx.Done(): 3008 return true 3009 default: 3010 fn(d) 3011 } 3012 return false 3013 } 3014 3015 for _, cs := range cd.PrefixSets { 3016 ad := &api.DefinedSet{ 3017 DefinedType: api.DefinedType_PREFIX, 3018 Name: cs.PrefixSetName, 3019 Prefixes: func() []*api.Prefix { 3020 l := make([]*api.Prefix, 0, len(cs.PrefixList)) 3021 for _, p := range cs.PrefixList { 3022 elems := _regexpPrefixMaskLengthRange.FindStringSubmatch(p.MasklengthRange) 3023 min, _ := strconv.ParseUint(elems[1], 10, 32) 3024 max, _ := strconv.ParseUint(elems[2], 10, 32) 3025 3026 l = append(l, &api.Prefix{IpPrefix: p.IpPrefix, MaskLengthMin: uint32(min), MaskLengthMax: uint32(max)}) 3027 } 3028 return l 3029 }(), 3030 } 3031 if exec(ad) { 3032 return nil 3033 } 3034 } 3035 for _, cs := range cd.NeighborSets { 3036 ad := &api.DefinedSet{ 3037 DefinedType: api.DefinedType_NEIGHBOR, 3038 Name: cs.NeighborSetName, 3039 List: cs.NeighborInfoList, 3040 } 3041 if exec(ad) { 3042 return nil 3043 } 3044 } 3045 for _, cs := range cd.BgpDefinedSets.CommunitySets { 3046 ad := &api.DefinedSet{ 3047 DefinedType: api.DefinedType_COMMUNITY, 3048 Name: cs.CommunitySetName, 3049 List: cs.CommunityList, 3050 } 3051 if exec(ad) { 3052 return nil 3053 } 3054 } 3055 for _, cs := range cd.BgpDefinedSets.ExtCommunitySets { 3056 ad := &api.DefinedSet{ 3057 DefinedType: api.DefinedType_EXT_COMMUNITY, 3058 Name: cs.ExtCommunitySetName, 3059 List: cs.ExtCommunityList, 3060 } 3061 if exec(ad) { 3062 return nil 3063 } 3064 } 3065 for _, cs := range cd.BgpDefinedSets.LargeCommunitySets { 3066 ad := &api.DefinedSet{ 3067 DefinedType: api.DefinedType_LARGE_COMMUNITY, 3068 Name: cs.LargeCommunitySetName, 3069 List: cs.LargeCommunityList, 3070 } 3071 if exec(ad) { 3072 return nil 3073 } 3074 } 3075 for _, cs := range cd.BgpDefinedSets.AsPathSets { 3076 ad := &api.DefinedSet{ 3077 DefinedType: api.DefinedType_AS_PATH, 3078 Name: cs.AsPathSetName, 3079 List: cs.AsPathList, 3080 } 3081 if exec(ad) { 3082 return nil 3083 } 3084 } 3085 return nil 3086 } 3087 3088 func (s *BgpServer) AddDefinedSet(ctx context.Context, r *api.AddDefinedSetRequest) error { 3089 return s.mgmtOperation(func() error { 3090 if r == nil || r.DefinedSet == nil { 3091 return fmt.Errorf("invalid request") 3092 } 3093 set, err := newDefinedSetFromApiStruct(r.DefinedSet) 3094 if err != nil { 3095 return err 3096 } 3097 return s.policy.AddDefinedSet(set) 3098 }, false) 3099 } 3100 3101 func (s *BgpServer) DeleteDefinedSet(ctx context.Context, r *api.DeleteDefinedSetRequest) error { 3102 return s.mgmtOperation(func() error { 3103 if r == nil || r.DefinedSet == nil { 3104 return fmt.Errorf("invalid request") 3105 } 3106 set, err := newDefinedSetFromApiStruct(r.DefinedSet) 3107 if err != nil { 3108 return err 3109 } 3110 return s.policy.DeleteDefinedSet(set, r.All) 3111 }, false) 3112 } 3113 3114 func (s *BgpServer) ListStatement(ctx context.Context, r *api.ListStatementRequest, fn func(*api.Statement)) error { 3115 var l []*api.Statement 3116 s.mgmtOperation(func() error { 3117 s := s.policy.GetStatement(r.Name) 3118 l = make([]*api.Statement, len(s)) 3119 for _, st := range s { 3120 l = append(l, toStatementApi(st)) 3121 } 3122 return nil 3123 }, false) 3124 for _, s := range l { 3125 select { 3126 case <-ctx.Done(): 3127 return nil 3128 default: 3129 fn(s) 3130 } 3131 } 3132 return nil 3133 } 3134 3135 func (s *BgpServer) AddStatement(ctx context.Context, r *api.AddStatementRequest) error { 3136 return s.mgmtOperation(func() error { 3137 if r == nil || r.Statement == nil { 3138 return fmt.Errorf("invalid request") 3139 } 3140 st, err := newStatementFromApiStruct(r.Statement) 3141 if err != nil { 3142 return err 3143 } 3144 return s.policy.AddStatement(st) 3145 }, false) 3146 } 3147 3148 func (s *BgpServer) DeleteStatement(ctx context.Context, r *api.DeleteStatementRequest) error { 3149 return s.mgmtOperation(func() error { 3150 if r == nil || r.Statement == nil { 3151 return fmt.Errorf("invalid request") 3152 } 3153 st, err := newStatementFromApiStruct(r.Statement) 3154 if err == nil { 3155 err = s.policy.DeleteStatement(st, r.All) 3156 } 3157 return err 3158 }, false) 3159 } 3160 3161 func (s *BgpServer) ListPolicy(ctx context.Context, r *api.ListPolicyRequest, fn func(*api.Policy)) error { 3162 var l []*api.Policy 3163 s.mgmtOperation(func() error { 3164 pl := s.policy.GetPolicy(r.Name) 3165 l = make([]*api.Policy, 0, len(pl)) 3166 for _, p := range pl { 3167 l = append(l, table.ToPolicyApi(p)) 3168 } 3169 return nil 3170 }, false) 3171 for _, p := range l { 3172 select { 3173 case <-ctx.Done(): 3174 return nil 3175 default: 3176 fn(p) 3177 } 3178 } 3179 return nil 3180 } 3181 3182 func (s *BgpServer) AddPolicy(ctx context.Context, r *api.AddPolicyRequest) error { 3183 return s.mgmtOperation(func() error { 3184 if r == nil || r.Policy == nil { 3185 return fmt.Errorf("invalid request") 3186 } 3187 p, err := newPolicyFromApiStruct(r.Policy) 3188 if err == nil { 3189 err = s.policy.AddPolicy(p, r.ReferExistingStatements) 3190 } 3191 return err 3192 }, false) 3193 } 3194 3195 func (s *BgpServer) DeletePolicy(ctx context.Context, r *api.DeletePolicyRequest) error { 3196 return s.mgmtOperation(func() error { 3197 if r == nil || r.Policy == nil { 3198 return fmt.Errorf("invalid request") 3199 } 3200 p, err := newPolicyFromApiStruct(r.Policy) 3201 if err != nil { 3202 return err 3203 } 3204 3205 l := make([]string, 0, len(s.neighborMap)+1) 3206 for _, peer := range s.neighborMap { 3207 l = append(l, peer.ID()) 3208 } 3209 l = append(l, table.GLOBAL_RIB_NAME) 3210 3211 return s.policy.DeletePolicy(p, r.All, r.PreserveStatements, l) 3212 }, false) 3213 } 3214 3215 func (s *BgpServer) toPolicyInfo(name string, dir api.PolicyDirection) (string, table.PolicyDirection, error) { 3216 if name == "" { 3217 return "", table.POLICY_DIRECTION_NONE, fmt.Errorf("empty table name") 3218 } 3219 3220 if name == table.GLOBAL_RIB_NAME { 3221 name = table.GLOBAL_RIB_NAME 3222 } else { 3223 peer, ok := s.neighborMap[name] 3224 if !ok { 3225 return "", table.POLICY_DIRECTION_NONE, fmt.Errorf("not found peer %s", name) 3226 } 3227 if !peer.isRouteServerClient() { 3228 return "", table.POLICY_DIRECTION_NONE, fmt.Errorf("non-rs-client peer %s doesn't have per peer policy", name) 3229 } 3230 name = peer.ID() 3231 } 3232 switch dir { 3233 case api.PolicyDirection_IMPORT: 3234 return name, table.POLICY_DIRECTION_IMPORT, nil 3235 case api.PolicyDirection_EXPORT: 3236 return name, table.POLICY_DIRECTION_EXPORT, nil 3237 } 3238 return "", table.POLICY_DIRECTION_NONE, fmt.Errorf("invalid policy type") 3239 } 3240 3241 func (s *BgpServer) ListPolicyAssignment(ctx context.Context, r *api.ListPolicyAssignmentRequest, fn func(*api.PolicyAssignment)) error { 3242 var a []*api.PolicyAssignment 3243 err := s.mgmtOperation(func() error { 3244 if r == nil { 3245 return fmt.Errorf("invalid request") 3246 } 3247 3248 names := make([]string, 0, len(s.neighborMap)+1) 3249 if r.Name == "" { 3250 names = append(names, table.GLOBAL_RIB_NAME) 3251 for name := range s.neighborMap { 3252 names = append(names, name) 3253 } 3254 } else { 3255 names = append(names, r.Name) 3256 } 3257 dirs := make([]api.PolicyDirection, 0, 2) 3258 if r.Direction == api.PolicyDirection_UNKNOWN { 3259 dirs = []api.PolicyDirection{api.PolicyDirection_EXPORT, api.PolicyDirection_IMPORT} 3260 } else { 3261 dirs = append(dirs, r.Direction) 3262 } 3263 3264 a = make([]*api.PolicyAssignment, 0, len(names)) 3265 for _, name := range names { 3266 for _, dir := range dirs { 3267 id, dir, err := s.toPolicyInfo(name, dir) 3268 if err != nil { 3269 return err 3270 } 3271 rt, policies, err := s.policy.GetPolicyAssignment(id, dir) 3272 if err != nil { 3273 return err 3274 } 3275 if len(policies) == 0 { 3276 continue 3277 } 3278 t := &table.PolicyAssignment{ 3279 Name: name, 3280 Type: dir, 3281 Default: rt, 3282 Policies: policies, 3283 } 3284 a = append(a, table.NewAPIPolicyAssignmentFromTableStruct(t)) 3285 } 3286 } 3287 return nil 3288 }, false) 3289 if err == nil { 3290 for _, p := range a { 3291 select { 3292 case <-ctx.Done(): 3293 return nil 3294 default: 3295 fn(p) 3296 } 3297 } 3298 } 3299 return err 3300 } 3301 3302 func (s *BgpServer) AddPolicyAssignment(ctx context.Context, r *api.AddPolicyAssignmentRequest) error { 3303 return s.mgmtOperation(func() error { 3304 if r == nil || r.Assignment == nil { 3305 return fmt.Errorf("invalid request") 3306 } 3307 id, dir, err := s.toPolicyInfo(r.Assignment.Name, r.Assignment.Direction) 3308 if err != nil { 3309 return err 3310 } 3311 return s.policy.AddPolicyAssignment(id, dir, toPolicyDefinition(r.Assignment.Policies), defaultRouteType(r.Assignment.DefaultAction)) 3312 }, false) 3313 } 3314 3315 func (s *BgpServer) DeletePolicyAssignment(ctx context.Context, r *api.DeletePolicyAssignmentRequest) error { 3316 return s.mgmtOperation(func() error { 3317 if r == nil || r.Assignment == nil { 3318 return fmt.Errorf("invalid request") 3319 } 3320 id, dir, err := s.toPolicyInfo(r.Assignment.Name, r.Assignment.Direction) 3321 if err != nil { 3322 return err 3323 } 3324 return s.policy.DeletePolicyAssignment(id, dir, toPolicyDefinition(r.Assignment.Policies), r.All) 3325 }, false) 3326 } 3327 3328 func (s *BgpServer) SetPolicyAssignment(ctx context.Context, r *api.SetPolicyAssignmentRequest) error { 3329 return s.mgmtOperation(func() error { 3330 if r == nil || r.Assignment == nil { 3331 return fmt.Errorf("invalid request") 3332 } 3333 id, dir, err := s.toPolicyInfo(r.Assignment.Name, r.Assignment.Direction) 3334 if err != nil { 3335 return err 3336 } 3337 return s.policy.SetPolicyAssignment(id, dir, toPolicyDefinition(r.Assignment.Policies), defaultRouteType(r.Assignment.DefaultAction)) 3338 }, false) 3339 } 3340 3341 func (s *BgpServer) EnableMrt(ctx context.Context, r *api.EnableMrtRequest) error { 3342 return s.mgmtOperation(func() error { 3343 return s.mrtManager.enable(&config.MrtConfig{ 3344 DumpInterval: r.DumpInterval, 3345 RotationInterval: r.RotationInterval, 3346 DumpType: config.IntToMrtTypeMap[int(r.DumpType)], 3347 FileName: r.Filename, 3348 }) 3349 }, false) 3350 } 3351 3352 func (s *BgpServer) DisableMrt(ctx context.Context, r *api.DisableMrtRequest) error { 3353 return s.mgmtOperation(func() error { 3354 return s.mrtManager.disable(&config.MrtConfig{}) 3355 }, false) 3356 } 3357 3358 func (s *BgpServer) ListRpki(ctx context.Context, r *api.ListRpkiRequest, fn func(*api.Rpki)) error { 3359 var l []*api.Rpki 3360 err := s.mgmtOperation(func() error { 3361 for _, r := range s.roaManager.GetServers() { 3362 received := &r.State.RpkiMessages.RpkiReceived 3363 sent := &r.State.RpkiMessages.RpkiSent 3364 rpki := &api.Rpki{ 3365 Conf: &api.RPKIConf{ 3366 Address: r.Config.Address, 3367 RemotePort: uint32(r.Config.Port), 3368 }, 3369 State: &api.RPKIState{ 3370 Uptime: config.ProtoTimestamp(r.State.Uptime), 3371 Downtime: config.ProtoTimestamp(r.State.Downtime), 3372 Up: r.State.Up, 3373 RecordIpv4: r.State.RecordsV4, 3374 RecordIpv6: r.State.RecordsV6, 3375 PrefixIpv4: r.State.PrefixesV4, 3376 PrefixIpv6: r.State.PrefixesV6, 3377 Serial: r.State.SerialNumber, 3378 ReceivedIpv4: received.Ipv4Prefix, 3379 ReceivedIpv6: received.Ipv6Prefix, 3380 SerialNotify: received.SerialNotify, 3381 CacheReset: received.CacheReset, 3382 CacheResponse: received.CacheResponse, 3383 EndOfData: received.EndOfData, 3384 Error: received.Error, 3385 SerialQuery: sent.SerialQuery, 3386 ResetQuery: sent.ResetQuery, 3387 }, 3388 } 3389 l = append(l, rpki) 3390 } 3391 return nil 3392 }, false) 3393 if err == nil { 3394 for _, r := range l { 3395 select { 3396 case <-ctx.Done(): 3397 return nil 3398 default: 3399 fn(r) 3400 } 3401 } 3402 } 3403 return err 3404 } 3405 3406 func (s *BgpServer) ListRpkiTable(ctx context.Context, r *api.ListRpkiTableRequest, fn func(*api.Roa)) error { 3407 var l []*api.Roa 3408 err := s.mgmtOperation(func() error { 3409 family := bgp.RouteFamily(0) 3410 if r.Family != nil { 3411 family = bgp.AfiSafiToRouteFamily(uint16(r.Family.Afi), uint8(r.Family.Safi)) 3412 } 3413 roas, err := s.roaManager.GetRoa(family) 3414 if err == nil { 3415 l = append(l, newRoaListFromTableStructList(roas)...) 3416 } 3417 return err 3418 }, false) 3419 if err == nil { 3420 for _, roa := range l { 3421 select { 3422 case <-ctx.Done(): 3423 return nil 3424 default: 3425 fn(roa) 3426 } 3427 } 3428 } 3429 return err 3430 } 3431 3432 func (s *BgpServer) AddRpki(ctx context.Context, r *api.AddRpkiRequest) error { 3433 return s.mgmtOperation(func() error { 3434 return s.roaManager.AddServer(net.JoinHostPort(r.Address, strconv.Itoa(int(r.Port))), r.Lifetime) 3435 }, false) 3436 } 3437 3438 func (s *BgpServer) DeleteRpki(ctx context.Context, r *api.DeleteRpkiRequest) error { 3439 return s.mgmtOperation(func() error { 3440 return s.roaManager.DeleteServer(r.Address) 3441 }, false) 3442 } 3443 3444 func (s *BgpServer) EnableRpki(ctx context.Context, r *api.EnableRpkiRequest) error { 3445 return s.mgmtOperation(func() error { 3446 return s.roaManager.Enable(r.Address) 3447 }, false) 3448 } 3449 3450 func (s *BgpServer) DisableRpki(ctx context.Context, r *api.DisableRpkiRequest) error { 3451 return s.mgmtOperation(func() error { 3452 return s.roaManager.Disable(r.Address) 3453 }, false) 3454 } 3455 3456 func (s *BgpServer) ResetRpki(ctx context.Context, r *api.ResetRpkiRequest) error { 3457 return s.mgmtOperation(func() error { 3458 if r.Soft { 3459 return s.roaManager.SoftReset(r.Address) 3460 } 3461 return s.roaManager.Reset(r.Address) 3462 }, false) 3463 } 3464 3465 func (s *BgpServer) MonitorTable(ctx context.Context, r *api.MonitorTableRequest, fn func(*api.Path)) error { 3466 if r == nil { 3467 return fmt.Errorf("nil request") 3468 } 3469 w, err := func() (*watcher, error) { 3470 switch r.TableType { 3471 case api.TableType_GLOBAL: 3472 return s.watch(watchBestPath(r.Current)), nil 3473 case api.TableType_ADJ_IN: 3474 if r.PostPolicy { 3475 return s.watch(watchPostUpdate(r.Current)), nil 3476 } 3477 return s.watch(watchUpdate(r.Current)), nil 3478 default: 3479 return nil, fmt.Errorf("unsupported resource type: %v", r.TableType) 3480 } 3481 }() 3482 if err != nil { 3483 return err 3484 } 3485 3486 go func() { 3487 defer func() { 3488 w.Stop() 3489 }() 3490 family := bgp.RouteFamily(0) 3491 if r.Family != nil { 3492 family = bgp.AfiSafiToRouteFamily(uint16(r.Family.Afi), uint8(r.Family.Safi)) 3493 } 3494 3495 for { 3496 select { 3497 case ev := <-w.Event(): 3498 var pl []*table.Path 3499 switch msg := ev.(type) { 3500 case *watchEventBestPath: 3501 if len(msg.MultiPathList) > 0 { 3502 l := make([]*table.Path, 0) 3503 for _, p := range msg.MultiPathList { 3504 l = append(l, p...) 3505 } 3506 pl = l 3507 } else { 3508 pl = msg.PathList 3509 } 3510 case *watchEventUpdate: 3511 pl = msg.PathList 3512 } 3513 for _, path := range pl { 3514 if path == nil || (r.Family != nil && family != path.GetRouteFamily()) { 3515 continue 3516 } 3517 select { 3518 case <-ctx.Done(): 3519 return 3520 default: 3521 fn(toPathApi(path, nil)) 3522 } 3523 } 3524 case <-ctx.Done(): 3525 return 3526 } 3527 } 3528 }() 3529 return nil 3530 } 3531 3532 func (s *BgpServer) MonitorPeer(ctx context.Context, r *api.MonitorPeerRequest, fn func(*api.Peer)) error { 3533 if r == nil { 3534 return fmt.Errorf("nil request") 3535 } 3536 3537 go func() { 3538 w := s.watch(watchPeerState(r.Current)) 3539 defer func() { 3540 w.Stop() 3541 }() 3542 for { 3543 select { 3544 case m := <-w.Event(): 3545 msg := m.(*watchEventPeerState) 3546 if len(r.Address) > 0 && r.Address != msg.PeerAddress.String() && r.Address != msg.PeerInterface { 3547 break 3548 } 3549 p := &api.Peer{ 3550 Conf: &api.PeerConf{ 3551 PeerAs: msg.PeerAS, 3552 LocalAs: msg.LocalAS, 3553 NeighborAddress: msg.PeerAddress.String(), 3554 NeighborInterface: msg.PeerInterface, 3555 }, 3556 State: &api.PeerState{ 3557 PeerAs: msg.PeerAS, 3558 LocalAs: msg.LocalAS, 3559 NeighborAddress: msg.PeerAddress.String(), 3560 SessionState: api.PeerState_SessionState(int(msg.State) + 1), 3561 AdminState: api.PeerState_AdminState(msg.AdminState), 3562 RouterId: msg.PeerID.String(), 3563 }, 3564 Transport: &api.Transport{ 3565 LocalAddress: msg.LocalAddress.String(), 3566 LocalPort: uint32(msg.LocalPort), 3567 RemotePort: uint32(msg.PeerPort), 3568 }, 3569 } 3570 fn(p) 3571 case <-ctx.Done(): 3572 return 3573 } 3574 } 3575 }() 3576 return nil 3577 } 3578 3579 type watchEventType string 3580 3581 const ( 3582 watchEventTypeBestPath watchEventType = "bestpath" 3583 watchEventTypePreUpdate watchEventType = "preupdate" 3584 watchEventTypePostUpdate watchEventType = "postupdate" 3585 watchEventTypePeerState watchEventType = "peerstate" 3586 watchEventTypeTable watchEventType = "table" 3587 watchEventTypeRecvMsg watchEventType = "receivedmessage" 3588 ) 3589 3590 type watchEvent interface { 3591 } 3592 3593 type watchEventUpdate struct { 3594 Message *bgp.BGPMessage 3595 PeerAS uint32 3596 LocalAS uint32 3597 PeerAddress net.IP 3598 LocalAddress net.IP 3599 PeerID net.IP 3600 FourBytesAs bool 3601 Timestamp time.Time 3602 Payload []byte 3603 PostPolicy bool 3604 Init bool 3605 PathList []*table.Path 3606 Neighbor *config.Neighbor 3607 } 3608 3609 type watchEventPeerState struct { 3610 PeerAS uint32 3611 LocalAS uint32 3612 PeerAddress net.IP 3613 LocalAddress net.IP 3614 PeerPort uint16 3615 LocalPort uint16 3616 PeerID net.IP 3617 SentOpen *bgp.BGPMessage 3618 RecvOpen *bgp.BGPMessage 3619 State bgp.FSMState 3620 StateReason *fsmStateReason 3621 AdminState adminState 3622 Timestamp time.Time 3623 PeerInterface string 3624 } 3625 3626 type watchEventAdjIn struct { 3627 PathList []*table.Path 3628 } 3629 3630 type watchEventTable struct { 3631 RouterID string 3632 PathList map[string][]*table.Path 3633 Neighbor []*config.Neighbor 3634 } 3635 3636 type watchEventBestPath struct { 3637 PathList []*table.Path 3638 MultiPathList [][]*table.Path 3639 Vrf map[string]uint32 3640 } 3641 3642 type watchEventMessage struct { 3643 Message *bgp.BGPMessage 3644 PeerAS uint32 3645 LocalAS uint32 3646 PeerAddress net.IP 3647 LocalAddress net.IP 3648 PeerID net.IP 3649 FourBytesAs bool 3650 Timestamp time.Time 3651 IsSent bool 3652 } 3653 3654 type watchOptions struct { 3655 bestpath bool 3656 preUpdate bool 3657 postUpdate bool 3658 peerState bool 3659 initBest bool 3660 initUpdate bool 3661 initPostUpdate bool 3662 initPeerState bool 3663 tableName string 3664 recvMessage bool 3665 } 3666 3667 type watchOption func(*watchOptions) 3668 3669 func watchBestPath(current bool) watchOption { 3670 return func(o *watchOptions) { 3671 o.bestpath = true 3672 if current { 3673 o.initBest = true 3674 } 3675 } 3676 } 3677 3678 func watchUpdate(current bool) watchOption { 3679 return func(o *watchOptions) { 3680 o.preUpdate = true 3681 if current { 3682 o.initUpdate = true 3683 } 3684 } 3685 } 3686 3687 func watchPostUpdate(current bool) watchOption { 3688 return func(o *watchOptions) { 3689 o.postUpdate = true 3690 if current { 3691 o.initPostUpdate = true 3692 } 3693 } 3694 } 3695 3696 func watchPeerState(current bool) watchOption { 3697 return func(o *watchOptions) { 3698 o.peerState = true 3699 if current { 3700 o.initPeerState = true 3701 } 3702 } 3703 } 3704 3705 func watchTableName(name string) watchOption { 3706 return func(o *watchOptions) { 3707 o.tableName = name 3708 } 3709 } 3710 3711 func watchMessage(isSent bool) watchOption { 3712 return func(o *watchOptions) { 3713 if isSent { 3714 log.WithFields(log.Fields{ 3715 "Topic": "Server", 3716 }).Warn("watch event for sent messages is not implemented yet") 3717 // o.sentMessage = true 3718 } else { 3719 o.recvMessage = true 3720 } 3721 } 3722 } 3723 3724 type watcher struct { 3725 opts watchOptions 3726 realCh chan watchEvent 3727 ch *channels.InfiniteChannel 3728 s *BgpServer 3729 } 3730 3731 func (w *watcher) Event() <-chan watchEvent { 3732 return w.realCh 3733 } 3734 3735 func (w *watcher) Generate(t watchEventType) error { 3736 return w.s.mgmtOperation(func() error { 3737 switch t { 3738 case watchEventTypePreUpdate: 3739 pathList := make([]*table.Path, 0) 3740 for _, peer := range w.s.neighborMap { 3741 pathList = append(pathList, peer.adjRibIn.PathList(peer.configuredRFlist(), false)...) 3742 } 3743 w.notify(&watchEventAdjIn{PathList: clonePathList(pathList)}) 3744 case watchEventTypeTable: 3745 rib := w.s.globalRib 3746 as := uint32(0) 3747 id := table.GLOBAL_RIB_NAME 3748 if len(w.opts.tableName) > 0 { 3749 peer, ok := w.s.neighborMap[w.opts.tableName] 3750 if !ok { 3751 return fmt.Errorf("Neighbor that has %v doesn't exist.", w.opts.tableName) 3752 } 3753 if !peer.isRouteServerClient() { 3754 return fmt.Errorf("Neighbor %v doesn't have local rib", w.opts.tableName) 3755 } 3756 id = peer.ID() 3757 as = peer.AS() 3758 rib = w.s.rsRib 3759 } 3760 3761 pathList := func() map[string][]*table.Path { 3762 pathList := make(map[string][]*table.Path) 3763 for _, t := range rib.Tables { 3764 for _, dst := range t.GetDestinations() { 3765 if paths := dst.GetKnownPathList(id, as); len(paths) > 0 { 3766 pathList[dst.GetNlri().String()] = clonePathList(paths) 3767 } 3768 } 3769 } 3770 return pathList 3771 }() 3772 l := make([]*config.Neighbor, 0, len(w.s.neighborMap)) 3773 for _, peer := range w.s.neighborMap { 3774 l = append(l, w.s.toConfig(peer, false)) 3775 } 3776 w.notify(&watchEventTable{PathList: pathList, Neighbor: l}) 3777 default: 3778 return fmt.Errorf("unsupported type %v", t) 3779 } 3780 return nil 3781 }, false) 3782 } 3783 3784 func (w *watcher) notify(v watchEvent) { 3785 w.ch.In() <- v 3786 } 3787 3788 func (w *watcher) loop() { 3789 for ev := range w.ch.Out() { 3790 w.realCh <- ev.(watchEvent) 3791 } 3792 close(w.realCh) 3793 } 3794 3795 func (w *watcher) Stop() { 3796 w.s.mgmtOperation(func() error { 3797 for k, l := range w.s.watcherMap { 3798 for i, v := range l { 3799 if w == v { 3800 w.s.watcherMap[k] = append(l[:i], l[i+1:]...) 3801 break 3802 } 3803 } 3804 } 3805 3806 cleanInfiniteChannel(w.ch) 3807 // the loop function goroutine might be blocked for 3808 // writing to realCh. make sure it finishes. 3809 for range w.realCh { 3810 } 3811 return nil 3812 }, false) 3813 } 3814 3815 func (s *BgpServer) isWatched(typ watchEventType) bool { 3816 return len(s.watcherMap[typ]) != 0 3817 } 3818 3819 func (s *BgpServer) notifyWatcher(typ watchEventType, ev watchEvent) { 3820 for _, w := range s.watcherMap[typ] { 3821 w.notify(ev) 3822 } 3823 } 3824 3825 func (s *BgpServer) watch(opts ...watchOption) (w *watcher) { 3826 s.mgmtOperation(func() error { 3827 w = &watcher{ 3828 s: s, 3829 realCh: make(chan watchEvent, 8), 3830 ch: channels.NewInfiniteChannel(), 3831 } 3832 3833 for _, opt := range opts { 3834 opt(&w.opts) 3835 } 3836 3837 register := func(t watchEventType, w *watcher) { 3838 s.watcherMap[t] = append(s.watcherMap[t], w) 3839 } 3840 3841 if w.opts.bestpath { 3842 register(watchEventTypeBestPath, w) 3843 } 3844 if w.opts.preUpdate { 3845 register(watchEventTypePreUpdate, w) 3846 } 3847 if w.opts.postUpdate { 3848 register(watchEventTypePostUpdate, w) 3849 } 3850 if w.opts.peerState { 3851 register(watchEventTypePeerState, w) 3852 } 3853 if w.opts.initPeerState { 3854 for _, peer := range s.neighborMap { 3855 peer.fsm.lock.RLock() 3856 notEstablished := peer.fsm.state != bgp.BGP_FSM_ESTABLISHED 3857 peer.fsm.lock.RUnlock() 3858 if notEstablished { 3859 continue 3860 } 3861 w.notify(newWatchEventPeerState(peer, nil)) 3862 } 3863 } 3864 if w.opts.initBest && s.active() == nil { 3865 w.notify(&watchEventBestPath{ 3866 PathList: s.globalRib.GetBestPathList(table.GLOBAL_RIB_NAME, 0, nil), 3867 MultiPathList: s.globalRib.GetBestMultiPathList(table.GLOBAL_RIB_NAME, nil), 3868 }) 3869 } 3870 if w.opts.initUpdate { 3871 for _, peer := range s.neighborMap { 3872 peer.fsm.lock.RLock() 3873 notEstablished := peer.fsm.state != bgp.BGP_FSM_ESTABLISHED 3874 peer.fsm.lock.RUnlock() 3875 if notEstablished { 3876 continue 3877 } 3878 configNeighbor := w.s.toConfig(peer, false) 3879 for _, rf := range peer.configuredRFlist() { 3880 peer.fsm.lock.RLock() 3881 _, y := peer.fsm.capMap[bgp.BGP_CAP_FOUR_OCTET_AS_NUMBER] 3882 l, _ := peer.fsm.LocalHostPort() 3883 update := &watchEventUpdate{ 3884 PeerAS: peer.fsm.peerInfo.AS, 3885 LocalAS: peer.fsm.peerInfo.LocalAS, 3886 PeerAddress: peer.fsm.peerInfo.Address, 3887 LocalAddress: net.ParseIP(l), 3888 PeerID: peer.fsm.peerInfo.ID, 3889 FourBytesAs: y, 3890 Init: true, 3891 PostPolicy: false, 3892 Neighbor: configNeighbor, 3893 PathList: peer.adjRibIn.PathList([]bgp.RouteFamily{rf}, false), 3894 } 3895 peer.fsm.lock.RUnlock() 3896 w.notify(update) 3897 3898 eor := bgp.NewEndOfRib(rf) 3899 eorBuf, _ := eor.Serialize() 3900 peer.fsm.lock.RLock() 3901 update = &watchEventUpdate{ 3902 Message: eor, 3903 PeerAS: peer.fsm.peerInfo.AS, 3904 LocalAS: peer.fsm.peerInfo.LocalAS, 3905 PeerAddress: peer.fsm.peerInfo.Address, 3906 LocalAddress: net.ParseIP(l), 3907 PeerID: peer.fsm.peerInfo.ID, 3908 FourBytesAs: y, 3909 Timestamp: time.Now(), 3910 Init: true, 3911 Payload: eorBuf, 3912 PostPolicy: false, 3913 Neighbor: configNeighbor, 3914 } 3915 peer.fsm.lock.RUnlock() 3916 w.notify(update) 3917 } 3918 } 3919 } 3920 if w.opts.initPostUpdate && s.active() == nil { 3921 for _, rf := range s.globalRib.GetRFlist() { 3922 if len(s.globalRib.Tables[rf].GetDestinations()) == 0 { 3923 continue 3924 } 3925 pathsByPeer := make(map[*table.PeerInfo][]*table.Path) 3926 for _, path := range s.globalRib.GetPathList(table.GLOBAL_RIB_NAME, 0, []bgp.RouteFamily{rf}) { 3927 pathsByPeer[path.GetSource()] = append(pathsByPeer[path.GetSource()], path) 3928 } 3929 for peerInfo, paths := range pathsByPeer { 3930 // create copy which can be access to without mutex 3931 var configNeighbor *config.Neighbor 3932 if peer, ok := s.neighborMap[peerInfo.Address.String()]; ok { 3933 configNeighbor = w.s.toConfig(peer, false) 3934 } 3935 3936 w.notify(&watchEventUpdate{ 3937 PeerAS: peerInfo.AS, 3938 PeerAddress: peerInfo.Address, 3939 PeerID: peerInfo.ID, 3940 PostPolicy: true, 3941 Neighbor: configNeighbor, 3942 PathList: paths, 3943 Init: true, 3944 }) 3945 3946 eor := bgp.NewEndOfRib(rf) 3947 eorBuf, _ := eor.Serialize() 3948 w.notify(&watchEventUpdate{ 3949 Message: eor, 3950 PeerAS: peerInfo.AS, 3951 PeerAddress: peerInfo.Address, 3952 PeerID: peerInfo.ID, 3953 Timestamp: time.Now(), 3954 Payload: eorBuf, 3955 PostPolicy: true, 3956 Neighbor: configNeighbor, 3957 Init: true, 3958 }) 3959 } 3960 } 3961 } 3962 if w.opts.recvMessage { 3963 register(watchEventTypeRecvMsg, w) 3964 } 3965 3966 go w.loop() 3967 return nil 3968 }, false) 3969 return w 3970 }