diff options
author | Satoshi Fujimoto <satoshi.fujimoto7@gmail.com> | 2018-05-31 16:49:57 +0900 |
---|---|---|
committer | Satoshi Fujimoto <satoshi.fujimoto7@gmail.com> | 2018-06-13 13:56:57 +0900 |
commit | c821cfbc8e04bb05bf0e300e52693b5085e1bfef (patch) | |
tree | 082a195fc38e678f188465ceacb1eed7951e9d17 /api/grpc_server.go | |
parent | 96034c286bdf02acac954e6860e48f1705b820ee (diff) |
api: Implement PeerGroup and DynamicNeighbor API
Signed-off-by: Satoshi Fujimoto <satoshi.fujimoto7@gmail.com>
Diffstat (limited to 'api/grpc_server.go')
-rw-r--r-- | api/grpc_server.go | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/api/grpc_server.go b/api/grpc_server.go index 8fc6e085..aab7c52c 100644 --- a/api/grpc_server.go +++ b/api/grpc_server.go @@ -349,6 +349,75 @@ func NewPeerFromConfigStruct(pconf *config.Neighbor) *Peer { } } +func NewPeerGroupFromConfigStruct(pconf *config.PeerGroup) *PeerGroup { + families := make([]uint32, 0, len(pconf.AfiSafis)) + afiSafis := make([]*AfiSafi, 0, len(pconf.AfiSafis)) + for _, f := range pconf.AfiSafis { + families = append(families, extractFamilyFromConfigAfiSafi(&f)) + if afiSafi := NewAfiSafiFromConfigStruct(&f); afiSafi != nil { + afiSafis = append(afiSafis, afiSafi) + } + } + + timer := pconf.Timers + s := pconf.State + return &PeerGroup{ + Families: families, + ApplyPolicy: NewApplyPolicyFromConfigStruct(&pconf.ApplyPolicy), + Conf: &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: &PeerGroupState{ + PeerAs: s.PeerAs, + PeerType: uint32(s.PeerType.ToInt()), + TotalPaths: s.TotalPaths, + TotalPrefixes: s.TotalPrefixes, + }, + Timers: &Timers{ + Config: &TimersConfig{ + ConnectRetry: uint64(timer.Config.ConnectRetry), + HoldTime: uint64(timer.Config.HoldTime), + KeepaliveInterval: uint64(timer.Config.KeepaliveInterval), + }, + State: &TimersState{ + KeepaliveInterval: uint64(timer.State.KeepaliveInterval), + NegotiatedHoldTime: uint64(timer.State.NegotiatedHoldTime), + Uptime: uint64(timer.State.Uptime), + Downtime: uint64(timer.State.Downtime), + }, + }, + RouteReflector: &RouteReflector{ + RouteReflectorClient: pconf.RouteReflector.Config.RouteReflectorClient, + RouteReflectorClusterId: string(pconf.RouteReflector.Config.RouteReflectorClusterId), + }, + RouteServer: &RouteServer{ + RouteServerClient: pconf.RouteServer.Config.RouteServerClient, + }, + GracefulRestart: &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: &Transport{ + RemotePort: uint32(pconf.Transport.Config.RemotePort), + LocalAddress: pconf.Transport.Config.LocalAddress, + PassiveMode: pconf.Transport.Config.PassiveMode, + }, + AfiSafis: afiSafis, + AddPaths: NewAddPathsFromConfigStruct(&pconf.AddPaths), + } +} + func (s *Server) GetNeighbor(ctx context.Context, arg *GetNeighborRequest) (*GetNeighborResponse, error) { if arg == nil { return nil, fmt.Errorf("invalid request") @@ -1345,6 +1414,112 @@ func NewNeighborFromAPIStruct(a *Peer) (*config.Neighbor, error) { return pconf, nil } +func NewPeerGroupFromAPIStruct(a *PeerGroup) (*config.PeerGroup, error) { + pconf := &config.PeerGroup{} + if a.Conf != nil { + pconf.Config.PeerAs = a.Conf.PeerAs + pconf.Config.LocalAs = a.Conf.LocalAs + pconf.Config.AuthPassword = a.Conf.AuthPassword + pconf.Config.RouteFlapDamping = a.Conf.RouteFlapDamping + pconf.Config.Description = a.Conf.Description + pconf.Config.PeerGroupName = a.Conf.PeerGroupName + + switch a.Conf.RemovePrivateAs { + case PeerGroupConf_ALL: + pconf.Config.RemovePrivateAs = config.REMOVE_PRIVATE_AS_OPTION_ALL + case PeerGroupConf_REPLACE: + pconf.Config.RemovePrivateAs = config.REMOVE_PRIVATE_AS_OPTION_REPLACE + } + + for _, af := range a.AfiSafis { + afiSafi := config.AfiSafi{} + ReadMpGracefulRestartFromAPIStruct(&afiSafi.MpGracefulRestart, af.MpGracefulRestart) + ReadAfiSafiConfigFromAPIStruct(&afiSafi.Config, af.Config) + ReadAfiSafiStateFromAPIStruct(&afiSafi.State, af.Config) + ReadApplyPolicyFromAPIStruct(&afiSafi.ApplyPolicy, af.ApplyPolicy) + ReadRouteSelectionOptionsFromAPIStruct(&afiSafi.RouteSelectionOptions, af.RouteSelectionOptions) + ReadUseMultiplePathsFromAPIStruct(&afiSafi.UseMultiplePaths, af.UseMultiplePaths) + ReadPrefixLimitFromAPIStruct(&afiSafi.PrefixLimit, af.PrefixLimits) + ReadRouteTargetMembershipFromAPIStruct(&afiSafi.RouteTargetMembership, af.RouteTargetMembership) + ReadLongLivedGracefulRestartFromAPIStruct(&afiSafi.LongLivedGracefulRestart, af.LongLivedGracefulRestart) + ReadAddPathsFromAPIStruct(&afiSafi.AddPaths, af.AddPaths) + pconf.AfiSafis = append(pconf.AfiSafis, afiSafi) + } + // For the backward compatibility, we override AfiSafi configurations + // with Peer.Families. + for _, family := range a.Families { + found := false + for _, afiSafi := range pconf.AfiSafis { + if uint32(afiSafi.State.Family) == family { + // If Peer.Families contains the same address family, + // we enable this address family. + afiSafi.Config.Enabled = true + found = true + } + } + if !found { + // If Peer.Families does not contain the same address family, + // we append AfiSafi structure with the default value. + pconf.AfiSafis = append(pconf.AfiSafis, config.AfiSafi{ + Config: config.AfiSafiConfig{ + AfiSafiName: config.AfiSafiType(bgp.RouteFamily(family).String()), + Enabled: true, + }, + }) + } + } + } + + if a.Timers != nil { + if a.Timers.Config != nil { + pconf.Timers.Config.ConnectRetry = float64(a.Timers.Config.ConnectRetry) + pconf.Timers.Config.HoldTime = float64(a.Timers.Config.HoldTime) + pconf.Timers.Config.KeepaliveInterval = float64(a.Timers.Config.KeepaliveInterval) + pconf.Timers.Config.MinimumAdvertisementInterval = float64(a.Timers.Config.MinimumAdvertisementInterval) + } + if a.Timers.State != nil { + pconf.Timers.State.KeepaliveInterval = float64(a.Timers.State.KeepaliveInterval) + pconf.Timers.State.NegotiatedHoldTime = float64(a.Timers.State.NegotiatedHoldTime) + pconf.Timers.State.Uptime = int64(a.Timers.State.Uptime) + pconf.Timers.State.Downtime = int64(a.Timers.State.Downtime) + } + } + if a.RouteReflector != nil { + pconf.RouteReflector.Config.RouteReflectorClusterId = config.RrClusterIdType(a.RouteReflector.RouteReflectorClusterId) + pconf.RouteReflector.Config.RouteReflectorClient = a.RouteReflector.RouteReflectorClient + } + if a.RouteServer != nil { + pconf.RouteServer.Config.RouteServerClient = a.RouteServer.RouteServerClient + } + if a.GracefulRestart != nil { + pconf.GracefulRestart.Config.Enabled = a.GracefulRestart.Enabled + pconf.GracefulRestart.Config.RestartTime = uint16(a.GracefulRestart.RestartTime) + pconf.GracefulRestart.Config.HelperOnly = a.GracefulRestart.HelperOnly + pconf.GracefulRestart.Config.DeferralTime = uint16(a.GracefulRestart.DeferralTime) + pconf.GracefulRestart.Config.NotificationEnabled = a.GracefulRestart.NotificationEnabled + pconf.GracefulRestart.Config.LongLivedEnabled = a.GracefulRestart.LonglivedEnabled + pconf.GracefulRestart.State.LocalRestarting = a.GracefulRestart.LocalRestarting + } + ReadApplyPolicyFromAPIStruct(&pconf.ApplyPolicy, a.ApplyPolicy) + if a.Transport != nil { + pconf.Transport.Config.LocalAddress = a.Transport.LocalAddress + pconf.Transport.Config.PassiveMode = a.Transport.PassiveMode + pconf.Transport.Config.RemotePort = uint16(a.Transport.RemotePort) + } + if a.EbgpMultihop != nil { + pconf.EbgpMultihop.Config.Enabled = a.EbgpMultihop.Enabled + pconf.EbgpMultihop.Config.MultihopTtl = uint8(a.EbgpMultihop.MultihopTtl) + } + if a.Info != nil { + pconf.State.TotalPaths = a.Info.TotalPaths + pconf.State.TotalPrefixes = a.Info.TotalPrefixes + pconf.State.PeerAs = a.Info.PeerAs + pconf.State.PeerType = config.IntToPeerTypeMap[int(a.Info.PeerType)] + } + ReadAddPathsFromAPIStruct(&pconf.AddPaths, a.AddPaths) + return pconf, nil +} + func (s *Server) AddNeighbor(ctx context.Context, arg *AddNeighborRequest) (*AddNeighborResponse, error) { c, err := NewNeighborFromAPIStruct(arg.Peer) if err != nil { @@ -1375,6 +1550,42 @@ func (s *Server) UpdateNeighbor(ctx context.Context, arg *UpdateNeighborRequest) return &UpdateNeighborResponse{NeedsSoftResetIn: needsSoftResetIn}, nil } +func (s *Server) AddPeerGroup(ctx context.Context, arg *AddPeerGroupRequest) (*AddPeerGroupResponse, error) { + c, err := NewPeerGroupFromAPIStruct(arg.PeerGroup) + if err != nil { + return nil, err + } + return &AddPeerGroupResponse{}, s.bgpServer.AddPeerGroup(c) +} + +func (s *Server) DeletePeerGroup(ctx context.Context, arg *DeletePeerGroupRequest) (*DeletePeerGroupResponse, error) { + return &DeletePeerGroupResponse{}, s.bgpServer.DeletePeerGroup(&config.PeerGroup{Config: config.PeerGroupConfig{ + PeerGroupName: arg.PeerGroup.Conf.PeerGroupName, + }}) +} + +func (s *Server) UpdatePeerGroup(ctx context.Context, arg *UpdatePeerGroupRequest) (*UpdatePeerGroupResponse, error) { + c, err := NewPeerGroupFromAPIStruct(arg.PeerGroup) + if err != nil { + return nil, err + } + needsSoftResetIn, err := s.bgpServer.UpdatePeerGroup(c) + if err != nil { + return nil, err + } + if arg.DoSoftResetIn && needsSoftResetIn { + return &UpdatePeerGroupResponse{NeedsSoftResetIn: false}, s.bgpServer.SoftResetIn("", bgp.RouteFamily(0)) + } + return &UpdatePeerGroupResponse{NeedsSoftResetIn: needsSoftResetIn}, nil +} + +func (s *Server) AddDynamicNeighbor(ctx context.Context, arg *AddDynamicNeighborRequest) (*AddDynamicNeighborResponse, error) { + return &AddDynamicNeighborResponse{}, s.bgpServer.AddDynamicNeighbor(&config.DynamicNeighbor{Config: config.DynamicNeighborConfig{ + Prefix: arg.DynamicNeighbor.Prefix, + PeerGroup: arg.DynamicNeighbor.PeerGroup, + }}) +} + func NewPrefixFromApiStruct(a *Prefix) (*table.Prefix, error) { _, prefix, err := net.ParseCIDR(a.IpPrefix) if err != nil { |