github.com/osrg/gobgp/v3@v3.30.0/pkg/server/peer.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  	"fmt"
    20  	"net"
    21  	"time"
    22  
    23  	"github.com/osrg/gobgp/v3/internal/pkg/table"
    24  	"github.com/osrg/gobgp/v3/pkg/config/oc"
    25  	"github.com/osrg/gobgp/v3/pkg/log"
    26  	"github.com/osrg/gobgp/v3/pkg/packet/bgp"
    27  )
    28  
    29  const (
    30  	flopThreshold = time.Second * 30
    31  )
    32  
    33  type peerGroup struct {
    34  	Conf             *oc.PeerGroup
    35  	members          map[string]oc.Neighbor
    36  	dynamicNeighbors map[string]*oc.DynamicNeighbor
    37  }
    38  
    39  func newPeerGroup(c *oc.PeerGroup) *peerGroup {
    40  	return &peerGroup{
    41  		Conf:             c,
    42  		members:          make(map[string]oc.Neighbor),
    43  		dynamicNeighbors: make(map[string]*oc.DynamicNeighbor),
    44  	}
    45  }
    46  
    47  func (pg *peerGroup) AddMember(c oc.Neighbor) {
    48  	pg.members[c.State.NeighborAddress] = c
    49  }
    50  
    51  func (pg *peerGroup) DeleteMember(c oc.Neighbor) {
    52  	delete(pg.members, c.State.NeighborAddress)
    53  }
    54  
    55  func (pg *peerGroup) AddDynamicNeighbor(c *oc.DynamicNeighbor) {
    56  	pg.dynamicNeighbors[c.Config.Prefix] = c
    57  }
    58  
    59  func (pg *peerGroup) DeleteDynamicNeighbor(prefix string) {
    60  	delete(pg.dynamicNeighbors, prefix)
    61  }
    62  
    63  func newDynamicPeer(g *oc.Global, neighborAddress string, pg *oc.PeerGroup, loc *table.TableManager, policy *table.RoutingPolicy, logger log.Logger) *peer {
    64  	conf := oc.Neighbor{
    65  		Config: oc.NeighborConfig{
    66  			PeerGroup: pg.Config.PeerGroupName,
    67  		},
    68  		State: oc.NeighborState{
    69  			NeighborAddress: neighborAddress,
    70  		},
    71  		Transport: oc.Transport{
    72  			Config: oc.TransportConfig{
    73  				PassiveMode: true,
    74  			},
    75  		},
    76  	}
    77  	if err := oc.OverwriteNeighborConfigWithPeerGroup(&conf, pg); err != nil {
    78  		logger.Debug("Can't overwrite neighbor config",
    79  			log.Fields{
    80  				"Topic": "Peer",
    81  				"Key":   neighborAddress,
    82  				"Error": err})
    83  		return nil
    84  	}
    85  	if err := oc.SetDefaultNeighborConfigValues(&conf, pg, g); err != nil {
    86  		logger.Debug("Can't set default config",
    87  			log.Fields{
    88  				"Topic": "Peer",
    89  				"Key":   neighborAddress,
    90  				"Error": err})
    91  		return nil
    92  	}
    93  	peer := newPeer(g, &conf, loc, policy, logger)
    94  	peer.fsm.lock.Lock()
    95  	peer.fsm.state = bgp.BGP_FSM_ACTIVE
    96  	peer.fsm.lock.Unlock()
    97  	return peer
    98  }
    99  
   100  type peer struct {
   101  	tableId           string
   102  	fsm               *fsm
   103  	adjRibIn          *table.AdjRib
   104  	policy            *table.RoutingPolicy
   105  	localRib          *table.TableManager
   106  	prefixLimitWarned map[bgp.RouteFamily]bool
   107  	// map of path local identifiers sent for that prefix
   108  	sentPaths           map[table.PathDestLocalKey]map[uint32]struct{}
   109  	sendMaxPathFiltered map[table.PathLocalKey]struct{}
   110  	llgrEndChs          []chan struct{}
   111  }
   112  
   113  func newPeer(g *oc.Global, conf *oc.Neighbor, loc *table.TableManager, policy *table.RoutingPolicy, logger log.Logger) *peer {
   114  	peer := &peer{
   115  		localRib:            loc,
   116  		policy:              policy,
   117  		fsm:                 newFSM(g, conf, logger),
   118  		prefixLimitWarned:   make(map[bgp.RouteFamily]bool),
   119  		sentPaths:           make(map[table.PathDestLocalKey]map[uint32]struct{}),
   120  		sendMaxPathFiltered: make(map[table.PathLocalKey]struct{}),
   121  	}
   122  	if peer.isRouteServerClient() {
   123  		peer.tableId = conf.State.NeighborAddress
   124  	} else {
   125  		peer.tableId = table.GLOBAL_RIB_NAME
   126  	}
   127  	rfs, _ := oc.AfiSafis(conf.AfiSafis).ToRfList()
   128  	peer.adjRibIn = table.NewAdjRib(peer.fsm.logger, rfs)
   129  	return peer
   130  }
   131  
   132  func (peer *peer) AS() uint32 {
   133  	peer.fsm.lock.RLock()
   134  	defer peer.fsm.lock.RUnlock()
   135  	return peer.fsm.pConf.State.PeerAs
   136  }
   137  
   138  func (peer *peer) ID() string {
   139  	peer.fsm.lock.RLock()
   140  	defer peer.fsm.lock.RUnlock()
   141  	return peer.fsm.pConf.State.NeighborAddress
   142  }
   143  
   144  func (peer *peer) routerID() net.IP {
   145  	peer.fsm.lock.RLock()
   146  	defer peer.fsm.lock.RUnlock()
   147  	return peer.fsm.peerInfo.ID
   148  }
   149  
   150  func (peer *peer) RouterID() string {
   151  	if id := peer.routerID(); id != nil {
   152  		return id.String()
   153  	}
   154  	return ""
   155  }
   156  
   157  func (peer *peer) TableID() string {
   158  	return peer.tableId
   159  }
   160  
   161  func (peer *peer) isIBGPPeer() bool {
   162  	peer.fsm.lock.RLock()
   163  	defer peer.fsm.lock.RUnlock()
   164  	return peer.fsm.pConf.State.PeerType == oc.PEER_TYPE_INTERNAL
   165  }
   166  
   167  func (peer *peer) isRouteServerClient() bool {
   168  	peer.fsm.lock.RLock()
   169  	defer peer.fsm.lock.RUnlock()
   170  	return peer.fsm.pConf.RouteServer.Config.RouteServerClient
   171  }
   172  
   173  func (peer *peer) isSecondaryRouteEnabled() bool {
   174  	peer.fsm.lock.RLock()
   175  	defer peer.fsm.lock.RUnlock()
   176  	return peer.fsm.pConf.RouteServer.Config.RouteServerClient && peer.fsm.pConf.RouteServer.Config.SecondaryRoute
   177  }
   178  
   179  func (peer *peer) isRouteReflectorClient() bool {
   180  	peer.fsm.lock.RLock()
   181  	defer peer.fsm.lock.RUnlock()
   182  	return peer.fsm.pConf.RouteReflector.Config.RouteReflectorClient
   183  }
   184  
   185  func (peer *peer) isGracefulRestartEnabled() bool {
   186  	peer.fsm.lock.RLock()
   187  	defer peer.fsm.lock.RUnlock()
   188  	return peer.fsm.pConf.GracefulRestart.State.Enabled
   189  }
   190  
   191  func (peer *peer) getAddPathMode(family bgp.RouteFamily) bgp.BGPAddPathMode {
   192  	peer.fsm.lock.RLock()
   193  	defer peer.fsm.lock.RUnlock()
   194  	if mode, y := peer.fsm.rfMap[family]; y {
   195  		return mode
   196  	}
   197  	return bgp.BGP_ADD_PATH_NONE
   198  }
   199  
   200  func (peer *peer) isAddPathReceiveEnabled(family bgp.RouteFamily) bool {
   201  	return (peer.getAddPathMode(family) & bgp.BGP_ADD_PATH_RECEIVE) > 0
   202  }
   203  
   204  func (peer *peer) isAddPathSendEnabled(family bgp.RouteFamily) bool {
   205  	return (peer.getAddPathMode(family) & bgp.BGP_ADD_PATH_SEND) > 0
   206  }
   207  
   208  func (peer *peer) getAddPathSendMax(family bgp.RouteFamily) uint8 {
   209  	peer.fsm.lock.RLock()
   210  	defer peer.fsm.lock.RUnlock()
   211  	for _, a := range peer.fsm.pConf.AfiSafis {
   212  		if a.State.Family == family {
   213  			return a.AddPaths.Config.SendMax
   214  		}
   215  	}
   216  	return 0
   217  }
   218  
   219  func (peer *peer) getRoutesCount(family bgp.RouteFamily, dstPrefix string) uint8 {
   220  	destLocalKey := table.NewPathDestLocalKey(family, dstPrefix)
   221  	if identifiers, ok := peer.sentPaths[*destLocalKey]; ok {
   222  		count := len(identifiers)
   223  		// the send-max config is uint8, so we need to check for overflow
   224  		if count > int(^uint8(0)) {
   225  			return ^uint8(0)
   226  		}
   227  		return uint8(count)
   228  	}
   229  	return 0
   230  }
   231  
   232  func (peer *peer) updateRoutes(paths ...*table.Path) {
   233  	if len(paths) == 0 {
   234  		return
   235  	}
   236  	for _, path := range paths {
   237  		localKey := path.GetLocalKey()
   238  		destLocalKey := localKey.PathDestLocalKey
   239  		identifiers, destExists := peer.sentPaths[destLocalKey]
   240  		if path.IsWithdraw && destExists {
   241  			delete(identifiers, path.GetNlri().PathLocalIdentifier())
   242  		} else if !path.IsWithdraw {
   243  			if !destExists {
   244  				peer.sentPaths[destLocalKey] = make(map[uint32]struct{})
   245  			}
   246  			identifiers := peer.sentPaths[destLocalKey]
   247  			if len(identifiers) < int(peer.getAddPathSendMax(destLocalKey.Family)) {
   248  				identifiers[localKey.Id] = struct{}{}
   249  			}
   250  		}
   251  	}
   252  }
   253  
   254  func (peer *peer) isPathSendMaxFiltered(path *table.Path) bool {
   255  	if path == nil {
   256  		return false
   257  	}
   258  	_, found := peer.sendMaxPathFiltered[path.GetLocalKey()]
   259  	return found
   260  }
   261  
   262  func (peer *peer) unsetPathSendMaxFiltered(path *table.Path) bool {
   263  	if path == nil {
   264  		return false
   265  	}
   266  	if _, ok := peer.sendMaxPathFiltered[path.GetLocalKey()]; !ok {
   267  		return false
   268  	}
   269  	delete(peer.sendMaxPathFiltered, path.GetLocalKey())
   270  	return true
   271  }
   272  
   273  func (peer *peer) hasPathAlreadyBeenSent(path *table.Path) bool {
   274  	if path == nil {
   275  		return false
   276  	}
   277  	destLocalKey := path.GetDestLocalKey()
   278  	if _, dstExist := peer.sentPaths[destLocalKey]; !dstExist {
   279  		return false
   280  	}
   281  	_, pathExist := peer.sentPaths[destLocalKey][path.GetNlri().PathLocalIdentifier()]
   282  	return pathExist
   283  }
   284  
   285  func (peer *peer) isDynamicNeighbor() bool {
   286  	peer.fsm.lock.RLock()
   287  	defer peer.fsm.lock.RUnlock()
   288  	return peer.fsm.pConf.Config.NeighborAddress == "" && peer.fsm.pConf.Config.NeighborInterface == ""
   289  }
   290  
   291  func (peer *peer) recvedAllEOR() bool {
   292  	peer.fsm.lock.RLock()
   293  	defer peer.fsm.lock.RUnlock()
   294  	for _, a := range peer.fsm.pConf.AfiSafis {
   295  		if s := a.MpGracefulRestart.State; s.Enabled && s.Received && !s.EndOfRibReceived {
   296  			return false
   297  		}
   298  	}
   299  	return true
   300  }
   301  
   302  func (peer *peer) configuredRFlist() []bgp.RouteFamily {
   303  	peer.fsm.lock.RLock()
   304  	defer peer.fsm.lock.RUnlock()
   305  	rfs, _ := oc.AfiSafis(peer.fsm.pConf.AfiSafis).ToRfList()
   306  	return rfs
   307  }
   308  
   309  func (peer *peer) negotiatedRFList() []bgp.RouteFamily {
   310  	peer.fsm.lock.RLock()
   311  	defer peer.fsm.lock.RUnlock()
   312  	l := make([]bgp.RouteFamily, 0, len(peer.fsm.rfMap))
   313  	for family := range peer.fsm.rfMap {
   314  		l = append(l, family)
   315  	}
   316  	return l
   317  }
   318  
   319  func (peer *peer) toGlobalFamilies(families []bgp.RouteFamily) []bgp.RouteFamily {
   320  	id := peer.ID()
   321  	peer.fsm.lock.RLock()
   322  	defer peer.fsm.lock.RUnlock()
   323  	if peer.fsm.pConf.Config.Vrf != "" {
   324  		fs := make([]bgp.RouteFamily, 0, len(families))
   325  		for _, f := range families {
   326  			switch f {
   327  			case bgp.RF_IPv4_UC:
   328  				fs = append(fs, bgp.RF_IPv4_VPN)
   329  			case bgp.RF_IPv6_UC:
   330  				fs = append(fs, bgp.RF_IPv6_VPN)
   331  			case bgp.RF_FS_IPv4_UC:
   332  				fs = append(fs, bgp.RF_FS_IPv4_VPN)
   333  			case bgp.RF_FS_IPv6_UC:
   334  				fs = append(fs, bgp.RF_FS_IPv6_VPN)
   335  			default:
   336  				peer.fsm.logger.Warn("invalid family configured for neighbor with vrf",
   337  					log.Fields{
   338  						"Topic":  "Peer",
   339  						"Key":    id,
   340  						"Family": f,
   341  						"VRF":    peer.fsm.pConf.Config.Vrf})
   342  			}
   343  		}
   344  		families = fs
   345  	}
   346  	return families
   347  }
   348  
   349  func classifyFamilies(all, part []bgp.RouteFamily) ([]bgp.RouteFamily, []bgp.RouteFamily) {
   350  	a := []bgp.RouteFamily{}
   351  	b := []bgp.RouteFamily{}
   352  	for _, f := range all {
   353  		p := true
   354  		for _, g := range part {
   355  			if f == g {
   356  				p = false
   357  				a = append(a, f)
   358  				break
   359  			}
   360  		}
   361  		if p {
   362  			b = append(b, f)
   363  		}
   364  	}
   365  	return a, b
   366  }
   367  
   368  func (peer *peer) forwardingPreservedFamilies() ([]bgp.RouteFamily, []bgp.RouteFamily) {
   369  	peer.fsm.lock.RLock()
   370  	list := []bgp.RouteFamily{}
   371  	for _, a := range peer.fsm.pConf.AfiSafis {
   372  		if s := a.MpGracefulRestart.State; s.Enabled && s.Received {
   373  			list = append(list, a.State.Family)
   374  		}
   375  	}
   376  	peer.fsm.lock.RUnlock()
   377  	return classifyFamilies(peer.configuredRFlist(), list)
   378  }
   379  
   380  func (peer *peer) llgrFamilies() ([]bgp.RouteFamily, []bgp.RouteFamily) {
   381  	peer.fsm.lock.RLock()
   382  	list := []bgp.RouteFamily{}
   383  	for _, a := range peer.fsm.pConf.AfiSafis {
   384  		if a.LongLivedGracefulRestart.State.Enabled {
   385  			list = append(list, a.State.Family)
   386  		}
   387  	}
   388  	peer.fsm.lock.RUnlock()
   389  	return classifyFamilies(peer.configuredRFlist(), list)
   390  }
   391  
   392  func (peer *peer) isLLGREnabledFamily(family bgp.RouteFamily) bool {
   393  	peer.fsm.lock.RLock()
   394  	llgrEnabled := peer.fsm.pConf.GracefulRestart.Config.LongLivedEnabled
   395  	peer.fsm.lock.RUnlock()
   396  	if !llgrEnabled {
   397  		return false
   398  	}
   399  	fs, _ := peer.llgrFamilies()
   400  	for _, f := range fs {
   401  		if f == family {
   402  			return true
   403  		}
   404  	}
   405  	return false
   406  }
   407  
   408  func (peer *peer) llgrRestartTime(family bgp.RouteFamily) uint32 {
   409  	peer.fsm.lock.RLock()
   410  	defer peer.fsm.lock.RUnlock()
   411  	for _, a := range peer.fsm.pConf.AfiSafis {
   412  		if a.State.Family == family {
   413  			return a.LongLivedGracefulRestart.State.PeerRestartTime
   414  		}
   415  	}
   416  	return 0
   417  }
   418  
   419  func (peer *peer) llgrRestartTimerExpired(family bgp.RouteFamily) bool {
   420  	peer.fsm.lock.RLock()
   421  	defer peer.fsm.lock.RUnlock()
   422  	all := true
   423  	for _, a := range peer.fsm.pConf.AfiSafis {
   424  		if a.State.Family == family {
   425  			a.LongLivedGracefulRestart.State.PeerRestartTimerExpired = true
   426  		}
   427  		s := a.LongLivedGracefulRestart.State
   428  		if s.Received && !s.PeerRestartTimerExpired {
   429  			all = false
   430  		}
   431  	}
   432  	return all
   433  }
   434  
   435  func (peer *peer) markLLGRStale(fs []bgp.RouteFamily) []*table.Path {
   436  	return peer.adjRibIn.MarkLLGRStaleOrDrop(fs)
   437  }
   438  
   439  func (peer *peer) stopPeerRestarting() {
   440  	peer.fsm.lock.Lock()
   441  	defer peer.fsm.lock.Unlock()
   442  	peer.fsm.pConf.GracefulRestart.State.PeerRestarting = false
   443  	for _, ch := range peer.llgrEndChs {
   444  		close(ch)
   445  	}
   446  	peer.llgrEndChs = make([]chan struct{}, 0)
   447  
   448  }
   449  
   450  func (peer *peer) filterPathFromSourcePeer(path, old *table.Path) *table.Path {
   451  	// Consider 3 peers - A, B, C and prefix P originated by C. Parallel eBGP
   452  	// sessions exist between A & B, and both have a single session with C.
   453  	//
   454  	// When A receives the withdraw from C, we enter this func for each peer of
   455  	// A, with the following:
   456  	// peer: [C, B #1, B #2]
   457  	// path: new best for P facing B
   458  	// old: old best for P facing C
   459  	//
   460  	// Our comparison between peer identifier and path source ID must be router
   461  	// ID-based (not neighbor address), otherwise we will return early. If we
   462  	// return early for one of the two sessions facing B
   463  	// (whichever is not the new best path), we fail to send a withdraw towards
   464  	// B, and the route is "stuck".
   465  	// TODO: considerations for RFC6286
   466  	if !peer.routerID().Equal(path.GetSource().ID) {
   467  		return path
   468  	}
   469  
   470  	// Note: Multiple paths having the same prefix could exist the withdrawals
   471  	// list in the case of Route Server setup with import policies modifying
   472  	// paths. In such case, gobgp sends duplicated update messages; withdraw
   473  	// messages for the same prefix.
   474  	if !peer.isRouteServerClient() {
   475  		if peer.isRouteReflectorClient() && path.GetRouteFamily() == bgp.RF_RTC_UC {
   476  			// When the peer is a Route Reflector client and the given path
   477  			// contains the Route Tartget Membership NLRI, the path should not
   478  			// be withdrawn in order to signal the client to distribute routes
   479  			// with the specific RT to Route Reflector.
   480  			return path
   481  		} else if !path.IsWithdraw && old != nil && old.GetSource().Address.String() != peer.ID() {
   482  			// Say, peer A and B advertized same prefix P, and best path
   483  			// calculation chose a path from B as best. When B withdraws prefix
   484  			// P, best path calculation chooses the path from A as best. For
   485  			// peers other than A, this path should be advertised (as implicit
   486  			// withdrawal). However for A, we should advertise the withdrawal
   487  			// path. Thing is same when peer A and we advertized prefix P (as
   488  			// local route), then, we withdraws the prefix.
   489  			return old.Clone(true)
   490  		}
   491  	}
   492  	if peer.fsm.logger.GetLevel() >= log.DebugLevel {
   493  		peer.fsm.logger.Debug("From me, ignore",
   494  			log.Fields{
   495  				"Topic": "Peer",
   496  				"Key":   peer.ID(),
   497  				"Data":  path})
   498  	}
   499  	return nil
   500  }
   501  
   502  func (peer *peer) doPrefixLimit(k bgp.RouteFamily, c *oc.PrefixLimitConfig) *bgp.BGPMessage {
   503  	if maxPrefixes := int(c.MaxPrefixes); maxPrefixes > 0 {
   504  		count := peer.adjRibIn.Count([]bgp.RouteFamily{k})
   505  		pct := int(c.ShutdownThresholdPct)
   506  		if pct > 0 && !peer.prefixLimitWarned[k] && count > (maxPrefixes*pct/100) {
   507  			peer.prefixLimitWarned[k] = true
   508  			peer.fsm.logger.Warn("prefix limit reached",
   509  				log.Fields{
   510  					"Topic":  "Peer",
   511  					"Key":    peer.ID(),
   512  					"Family": k.String(),
   513  					"Pct":    pct})
   514  		}
   515  		if count > maxPrefixes {
   516  			peer.fsm.logger.Warn("prefix limit reached",
   517  				log.Fields{
   518  					"Topic":  "Peer",
   519  					"Key":    peer.ID(),
   520  					"Family": k.String()})
   521  			return bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_MAXIMUM_NUMBER_OF_PREFIXES_REACHED, nil)
   522  		}
   523  	}
   524  	return nil
   525  }
   526  
   527  func (peer *peer) updatePrefixLimitConfig(c []oc.AfiSafi) error {
   528  	peer.fsm.lock.RLock()
   529  	x := peer.fsm.pConf.AfiSafis
   530  	peer.fsm.lock.RUnlock()
   531  	y := c
   532  	if len(x) != len(y) {
   533  		return fmt.Errorf("changing supported afi-safi is not allowed")
   534  	}
   535  	m := make(map[bgp.RouteFamily]oc.PrefixLimitConfig)
   536  	for _, e := range x {
   537  		m[e.State.Family] = e.PrefixLimit.Config
   538  	}
   539  	for _, e := range y {
   540  		if p, ok := m[e.State.Family]; !ok {
   541  			return fmt.Errorf("changing supported afi-safi is not allowed")
   542  		} else if !p.Equal(&e.PrefixLimit.Config) {
   543  			peer.fsm.logger.Warn("update prefix limit configuration",
   544  				log.Fields{
   545  					"Topic":                   "Peer",
   546  					"Key":                     peer.ID(),
   547  					"AddressFamily":           e.Config.AfiSafiName,
   548  					"OldMaxPrefixes":          p.MaxPrefixes,
   549  					"NewMaxPrefixes":          e.PrefixLimit.Config.MaxPrefixes,
   550  					"OldShutdownThresholdPct": p.ShutdownThresholdPct,
   551  					"NewShutdownThresholdPct": e.PrefixLimit.Config.ShutdownThresholdPct})
   552  			peer.prefixLimitWarned[e.State.Family] = false
   553  			if msg := peer.doPrefixLimit(e.State.Family, &e.PrefixLimit.Config); msg != nil {
   554  				sendfsmOutgoingMsg(peer, nil, msg, true)
   555  			}
   556  		}
   557  	}
   558  	peer.fsm.lock.Lock()
   559  	peer.fsm.pConf.AfiSafis = c
   560  	peer.fsm.lock.Unlock()
   561  	return nil
   562  }
   563  
   564  func (peer *peer) handleUpdate(e *fsmMsg) ([]*table.Path, []bgp.RouteFamily, *bgp.BGPMessage) {
   565  	m := e.MsgData.(*bgp.BGPMessage)
   566  	update := m.Body.(*bgp.BGPUpdate)
   567  
   568  	if peer.fsm.logger.GetLevel() >= log.DebugLevel {
   569  		peer.fsm.logger.Debug("received update",
   570  			log.Fields{
   571  				"Topic":       "Peer",
   572  				"Key":         peer.fsm.pConf.State.NeighborAddress,
   573  				"nlri":        update.NLRI,
   574  				"withdrawals": update.WithdrawnRoutes,
   575  				"attributes":  update.PathAttributes})
   576  	}
   577  
   578  	peer.fsm.lock.Lock()
   579  	peer.fsm.pConf.Timers.State.UpdateRecvTime = time.Now().Unix()
   580  	peer.fsm.lock.Unlock()
   581  	if len(e.PathList) > 0 {
   582  		paths := make([]*table.Path, 0, len(e.PathList))
   583  		eor := []bgp.RouteFamily{}
   584  		for _, path := range e.PathList {
   585  			if path.IsEOR() {
   586  				family := path.GetRouteFamily()
   587  				peer.fsm.logger.Debug("EOR received",
   588  					log.Fields{
   589  						"Topic":         "Peer",
   590  						"Key":           peer.ID(),
   591  						"AddressFamily": family})
   592  				eor = append(eor, family)
   593  				continue
   594  			}
   595  			// RFC4271 9.1.2 Phase 2: Route Selection
   596  			//
   597  			// If the AS_PATH attribute of a BGP route contains an AS loop, the BGP
   598  			// route should be excluded from the Phase 2 decision function.
   599  			if aspath := path.GetAsPath(); aspath != nil {
   600  				peer.fsm.lock.RLock()
   601  				localAS := peer.fsm.peerInfo.LocalAS
   602  				allowOwnAS := int(peer.fsm.pConf.AsPathOptions.Config.AllowOwnAs)
   603  				peer.fsm.lock.RUnlock()
   604  				if hasOwnASLoop(localAS, allowOwnAS, aspath) {
   605  					path.SetRejected(true)
   606  					continue
   607  				}
   608  			}
   609  			// RFC4456 8. Avoiding Routing Information Loops
   610  			// A router that recognizes the ORIGINATOR_ID attribute SHOULD
   611  			// ignore a route received with its BGP Identifier as the ORIGINATOR_ID.
   612  			isIBGPPeer := peer.isIBGPPeer()
   613  			peer.fsm.lock.RLock()
   614  			routerId := peer.fsm.gConf.Config.RouterId
   615  			peer.fsm.lock.RUnlock()
   616  			if isIBGPPeer {
   617  				if id := path.GetOriginatorID(); routerId == id.String() {
   618  					peer.fsm.logger.Debug("Originator ID is mine, ignore",
   619  						log.Fields{
   620  							"Topic":        "Peer",
   621  							"Key":          peer.ID(),
   622  							"OriginatorID": id,
   623  							"Data":         path})
   624  					path.SetRejected(true)
   625  					continue
   626  				}
   627  			}
   628  			paths = append(paths, path)
   629  		}
   630  		peer.adjRibIn.Update(e.PathList)
   631  		peer.fsm.lock.RLock()
   632  		peerAfiSafis := peer.fsm.pConf.AfiSafis
   633  		peer.fsm.lock.RUnlock()
   634  		for _, af := range peerAfiSafis {
   635  			if msg := peer.doPrefixLimit(af.State.Family, &af.PrefixLimit.Config); msg != nil {
   636  				return nil, nil, msg
   637  			}
   638  		}
   639  		return paths, eor, nil
   640  	}
   641  	return nil, nil, nil
   642  }
   643  
   644  func (peer *peer) startFSMHandler() {
   645  	handler := newFSMHandler(peer.fsm, peer.fsm.outgoingCh)
   646  	peer.fsm.lock.Lock()
   647  	peer.fsm.h = handler
   648  	peer.fsm.lock.Unlock()
   649  }
   650  
   651  func (peer *peer) StaleAll(rfList []bgp.RouteFamily) []*table.Path {
   652  	return peer.adjRibIn.StaleAll(rfList)
   653  }
   654  
   655  func (peer *peer) PassConn(conn *net.TCPConn) {
   656  	select {
   657  	case peer.fsm.connCh <- conn:
   658  	default:
   659  		conn.Close()
   660  		peer.fsm.logger.Warn("accepted conn is closed to avoid be blocked",
   661  			log.Fields{
   662  				"Topic": "Peer",
   663  				"Key":   peer.ID()})
   664  	}
   665  }
   666  
   667  func (peer *peer) DropAll(rfList []bgp.RouteFamily) []*table.Path {
   668  	return peer.adjRibIn.Drop(rfList)
   669  }