diff options
-rw-r--r-- | config/bgp_configs.go | 6 | ||||
-rw-r--r-- | config/default.go | 14 | ||||
-rw-r--r-- | config/util.go | 19 | ||||
-rw-r--r-- | server/fsm.go | 43 | ||||
-rw-r--r-- | server/peer.go | 34 | ||||
-rw-r--r-- | tools/pyang_plugins/gobgp.yang | 13 |
6 files changed, 92 insertions, 37 deletions
diff --git a/config/bgp_configs.go b/config/bgp_configs.go index 7c5eddb8..1c87bb88 100644 --- a/config/bgp_configs.go +++ b/config/bgp_configs.go @@ -3933,6 +3933,9 @@ type AfiSafi struct { RouteTargetMembership RouteTargetMembership `mapstructure:"route-target-membership" json:"route-target-membership,omitempty"` // original -> gobgp:long-lived-graceful-restart LongLivedGracefulRestart LongLivedGracefulRestart `mapstructure:"long-lived-graceful-restart" json:"long-lived-graceful-restart,omitempty"` + // original -> gobgp:add-paths + // add-paths configuration options related to a particular AFI-SAFI. + AddPaths AddPaths `mapstructure:"add-paths" json:"add-paths,omitempty"` } func (lhs *AfiSafi) Equal(rhs *AfiSafi) bool { @@ -3993,6 +3996,9 @@ func (lhs *AfiSafi) Equal(rhs *AfiSafi) bool { if !lhs.LongLivedGracefulRestart.Equal(&(rhs.LongLivedGracefulRestart)) { return false } + if !lhs.AddPaths.Equal(&(rhs.AddPaths)) { + return false + } return true } diff --git a/config/default.go b/config/default.go index 93693ce6..ed1fac91 100644 --- a/config/default.go +++ b/config/default.go @@ -201,6 +201,12 @@ func setDefaultNeighborConfigValuesWithViper(v *viper.Viper, n *Neighbor, asn ui } else { n.AfiSafis = []AfiSafi{defaultAfiSafi(AFI_SAFI_TYPE_IPV6_UNICAST, true)} } + for i := range n.AfiSafis { + n.AfiSafis[i].AddPaths.Config.Receive = n.AddPaths.Config.Receive + n.AfiSafis[i].AddPaths.State.Receive = n.AddPaths.Config.Receive + n.AfiSafis[i].AddPaths.Config.SendMax = n.AddPaths.Config.SendMax + n.AfiSafis[i].AddPaths.State.SendMax = n.AddPaths.Config.SendMax + } } else { afs, err := extractArray(v.Get("neighbor.afi-safis")) if err != nil { @@ -221,6 +227,14 @@ func setDefaultNeighborConfigValuesWithViper(v *viper.Viper, n *Neighbor, asn ui n.AfiSafis[i].Config.Enabled = true } n.AfiSafis[i].MpGracefulRestart.State.Enabled = n.AfiSafis[i].MpGracefulRestart.Config.Enabled + if !vv.IsSet("afi-safi.add-paths.config.receive") { + n.AfiSafis[i].AddPaths.Config.Receive = n.AddPaths.Config.Receive + } + n.AfiSafis[i].AddPaths.State.Receive = n.AfiSafis[i].AddPaths.Config.Receive + if !vv.IsSet("afi-safi.add-paths.config.send-max") { + n.AfiSafis[i].AddPaths.Config.SendMax = n.AddPaths.Config.SendMax + } + n.AfiSafis[i].AddPaths.State.SendMax = n.AfiSafis[i].AddPaths.Config.SendMax } } diff --git a/config/util.go b/config/util.go index de7ba3d4..f63e6d69 100644 --- a/config/util.go +++ b/config/util.go @@ -66,17 +66,16 @@ func (c AfiSafis) ToRfList() ([]bgp.RouteFamily, error) { } func CreateRfMap(p *Neighbor) map[bgp.RouteFamily]bgp.BGPAddPathMode { - rfs, _ := AfiSafis(p.AfiSafis).ToRfList() - mode := bgp.BGP_ADD_PATH_NONE - if p.AddPaths.Config.Receive { - mode |= bgp.BGP_ADD_PATH_RECEIVE - } - if p.AddPaths.Config.SendMax > 0 { - mode |= bgp.BGP_ADD_PATH_SEND - } rfMap := make(map[bgp.RouteFamily]bgp.BGPAddPathMode) - for _, rf := range rfs { - rfMap[rf] = mode + for _, af := range p.AfiSafis { + mode := bgp.BGP_ADD_PATH_NONE + if af.AddPaths.State.Receive { + mode |= bgp.BGP_ADD_PATH_RECEIVE + } + if af.AddPaths.State.SendMax > 0 { + mode |= bgp.BGP_ADD_PATH_SEND + } + rfMap[af.State.Family] = mode } return rfMap } diff --git a/server/fsm.go b/server/fsm.go index 0d208eb4..03542263 100644 --- a/server/fsm.go +++ b/server/fsm.go @@ -559,6 +559,26 @@ func (h *FSMHandler) active() (bgp.FSMState, FsmStateReason) { } } +func capAddPathFromConfig(pConf *config.Neighbor) bgp.ParameterCapabilityInterface { + tuples := make([]*bgp.CapAddPathTuple, 0, len(pConf.AfiSafis)) + for _, af := range pConf.AfiSafis { + var mode bgp.BGPAddPathMode + if af.AddPaths.State.Receive { + mode |= bgp.BGP_ADD_PATH_RECEIVE + } + if af.AddPaths.State.SendMax > 0 { + mode |= bgp.BGP_ADD_PATH_SEND + } + if mode > 0 { + tuples = append(tuples, bgp.NewCapAddPathTuple(af.State.Family, mode)) + } + } + if len(tuples) == 0 { + return nil + } + return bgp.NewCapAddPath(tuples) +} + func capabilitiesFromConfig(pConf *config.Neighbor) []bgp.ParameterCapabilityInterface { caps := make([]bgp.ParameterCapabilityInterface, 0, 4) caps = append(caps, bgp.NewCapRouteRefresh()) @@ -595,9 +615,9 @@ func capabilitiesFromConfig(pConf *config.Neighbor) []bgp.ParameterCapabilityInt } } } - time := c.RestartTime + restartTime := c.RestartTime notification := c.NotificationEnabled - caps = append(caps, bgp.NewCapGracefulRestart(restarting, notification, time, tuples)) + caps = append(caps, bgp.NewCapGracefulRestart(restarting, notification, restartTime, tuples)) if c.LongLivedEnabled { caps = append(caps, bgp.NewCapLongLivedGracefulRestart(ltuples)) } @@ -614,23 +634,12 @@ func capabilitiesFromConfig(pConf *config.Neighbor) []bgp.ParameterCapabilityInt tuple := bgp.NewCapExtendedNexthopTuple(family, bgp.AFI_IP6) tuples = append(tuples, tuple) } - cap := bgp.NewCapExtendedNexthop(tuples) - caps = append(caps, cap) + caps = append(caps, bgp.NewCapExtendedNexthop(tuples)) } - var mode bgp.BGPAddPathMode - if pConf.AddPaths.Config.Receive { - mode |= bgp.BGP_ADD_PATH_RECEIVE - } - if pConf.AddPaths.Config.SendMax > 0 { - mode |= bgp.BGP_ADD_PATH_SEND - } - if uint8(mode) > 0 { - items := make([]*bgp.CapAddPathTuple, 0, len(pConf.AfiSafis)) - for _, af := range pConf.AfiSafis { - items = append(items, bgp.NewCapAddPathTuple(af.State.Family, mode)) - } - caps = append(caps, bgp.NewCapAddPath(items)) + // ADD-PATH Capability + if c := capAddPathFromConfig(pConf); c != nil { + caps = append(caps, capAddPathFromConfig(pConf)) } return caps diff --git a/server/peer.go b/server/peer.go index 4a1860e8..04ca0de6 100644 --- a/server/peer.go +++ b/server/peer.go @@ -144,11 +144,19 @@ func (peer *Peer) isGracefulRestartEnabled() bool { return peer.fsm.pConf.GracefulRestart.State.Enabled } -func (peer *Peer) isAddPathSendEnabled(family bgp.RouteFamily) bool { - if mode, y := peer.fsm.rfMap[family]; y && (mode&bgp.BGP_ADD_PATH_SEND) > 0 { - return true +func (peer *Peer) getAddPathMode(family bgp.RouteFamily) bgp.BGPAddPathMode { + if mode, y := peer.fsm.rfMap[family]; y { + return mode } - return false + return bgp.BGP_ADD_PATH_NONE +} + +func (peer *Peer) isAddPathReceiveEnabled(family bgp.RouteFamily) bool { + return (peer.getAddPathMode(family) & bgp.BGP_ADD_PATH_RECEIVE) > 0 +} + +func (peer *Peer) isAddPathSendEnabled(family bgp.RouteFamily) bool { + return (peer.getAddPathMode(family) & bgp.BGP_ADD_PATH_SEND) > 0 } func (peer *Peer) isDynamicNeighbor() bool { @@ -588,17 +596,23 @@ func (peer *Peer) ToConfig(getAdvertised bool) *config.Neighbor { conf := *peer.fsm.pConf conf.AfiSafis = make([]config.AfiSafi, len(peer.fsm.pConf.AfiSafis)) - for i := 0; i < len(peer.fsm.pConf.AfiSafis); i++ { - conf.AfiSafis[i] = peer.fsm.pConf.AfiSafis[i] + for i, af := range peer.fsm.pConf.AfiSafis { + conf.AfiSafis[i] = af + conf.AfiSafis[i].AddPaths.State.Receive = peer.isAddPathReceiveEnabled(af.State.Family) + if peer.isAddPathSendEnabled(af.State.Family) { + conf.AfiSafis[i].AddPaths.State.SendMax = af.AddPaths.State.SendMax + } else { + conf.AfiSafis[i].AddPaths.State.SendMax = 0 + } } remoteCap := make([]bgp.ParameterCapabilityInterface, 0, len(peer.fsm.capMap)) - for _, c := range peer.fsm.capMap { - for _, m := range c { + for _, caps := range peer.fsm.capMap { + for _, m := range caps { // need to copy all values here buf, _ := m.Serialize() - cap, _ := bgp.DecodeCapability(buf) - remoteCap = append(remoteCap, cap) + c, _ := bgp.DecodeCapability(buf) + remoteCap = append(remoteCap, c) } } conf.State.RemoteCapabilityList = remoteCap diff --git a/tools/pyang_plugins/gobgp.yang b/tools/pyang_plugins/gobgp.yang index a06a7fa2..a1c151b0 100644 --- a/tools/pyang_plugins/gobgp.yang +++ b/tools/pyang_plugins/gobgp.yang @@ -1251,4 +1251,17 @@ module gobgp { uses long-lived-graceful-restart; } + + augment "/bgp:bgp/bgp:global/bgp:afi-safis/bgp:afi-safi" { + container add-paths { + description + "add-paths configuration options related to a particular AFI-SAFI."; + container config { + uses bgp:bgp-neighbor-add-paths_config; + } + container state { + uses bgp:bgp-neighbor-add-paths_config; + } + } + } } |