diff options
-rwxr-xr-x | cli/gobgpcli | 5 | ||||
-rw-r--r-- | packet/bgp.go | 4 | ||||
-rw-r--r-- | packet/validate.go | 21 | ||||
-rw-r--r-- | packet/validate_test.go | 26 | ||||
-rw-r--r-- | server/fsm.go | 15 | ||||
-rw-r--r-- | server/peer.go | 112 | ||||
-rw-r--r-- | server/peer_test.go | 5 | ||||
-rw-r--r-- | table/table_manager.go | 25 |
8 files changed, 118 insertions, 95 deletions
diff --git a/cli/gobgpcli b/cli/gobgpcli index c4ca602f..553d8121 100755 --- a/cli/gobgpcli +++ b/cli/gobgpcli @@ -310,8 +310,9 @@ class Show(object): elif self.args[2] == "adj-rib-in" or self.args[2] == "adj-rib-out": rfs = ["RF_IPv4_UC", "RF_IPv6_UC"] for rf in rfs: - paths = r.json()[rf] - self.show_routes(f, paths, False, timestamp) + if rf in r.json(): + paths = r.json()[rf] + self.show_routes(f, paths, False, timestamp) return 0 def show_routes(self, f, paths, showBest=False, timestamp=False): diff --git a/packet/bgp.go b/packet/bgp.go index 3a27bce0..1b80e543 100644 --- a/packet/bgp.go +++ b/packet/bgp.go @@ -959,6 +959,10 @@ func AfiSafiToRouteFamily(afi uint16, safi uint8) RouteFamily { return RouteFamily(int(afi)<<16 | int(safi)) } +func RouteFamilyToAfiSafi(rf RouteFamily) (uint16, uint8) { + return uint16(int(rf) >> 16), uint8(int(rf) & 0xff) +} + type RouteFamily int const ( diff --git a/packet/validate.go b/packet/validate.go index 80d51a9e..b05574b2 100644 --- a/packet/validate.go +++ b/packet/validate.go @@ -7,23 +7,14 @@ import ( "strconv" ) -func isRfSupported(rf RouteFamily, rfs []RouteFamily) bool { - for _, r := range rfs { - if rf == r { - return true - } - } - return false -} - // Validator for BGPUpdate -func ValidateUpdateMsg(m *BGPUpdate, rfs []RouteFamily) (bool, error) { +func ValidateUpdateMsg(m *BGPUpdate, rfs map[RouteFamily]bool) (bool, error) { eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) eSubCodeAttrList := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) eSubCodeMissing := uint8(BGP_ERROR_SUB_MISSING_WELL_KNOWN_ATTRIBUTE) if len(m.NLRI) > 0 || len(m.WithdrawnRoutes) > 0 { - if isRfSupported(RF_IPv4_UC, rfs) == false { + if _, ok := rfs[RF_IPv4_UC]; !ok { return false, NewMessageError(0, 0, nil, fmt.Sprintf("Address-family rf %d not avalible for session", RF_IPv4_UC)) } } @@ -67,7 +58,7 @@ func ValidateUpdateMsg(m *BGPUpdate, rfs []RouteFamily) (bool, error) { return true, nil } -func ValidateAttribute(a PathAttributeInterface, rfs []RouteFamily) (bool, error) { +func ValidateAttribute(a PathAttributeInterface, rfs map[RouteFamily]bool) (bool, error) { eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) eSubCodeBadOrigin := uint8(BGP_ERROR_SUB_INVALID_ORIGIN_ATTRIBUTE) @@ -77,7 +68,7 @@ func ValidateAttribute(a PathAttributeInterface, rfs []RouteFamily) (bool, error checkPrefix := func(l []AddrPrefixInterface) bool { for _, prefix := range l { rf := AfiSafiToRouteFamily(prefix.AFI(), prefix.SAFI()) - if isRfSupported(rf, rfs) == false { + if _, ok := rfs[rf]; !ok { return false } } @@ -87,7 +78,7 @@ func ValidateAttribute(a PathAttributeInterface, rfs []RouteFamily) (bool, error switch p := a.(type) { case *PathAttributeMpUnreachNLRI: rf := AfiSafiToRouteFamily(p.AFI, p.SAFI) - if isRfSupported(rf, rfs) == false { + if _, ok := rfs[rf]; !ok { return false, NewMessageError(0, 0, nil, fmt.Sprintf("Address-family rf %d not avalible for session", rf)) } if checkPrefix(p.Value) == false { @@ -95,7 +86,7 @@ func ValidateAttribute(a PathAttributeInterface, rfs []RouteFamily) (bool, error } case *PathAttributeMpReachNLRI: rf := AfiSafiToRouteFamily(p.AFI, p.SAFI) - if isRfSupported(rf, rfs) == false { + if _, ok := rfs[rf]; !ok { return false, NewMessageError(0, 0, nil, fmt.Sprintf("Address-family rf %d not avalible for session", rf)) } if checkPrefix(p.Value) == false { diff --git a/packet/validate_test.go b/packet/validate_test.go index effd9d89..46ee3798 100644 --- a/packet/validate_test.go +++ b/packet/validate_test.go @@ -41,29 +41,29 @@ func bgpupdateV6() *BGPMessage { func Test_Validate_CapV4(t *testing.T) { assert := assert.New(t) message := bgpupdate().Body.(*BGPUpdate) - res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv6_UC}) + res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv6_UC: true}) assert.Equal(false, res) assert.Error(err) - res, err = ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC}) + res, err = ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}) assert.Equal(true, res) } func Test_Validate_CapV6(t *testing.T) { assert := assert.New(t) message := bgpupdateV6().Body.(*BGPUpdate) - res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv6_UC}) + res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv6_UC: true}) assert.Equal(true, res) assert.NoError(err) - res, err = ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC}) + res, err = ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}) assert.Equal(false, res) } func Test_Validate_OK(t *testing.T) { assert := assert.New(t) message := bgpupdate().Body.(*BGPUpdate) - res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC}) + res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}) assert.Equal(true, res) assert.NoError(err) @@ -151,7 +151,7 @@ func Test_Validate_duplicate_attribute(t *testing.T) { origin.DecodeFromBytes(originBytes) message.PathAttributes = append(message.PathAttributes, origin) - res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC}) + res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}) assert.Equal(false, res) assert.Error(err) e := err.(*MessageError) @@ -164,7 +164,7 @@ func Test_Validate_mandatory_missing(t *testing.T) { assert := assert.New(t) message := bgpupdate().Body.(*BGPUpdate) message.PathAttributes = message.PathAttributes[1:] - res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC}) + res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}) assert.Equal(false, res) assert.Error(err) e := err.(*MessageError) @@ -180,7 +180,7 @@ func Test_Validate_mandatory_missing_nocheck(t *testing.T) { message.PathAttributes = message.PathAttributes[1:] message.NLRI = nil - res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC}) + res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}) assert.Equal(true, res) assert.NoError(err) } @@ -194,7 +194,7 @@ func Test_Validate_invalid_origin(t *testing.T) { origin.DecodeFromBytes(originBytes) message.PathAttributes[0] = origin - res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC}) + res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}) assert.Equal(false, res) assert.Error(err) e := err.(*MessageError) @@ -215,7 +215,7 @@ func Test_Validate_invalid_nexthop_zero(t *testing.T) { nexthop.DecodeFromBytes(nexthopBytes) message.PathAttributes[2] = nexthop - res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC}) + res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}) assert.Equal(false, res) assert.Error(err) e := err.(*MessageError) @@ -236,7 +236,7 @@ func Test_Validate_invalid_nexthop_lo(t *testing.T) { nexthop.DecodeFromBytes(nexthopBytes) message.PathAttributes[2] = nexthop - res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC}) + res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}) assert.Equal(false, res) assert.Error(err) e := err.(*MessageError) @@ -257,7 +257,7 @@ func Test_Validate_invalid_nexthop_de(t *testing.T) { nexthop.DecodeFromBytes(nexthopBytes) message.PathAttributes[2] = nexthop - res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC}) + res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}) assert.Equal(false, res) assert.Error(err) e := err.(*MessageError) @@ -277,7 +277,7 @@ func Test_Validate_unrecognized_well_known(t *testing.T) { unknown.DecodeFromBytes(unknownBytes) message.PathAttributes = append(message.PathAttributes, unknown) - res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC}) + res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}) assert.Equal(false, res) assert.Error(err) e := err.(*MessageError) diff --git a/server/fsm.go b/server/fsm.go index 94bfc85d..f519e984 100644 --- a/server/fsm.go +++ b/server/fsm.go @@ -288,16 +288,15 @@ func (h *FSMHandler) active() bgp.FSMState { } func buildopen(global *config.Global, peerConf *config.Neighbor) *bgp.BGPMessage { - var afi int - if peerConf.NeighborAddress.To4() != nil { - afi = bgp.AFI_IP - } else { - afi = bgp.AFI_IP6 - } p1 := bgp.NewOptionParameterCapability( []bgp.ParameterCapabilityInterface{bgp.NewCapRouteRefresh()}) - p2 := bgp.NewOptionParameterCapability( - []bgp.ParameterCapabilityInterface{bgp.NewCapMultiProtocol(uint16(afi), bgp.SAFI_UNICAST)}) + c := []bgp.ParameterCapabilityInterface{} + for _, rf := range peerConf.AfiSafiList { + k, _ := bgp.GetRouteFamily(rf.AfiSafiName) + afi, safi := bgp.RouteFamilyToAfiSafi(k) + c = append(c, bgp.NewCapMultiProtocol(afi, safi)) + } + p2 := bgp.NewOptionParameterCapability(c) p3 := bgp.NewOptionParameterCapability( []bgp.ParameterCapabilityInterface{bgp.NewCapFourOctetASNumber(global.As)}) holdTime := uint16(peerConf.Timers.HoldTime) diff --git a/server/peer.go b/server/peer.go index d32eacb0..5bf990de 100644 --- a/server/peer.go +++ b/server/peer.go @@ -56,9 +56,8 @@ type Peer struct { adjRib *table.AdjRib // peer and rib are always not one-to-one so should not be // here but it's the simplest and works our first target. - rib *table.TableManager - // for now we support only the same afi as transport - rf bgp.RouteFamily + rib *table.TableManager + rfMap map[bgp.RouteFamily]bool capMap map[bgp.BGPCapabilityCode]bgp.ParameterCapabilityInterface peerInfo *table.PeerInfo siblings map[string]*serverMsgDataPeer @@ -72,6 +71,7 @@ func NewPeer(g config.Global, peer config.Neighbor, serverMsgCh chan *serverMsg, acceptedConnCh: make(chan net.Conn), serverMsgCh: serverMsgCh, peerMsgCh: peerMsgCh, + rfMap: make(map[bgp.RouteFamily]bool), capMap: make(map[bgp.BGPCapabilityCode]bgp.ParameterCapabilityInterface), } p.siblings = make(map[string]*serverMsgDataPeer) @@ -81,10 +81,11 @@ func NewPeer(g config.Global, peer config.Neighbor, serverMsgCh chan *serverMsg, p.fsm = NewFSM(&g, &peer, p.acceptedConnCh) peer.BgpNeighborCommonState.State = uint32(bgp.BGP_FSM_IDLE) peer.BgpNeighborCommonState.Downtime = time.Now().Unix() - if peer.NeighborAddress.To4() != nil { - p.rf = bgp.RF_IPv4_UC - } else { - p.rf = bgp.RF_IPv6_UC + rfList := []bgp.RouteFamily{} + for _, rf := range peer.AfiSafiList { + k, _ := bgp.GetRouteFamily(rf.AfiSafiName) + p.rfMap[k] = true + rfList = append(rfList, k) } p.peerInfo = &table.PeerInfo{ AS: peer.PeerAs, @@ -92,7 +93,7 @@ func NewPeer(g config.Global, peer config.Neighbor, serverMsgCh chan *serverMsg, Address: peer.NeighborAddress, } p.adjRib = table.NewAdjRib() - p.rib = table.NewTableManager(p.peerConfig.NeighborAddress.String(), []bgp.RouteFamily{p.rf}) + p.rib = table.NewTableManager(p.peerConfig.NeighborAddress.String(), rfList) p.t.Go(p.loop) return p } @@ -134,7 +135,7 @@ func (peer *Peer) handleBGPmessage(m *bgp.BGPMessage) { case bgp.BGP_MSG_ROUTE_REFRESH: rr := m.Body.(*bgp.BGPRouteRefresh) rf := bgp.AfiSafiToRouteFamily(rr.AFI, rr.SAFI) - if peer.rf != rf { + if _, ok := peer.rfMap[rf]; !ok { log.WithFields(log.Fields{ "Topic": "Peer", "Key": peer.peerConfig.NeighborAddress, @@ -143,7 +144,7 @@ func (peer *Peer) handleBGPmessage(m *bgp.BGPMessage) { return } if _, ok := peer.capMap[bgp.BGP_CAP_ROUTE_REFRESH]; ok { - pathList := peer.adjRib.GetOutPathList(peer.rf) + pathList := peer.adjRib.GetOutPathList(rf) peer.sendMessages(table.CreateUpdateMsgFromPaths(pathList)) } else { log.WithFields(log.Fields{ @@ -154,7 +155,7 @@ func (peer *Peer) handleBGPmessage(m *bgp.BGPMessage) { case bgp.BGP_MSG_UPDATE: peer.peerConfig.BgpNeighborCommonState.UpdateRecvTime = time.Now().Unix() body := m.Body.(*bgp.BGPUpdate) - _, err := bgp.ValidateUpdateMsg(body, []bgp.RouteFamily{peer.rf}) + _, err := bgp.ValidateUpdateMsg(body, peer.rfMap) if err != nil { log.WithFields(log.Fields{ "Topic": "Peer", @@ -212,17 +213,13 @@ func (peer *Peer) handleREST(restReq *api.RestRequest) { result := &api.RestResponse{} switch restReq.RequestType { case api.REQ_LOCAL_RIB: - var t table.Table - if peer.fsm.adminState == ADMIN_STATE_DOWN { - if peer.rf == bgp.RF_IPv4_UC { - t = table.NewIPv4Table(0) - } else { - t = table.NewIPv6Table(0) + // just empty so we use ipv4 for any route family + j, _ := json.Marshal(table.NewIPv4Table(0)) + if peer.fsm.adminState != ADMIN_STATE_DOWN { + if _, ok := peer.rfMap[restReq.RouteFamily]; ok { + j, _ = json.Marshal(peer.rib.Tables[restReq.RouteFamily]) } - } else { - t = peer.rib.Tables[peer.rf] } - j, _ := json.Marshal(t) result.Data = j case api.REQ_NEIGHBOR_SHUTDOWN: peer.outgoing <- bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN, nil) @@ -231,7 +228,7 @@ func (peer *Peer) handleREST(restReq *api.RestRequest) { peer.outgoing <- bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_RESET, nil) case api.REQ_NEIGHBOR_SOFT_RESET, api.REQ_NEIGHBOR_SOFT_RESET_IN: // soft-reconfiguration inbound - pathList := peer.adjRib.GetInPathList(peer.rf) + pathList := peer.adjRib.GetInPathList(restReq.RouteFamily) pm := &peerMsg{ msgType: PEER_MSG_PATH, msgData: pathList, @@ -244,20 +241,17 @@ func (peer *Peer) handleREST(restReq *api.RestRequest) { } fallthrough case api.REQ_NEIGHBOR_SOFT_RESET_OUT: - pathList := peer.adjRib.GetOutPathList(peer.rf) + pathList := peer.adjRib.GetOutPathList(restReq.RouteFamily) peer.sendMessages(table.CreateUpdateMsgFromPaths(pathList)) case api.REQ_ADJ_RIB_IN, api.REQ_ADJ_RIB_OUT: - rfs := []bgp.RouteFamily{bgp.RF_IPv4_UC, bgp.RF_IPv6_UC} adjrib := make(map[string][]table.Path) - - if restReq.RequestType == api.REQ_ADJ_RIB_IN { - for _, rf := range rfs { + rf := restReq.RouteFamily + if _, ok := peer.rfMap[rf]; ok { + if restReq.RequestType == api.REQ_ADJ_RIB_IN { paths := peer.adjRib.GetInPathList(rf) adjrib[rf.String()] = paths log.Debugf("RouteFamily=%v adj-rib-in found : %d", rf.String(), len(paths)) - } - } else { - for _, rf := range rfs { + } else { paths := peer.adjRib.GetOutPathList(rf) adjrib[rf.String()] = paths log.Debugf("RouteFamily=%v adj-rib-out found : %d", rf.String(), len(paths)) @@ -318,8 +312,10 @@ func (peer *Peer) handlePeerMsg(m *peerMsg) { pList, wList, _ := peer.rib.ProcessPaths(m.msgData.([]table.Path)) peer.sendUpdateMsgFromPaths(pList, wList) case PEER_MSG_PEER_DOWN: - pList, wList, _ := peer.rib.DeletePathsforPeer(m.msgData.(*table.PeerInfo), peer.rf) - peer.sendUpdateMsgFromPaths(pList, wList) + for rf, _ := range peer.rfMap { + pList, wList, _ := peer.rib.DeletePathsforPeer(m.msgData.(*table.PeerInfo), rf) + peer.sendUpdateMsgFromPaths(pList, wList) + } } } @@ -328,24 +324,27 @@ func (peer *Peer) handleServerMsg(m *serverMsg) { case SRV_MSG_PEER_ADDED: d := m.msgData.(*serverMsgDataPeer) peer.siblings[d.address.String()] = d - pathList := peer.adjRib.GetInPathList(peer.rf) - if len(pathList) == 0 { - return - } - pm := &peerMsg{ - msgType: PEER_MSG_PATH, - msgData: pathList, - } - for _, s := range peer.siblings { - s.peerMsgCh <- pm + for rf, _ := range peer.rfMap { + pathList := peer.adjRib.GetInPathList(rf) + if len(pathList) == 0 { + continue + } + pm := &peerMsg{ + msgType: PEER_MSG_PATH, + msgData: pathList, + } + for _, s := range peer.siblings { + s.peerMsgCh <- pm + } } case SRV_MSG_PEER_DELETED: d := m.msgData.(*table.PeerInfo) - _, found := peer.siblings[d.Address.String()] - if found { + if _, ok := peer.siblings[d.Address.String()]; ok { delete(peer.siblings, d.Address.String()) - pList, wList, _ := peer.rib.DeletePathsforPeer(d, peer.rf) - peer.sendUpdateMsgFromPaths(pList, wList) + for rf, _ := range peer.rfMap { + pList, wList, _ := peer.rib.DeletePathsforPeer(d, rf) + peer.sendUpdateMsgFromPaths(pList, wList) + } } else { log.Warning("can not find peer: ", d.Address.String()) } @@ -364,8 +363,10 @@ func (peer *Peer) loop() error { h := NewFSMHandler(peer.fsm, incoming, peer.outgoing) if peer.peerConfig.BgpNeighborCommonState.State == uint32(bgp.BGP_FSM_ESTABLISHED) { - pathList := peer.adjRib.GetOutPathList(peer.rf) - peer.sendMessages(table.CreateUpdateMsgFromPaths(pathList)) + for rf, _ := range peer.rfMap { + pathList := peer.adjRib.GetOutPathList(rf) + peer.sendMessages(table.CreateUpdateMsgFromPaths(pathList)) + } peer.fsm.peerConfig.BgpNeighborCommonState.Uptime = time.Now().Unix() peer.fsm.peerConfig.BgpNeighborCommonState.EstablishedCount++ } else { @@ -398,7 +399,10 @@ func (peer *Peer) loop() error { if t.Sub(time.Unix(peer.fsm.peerConfig.BgpNeighborCommonState.Uptime, 0)) < FLOP_THRESHOLD { peer.fsm.peerConfig.BgpNeighborCommonState.Flops++ } - peer.adjRib.DropAllIn(peer.rf) + + for rf, _ := range peer.rfMap { + peer.adjRib.DropAllIn(rf) + } pm := &peerMsg{ msgType: PEER_MSG_PEER_DOWN, msgData: peer.peerInfo, @@ -484,8 +488,14 @@ func (peer *Peer) MarshalJSON() ([]byte, error) { } advertized := uint32(0) + received := uint32(0) + accepted := uint32(0) if f.state == bgp.BGP_FSM_ESTABLISHED { - advertized = uint32(peer.adjRib.GetOutCount(peer.rf)) + for rf, _ := range peer.rfMap { + advertized += uint32(peer.adjRib.GetOutCount(rf)) + received += uint32(peer.adjRib.GetInCount(rf)) + accepted += uint32(peer.adjRib.GetInCount(rf)) + } } p["info"] = struct { @@ -535,8 +545,8 @@ func (peer *Peer) MarshalJSON() ([]byte, error) { DiscardedIn: s.DiscardedIn, Uptime: uptime, Downtime: downtime, - Received: uint32(peer.adjRib.GetInCount(peer.rf)), - Accepted: uint32(peer.adjRib.GetInCount(peer.rf)), + Received: received, + Accepted: accepted, Advertized: advertized, OutQ: len(peer.outgoing), Flops: s.Flops, diff --git a/server/peer_test.go b/server/peer_test.go index a637a18d..a4c60de7 100644 --- a/server/peer_test.go +++ b/server/peer_test.go @@ -505,6 +505,7 @@ func makePeer(globalConfig config.Global, peerConfig config.Neighbor) *Peer { acceptedConnCh: make(chan net.Conn), serverMsgCh: sch, peerMsgCh: pch, + rfMap: make(map[bgp.RouteFamily]bool), capMap: make(map[bgp.BGPCapabilityCode]bgp.ParameterCapabilityInterface), } p.siblings = make(map[string]*serverMsgDataPeer) @@ -513,9 +514,9 @@ func makePeer(globalConfig config.Global, peerConfig config.Neighbor) *Peer { peerConfig.BgpNeighborCommonState.State = uint32(bgp.BGP_FSM_IDLE) peerConfig.BgpNeighborCommonState.Downtime = time.Now().Unix() if peerConfig.NeighborAddress.To4() != nil { - p.rf = bgp.RF_IPv4_UC + p.rfMap[bgp.RF_IPv4_UC] = true } else { - p.rf = bgp.RF_IPv6_UC + p.rfMap[bgp.RF_IPv6_UC] = true } p.peerInfo = &table.PeerInfo{ diff --git a/table/table_manager.go b/table/table_manager.go index 59b0a275..e135f58e 100644 --- a/table/table_manager.go +++ b/table/table_manager.go @@ -241,8 +241,11 @@ func (manager *TableManager) calculate(destinationList []Destination) ([]Path, [ } func (manager *TableManager) DeletePathsforPeer(peerInfo *PeerInfo, rf bgp.RouteFamily) ([]Path, []Path, error) { - destinationList := manager.Tables[rf].DeleteDestByPeer(peerInfo) - return manager.calculate(destinationList) + if _, ok := manager.Tables[rf]; ok { + destinationList := manager.Tables[rf].DeleteDestByPeer(peerInfo) + return manager.calculate(destinationList) + } + return []Path{}, []Path{}, nil } func (manager *TableManager) ProcessPaths(pathList []Path) ([]Path, []Path, error) { @@ -339,24 +342,38 @@ func (adj *AdjRib) getPathList(rib map[string]*ReceivedRoute) []Path { } func (adj *AdjRib) GetInPathList(rf bgp.RouteFamily) []Path { + if _, ok := adj.adjRibIn[rf]; !ok { + return []Path{} + } return adj.getPathList(adj.adjRibIn[rf]) } func (adj *AdjRib) GetOutPathList(rf bgp.RouteFamily) []Path { + if _, ok := adj.adjRibOut[rf]; !ok { + return []Path{} + } return adj.getPathList(adj.adjRibOut[rf]) } func (adj *AdjRib) GetInCount(rf bgp.RouteFamily) int { + if _, ok := adj.adjRibIn[rf]; !ok { + return 0 + } return len(adj.adjRibIn[rf]) } func (adj *AdjRib) GetOutCount(rf bgp.RouteFamily) int { + if _, ok := adj.adjRibOut[rf]; !ok { + return 0 + } return len(adj.adjRibOut[rf]) } func (adj *AdjRib) DropAllIn(rf bgp.RouteFamily) { - // replace old one - adj.adjRibIn[rf] = make(map[string]*ReceivedRoute) + if _, ok := adj.adjRibIn[rf]; ok { + // replace old one + adj.adjRibIn[rf] = make(map[string]*ReceivedRoute) + } } type ReceivedRoute struct { |