diff options
Diffstat (limited to 'internal/pkg/config')
-rw-r--r-- | internal/pkg/config/util.go | 380 |
1 files changed, 380 insertions, 0 deletions
diff --git a/internal/pkg/config/util.go b/internal/pkg/config/util.go index 591252b4..47c7d37f 100644 --- a/internal/pkg/config/util.go +++ b/internal/pkg/config/util.go @@ -21,7 +21,10 @@ import ( "path/filepath" "regexp" "strconv" + "strings" + api "github.com/osrg/gobgp/api" + "github.com/osrg/gobgp/internal/pkg/apiutil" "github.com/osrg/gobgp/pkg/packet/bgp" ) @@ -262,3 +265,380 @@ func ParseMaskLength(prefix, mask string) (int, int, error) { } return int(min), int(max), nil } + +func extractFamilyFromConfigAfiSafi(c *AfiSafi) uint32 { + if c == nil { + return 0 + } + // If address family value is already stored in AfiSafiState structure, + // we prefer to use this value. + if c.State.Family != 0 { + return uint32(c.State.Family) + } + // In case that Neighbor structure came from CLI or gRPC, address family + // value in AfiSafiState structure can be omitted. + // Here extracts value from AfiSafiName field in AfiSafiConfig structure. + if rf, err := bgp.GetRouteFamily(string(c.Config.AfiSafiName)); err == nil { + return uint32(rf) + } + // Ignores invalid address family name + return 0 +} + +func newAfiSafiConfigFromConfigStruct(c *AfiSafi) *api.AfiSafiConfig { + rf := extractFamilyFromConfigAfiSafi(c) + afi, safi := bgp.RouteFamilyToAfiSafi(bgp.RouteFamily(rf)) + return &api.AfiSafiConfig{ + Family: &api.Family{Afi: api.Family_Afi(afi), Safi: api.Family_Safi(safi)}, + Enabled: c.Config.Enabled, + } +} + +func newApplyPolicyFromConfigStruct(c *ApplyPolicy) *api.ApplyPolicy { + applyPolicy := &api.ApplyPolicy{ + ImportPolicy: &api.PolicyAssignment{ + Direction: api.PolicyDirection_IMPORT, + DefaultAction: api.RouteAction(c.Config.DefaultImportPolicy.ToInt()), + }, + ExportPolicy: &api.PolicyAssignment{ + Direction: api.PolicyDirection_EXPORT, + DefaultAction: api.RouteAction(c.Config.DefaultExportPolicy.ToInt()), + }, + } + + for _, pname := range c.Config.ImportPolicyList { + applyPolicy.ImportPolicy.Policies = append(applyPolicy.ImportPolicy.Policies, &api.Policy{Name: pname}) + } + for _, pname := range c.Config.ExportPolicyList { + applyPolicy.ExportPolicy.Policies = append(applyPolicy.ExportPolicy.Policies, &api.Policy{Name: pname}) + } + + return applyPolicy +} + +func newPrefixLimitFromConfigStruct(c *AfiSafi) *api.PrefixLimit { + if c.PrefixLimit.Config.MaxPrefixes == 0 { + return nil + } + afi, safi := bgp.RouteFamilyToAfiSafi(bgp.RouteFamily(c.State.Family)) + return &api.PrefixLimit{ + Family: &api.Family{Afi: api.Family_Afi(afi), Safi: api.Family_Safi(safi)}, + MaxPrefixes: c.PrefixLimit.Config.MaxPrefixes, + ShutdownThresholdPct: uint32(c.PrefixLimit.Config.ShutdownThresholdPct), + } +} + +func newRouteTargetMembershipFromConfigStruct(c *RouteTargetMembership) *api.RouteTargetMembership { + return &api.RouteTargetMembership{ + Config: &api.RouteTargetMembershipConfig{ + DeferralTime: uint32(c.Config.DeferralTime), + }, + } +} + +func newLongLivedGracefulRestartFromConfigStruct(c *LongLivedGracefulRestart) *api.LongLivedGracefulRestart { + return &api.LongLivedGracefulRestart{ + Config: &api.LongLivedGracefulRestartConfig{ + Enabled: c.Config.Enabled, + RestartTime: c.Config.RestartTime, + }, + } +} + +func newAddPathsFromConfigStruct(c *AddPaths) *api.AddPaths { + return &api.AddPaths{ + Config: &api.AddPathsConfig{ + Receive: c.Config.Receive, + SendMax: uint32(c.Config.SendMax), + }, + } +} + +func newRouteSelectionOptionsFromConfigStruct(c *RouteSelectionOptions) *api.RouteSelectionOptions { + return &api.RouteSelectionOptions{ + Config: &api.RouteSelectionOptionsConfig{ + AlwaysCompareMed: c.Config.AlwaysCompareMed, + IgnoreAsPathLength: c.Config.IgnoreAsPathLength, + ExternalCompareRouterId: c.Config.ExternalCompareRouterId, + AdvertiseInactiveRoutes: c.Config.AdvertiseInactiveRoutes, + EnableAigp: c.Config.EnableAigp, + IgnoreNextHopIgpMetric: c.Config.IgnoreNextHopIgpMetric, + }, + } +} + +func newMpGracefulRestartFromConfigStruct(c *MpGracefulRestart) *api.MpGracefulRestart { + return &api.MpGracefulRestart{ + Config: &api.MpGracefulRestartConfig{ + Enabled: c.Config.Enabled, + }, + } +} + +func newUseMultiplePathsFromConfigStruct(c *UseMultiplePaths) *api.UseMultiplePaths { + return &api.UseMultiplePaths{ + Config: &api.UseMultiplePathsConfig{ + Enabled: c.Config.Enabled, + }, + Ebgp: &api.Ebgp{ + Config: &api.EbgpConfig{ + AllowMultipleAs: c.Ebgp.Config.AllowMultipleAs, + MaximumPaths: c.Ebgp.Config.MaximumPaths, + }, + }, + Ibgp: &api.Ibgp{ + Config: &api.IbgpConfig{ + MaximumPaths: c.Ibgp.Config.MaximumPaths, + }, + }, + } +} + +func newAfiSafiFromConfigStruct(c *AfiSafi) *api.AfiSafi { + return &api.AfiSafi{ + MpGracefulRestart: newMpGracefulRestartFromConfigStruct(&c.MpGracefulRestart), + Config: newAfiSafiConfigFromConfigStruct(c), + ApplyPolicy: newApplyPolicyFromConfigStruct(&c.ApplyPolicy), + RouteSelectionOptions: newRouteSelectionOptionsFromConfigStruct(&c.RouteSelectionOptions), + UseMultiplePaths: newUseMultiplePathsFromConfigStruct(&c.UseMultiplePaths), + PrefixLimits: newPrefixLimitFromConfigStruct(c), + RouteTargetMembership: newRouteTargetMembershipFromConfigStruct(&c.RouteTargetMembership), + LongLivedGracefulRestart: newLongLivedGracefulRestartFromConfigStruct(&c.LongLivedGracefulRestart), + AddPaths: newAddPathsFromConfigStruct(&c.AddPaths), + } +} + +func NewPeerFromConfigStruct(pconf *Neighbor) *api.Peer { + afiSafis := make([]*api.AfiSafi, 0, len(pconf.AfiSafis)) + for _, f := range pconf.AfiSafis { + if afiSafi := newAfiSafiFromConfigStruct(&f); afiSafi != nil { + afiSafis = append(afiSafis, afiSafi) + } + } + + timer := pconf.Timers + s := pconf.State + localAddress := pconf.Transport.Config.LocalAddress + if pconf.Transport.State.LocalAddress != "" { + localAddress = pconf.Transport.State.LocalAddress + } + remoteCap, err := apiutil.MarshalCapabilities(pconf.State.RemoteCapabilityList) + if err != nil { + return nil + } + localCap, err := apiutil.MarshalCapabilities(pconf.State.LocalCapabilityList) + if err != nil { + return nil + } + var removePrivateAs api.PeerConf_RemovePrivateAs + switch pconf.Config.RemovePrivateAs { + case REMOVE_PRIVATE_AS_OPTION_ALL: + removePrivateAs = api.PeerConf_ALL + case REMOVE_PRIVATE_AS_OPTION_REPLACE: + removePrivateAs = api.PeerConf_REPLACE + } + return &api.Peer{ + ApplyPolicy: newApplyPolicyFromConfigStruct(&pconf.ApplyPolicy), + Conf: &api.PeerConf{ + NeighborAddress: pconf.Config.NeighborAddress, + Id: s.RemoteRouterId, + PeerAs: pconf.Config.PeerAs, + LocalAs: pconf.Config.LocalAs, + PeerType: uint32(pconf.Config.PeerType.ToInt()), + AuthPassword: pconf.Config.AuthPassword, + RouteFlapDamping: pconf.Config.RouteFlapDamping, + Description: pconf.Config.Description, + PeerGroup: pconf.Config.PeerGroup, + RemoteCap: remoteCap, + LocalCap: localCap, + NeighborInterface: pconf.Config.NeighborInterface, + Vrf: pconf.Config.Vrf, + AllowOwnAs: uint32(pconf.AsPathOptions.Config.AllowOwnAs), + RemovePrivateAs: removePrivateAs, + ReplacePeerAs: pconf.AsPathOptions.Config.ReplacePeerAs, + }, + State: &api.PeerState{ + SessionState: api.PeerState_SessionState(api.PeerState_SessionState_value[strings.ToUpper(string(s.SessionState))]), + AdminState: api.PeerState_AdminState(s.AdminState.ToInt()), + Messages: &api.Messages{ + Received: &api.Message{ + Notification: s.Messages.Received.Notification, + Update: s.Messages.Received.Update, + Open: s.Messages.Received.Open, + Keepalive: s.Messages.Received.Keepalive, + Refresh: s.Messages.Received.Refresh, + Discarded: s.Messages.Received.Discarded, + Total: s.Messages.Received.Total, + }, + Sent: &api.Message{ + Notification: s.Messages.Sent.Notification, + Update: s.Messages.Sent.Update, + Open: s.Messages.Sent.Open, + Keepalive: s.Messages.Sent.Keepalive, + Refresh: s.Messages.Sent.Refresh, + Discarded: s.Messages.Sent.Discarded, + Total: s.Messages.Sent.Total, + }, + }, + Received: s.AdjTable.Received, + Accepted: s.AdjTable.Accepted, + Advertised: s.AdjTable.Advertised, + PeerAs: s.PeerAs, + PeerType: uint32(s.PeerType.ToInt()), + NeighborAddress: pconf.State.NeighborAddress, + Queues: &api.Queues{}, + }, + EbgpMultihop: &api.EbgpMultihop{ + Enabled: pconf.EbgpMultihop.Config.Enabled, + MultihopTtl: uint32(pconf.EbgpMultihop.Config.MultihopTtl), + }, + Timers: &api.Timers{ + Config: &api.TimersConfig{ + ConnectRetry: uint64(timer.Config.ConnectRetry), + HoldTime: uint64(timer.Config.HoldTime), + KeepaliveInterval: uint64(timer.Config.KeepaliveInterval), + }, + State: &api.TimersState{ + KeepaliveInterval: uint64(timer.State.KeepaliveInterval), + NegotiatedHoldTime: uint64(timer.State.NegotiatedHoldTime), + Uptime: uint64(timer.State.Uptime), + Downtime: uint64(timer.State.Downtime), + }, + }, + RouteReflector: &api.RouteReflector{ + RouteReflectorClient: pconf.RouteReflector.Config.RouteReflectorClient, + RouteReflectorClusterId: string(pconf.RouteReflector.State.RouteReflectorClusterId), + }, + RouteServer: &api.RouteServer{ + RouteServerClient: pconf.RouteServer.Config.RouteServerClient, + }, + GracefulRestart: &api.GracefulRestart{ + Enabled: pconf.GracefulRestart.Config.Enabled, + RestartTime: uint32(pconf.GracefulRestart.Config.RestartTime), + HelperOnly: pconf.GracefulRestart.Config.HelperOnly, + DeferralTime: uint32(pconf.GracefulRestart.Config.DeferralTime), + NotificationEnabled: pconf.GracefulRestart.Config.NotificationEnabled, + LonglivedEnabled: pconf.GracefulRestart.Config.LongLivedEnabled, + LocalRestarting: pconf.GracefulRestart.State.LocalRestarting, + }, + Transport: &api.Transport{ + RemotePort: uint32(pconf.Transport.Config.RemotePort), + LocalAddress: localAddress, + PassiveMode: pconf.Transport.Config.PassiveMode, + }, + AfiSafis: afiSafis, + AddPaths: newAddPathsFromConfigStruct(&pconf.AddPaths), + } +} + +func NewPeerGroupFromConfigStruct(pconf *PeerGroup) *api.PeerGroup { + afiSafis := make([]*api.AfiSafi, 0, len(pconf.AfiSafis)) + for _, f := range pconf.AfiSafis { + if afiSafi := newAfiSafiFromConfigStruct(&f); afiSafi != nil { + afiSafis = append(afiSafis, afiSafi) + } + } + + timer := pconf.Timers + s := pconf.State + return &api.PeerGroup{ + ApplyPolicy: newApplyPolicyFromConfigStruct(&pconf.ApplyPolicy), + Conf: &api.PeerGroupConf{ + PeerAs: pconf.Config.PeerAs, + LocalAs: pconf.Config.LocalAs, + PeerType: uint32(pconf.Config.PeerType.ToInt()), + AuthPassword: pconf.Config.AuthPassword, + RouteFlapDamping: pconf.Config.RouteFlapDamping, + Description: pconf.Config.Description, + PeerGroupName: pconf.Config.PeerGroupName, + }, + Info: &api.PeerGroupState{ + PeerAs: s.PeerAs, + PeerType: uint32(s.PeerType.ToInt()), + TotalPaths: s.TotalPaths, + TotalPrefixes: s.TotalPrefixes, + }, + Timers: &api.Timers{ + Config: &api.TimersConfig{ + ConnectRetry: uint64(timer.Config.ConnectRetry), + HoldTime: uint64(timer.Config.HoldTime), + KeepaliveInterval: uint64(timer.Config.KeepaliveInterval), + }, + State: &api.TimersState{ + KeepaliveInterval: uint64(timer.State.KeepaliveInterval), + NegotiatedHoldTime: uint64(timer.State.NegotiatedHoldTime), + Uptime: uint64(timer.State.Uptime), + Downtime: uint64(timer.State.Downtime), + }, + }, + RouteReflector: &api.RouteReflector{ + RouteReflectorClient: pconf.RouteReflector.Config.RouteReflectorClient, + RouteReflectorClusterId: string(pconf.RouteReflector.Config.RouteReflectorClusterId), + }, + RouteServer: &api.RouteServer{ + RouteServerClient: pconf.RouteServer.Config.RouteServerClient, + }, + GracefulRestart: &api.GracefulRestart{ + Enabled: pconf.GracefulRestart.Config.Enabled, + RestartTime: uint32(pconf.GracefulRestart.Config.RestartTime), + HelperOnly: pconf.GracefulRestart.Config.HelperOnly, + DeferralTime: uint32(pconf.GracefulRestart.Config.DeferralTime), + NotificationEnabled: pconf.GracefulRestart.Config.NotificationEnabled, + LonglivedEnabled: pconf.GracefulRestart.Config.LongLivedEnabled, + LocalRestarting: pconf.GracefulRestart.State.LocalRestarting, + }, + Transport: &api.Transport{ + RemotePort: uint32(pconf.Transport.Config.RemotePort), + LocalAddress: pconf.Transport.Config.LocalAddress, + PassiveMode: pconf.Transport.Config.PassiveMode, + }, + AfiSafis: afiSafis, + AddPaths: newAddPathsFromConfigStruct(&pconf.AddPaths), + } +} + +func NewGlobalFromConfigStruct(c *Global) *api.Global { + families := make([]uint32, 0, len(c.AfiSafis)) + for _, f := range c.AfiSafis { + families = append(families, uint32(AfiSafiTypeToIntMap[f.Config.AfiSafiName])) + } + + applyPolicy := newApplyPolicyFromConfigStruct(&c.ApplyPolicy) + + return &api.Global{ + As: c.Config.As, + RouterId: c.Config.RouterId, + ListenPort: c.Config.Port, + ListenAddresses: c.Config.LocalAddressList, + Families: families, + UseMultiplePaths: c.UseMultiplePaths.Config.Enabled, + RouteSelectionOptions: &api.RouteSelectionOptionsConfig{ + AlwaysCompareMed: c.RouteSelectionOptions.Config.AlwaysCompareMed, + IgnoreAsPathLength: c.RouteSelectionOptions.Config.IgnoreAsPathLength, + ExternalCompareRouterId: c.RouteSelectionOptions.Config.ExternalCompareRouterId, + AdvertiseInactiveRoutes: c.RouteSelectionOptions.Config.AdvertiseInactiveRoutes, + EnableAigp: c.RouteSelectionOptions.Config.EnableAigp, + IgnoreNextHopIgpMetric: c.RouteSelectionOptions.Config.IgnoreNextHopIgpMetric, + DisableBestPathSelection: c.RouteSelectionOptions.Config.DisableBestPathSelection, + }, + DefaultRouteDistance: &api.DefaultRouteDistance{ + ExternalRouteDistance: uint32(c.DefaultRouteDistance.Config.ExternalRouteDistance), + InternalRouteDistance: uint32(c.DefaultRouteDistance.Config.InternalRouteDistance), + }, + Confederation: &api.Confederation{ + Enabled: c.Confederation.Config.Enabled, + Identifier: c.Confederation.Config.Identifier, + MemberAsList: c.Confederation.Config.MemberAsList, + }, + GracefulRestart: &api.GracefulRestart{ + Enabled: c.GracefulRestart.Config.Enabled, + RestartTime: uint32(c.GracefulRestart.Config.RestartTime), + StaleRoutesTime: uint32(c.GracefulRestart.Config.StaleRoutesTime), + HelperOnly: c.GracefulRestart.Config.HelperOnly, + DeferralTime: uint32(c.GracefulRestart.Config.DeferralTime), + NotificationEnabled: c.GracefulRestart.Config.NotificationEnabled, + LonglivedEnabled: c.GracefulRestart.Config.LongLivedEnabled, + }, + ApplyPolicy: applyPolicy, + } +} |