diff options
author | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2016-07-29 13:54:18 +0000 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2016-07-29 16:31:35 +0900 |
commit | e97a59c5390fc05ba75673fb4ff7e061c1e73e4f (patch) | |
tree | 07813290b57b33708e2b70a6724b0573a4e230fe /config | |
parent | 4fec73235a5fe507bfdd6e9c1bc19325b2d65dbd (diff) |
config: curve out code specific to default neighbor config setting
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'config')
-rw-r--r-- | config/default.go | 249 | ||||
-rw-r--r-- | config/serve.go | 2 |
2 files changed, 136 insertions, 115 deletions
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 { |