github.com/osrg/gobgp/v3@v3.30.0/pkg/server/server.go (about)

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