github.com/osrg/gobgp@v2.0.0+incompatible/pkg/server/server.go (about)

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