diff options
-rw-r--r-- | server/peer.go | 23 | ||||
-rw-r--r-- | server/server.go | 1 | ||||
-rw-r--r-- | table/destination.go | 5 | ||||
-rw-r--r-- | table/path.go | 9 | ||||
-rw-r--r-- | table/table.go | 18 | ||||
-rw-r--r-- | table/table_manager.go | 26 |
6 files changed, 66 insertions, 16 deletions
diff --git a/server/peer.go b/server/peer.go index faea1a02..3c852ccf 100644 --- a/server/peer.go +++ b/server/peer.go @@ -29,6 +29,7 @@ type Peer struct { t tomb.Tomb globalConfig config.GlobalType peerConfig config.NeighborType + state int acceptedConnCh chan *net.TCPConn incoming chan *bgp.BGPMessage outgoing chan *bgp.BGPMessage @@ -45,6 +46,7 @@ func NewPeer(g config.GlobalType, peer config.NeighborType, outEventCh chan *mes p := &Peer{ globalConfig: g, peerConfig: peer, + state: bgp.BGP_FSM_IDLE, acceptedConnCh: make(chan *net.TCPConn), incoming: make(chan *bgp.BGPMessage, 4096), outgoing: make(chan *bgp.BGPMessage, 4096), @@ -102,20 +104,26 @@ func (peer *Peer) path2update(pathList []table.Path) []*bgp.BGPMessage { } func (peer *Peer) handlePeermessage(m *message) { - switch m.event { - case PEER_MSG_PATH: - pList, wList, _ := peer.rib.ProcessPaths(m.data.([]table.Path)) + + sendpath := func(pList []table.Path, wList []table.Destination) { pathList := append([]table.Path(nil), pList...) for _, dest := range wList { p := dest.GetOldBestPath() pathList = append(pathList, p.Clone(true)) } - peer.adjRib.UpdateOut(pathList) - peer.sendMessages(peer.path2update(pathList)) } + + switch m.event { + case PEER_MSG_PATH: + pList, wList, _ := peer.rib.ProcessPaths(m.data.([]table.Path)) + sendpath(pList, wList) + case PEER_MSG_DOWN: + pList, wList, _ := peer.rib.DeletePathsforPeer(m.data.(*table.PeerInfo)) + sendpath(pList, wList) + } } // this goroutine handles routing table operations @@ -128,6 +136,8 @@ func (peer *Peer) loop() error { case nextState := <-peer.fsm.StateChanged(): // waits for all goroutines created for the current state h.Wait() + oldState := peer.fsm.state + peer.fsm.state = nextState peer.fsm.StateChange(nextState) sameState = false // TODO: check peer's rf @@ -135,6 +145,9 @@ func (peer *Peer) loop() error { pathList := peer.adjRib.GetOutPathList(table.RF_IPv4_UC) peer.sendMessages(peer.path2update(pathList)) } + if oldState == bgp.BGP_FSM_ESTABLISHED { + peer.sendToHub("", PEER_MSG_DOWN, peer.fsm.peerInfo) + } case <-peer.t.Dying(): close(peer.acceptedConnCh) h.Stop() diff --git a/server/server.go b/server/server.go index a1c0ccad..54644560 100644 --- a/server/server.go +++ b/server/server.go @@ -28,6 +28,7 @@ const ( _ = iota PEER_MSG_NEW PEER_MSG_PATH + PEER_MSG_DOWN ) type message struct { diff --git a/table/destination.go b/table/destination.go index 9461713b..7be547c4 100644 --- a/table/destination.go +++ b/table/destination.go @@ -58,6 +58,7 @@ type Destination interface { GetOldBestPath() Path setOldBestPath(path Path) getKnownPathList() []Path + setKnownPathList([]Path) String() string addWithdraw(withdraw Path) addNewPath(newPath Path) @@ -133,6 +134,10 @@ func (dd *DestinationDefault) getKnownPathList() []Path { return dd.knownPathList } +func (dd *DestinationDefault) setKnownPathList(List []Path) { + dd.knownPathList = List +} + func (dd *DestinationDefault) addWithdraw(withdraw Path) { dd.validatePath(withdraw) dd.withdrawList = append(dd.withdrawList, withdraw) diff --git a/table/path.go b/table/path.go index 269f6129..b9362bd9 100644 --- a/table/path.go +++ b/table/path.go @@ -76,7 +76,12 @@ func NewPathDefault(rf RouteFamily, source *PeerInfo, nlri bgp.AddrPrefixInterfa // create new PathAttributes func (pd *PathDefault) Clone(isWithdraw bool) Path { copiedAttrs := []bgp.PathAttributeInterface(nil) - if !isWithdraw { + nlri := pd.nlri + if isWithdraw { + if !pd.IsWithdraw() { + nlri = &bgp.WithdrawnRoute{pd.nlri.(*bgp.NLRInfo).IPAddrPrefix} + } + } else { copiedAttrs = append(copiedAttrs, pd.pathAttrs...) for i, attr := range copiedAttrs { t, v := reflect.TypeOf(attr), reflect.ValueOf(attr) @@ -85,7 +90,7 @@ func (pd *PathDefault) Clone(isWithdraw bool) Path { copiedAttrs[i] = newAttrObjp.Interface().(bgp.PathAttributeInterface) } } - return CreatePath(pd.source, pd.nlri, copiedAttrs, isWithdraw) + return CreatePath(pd.source, nlri, copiedAttrs, isWithdraw) } func (pd *PathDefault) getRouteFamily() RouteFamily { diff --git a/table/table.go b/table/table.go index f60c2dfb..6f2f23eb 100644 --- a/table/table.go +++ b/table/table.go @@ -30,6 +30,7 @@ type Table interface { tableKey(nlri bgp.AddrPrefixInterface) net.IP validatePath(path Path) validateNlri(nlri bgp.AddrPrefixInterface) + DeleteDestByPeer(*PeerInfo) []Destination } type TableDefault struct { @@ -92,6 +93,23 @@ func (td *TableDefault) cleanUninterestingPaths(interested_rts) int { } */ +func (td *TableDefault) DeleteDestByPeer(peerInfo *PeerInfo) []Destination { + changedDests := make([]Destination, 0) + for _, dest := range td.destinations { + newKnownPathList := make([]Path, 0) + for _, p := range dest.getKnownPathList() { + if peerInfo != p.getSource() || peerInfo.VersionNum != p.getSourceVerNum() { + newKnownPathList = append(newKnownPathList, p) + } + } + if len(newKnownPathList) != len(dest.getKnownPathList()) { + changedDests = append(changedDests, dest) + dest.setKnownPathList(newKnownPathList) + } + } + return changedDests +} + func deleteDestByNlri(table Table, nlri bgp.AddrPrefixInterface) Destination { table.validateNlri(nlri) destinations := table.getDestinations() diff --git a/table/table_manager.go b/table/table_manager.go index 9dfae5bf..4a71bf6f 100644 --- a/table/table_manager.go +++ b/table/table_manager.go @@ -234,18 +234,10 @@ func setLogger(loggerInstance *log.Logger) { logger = loggerInstance } -func (manager *TableManager) ProcessPaths(pathList []Path) ([]Path, []Destination, error) { +func (manager *TableManager) calculate(destinationList []Destination) ([]Path, []Destination, error) { bestPaths := make([]Path, 0) lostDest := make([]Destination, 0) - destinationList := make([]Destination, 0) - for _, path := range pathList { - rf := path.getRouteFamily() - // push Path into table - destination := insert(manager.Tables[rf], path) - destinationList = append(destinationList, destination) - } - for _, destination := range destinationList { // compute best path logger.Infof("Processing destination: %v", destination.String()) @@ -299,6 +291,22 @@ func (manager *TableManager) ProcessPaths(pathList []Path) ([]Path, []Destinatio return bestPaths, lostDest, nil } +func (manager *TableManager) DeletePathsforPeer(peerInfo *PeerInfo) ([]Path, []Destination, error) { + destinationList := manager.Tables[RF_IPv4_UC].DeleteDestByPeer(peerInfo) + return manager.calculate(destinationList) +} + +func (manager *TableManager) ProcessPaths(pathList []Path) ([]Path, []Destination, error) { + destinationList := make([]Destination, 0) + for _, path := range pathList { + rf := path.getRouteFamily() + // push Path into table + destination := insert(manager.Tables[rf], path) + destinationList = append(destinationList, destination) + } + return manager.calculate(destinationList) +} + // process BGPUpdate message // this function processes only BGPUpdate func (manager *TableManager) ProcessUpdate(fromPeer *PeerInfo, message *bgp.BGPMessage) ([]Path, []Destination, error) { |