summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/peer.go23
-rw-r--r--server/server.go1
-rw-r--r--table/destination.go5
-rw-r--r--table/path.go9
-rw-r--r--table/table.go18
-rw-r--r--table/table_manager.go26
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) {