diff options
Diffstat (limited to 'config')
-rw-r--r-- | config/bgp_configs.go | 26 | ||||
-rw-r--r-- | config/default.go | 130 | ||||
-rw-r--r-- | config/serve.go | 49 |
3 files changed, 106 insertions, 99 deletions
diff --git a/config/bgp_configs.go b/config/bgp_configs.go index fbe829db..c8d61dca 100644 --- a/config/bgp_configs.go +++ b/config/bgp_configs.go @@ -15,8 +15,6 @@ package config -import "net" - // typedef for typedef bgp-types:rr-cluster-id-type type RrClusterIdType string @@ -148,7 +146,7 @@ type BmpServerState struct { type BmpServerConfig struct { // original -> gobgp:address //gobgp:address's original type is inet:ip-address - Address net.IP + Address string // original -> gobgp:port Port uint32 // original -> gobgp:route-monitoring-policy @@ -221,7 +219,7 @@ type RpkiServerState struct { type RpkiServerConfig struct { // original -> gobgp:address //gobgp:address's original type is inet:ip-address - Address net.IP + Address string // original -> gobgp:port Port uint32 // original -> gobgp:refresh-time @@ -541,13 +539,13 @@ type TransportState struct { LocalPort uint16 // original -> bgp-op:remote-address //bgp-op:remote-address's original type is inet:ip-address - RemoteAddress net.IP + RemoteAddress string // original -> bgp-op:remote-port //bgp-op:remote-port's original type is inet:port-number RemotePort uint16 // original -> gobgp:local-address //gobgp:local-address's original type is inet:ip-address - LocalAddress net.IP + LocalAddress string } //struct for container bgp:config @@ -562,7 +560,7 @@ type TransportConfig struct { PassiveMode bool // original -> gobgp:local-address //gobgp:local-address's original type is inet:ip-address - LocalAddress net.IP + LocalAddress string } //struct for container bgp:transport @@ -711,7 +709,7 @@ type NeighborState struct { PeerGroup string // original -> bgp:neighbor-address //bgp:neighbor-address's original type is inet:ip-address - NeighborAddress net.IP + NeighborAddress string // original -> bgp-op:session-state //bgp-op:session-state's original type is enumeration SessionState uint32 @@ -756,14 +754,14 @@ type NeighborConfig struct { PeerGroup string // original -> bgp:neighbor-address //bgp:neighbor-address's original type is inet:ip-address - NeighborAddress net.IP + NeighborAddress string } //struct for container bgp:neighbor type Neighbor struct { // original -> bgp:neighbor-address //bgp:neighbor-address's original type is inet:ip-address - NeighborAddress net.IP + NeighborAddress string // original -> bgp:neighbor-config Config NeighborConfig // original -> bgp:neighbor-state @@ -1339,7 +1337,7 @@ type GlobalState struct { As uint32 // original -> bgp:router-id //bgp:router-id's original type is inet:ipv4-address - RouterId net.IP + RouterId string // original -> bgp-op:total-paths TotalPaths uint32 // original -> bgp-op:total-prefixes @@ -1353,7 +1351,7 @@ type GlobalConfig struct { As uint32 // original -> bgp:router-id //bgp:router-id's original type is inet:ipv4-address - RouterId net.IP + RouterId string } //struct for container bgp:global @@ -1543,7 +1541,7 @@ type BgpConditions struct { OriginEq BgpOriginAttrType // original -> bgp-pol:next-hop-in //original type is list of inet:ip-address - NextHopIn []net.IP + NextHopIn []string // original -> bgp-pol:local-pref-eq LocalPrefEq uint32 // original -> bgp-pol:community-count @@ -1727,7 +1725,7 @@ type TagSets struct { type NeighborInfo struct { // original -> gobgp:address //gobgp:address's original type is inet:ip-address - Address net.IP + Address string } //struct for container rpol:neighbor-set diff --git a/config/default.go b/config/default.go index 5e5c8a53..11b62a71 100644 --- a/config/default.go +++ b/config/default.go @@ -1,8 +1,10 @@ package config import ( - "github.com/BurntSushi/toml" + "fmt" "github.com/osrg/gobgp/packet" + "github.com/spf13/viper" + "net" "strings" ) @@ -14,25 +16,12 @@ const ( DEFAULT_MPLS_LABEL_MAX = 1048575 ) -type neighbor struct { - attributes map[string]bool -} - -func SetDefaultConfigValues(md toml.MetaData, bt *Bgp) error { - neighbors := []neighbor{} - global := make(map[string]bool) - - for _, key := range md.Keys() { - if !strings.HasPrefix(key.String(), "Global") { - continue - } - if key.String() != "Global" { - global[key.String()] = true - } +func SetDefaultConfigValues(v *viper.Viper, b *Bgp) error { + if v == nil { + v = viper.New() } - - if _, ok := global["Global.AfiSafis.AfiSafiList"]; !ok { - bt.Global.AfiSafis.AfiSafiList = []AfiSafi{ + if !v.IsSet("global.afisafis.afisafilist") { + b.Global.AfiSafis.AfiSafiList = []AfiSafi{ AfiSafi{AfiSafiName: "ipv4-unicast"}, AfiSafi{AfiSafiName: "ipv6-unicast"}, AfiSafi{AfiSafiName: "l3vpn-ipv4-unicast"}, @@ -47,77 +36,84 @@ func SetDefaultConfigValues(md toml.MetaData, bt *Bgp) error { } } - if bt.Global.ListenConfig.Port == 0 { - bt.Global.ListenConfig.Port = bgp.BGP_PORT + if b.Global.ListenConfig.Port == 0 { + b.Global.ListenConfig.Port = bgp.BGP_PORT } - if _, ok := global["Global.MplsLabelRange.MinLabel"]; !ok { - bt.Global.MplsLabelRange.MinLabel = DEFAULT_MPLS_LABEL_MIN + if !v.IsSet("global.mplslabelrange.minlabel") { + b.Global.MplsLabelRange.MinLabel = DEFAULT_MPLS_LABEL_MIN } - if _, ok := global["Global.MplsLabelRange.MaxLabel"]; !ok { - bt.Global.MplsLabelRange.MaxLabel = DEFAULT_MPLS_LABEL_MAX + if !v.IsSet("global.mplslabelrange.maxlabel") { + b.Global.MplsLabelRange.MaxLabel = DEFAULT_MPLS_LABEL_MAX } - - nidx := 0 - for _, key := range md.Keys() { - if !strings.HasPrefix(key.String(), "Neighbors.NeighborList") { - continue - } - if key.String() == "Neighbors.NeighborList" { - neighbors = append(neighbors, neighbor{attributes: make(map[string]bool)}) - nidx++ - } else { - neighbors[nidx-1].attributes[key.String()] = true + var list []interface{} + for k, val := range v.GetStringMap("neighbors") { + if strings.ToLower(k) == "neighborlist" { + var ok bool + // yaml is decoded as []interface{} + // but toml is decoded as []map[string]interface{}. + // currently, viper can't hide this difference. + // handle the difference here. + list, ok = val.([]interface{}) + if !ok { + l, ok := val.([]map[string]interface{}) + if !ok { + return fmt.Errorf("invalid configuration: neighborlist must be a list") + } + for _, m := range l { + list = append(list, m) + } + } } } - for i, n := range neighbors { - neighbor := &bt.Neighbors.NeighborList[i] - timerConfig := &neighbor.Timers.Config - - if _, ok := n.attributes["Neighbors.NeighborList.Timers.Config.ConnectRetry"]; !ok { - timerConfig.HoldTime = float64(DEFAULT_CONNECT_RETRY) + for idx, n := range b.Neighbors.NeighborList { + vv := viper.New() + if len(list) > idx { + vv.Set("neighbor", list[idx]) } - if _, ok := n.attributes["Neighbors.NeighborList.Timers.Config.HoldTime"]; !ok { - timerConfig.HoldTime = float64(DEFAULT_HOLDTIME) + if !vv.IsSet("neighbor.timers.config.connectretry") { + n.Timers.Config.ConnectRetry = float64(DEFAULT_CONNECT_RETRY) } - if _, ok := n.attributes["Neighbors.NeighborList.Timers.Config.KeepaliveInterval"]; !ok { - timerConfig.KeepaliveInterval = timerConfig.HoldTime / 3 + if !vv.IsSet("neighbor.timers.config.holdtime") { + n.Timers.Config.HoldTime = float64(DEFAULT_HOLDTIME) } - - if _, ok := n.attributes["Neighbors.NeighborList.Timers.Config.IdleHoldTimeAfterReset"]; !ok { - timerConfig.IdleHoldTimeAfterReset = float64(DEFAULT_IDLE_HOLDTIME_AFTER_RESET) + if !vv.IsSet("neighbor.timers.config.keepaliveinterval") { + n.Timers.Config.KeepaliveInterval = n.Timers.Config.HoldTime / 3 + } + if !vv.IsSet("neighbor.timers.config.idleholdtimeafterreset") { + n.Timers.Config.IdleHoldTimeAfterReset = float64(DEFAULT_IDLE_HOLDTIME_AFTER_RESET) } - if _, ok := n.attributes["Neighbors.NeighborList.AfiSafis.AfiSafiList"]; !ok { - if neighbor.Config.NeighborAddress.To4() != nil { - neighbor.AfiSafis.AfiSafiList = []AfiSafi{ - AfiSafi{AfiSafiName: "ipv4-unicast"}} - } else { - neighbor.AfiSafis.AfiSafiList = []AfiSafi{ - AfiSafi{AfiSafiName: "ipv6-unicast"}} - } - } else { - for _, rf := range neighbor.AfiSafis.AfiSafiList { - _, err := bgp.GetRouteFamily(rf.AfiSafiName) - if err != nil { - return err + if !vv.IsSet("neighbor.afisafis.afisafilist") { + if ip := net.ParseIP(n.Config.NeighborAddress); ip.To4() != nil { + n.AfiSafis.AfiSafiList = []AfiSafi{ + AfiSafi{AfiSafiName: "ipv4-unicast"}, + } + } else if ip.To16() != nil { + n.AfiSafis.AfiSafiList = []AfiSafi{ + AfiSafi{AfiSafiName: "ipv6-unicast"}, } + } else { + return fmt.Errorf("invalid neighbor address: %s", n.Config.NeighborAddress) } } - if _, ok := n.attributes["Neighbors.NeighborList.Config.PeerType"]; !ok { - if neighbor.Config.PeerAs != bt.Global.Config.As { - neighbor.Config.PeerType = PEER_TYPE_EXTERNAL + if !vv.IsSet("neighbor.config.peertype") { + if n.Config.PeerAs != b.Global.Config.As { + n.Config.PeerType = PEER_TYPE_EXTERNAL } else { - neighbor.Config.PeerType = PEER_TYPE_INTERNAL + n.Config.PeerType = PEER_TYPE_INTERNAL } } + b.Neighbors.NeighborList[idx] = n } - for _, r := range bt.RpkiServers.RpkiServerList { + + for _, r := range b.RpkiServers.RpkiServerList { if r.Config.Port == 0 { r.Config.Port = bgp.RPKI_DEFAULT_PORT } } + return nil } diff --git a/config/serve.go b/config/serve.go index ef9b0ae0..6de993b8 100644 --- a/config/serve.go +++ b/config/serve.go @@ -1,8 +1,8 @@ package config import ( - "github.com/BurntSushi/toml" log "github.com/Sirupsen/logrus" + "github.com/spf13/viper" "reflect" ) @@ -11,41 +11,54 @@ type BgpConfigSet struct { Policy RoutingPolicy } -func ReadConfigfileServe(path string, configCh chan BgpConfigSet, reloadCh chan bool) { +func ReadConfigfileServe(path, format string, configCh chan BgpConfigSet, reloadCh chan bool) { cnt := 0 for { <-reloadCh b := Bgp{} p := RoutingPolicy{} - md, err := toml.DecodeFile(path, &b) - if err == nil { - err = SetDefaultConfigValues(md, &b) - if err == nil { - _, err = toml.DecodeFile(path, &p) - } + v := viper.New() + v.SetConfigFile(path) + v.SetConfigType(format) + err := v.ReadInConfig() + if err != nil { + goto ERROR } - + err = v.Unmarshal(&b) if err != nil { - if cnt == 0 { - log.Fatal("can't read config file ", path, ", ", err) - } else { - log.Warning("can't read config file ", path, ", ", err) - continue - } + goto ERROR + } + err = SetDefaultConfigValues(v, &b) + if err != nil { + goto ERROR + } + err = v.Unmarshal(&p) + if err != nil { + goto ERROR } + if cnt == 0 { log.Info("finished reading the config file") } cnt++ - bgpConfig := BgpConfigSet{Bgp: b, Policy: p} - configCh <- bgpConfig + configCh <- BgpConfigSet{Bgp: b, Policy: p} + continue + + ERROR: + if cnt == 0 { + log.Fatal("can't read config file ", path, ", ", err) + } else { + log.Warning("can't read config file ", path, ", ", err) + continue + } + } } func inSlice(n Neighbor, b []Neighbor) int { for i, nb := range b { - if nb.Config.NeighborAddress.String() == n.Config.NeighborAddress.String() { + if nb.Config.NeighborAddress == n.Config.NeighborAddress { return i } } |