diff options
author | Satoshi Fujimoto <satoshi.fujimoto7@gmail.com> | 2017-06-15 08:56:11 +0900 |
---|---|---|
committer | Satoshi Fujimoto <satoshi.fujimoto7@gmail.com> | 2017-06-16 15:53:18 +0900 |
commit | d75edf18d7febd3f687393e8b0707e57438931eb (patch) | |
tree | 387a5f11b64b11cddf2c988eeff85a7ce6eb269c /server/peer.go | |
parent | 369626d2221bb175fbf81bd59738104f77aca835 (diff) |
server: Support Dynamic Neighbor
Signed-off-by: Satoshi Fujimoto <satoshi.fujimoto7@gmail.com>
Diffstat (limited to 'server/peer.go')
-rw-r--r-- | server/peer.go | 76 |
1 files changed, 72 insertions, 4 deletions
diff --git a/server/peer.go b/server/peer.go index 4e5b7435..a1ec2404 100644 --- a/server/peer.go +++ b/server/peer.go @@ -32,14 +32,16 @@ const ( ) type PeerGroup struct { - Conf *config.PeerGroup - members map[string]config.Neighbor + Conf *config.PeerGroup + members map[string]config.Neighbor + dynamicNeighbors map[string]*config.DynamicNeighbor } func NewPeerGroup(c *config.PeerGroup) *PeerGroup { return &PeerGroup{ - Conf: c, - members: make(map[string]config.Neighbor, 0), + Conf: c, + members: make(map[string]config.Neighbor, 0), + dynamicNeighbors: make(map[string]*config.DynamicNeighbor, 0), } } @@ -51,6 +53,29 @@ func (pg *PeerGroup) DeleteMember(c config.Neighbor) { delete(pg.members, c.State.NeighborAddress) } +func (pg *PeerGroup) AddDynamicNeighbor(c *config.DynamicNeighbor) { + pg.dynamicNeighbors[c.Config.Prefix] = c +} + +func newDynamicPeer(g *config.Global, neighborAddress string, pg *config.PeerGroup, loc *table.TableManager, policy *table.RoutingPolicy) *Peer { + conf := config.Neighbor{ + Config: config.NeighborConfig{ + PeerGroup: pg.Config.PeerGroupName, + }, + Transport: config.Transport{ + Config: config.TransportConfig{ + PassiveMode: true, + }, + }, + } + config.OverwriteNeighborConfigWithPeerGroup(&conf, pg) + config.SetDefaultNeighborConfigValues(&conf, g.Config.As) + conf.State.NeighborAddress = neighborAddress + peer := NewPeer(g, &conf, loc, policy) + peer.fsm.state = bgp.BGP_FSM_ACTIVE + return peer +} + type Peer struct { tableId string fsm *FSM @@ -104,6 +129,10 @@ func (peer *Peer) isGracefulRestartEnabled() bool { return peer.fsm.pConf.GracefulRestart.State.Enabled } +func (peer *Peer) isDynamicNeighbor() bool { + return peer.fsm.pConf.Config.NeighborAddress == "" && peer.fsm.pConf.Config.NeighborInterface == "" +} + func (peer *Peer) recvedAllEOR() bool { for _, a := range peer.fsm.pConf.AfiSafis { if s := a.MpGracefulRestart.State; s.Enabled && !s.EndOfRibReceived { @@ -585,3 +614,42 @@ func (peer *Peer) ToConfig(getAdvertised bool) *config.Neighbor { func (peer *Peer) DropAll(rfList []bgp.RouteFamily) { peer.adjRibIn.Drop(rfList) } + +func (peer *Peer) stopFSM() error { + failed := false + addr := peer.fsm.pConf.State.NeighborAddress + t1 := time.AfterFunc(time.Minute*5, func() { + log.WithFields(log.Fields{ + "Topic": "Peer", + }).Warnf("Failed to free the fsm.h.t for %s", addr) + failed = true + }) + peer.fsm.h.t.Kill(nil) + peer.fsm.h.t.Wait() + t1.Stop() + if !failed { + log.WithFields(log.Fields{ + "Topic": "Peer", + "Key": addr, + }).Debug("freed fsm.h.t") + cleanInfiniteChannel(peer.outgoing) + } + failed = false + t2 := time.AfterFunc(time.Minute*5, func() { + log.WithFields(log.Fields{ + "Topic": "Peer", + }).Warnf("Failed to free the fsm.t for %s", addr) + failed = true + }) + peer.fsm.t.Kill(nil) + peer.fsm.t.Wait() + t2.Stop() + if !failed { + log.WithFields(log.Fields{ + "Topic": "Peer", + "Key": addr, + }).Debug("freed fsm.t") + return nil + } + return fmt.Errorf("Failed to free FSM for %s", addr) +} |