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