diff options
-rw-r--r-- | config/default.go | 91 | ||||
-rw-r--r-- | config/serve.go | 40 | ||||
-rw-r--r-- | docs/sources/configuration.md | 10 | ||||
-rw-r--r-- | gobgpd/main.go | 28 | ||||
-rw-r--r-- | server/peer.go | 20 | ||||
-rw-r--r-- | server/server.go | 268 | ||||
-rw-r--r-- | server/server_test.go | 81 |
7 files changed, 452 insertions, 86 deletions
diff --git a/config/default.go b/config/default.go index 224a6218..3b0db592 100644 --- a/config/default.go +++ b/config/default.go @@ -7,6 +7,7 @@ import ( "github.com/osrg/gobgp/packet/rtr" "github.com/spf13/viper" "net" + "reflect" ) const ( @@ -15,6 +16,20 @@ const ( DEFAULT_CONNECT_RETRY = 120 ) +var forcedOverwrittenConfig = []string{ + "neighbor.config.peer-as", + "neighbor.timers.config.minimum-advertisement-interval", +} + +var configuredFields map[string]interface{} + +func RegisterConfiguredFields(addr string, n interface{}) { + if configuredFields == nil { + configuredFields = make(map[string]interface{}, 0) + } + configuredFields[addr] = n +} + func defaultAfiSafi(typ AfiSafiType, enable bool) AfiSafi { return AfiSafi{ Config: AfiSafiConfig{ @@ -255,6 +270,22 @@ func setDefaultPolicyConfigValuesWithViper(v *viper.Viper, p *PolicyDefinition) return nil } +func validatePeerGroupConfig(n *Neighbor, b *BgpConfigSet) error { + name := n.Config.PeerGroup + if name == "" { + return nil + } + for _, pg := range b.PeerGroups { + if name == pg.Config.PeerGroupName { + if pg.Config.PeerAs != 0 && n.Config.PeerAs != 0 { + return fmt.Errorf("Cannot configure remote-as for members. Peer-group AS %d.", pg.Config.PeerAs) + } + return nil + } + } + return fmt.Errorf("No such peer-group: %s", name) +} + func setDefaultConfigValuesWithViper(v *viper.Viper, b *BgpConfigSet) error { if v == nil { v = viper.New() @@ -294,6 +325,10 @@ func setDefaultConfigValuesWithViper(v *viper.Viper, b *BgpConfigSet) error { } for idx, n := range b.Neighbors { + if err := validatePeerGroupConfig(&n, b); err != nil { + return err + } + vv := viper.New() if len(list) > idx { vv.Set("neighbor", list[idx]) @@ -302,6 +337,10 @@ func setDefaultConfigValuesWithViper(v *viper.Viper, b *BgpConfigSet) error { return err } b.Neighbors[idx] = n + + if n.Config.PeerGroup != "" { + RegisterConfiguredFields(vv.Get("neighbor.config.neighbor-address").(string), list[idx]) + } } for idx, r := range b.RpkiServers { @@ -328,3 +367,55 @@ func setDefaultConfigValuesWithViper(v *viper.Viper, b *BgpConfigSet) error { return nil } + +func OverwriteNeighborConfigWithPeerGroup(c *Neighbor, pg *PeerGroup) error { + v := viper.New() + + val, ok := configuredFields[c.Config.NeighborAddress] + if !ok { + return fmt.Errorf("No such neighbor %s", c.Config.NeighborAddress) + } + v.Set("neighbor", val) + + overwriteConfig(&c.Config, &pg.Config, "neighbor.config", v) + overwriteConfig(&c.Timers.Config, &pg.Timers.Config, "neighbor.timers.config", v) + overwriteConfig(&c.Transport.Config, &pg.Transport.Config, "neighbor.transport.config", v) + overwriteConfig(&c.ErrorHandling.Config, &pg.ErrorHandling.Config, "neighbor.error-handling.config", v) + overwriteConfig(&c.LoggingOptions.Config, &pg.LoggingOptions.Config, "neighbor.logging-options.config", v) + overwriteConfig(&c.EbgpMultihop.Config, &pg.EbgpMultihop.Config, "neighbor.ebgp-multihop.config", v) + overwriteConfig(&c.RouteReflector.Config, &pg.RouteReflector.Config, "neighbor.route-reflector.config", v) + overwriteConfig(&c.AsPathOptions.Config, &pg.AsPathOptions.Config, "neighbor.as-path-options.config", v) + overwriteConfig(&c.AddPaths.Config, &pg.AddPaths.Config, "neighbor.add-paths.config", v) + overwriteConfig(&c.GracefulRestart.Config, &pg.GracefulRestart.Config, "neighbor.gradeful-restart.config", v) + overwriteConfig(&c.ApplyPolicy.Config, &pg.ApplyPolicy.Config, "neighbor.apply-policy.config", v) + overwriteConfig(&c.UseMultiplePaths.Config, &pg.UseMultiplePaths.Config, "neighbor.use-multiple-paths.config", v) + overwriteConfig(&c.RouteServer.Config, &pg.RouteServer.Config, "neighbor.route-server.config", v) + + if !v.IsSet("neighbor.afi-safis") { + c.AfiSafis = pg.AfiSafis + } + + return nil +} + +func overwriteConfig(c, pg interface{}, tagPrefix string, v *viper.Viper) { + nValue := reflect.Indirect(reflect.ValueOf(c)) + nType := reflect.Indirect(nValue).Type() + pgValue := reflect.Indirect(reflect.ValueOf(pg)) + pgType := reflect.Indirect(pgValue).Type() + + for i := 0; i < pgType.NumField(); i++ { + field := pgType.Field(i).Name + tag := tagPrefix + "." + nType.Field(i).Tag.Get("mapstructure") + if func() bool { + for _, t := range forcedOverwrittenConfig { + if t == tag { + return true + } + } + return false + }() || !v.IsSet(tag) { + nValue.FieldByName(field).Set(pgValue.FieldByName(field)) + } + } +} diff --git a/config/serve.go b/config/serve.go index eeb7cb4d..ac893ea7 100644 --- a/config/serve.go +++ b/config/serve.go @@ -83,6 +83,15 @@ func inSlice(n Neighbor, b []Neighbor) int { return -1 } +func existPeerGroup(n string, b []PeerGroup) int { + for i, nb := range b { + if nb.Config.PeerGroupName == n { + return i + } + } + return -1 +} + func ConfigSetToRoutingPolicy(c *BgpConfigSet) *RoutingPolicy { return &RoutingPolicy{ DefinedSets: c.DefinedSets, @@ -90,8 +99,34 @@ func ConfigSetToRoutingPolicy(c *BgpConfigSet) *RoutingPolicy { } } -func UpdateConfig(curC, newC *BgpConfigSet) ([]Neighbor, []Neighbor, []Neighbor, bool) { +func UpdatePeerGroupConfig(curC, newC *BgpConfigSet) ([]PeerGroup, []PeerGroup, []PeerGroup) { + addedPg := []PeerGroup{} + deletedPg := []PeerGroup{} + updatedPg := []PeerGroup{} + for _, n := range newC.PeerGroups { + if idx := existPeerGroup(n.Config.PeerGroupName, curC.PeerGroups); idx < 0 { + addedPg = append(addedPg, n) + } else if !n.Equal(&curC.PeerGroups[idx]) { + log.WithFields(log.Fields{ + "Topic": "Config", + }).Debugf("Current peer-group config:%s", curC.PeerGroups[idx]) + log.WithFields(log.Fields{ + "Topic": "Config", + }).Debugf("New peer-group config:%s", n) + updatedPg = append(updatedPg, n) + } + } + + for _, n := range curC.PeerGroups { + if existPeerGroup(n.Config.PeerGroupName, newC.PeerGroups) < 0 { + deletedPg = append(deletedPg, n) + } + } + return addedPg, deletedPg, updatedPg +} + +func UpdateNeighborConfig(curC, newC *BgpConfigSet) ([]Neighbor, []Neighbor, []Neighbor) { added := []Neighbor{} deleted := []Neighbor{} updated := []Neighbor{} @@ -115,8 +150,7 @@ func UpdateConfig(curC, newC *BgpConfigSet) ([]Neighbor, []Neighbor, []Neighbor, deleted = append(deleted, n) } } - - return added, deleted, updated, CheckPolicyDifference(ConfigSetToRoutingPolicy(curC), ConfigSetToRoutingPolicy(newC)) + return added, deleted, updated } func CheckPolicyDifference(currentPolicy *RoutingPolicy, newPolicy *RoutingPolicy) bool { diff --git a/docs/sources/configuration.md b/docs/sources/configuration.md index 7403834c..67c7c167 100644 --- a/docs/sources/configuration.md +++ b/docs/sources/configuration.md @@ -52,6 +52,8 @@ # override global.config.as value local-as = 1000 remove-private-as = "all" + # To enable peer group setting, uncomment the following + #peer-group = "my-peer-group" [neighbors.as-path-options.config] allow-own-as = 1 replace-peer-as = true @@ -130,6 +132,14 @@ [neighbors.route-server.config] route-server-client = true +[[peer-groups]] + [peer-groups.config] + peer-group-name = "my-peer-group" + peer-as = 65000 + [[peer-groups.afi-safis]] + [peer-groups.afi-safis.config] + afi-safi-name = "ipv4-unicast" + [[defined-sets.prefix-sets]] prefix-set-name = "ps0" [[defined-sets.prefix-sets.prefix-list]] diff --git a/gobgpd/main.go b/gobgpd/main.go index 91e98f6c..c80faa84 100644 --- a/gobgpd/main.go +++ b/gobgpd/main.go @@ -149,6 +149,7 @@ func main() { select { case newConfig := <-configCh: var added, deleted, updated []config.Neighbor + var addedPg, deletedPg, updatedPg []config.PeerGroup var updatePolicy bool if c == nil { @@ -190,6 +191,7 @@ func main() { } added = newConfig.Neighbors + addedPg = newConfig.PeerGroups if opts.GracefulRestart { for i, n := range added { if n.GracefulRestart.Config.Enabled { @@ -199,7 +201,10 @@ func main() { } } else { - added, deleted, updated, updatePolicy = config.UpdateConfig(c, newConfig) + addedPg, deletedPg, updatedPg = config.UpdatePeerGroupConfig(c, newConfig) + added, deleted, updated = config.UpdateNeighborConfig(c, newConfig) + updatePolicy = config.CheckPolicyDifference(config.ConfigSetToRoutingPolicy(c), config.ConfigSetToRoutingPolicy(newConfig)) + if updatePolicy { log.Info("Policy config is updated") p := config.ConfigSetToRoutingPolicy(newConfig) @@ -241,7 +246,26 @@ func main() { } c = newConfig } - + for i, pg := range addedPg { + log.Infof("PeerGroup %s is added", pg.Config.PeerGroupName) + if err := bgpServer.AddPeerGroup(&addedPg[i]); err != nil { + log.Warn(err) + } + } + for i, pg := range deletedPg { + log.Infof("PeerGroup %s is deleted", pg.Config.PeerGroupName) + if err := bgpServer.DeletePeerGroup(&deletedPg[i]); err != nil { + log.Warn(err) + } + } + for i, pg := range updatedPg { + log.Infof("PeerGroup %s is updated", pg.Config.PeerGroupName) + u, err := bgpServer.UpdatePeerGroup(&updatedPg[i]) + if err != nil { + log.Warn(err) + } + updatePolicy = updatePolicy || u + } for i, p := range added { log.Infof("Peer %v is added", p.Config.NeighborAddress) if err := bgpServer.AddNeighbor(&added[i]); err != nil { diff --git a/server/peer.go b/server/peer.go index 6ead5fbe..a629a16d 100644 --- a/server/peer.go +++ b/server/peer.go @@ -31,6 +31,26 @@ const ( MIN_CONNECT_RETRY = 10 ) +type PeerGroup struct { + Conf *config.PeerGroup + members map[string]config.Neighbor +} + +func NewPeerGroup(c *config.PeerGroup) *PeerGroup { + return &PeerGroup{ + Conf: c, + members: make(map[string]config.Neighbor, 0), + } +} + +func (pg *PeerGroup) AddMember(c config.Neighbor) { + pg.members[c.Config.NeighborAddress] = c +} + +func (pg *PeerGroup) DeleteMember(c config.Neighbor) { + delete(pg.members, c.Config.NeighborAddress) +} + type Peer struct { tableId string fsm *FSM diff --git a/server/server.go b/server/server.go index 79316daa..48af87da 100644 --- a/server/server.go +++ b/server/server.go @@ -92,27 +92,29 @@ type BgpServer struct { fsmStateCh chan *FsmMsg acceptCh chan *net.TCPConn - mgmtCh chan *mgmtOp - policy *table.RoutingPolicy - listeners []*TCPListener - neighborMap map[string]*Peer - globalRib *table.TableManager - roaManager *roaManager - shutdown bool - watcherMap map[WatchEventType][]*Watcher - zclient *zebraClient - bmpManager *bmpClientManager - mrtManager *mrtManager + mgmtCh chan *mgmtOp + policy *table.RoutingPolicy + listeners []*TCPListener + neighborMap map[string]*Peer + peerGroupMap map[string]*PeerGroup + globalRib *table.TableManager + roaManager *roaManager + shutdown bool + watcherMap map[WatchEventType][]*Watcher + zclient *zebraClient + bmpManager *bmpClientManager + mrtManager *mrtManager } func NewBgpServer() *BgpServer { roaManager, _ := NewROAManager(0) s := &BgpServer{ - neighborMap: make(map[string]*Peer), - policy: table.NewRoutingPolicy(), - roaManager: roaManager, - mgmtCh: make(chan *mgmtOp, 1), - watcherMap: make(map[WatchEventType][]*Watcher), + neighborMap: make(map[string]*Peer), + peerGroupMap: make(map[string]*PeerGroup), + policy: table.NewRoutingPolicy(), + roaManager: roaManager, + mgmtCh: make(chan *mgmtOp, 1), + watcherMap: make(map[WatchEventType][]*Watcher), } s.bmpManager = newBmpClientManager(s) s.mrtManager = newMrtManager(s) @@ -1603,17 +1605,38 @@ func (s *BgpServer) GetNeighbor(address string, getAdvertised bool) (l []*config return l } -func (server *BgpServer) addNeighbor(c *config.Neighbor) error { - - if err := config.SetDefaultNeighborConfigValues(c, server.bgpConfig.Global.Config.As); err != nil { - return err +func (server *BgpServer) addPeerGroup(c *config.PeerGroup) error { + name := c.Config.PeerGroupName + if _, y := server.peerGroupMap[name]; y { + return fmt.Errorf("Can't overwrite the existing peer-group: %s", name) } + log.WithFields(log.Fields{ + "Topic": "Peer", + "Name": name, + }).Info("Add a peer group configuration") + + server.peerGroupMap[c.Config.PeerGroupName] = NewPeerGroup(c) + + return nil +} + +func (server *BgpServer) addNeighbor(c *config.Neighbor) error { addr := c.Config.NeighborAddress if _, y := server.neighborMap[addr]; y { return fmt.Errorf("Can't overwrite the existing peer: %s", addr) } + if c.Config.PeerGroup != "" { + if err := config.OverwriteNeighborConfigWithPeerGroup(c, server.peerGroupMap[c.Config.PeerGroup].Conf); err != nil { + return err + } + } + + if err := config.SetDefaultNeighborConfigValues(c, server.bgpConfig.Global.Config.As); err != nil { + return err + } + if vrf := c.Config.Vrf; vrf != "" { if c.RouteServer.Config.RouteServerClient { return fmt.Errorf("route server client can't be enslaved to VRF") @@ -1668,18 +1691,50 @@ func (server *BgpServer) addNeighbor(c *config.Neighbor) error { } } server.neighborMap[addr] = peer + if name := c.Config.PeerGroup; name != "" { + server.peerGroupMap[name].AddMember(*c) + } peer.startFSMHandler(server.fsmincomingCh, server.fsmStateCh) server.broadcastPeerState(peer, bgp.BGP_FSM_IDLE) return nil } +func (s *BgpServer) AddPeerGroup(c *config.PeerGroup) error { + return s.mgmtOperation(func() error { + return s.addPeerGroup(c) + }, true) +} + func (s *BgpServer) AddNeighbor(c *config.Neighbor) error { return s.mgmtOperation(func() error { return s.addNeighbor(c) }, true) } +func (server *BgpServer) deletePeerGroup(pg *config.PeerGroup) error { + name := pg.Config.PeerGroupName + + if _, y := server.peerGroupMap[name]; !y { + return fmt.Errorf("Can't delete a peer-group %s which does not exist", name) + } + + log.WithFields(log.Fields{ + "Topic": "Peer", + "Name": name, + }).Info("Delete a peer group configuration") + + delete(server.peerGroupMap, name) + return nil +} + func (server *BgpServer) deleteNeighbor(c *config.Neighbor, code, subcode uint8) error { + if c.Config.PeerGroup != "" { + _, y := server.peerGroupMap[c.Config.PeerGroup] + if y { + server.peerGroupMap[c.Config.PeerGroup].DeleteMember(*c) + } + } + addr := c.Config.NeighborAddress if intf := c.Config.NeighborInterface; intf != "" { var err error @@ -1742,90 +1797,141 @@ func (server *BgpServer) deleteNeighbor(c *config.Neighbor, code, subcode uint8) return nil } +func (s *BgpServer) DeletePeerGroup(c *config.PeerGroup) error { + return s.mgmtOperation(func() error { + name := c.Config.PeerGroupName + for _, n := range s.neighborMap { + if n.fsm.pConf.Config.PeerGroup == name { + return fmt.Errorf("failed to delete peer-group %s: neighbor %s is in use", name, n.ID()) + } + } + return s.deletePeerGroup(c) + }, true) +} + func (s *BgpServer) DeleteNeighbor(c *config.Neighbor) error { return s.mgmtOperation(func() error { return s.deleteNeighbor(c, bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_PEER_DECONFIGURED) }, true) } -func (s *BgpServer) UpdateNeighbor(c *config.Neighbor) (needsSoftResetIn bool, err error) { - err = s.mgmtOperation(func() error { - addr := c.Config.NeighborAddress - peer, ok := s.neighborMap[addr] - if !ok { - return fmt.Errorf("Neighbor that has %v doesn't exist.", addr) +func (s *BgpServer) updatePeerGroup(pg *config.PeerGroup) (needsSoftResetIn bool, err error) { + name := pg.Config.PeerGroupName + + _, ok := s.peerGroupMap[name] + if !ok { + return false, fmt.Errorf("Peer-group %s doesn't exist.", name) + } + s.peerGroupMap[name].Conf = pg + + for _, n := range s.peerGroupMap[name].members { + c := n + u, err := s.updateNeighbor(&c) + if err != nil { + return needsSoftResetIn, err } + needsSoftResetIn = needsSoftResetIn || u + } + return needsSoftResetIn, nil +} - if !peer.fsm.pConf.ApplyPolicy.Equal(&c.ApplyPolicy) { - log.WithFields(log.Fields{ - "Topic": "Peer", - "Key": addr, - }).Info("Update ApplyPolicy") - s.policy.Reset(nil, map[string]config.ApplyPolicy{peer.ID(): c.ApplyPolicy}) - peer.fsm.pConf.ApplyPolicy = c.ApplyPolicy - needsSoftResetIn = true +func (s *BgpServer) UpdatePeerGroup(pg *config.PeerGroup) (needsSoftResetIn bool, err error) { + err = s.mgmtOperation(func() error { + needsSoftResetIn, err = s.updatePeerGroup(pg) + return err + }, true) + return needsSoftResetIn, err +} + +func (s *BgpServer) updateNeighbor(c *config.Neighbor) (needsSoftResetIn bool, err error) { + if c.Config.PeerGroup != "" { + if err := config.OverwriteNeighborConfigWithPeerGroup(c, s.peerGroupMap[c.Config.PeerGroup].Conf); err != nil { + return needsSoftResetIn, err } - original := peer.fsm.pConf + } + + addr := c.Config.NeighborAddress + peer, ok := s.neighborMap[addr] + if !ok { + return needsSoftResetIn, fmt.Errorf("Neighbor that has %v doesn't exist.", addr) + } + + if !peer.fsm.pConf.ApplyPolicy.Equal(&c.ApplyPolicy) { + log.WithFields(log.Fields{ + "Topic": "Peer", + "Key": addr, + }).Info("Update ApplyPolicy") + s.policy.Reset(nil, map[string]config.ApplyPolicy{peer.ID(): c.ApplyPolicy}) + peer.fsm.pConf.ApplyPolicy = c.ApplyPolicy + needsSoftResetIn = true + } + original := peer.fsm.pConf - if !original.AsPathOptions.Config.Equal(&c.AsPathOptions.Config) { + if !original.AsPathOptions.Config.Equal(&c.AsPathOptions.Config) { + log.WithFields(log.Fields{ + "Topic": "Peer", + "Key": peer.ID(), + }).Info("Update aspath options") + peer.fsm.pConf.AsPathOptions = c.AsPathOptions + needsSoftResetIn = true + } + + if !original.Config.Equal(&c.Config) || !original.Transport.Config.Equal(&c.Transport.Config) || config.CheckAfiSafisChange(original.AfiSafis, c.AfiSafis) { + sub := uint8(bgp.BGP_ERROR_SUB_OTHER_CONFIGURATION_CHANGE) + if original.Config.AdminDown != c.Config.AdminDown { + sub = bgp.BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN + state := "Admin Down" + if c.Config.AdminDown == false { + state = "Admin Up" + } log.WithFields(log.Fields{ "Topic": "Peer", "Key": peer.ID(), - }).Info("Update aspath options") - peer.fsm.pConf.AsPathOptions = c.AsPathOptions - needsSoftResetIn = true - } - - if !original.Config.Equal(&c.Config) || !original.Transport.Config.Equal(&c.Transport.Config) || config.CheckAfiSafisChange(original.AfiSafis, c.AfiSafis) { - sub := uint8(bgp.BGP_ERROR_SUB_OTHER_CONFIGURATION_CHANGE) - if original.Config.AdminDown != c.Config.AdminDown { - sub = bgp.BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN - state := "Admin Down" - if c.Config.AdminDown == false { - state = "Admin Up" - } - log.WithFields(log.Fields{ - "Topic": "Peer", - "Key": peer.ID(), - "State": state, - }).Info("Update admin-state configuration") - } else if original.Config.PeerAs != c.Config.PeerAs { - sub = bgp.BGP_ERROR_SUB_PEER_DECONFIGURED - } - if err = s.deleteNeighbor(peer.fsm.pConf, bgp.BGP_ERROR_CEASE, sub); err != nil { - log.WithFields(log.Fields{ - "Topic": "Peer", - "Key": addr, - }).Error(err) - return err - } - err = s.addNeighbor(c) - if err != nil { - log.WithFields(log.Fields{ - "Topic": "Peer", - "Key": addr, - }).Error(err) - } - return err + "State": state, + }).Info("Update admin-state configuration") + } else if original.Config.PeerAs != c.Config.PeerAs { + sub = bgp.BGP_ERROR_SUB_PEER_DECONFIGURED } - - if !original.Timers.Config.Equal(&c.Timers.Config) { + if err = s.deleteNeighbor(peer.fsm.pConf, bgp.BGP_ERROR_CEASE, sub); err != nil { log.WithFields(log.Fields{ "Topic": "Peer", - "Key": peer.ID(), - }).Info("Update timer configuration") - peer.fsm.pConf.Timers.Config = c.Timers.Config + "Key": addr, + }).Error(err) + return needsSoftResetIn, err } - - err = peer.updatePrefixLimitConfig(c.AfiSafis) + err = s.addNeighbor(c) if err != nil { log.WithFields(log.Fields{ "Topic": "Peer", "Key": addr, }).Error(err) - // rollback to original state - peer.fsm.pConf = original } + return needsSoftResetIn, err + } + + if !original.Timers.Config.Equal(&c.Timers.Config) { + log.WithFields(log.Fields{ + "Topic": "Peer", + "Key": peer.ID(), + }).Info("Update timer configuration") + peer.fsm.pConf.Timers.Config = c.Timers.Config + } + + err = peer.updatePrefixLimitConfig(c.AfiSafis) + if err != nil { + log.WithFields(log.Fields{ + "Topic": "Peer", + "Key": addr, + }).Error(err) + // rollback to original state + peer.fsm.pConf = original + } + return needsSoftResetIn, err +} + +func (s *BgpServer) UpdateNeighbor(c *config.Neighbor) (needsSoftResetIn bool, err error) { + err = s.mgmtOperation(func() error { + needsSoftResetIn, err = s.updateNeighbor(c) return err }, true) return needsSoftResetIn, err diff --git a/server/server_test.go b/server/server_test.go index 9caf8a62..99e63f54 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -343,3 +343,84 @@ func TestFilterpathWithRejectPolicy(t *testing.T) { } } + +func TestPeerGroup(test *testing.T) { + log.SetLevel(log.DebugLevel) + s := NewBgpServer() + go s.Serve() + s.Start(&config.Global{ + Config: config.GlobalConfig{ + As: 1, + RouterId: "1.1.1.1", + Port: 10180, + }, + }) + g := &config.PeerGroup{ + Config: config.PeerGroupConfig{ + PeerAs: 2, + PeerGroupName: "g", + }, + } + if err := s.AddPeerGroup(g); err != nil { + log.Fatal(err) + } + n := &config.Neighbor{ + Config: config.NeighborConfig{ + NeighborAddress: "127.0.0.1", + PeerGroup: "g", + }, + Transport: config.Transport{ + Config: config.TransportConfig{ + PassiveMode: true, + }, + }, + } + configured := map[string]interface{}{ + "config": map[string]interface{}{ + "neigbor-address": "127.0.0.1", + "peer-group": "g", + }, + "transport": map[string]interface{}{ + "config": map[string]interface{}{ + "passive-mode": true, + }, + }, + } + config.RegisterConfiguredFields("127.0.0.1", configured) + + if err := s.AddNeighbor(n); err != nil { + log.Fatal(err) + } + + t := NewBgpServer() + go t.Serve() + t.Start(&config.Global{ + Config: config.GlobalConfig{ + As: 2, + RouterId: "2.2.2.2", + Port: -1, + }, + }) + + m := &config.Neighbor{ + Config: config.NeighborConfig{ + NeighborAddress: "127.0.0.1", + PeerAs: 1, + }, + Transport: config.Transport{ + Config: config.TransportConfig{ + RemotePort: 10180, + }, + }, + } + if err := t.AddNeighbor(m); err != nil { + log.Fatal(err) + } + + for { + time.Sleep(time.Second) + if t.GetNeighbor("", false)[0].State.SessionState == config.SESSION_STATE_ESTABLISHED { + break + } + } +} |