From e97a59c5390fc05ba75673fb4ff7e061c1e73e4f Mon Sep 17 00:00:00 2001 From: ISHIDA Wataru Date: Fri, 29 Jul 2016 13:54:18 +0000 Subject: config: curve out code specific to default neighbor config setting Signed-off-by: ISHIDA Wataru --- api/grpc_server.go | 2 +- config/default.go | 249 ++++++++++++++++++++++++++++------------------------ config/serve.go | 2 +- docs/sources/lib.md | 25 ++---- server/server.go | 4 - 5 files changed, 146 insertions(+), 136 deletions(-) diff --git a/api/grpc_server.go b/api/grpc_server.go index 69864831..69ade16c 100644 --- a/api/grpc_server.go +++ b/api/grpc_server.go @@ -1662,7 +1662,7 @@ func (s *Server) StartServer(ctx context.Context, arg *StartServerRequest) (*Sta AfiSafis: families, }, } - if err := config.SetDefaultConfigValues(nil, b); err != nil { + if err := config.SetDefaultConfigValues(b); err != nil { return nil, err } return &StartServerResponse{}, s.bgpServer.Start(&b.Global) diff --git a/config/default.go b/config/default.go index ea1c731f..6b47806c 100644 --- a/config/default.go +++ b/config/default.go @@ -17,23 +17,146 @@ const ( DEFAULT_MPLS_LABEL_MAX = 1048575 ) -func SetDefaultConfigValues(v *viper.Viper, b *BgpConfigSet) error { +func defaultAfiSafi(typ AfiSafiType, enable bool) AfiSafi { + return AfiSafi{ + Config: AfiSafiConfig{ + AfiSafiName: typ, + Enabled: enable, + }, + State: AfiSafiState{ + AfiSafiName: typ, + }, + } +} + +// yaml is decoded as []interface{} +// but toml is decoded as []map[string]interface{}. +// currently, viper can't hide this difference. +// handle the difference here. +func extractArray(intf interface{}) ([]interface{}, error) { + if intf != nil { + list, ok := intf.([]interface{}) + if ok { + return list, nil + } + l, ok := intf.([]map[string]interface{}) + if !ok { + return nil, fmt.Errorf("invalid configuration: neither []interface{} nor []map[string]interface{}") + } + list = make([]interface{}, 0, len(l)) + for _, m := range l { + list = append(list, m) + } + return list, nil + } + return nil, nil +} + +func SetDefaultNeighborConfigValues(n *Neighbor, asn uint32) error { + return setDefaultNeighborConfigValuesWithViper(nil, n, asn) +} + +func setDefaultNeighborConfigValuesWithViper(v *viper.Viper, n *Neighbor, asn uint32) error { if v == nil { v = viper.New() } - defaultAfiSafi := func(typ AfiSafiType, enable bool) AfiSafi { - return AfiSafi{ - Config: AfiSafiConfig{ - AfiSafiName: typ, - Enabled: enable, - }, - State: AfiSafiState{ - AfiSafiName: typ, - }, + if n.Config.LocalAs == 0 { + n.Config.LocalAs = asn + } + + if n.Config.PeerAs != n.Config.LocalAs { + n.Config.PeerType = PEER_TYPE_EXTERNAL + } else { + n.Config.PeerType = PEER_TYPE_INTERNAL + } + + if !v.IsSet("neighbor.timers.config.connect-retry") && n.Timers.Config.ConnectRetry == 0 { + n.Timers.Config.ConnectRetry = float64(DEFAULT_CONNECT_RETRY) + } + if !v.IsSet("neighbor.timers.config.hold-time") && n.Timers.Config.HoldTime == 0 { + n.Timers.Config.HoldTime = float64(DEFAULT_HOLDTIME) + } + if !v.IsSet("neighbor.timers.config.keepalive-interval") && n.Timers.Config.KeepaliveInterval == 0 { + n.Timers.Config.KeepaliveInterval = n.Timers.Config.HoldTime / 3 + } + if !v.IsSet("neighbor.timers.config.idle-hold-time-after-reset") && n.Timers.Config.IdleHoldTimeAfterReset == 0 { + n.Timers.Config.IdleHoldTimeAfterReset = float64(DEFAULT_IDLE_HOLDTIME_AFTER_RESET) + } + + if n.Transport.Config.LocalAddress == "" { + if n.Config.NeighborAddress != "" { + v6 := true + if ip := net.ParseIP(n.Config.NeighborAddress); ip.To4() != nil { + v6 = false + } + if v6 { + n.Transport.Config.LocalAddress = "::" + } else { + n.Transport.Config.LocalAddress = "0.0.0.0" + } + } else { + return fmt.Errorf("no neighbor address/interface specified") } } + if len(n.AfiSafis) == 0 { + if ip := net.ParseIP(n.Config.NeighborAddress); ip.To4() != nil { + n.AfiSafis = []AfiSafi{defaultAfiSafi(AFI_SAFI_TYPE_IPV4_UNICAST, true)} + } else if ip.To16() != nil { + n.AfiSafis = []AfiSafi{defaultAfiSafi(AFI_SAFI_TYPE_IPV6_UNICAST, true)} + } else { + return fmt.Errorf("invalid neighbor address: %s", n.Config.NeighborAddress) + } + } else { + afs, err := extractArray(v.Get("neighbor.afi-safis")) + if err != nil { + return err + } + for i, af := range n.AfiSafis { + vv := viper.New() + if len(afs) > i { + vv.Set("afi-safi", afs[i]) + } + af.State.AfiSafiName = af.Config.AfiSafiName + if !vv.IsSet("afi-safi.config") { + af.Config.Enabled = true + } + n.AfiSafis[i] = af + } + } + + n.State.Description = n.Config.Description + n.Config.Description = "" + n.State.AdminDown = n.Config.AdminDown + + if n.GracefulRestart.Config.Enabled { + if !v.IsSet("neighbor.graceful-restart.config.restart-time") && n.GracefulRestart.Config.RestartTime == 0 { + // RFC 4724 4. Operation + // A suggested default for the Restart Time is a value less than or + // equal to the HOLDTIME carried in the OPEN. + n.GracefulRestart.Config.RestartTime = uint16(n.Timers.Config.HoldTime) + } + if !v.IsSet("neighbor.graceful-restart.config.deferral-time") && n.GracefulRestart.Config.DeferralTime == 0 { + // RFC 4724 4.1. Procedures for the Restarting Speaker + // The value of this timer should be large + // enough, so as to provide all the peers of the Restarting Speaker with + // enough time to send all the routes to the Restarting Speaker + n.GracefulRestart.Config.DeferralTime = uint16(360) + } + } + return nil +} + +func SetDefaultConfigValues(b *BgpConfigSet) error { + return setDefaultConfigValuesWithViper(nil, b) +} + +func setDefaultConfigValuesWithViper(v *viper.Viper, b *BgpConfigSet) error { + if v == nil { + v = viper.New() + } + if b.Zebra.Config.Url == "" { b.Zebra.Config.Url = "unix:/var/run/quagga/zserv.api" } @@ -68,119 +191,17 @@ func SetDefaultConfigValues(v *viper.Viper, b *BgpConfigSet) error { b.Global.MplsLabelRange.MaxLabel = DEFAULT_MPLS_LABEL_MAX } - // yaml is decoded as []interface{} - // but toml is decoded as []map[string]interface{}. - // currently, viper can't hide this difference. - // handle the difference here. - extractArray := func(intf interface{}) ([]interface{}, error) { - if intf != nil { - list, ok := intf.([]interface{}) - if ok { - return list, nil - } - l, ok := intf.([]map[string]interface{}) - if !ok { - return nil, fmt.Errorf("invalid configuration: neither []interface{} nor []map[string]interface{}") - } - list = make([]interface{}, 0, len(l)) - for _, m := range l { - list = append(list, m) - } - return list, nil - } - return nil, nil - } - list, err := extractArray(v.Get("neighbors")) if err != nil { return err } + for idx, n := range b.Neighbors { vv := viper.New() if len(list) > idx { vv.Set("neighbor", list[idx]) } - if !vv.IsSet("neighbor.timers.config.connect-retry") { - n.Timers.Config.ConnectRetry = float64(DEFAULT_CONNECT_RETRY) - } - if !vv.IsSet("neighbor.timers.config.hold-time") { - n.Timers.Config.HoldTime = float64(DEFAULT_HOLDTIME) - } - if !vv.IsSet("neighbor.timers.config.keepalive-interval") { - n.Timers.Config.KeepaliveInterval = n.Timers.Config.HoldTime / 3 - } - if !vv.IsSet("neighbor.timers.config.idle-hold-time-after-reset") { - n.Timers.Config.IdleHoldTimeAfterReset = float64(DEFAULT_IDLE_HOLDTIME_AFTER_RESET) - } - - if !vv.IsSet("neighbor.transport.config.local-address") { - v6 := true - if ip := net.ParseIP(n.Config.NeighborAddress); ip.To4() != nil { - v6 = false - } - if v6 { - n.Transport.Config.LocalAddress = "::" - } else { - n.Transport.Config.LocalAddress = "0.0.0.0" - } - } - if !vv.IsSet("neighbor.afi-safis") { - if ip := net.ParseIP(n.Config.NeighborAddress); ip.To4() != nil { - n.AfiSafis = []AfiSafi{defaultAfiSafi(AFI_SAFI_TYPE_IPV4_UNICAST, true)} - } else if ip.To16() != nil { - n.AfiSafis = []AfiSafi{defaultAfiSafi(AFI_SAFI_TYPE_IPV6_UNICAST, true)} - } else { - return fmt.Errorf("invalid neighbor address: %s", n.Config.NeighborAddress) - } - } else { - afs, err := extractArray(vv.Get("neighbor.afi-safis")) - if err != nil { - return err - } - for i, af := range n.AfiSafis { - vvv := viper.New() - if len(afs) > i { - vvv.Set("afi-safi", afs[i]) - } - af.State.AfiSafiName = af.Config.AfiSafiName - if !vvv.IsSet("afi-safi.config") { - af.Config.Enabled = true - } - n.AfiSafis[i] = af - } - } - - n.State.Description = n.Config.Description - n.Config.Description = "" - n.State.AdminDown = n.Config.AdminDown - - if !vv.IsSet("neighbor.config.local-as") { - n.Config.LocalAs = b.Global.Config.As - } - - if !vv.IsSet("neighbor.config.peer-type") { - if n.Config.PeerAs != n.Config.LocalAs { - n.Config.PeerType = PEER_TYPE_EXTERNAL - } else { - n.Config.PeerType = PEER_TYPE_INTERNAL - } - } - - if n.GracefulRestart.Config.Enabled { - if !vv.IsSet("neighbor.graceful-restart.config.restart-time") { - // RFC 4724 4. Operation - // A suggested default for the Restart Time is a value less than or - // equal to the HOLDTIME carried in the OPEN. - n.GracefulRestart.Config.RestartTime = uint16(n.Timers.Config.HoldTime) - } - if !vv.IsSet("neighbor.graceful-restart.config.deferral-time") { - // RFC 4724 4.1. Procedures for the Restarting Speaker - // The value of this timer should be large - // enough, so as to provide all the peers of the Restarting Speaker with - // enough time to send all the routes to the Restarting Speaker - n.GracefulRestart.Config.DeferralTime = uint16(360) - } - } + setDefaultNeighborConfigValuesWithViper(vv, &n, b.Global.Config.As) b.Neighbors[idx] = n } diff --git a/config/serve.go b/config/serve.go index 95658a97..6423dfd7 100644 --- a/config/serve.go +++ b/config/serve.go @@ -38,7 +38,7 @@ func ReadConfigfileServe(path, format string, configCh chan *BgpConfigSet) { if err = v.UnmarshalExact(c); err != nil { goto ERROR } - if err = SetDefaultConfigValues(v, c); err != nil { + if err = setDefaultConfigValuesWithViper(v, c); err != nil { goto ERROR } if cnt == 0 { diff --git a/docs/sources/lib.md b/docs/sources/lib.md index fd4182ca..7688e71f 100644 --- a/docs/sources/lib.md +++ b/docs/sources/lib.md @@ -42,7 +42,7 @@ func main() { }, } - if err := config.SetDefaultConfigValues(nil, b); err != nil { + if err := config.SetDefaultConfigValues(b); err != nil { log.Fatal(err) } @@ -51,25 +51,18 @@ func main() { } // neighbor configuration - if err := s.AddNeighbor(&config.Neighbor{ + n := &config.Neighbor{ Config: config.NeighborConfig{ NeighborAddress: "10.0.255.1", PeerAs: 65001, }, - Timers: config.Timers{ - Config: config.TimersConfig{ - HoldTime: 90, - KeepaliveInterval: 30, - }, - }, - AfiSafis: []config.AfiSafi{ - config.AfiSafi{ - Config: config.AfiSafiConfig{ - AfiSafiName: config.AFI_SAFI_TYPE_IPV4_UNICAST, - }, - }, - }, - }); err != nil { + } + + if err := config.SetDefaultNeighborConfigValues(n, b.Global.Config.As); err != nil { + log.Fatal(err) + } + + if err := s.AddNeighbor(n); err != nil { log.Fatal(err) } diff --git a/server/server.go b/server/server.go index f6b08246..6841a854 100644 --- a/server/server.go +++ b/server/server.go @@ -1657,10 +1657,6 @@ func (server *BgpServer) addNeighbor(c *config.Neighbor) error { } log.Info("Add a peer configuration for ", addr) - if c.Config.LocalAs == 0 { - c.Config.LocalAs = server.bgpConfig.Global.Config.As - } - peer := NewPeer(&server.bgpConfig.Global, c, server.globalRib, server.policy) server.setPolicyByConfig(peer.ID(), c.ApplyPolicy) if peer.isRouteServerClient() { -- cgit v1.2.3