diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2018-07-06 15:49:35 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2018-07-06 23:56:54 +0900 |
commit | e4031c14a5060c4fadf7e3c655bd0f6d7714b634 (patch) | |
tree | 101986ba40d8cd3a5e2cfa8471bbc41b8bada765 /api | |
parent | 69f866a77cb83db8925fb95fb55d6086fbfe899c (diff) |
api: decrease the dependency
move grpc_server.go to server/
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'api')
-rw-r--r-- | api/grpc_server.go | 2997 | ||||
-rw-r--r-- | api/util.go | 20 |
2 files changed, 0 insertions, 3017 deletions
diff --git a/api/grpc_server.go b/api/grpc_server.go deleted file mode 100644 index f6f5913f..00000000 --- a/api/grpc_server.go +++ /dev/null @@ -1,2997 +0,0 @@ -// Copyright (C) 2014-2016 Nippon Telegraph and Telephone Corporation. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package gobgpapi - -import ( - "bytes" - "fmt" - "io" - "net" - "reflect" - "regexp" - "strconv" - "strings" - "sync" - "time" - - farm "github.com/dgryski/go-farm" - "github.com/golang/protobuf/ptypes/any" - log "github.com/sirupsen/logrus" - "golang.org/x/net/context" - "google.golang.org/grpc" - - "github.com/osrg/gobgp/config" - "github.com/osrg/gobgp/packet/bgp" - "github.com/osrg/gobgp/server" - "github.com/osrg/gobgp/table" - "github.com/osrg/gobgp/zebra" -) - -type Server struct { - bgpServer *server.BgpServer - grpcServer *grpc.Server - hosts string -} - -func NewGrpcServer(b *server.BgpServer, hosts string) *Server { - size := 256 << 20 - return NewServer(b, grpc.NewServer(grpc.MaxRecvMsgSize(size), grpc.MaxSendMsgSize(size)), hosts) -} - -func NewServer(b *server.BgpServer, g *grpc.Server, hosts string) *Server { - grpc.EnableTracing = false - s := &Server{ - bgpServer: b, - grpcServer: g, - hosts: hosts, - } - RegisterGobgpApiServer(g, s) - return s -} - -func (s *Server) Serve() error { - var wg sync.WaitGroup - l := strings.Split(s.hosts, ",") - wg.Add(len(l)) - - serve := func(host string) { - defer wg.Done() - lis, err := net.Listen("tcp", host) - if err != nil { - log.WithFields(log.Fields{ - "Topic": "grpc", - "Key": host, - "Error": err, - }).Warn("listen failed") - return - } - err = s.grpcServer.Serve(lis) - log.WithFields(log.Fields{ - "Topic": "grpc", - "Key": host, - "Error": err, - }).Warn("accept failed") - } - - for _, host := range l { - go serve(host) - } - wg.Wait() - return nil -} - -func NewMpGracefulRestartFromConfigStruct(c *config.MpGracefulRestart) *MpGracefulRestart { - return &MpGracefulRestart{ - Config: &MpGracefulRestartConfig{ - Enabled: c.Config.Enabled, - }, - } -} - -func NewAfiSafiConfigFromConfigStruct(c *config.AfiSafi) *AfiSafiConfig { - return &AfiSafiConfig{ - Family: extractFamilyFromConfigAfiSafi(c), - Enabled: c.Config.Enabled, - } -} - -func NewApplyPolicyFromConfigStruct(c *config.ApplyPolicy) *ApplyPolicy { - applyPolicy := &ApplyPolicy{ - ImportPolicy: &PolicyAssignment{ - Type: PolicyType_IMPORT, - Default: RouteAction(c.Config.DefaultImportPolicy.ToInt()), - }, - ExportPolicy: &PolicyAssignment{ - Type: PolicyType_EXPORT, - Default: RouteAction(c.Config.DefaultExportPolicy.ToInt()), - }, - InPolicy: &PolicyAssignment{ - Type: PolicyType_IN, - Default: RouteAction(c.Config.DefaultInPolicy.ToInt()), - }, - } - - for _, pname := range c.Config.ImportPolicyList { - applyPolicy.ImportPolicy.Policies = append(applyPolicy.ImportPolicy.Policies, &Policy{Name: pname}) - } - for _, pname := range c.Config.ExportPolicyList { - applyPolicy.ExportPolicy.Policies = append(applyPolicy.ExportPolicy.Policies, &Policy{Name: pname}) - } - for _, pname := range c.Config.InPolicyList { - applyPolicy.InPolicy.Policies = append(applyPolicy.InPolicy.Policies, &Policy{Name: pname}) - } - - return applyPolicy -} - -func NewRouteSelectionOptionsFromConfigStruct(c *config.RouteSelectionOptions) *RouteSelectionOptions { - return &RouteSelectionOptions{ - Config: &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 NewUseMultiplePathsFromConfigStruct(c *config.UseMultiplePaths) *UseMultiplePaths { - return &UseMultiplePaths{ - Config: &UseMultiplePathsConfig{ - Enabled: c.Config.Enabled, - }, - Ebgp: &Ebgp{ - Config: &EbgpConfig{ - AllowMultipleAs: c.Ebgp.Config.AllowMultipleAs, - MaximumPaths: c.Ebgp.Config.MaximumPaths, - }, - }, - Ibgp: &Ibgp{ - Config: &IbgpConfig{ - MaximumPaths: c.Ibgp.Config.MaximumPaths, - }, - }, - } -} - -func NewPrefixLimitFromConfigStruct(c *config.AfiSafi) *PrefixLimit { - if c.PrefixLimit.Config.MaxPrefixes == 0 { - return nil - } - - return &PrefixLimit{ - Family: uint32(c.State.Family), - MaxPrefixes: c.PrefixLimit.Config.MaxPrefixes, - ShutdownThresholdPct: uint32(c.PrefixLimit.Config.ShutdownThresholdPct), - } -} - -func NewRouteTargetMembershipFromConfigStruct(c *config.RouteTargetMembership) *RouteTargetMembership { - return &RouteTargetMembership{ - Config: &RouteTargetMembershipConfig{ - DeferralTime: uint32(c.Config.DeferralTime), - }, - } -} - -func NewLongLivedGracefulRestartFromConfigStruct(c *config.LongLivedGracefulRestart) *LongLivedGracefulRestart { - return &LongLivedGracefulRestart{ - Config: &LongLivedGracefulRestartConfig{ - Enabled: c.Config.Enabled, - RestartTime: c.Config.RestartTime, - }, - } -} - -func NewAddPathsFromConfigStruct(c *config.AddPaths) *AddPaths { - return &AddPaths{ - Config: &AddPathsConfig{ - Receive: c.Config.Receive, - SendMax: uint32(c.Config.SendMax), - }, - } -} - -func NewAfiSafiFromConfigStruct(c *config.AfiSafi) *AfiSafi { - return &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 *config.Neighbor) *Peer { - families := make([]uint32, 0, len(pconf.AfiSafis)) - prefixLimits := make([]*PrefixLimit, 0, len(pconf.AfiSafis)) - afiSafis := make([]*AfiSafi, 0, len(pconf.AfiSafis)) - for _, f := range pconf.AfiSafis { - families = append(families, extractFamilyFromConfigAfiSafi(&f)) - if prefixLimit := NewPrefixLimitFromConfigStruct(&f); prefixLimit != nil { - prefixLimits = append(prefixLimits, prefixLimit) - } - 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 := MarshalCapabilities(pconf.State.RemoteCapabilityList) - if err != nil { - return nil - } - localCap, err := MarshalCapabilities(pconf.State.LocalCapabilityList) - if err != nil { - return nil - } - var removePrivateAs PeerConf_RemovePrivateAs - switch pconf.Config.RemovePrivateAs { - case config.REMOVE_PRIVATE_AS_OPTION_ALL: - removePrivateAs = PeerConf_ALL - case config.REMOVE_PRIVATE_AS_OPTION_REPLACE: - removePrivateAs = PeerConf_REPLACE - } - return &Peer{ - Families: families, - ApplyPolicy: NewApplyPolicyFromConfigStruct(&pconf.ApplyPolicy), - Conf: &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, - PrefixLimits: prefixLimits, - LocalAddress: localAddress, - NeighborInterface: pconf.Config.NeighborInterface, - Vrf: pconf.Config.Vrf, - AllowOwnAs: uint32(pconf.AsPathOptions.Config.AllowOwnAs), - RemovePrivateAs: removePrivateAs, - ReplacePeerAs: pconf.AsPathOptions.Config.ReplacePeerAs, - }, - Info: &PeerState{ - BgpState: string(s.SessionState), - AdminState: PeerState_AdminState(s.AdminState.ToInt()), - Messages: &Messages{ - Received: &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: &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, - }, - 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.State.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 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") - } - neighbors := s.bgpServer.GetNeighbor(arg.Address, arg.EnableAdvertised) - peers := make([]*Peer, 0, len(neighbors)) - for _, e := range neighbors { - peers = append(peers, NewPeerFromConfigStruct(e)) - } - return &GetNeighborResponse{Peers: peers}, nil -} - -func NewValidationFromTableStruct(v *table.Validation) *RPKIValidation { - if v == nil { - return &RPKIValidation{} - } - return &RPKIValidation{ - Reason: RPKIValidation_Reason(v.Reason.ToInt()), - Matched: NewRoaListFromTableStructList(v.Matched), - UnmatchedAs: NewRoaListFromTableStructList(v.UnmatchedAs), - UnmatchedLength: NewRoaListFromTableStructList(v.UnmatchedLength), - } -} - -func toPathAPI(binNlri []byte, binPattrs [][]byte, anyNlri *any.Any, anyPattrs []*any.Any, path *table.Path, v *table.Validation) *Path { - nlri := path.GetNlri() - family := uint32(path.GetRouteFamily()) - vv := config.RPKI_VALIDATION_RESULT_TYPE_NONE.ToInt() - if v != nil { - vv = v.Status.ToInt() - } - p := &Path{ - Nlri: binNlri, - Pattrs: binPattrs, - Age: path.GetTimestamp().Unix(), - IsWithdraw: path.IsWithdraw, - Validation: int32(vv), - ValidationDetail: NewValidationFromTableStruct(v), - Family: family, - Stale: path.IsStale(), - IsFromExternal: path.IsFromExternal(), - NoImplicitWithdraw: path.NoImplicitWithdraw(), - IsNexthopInvalid: path.IsNexthopInvalid, - Identifier: nlri.PathIdentifier(), - LocalIdentifier: nlri.PathLocalIdentifier(), - AnyNlri: anyNlri, - AnyPattrs: anyPattrs, - } - if s := path.GetSource(); s != nil { - p.SourceAsn = s.AS - p.SourceId = s.ID.String() - p.NeighborIp = s.Address.String() - } - return p -} - -func ToPathApi(path *table.Path, v *table.Validation) *Path { - nlri := path.GetNlri() - anyNlri := MarshalNLRI(nlri) - if path.IsWithdraw { - return toPathAPI(nil, nil, anyNlri, nil, path, v) - } - anyPattrs := MarshalPathAttributes(path.GetPathAttrs()) - return toPathAPI(nil, nil, anyNlri, anyPattrs, path, v) -} - -func getValidation(v []*table.Validation, i int) *table.Validation { - if v == nil { - return nil - } else { - return v[i] - } -} - -func (s *Server) GetRib(ctx context.Context, arg *GetRibRequest) (*GetRibResponse, error) { - if arg == nil || arg.Table == nil { - return nil, fmt.Errorf("invalid request") - } - f := func() []*table.LookupPrefix { - l := make([]*table.LookupPrefix, 0, len(arg.Table.Destinations)) - for _, p := range arg.Table.Destinations { - l = append(l, &table.LookupPrefix{ - Prefix: p.Prefix, - LookupOption: func() table.LookupOption { - if p.LongerPrefixes { - return table.LOOKUP_LONGER - } else if p.ShorterPrefixes { - return table.LOOKUP_SHORTER - } - return table.LOOKUP_EXACT - }(), - }) - } - return l - } - - var in bool - var err error - var tbl *table.Table - var v []*table.Validation - - family := bgp.RouteFamily(arg.Table.Family) - switch arg.Table.Type { - case Resource_LOCAL, Resource_GLOBAL: - tbl, v, err = s.bgpServer.GetRib(arg.Table.Name, family, f()) - case Resource_ADJ_IN: - in = true - fallthrough - case Resource_ADJ_OUT: - tbl, v, err = s.bgpServer.GetAdjRib(arg.Table.Name, family, in, f()) - case Resource_VRF: - tbl, err = s.bgpServer.GetVrfRib(arg.Table.Name, family, []*table.LookupPrefix{}) - default: - return nil, fmt.Errorf("unsupported resource type: %v", arg.Table.Type) - } - - if err != nil { - return nil, err - } - - tblDsts := tbl.GetDestinations() - dsts := make([]*Destination, 0, len(tblDsts)) - idx := 0 - for _, dst := range tblDsts { - dsts = append(dsts, &Destination{ - Prefix: dst.GetNlri().String(), - Paths: func(paths []*table.Path) []*Path { - l := make([]*Path, 0, len(paths)) - for i, p := range paths { - pp := ToPathApi(p, getValidation(v, idx)) - idx++ - switch arg.Table.Type { - case Resource_LOCAL, Resource_GLOBAL: - if i == 0 && !table.SelectionOptions.DisableBestPathSelection { - pp.Best = true - } - } - l = append(l, pp) - } - return l - }(dst.GetAllKnownPathList()), - }) - } - - return &GetRibResponse{Table: &Table{ - Type: arg.Table.Type, - Family: uint32(tbl.GetRoutefamily()), - Destinations: dsts}, - }, err -} - -func (s *Server) GetPath(arg *GetPathRequest, stream GobgpApi_GetPathServer) error { - f := func() []*table.LookupPrefix { - l := make([]*table.LookupPrefix, 0, len(arg.Prefixes)) - for _, p := range arg.Prefixes { - l = append(l, &table.LookupPrefix{ - Prefix: p.Prefix, - LookupOption: table.LookupOption(p.LookupOption), - }) - } - return l - } - - in := false - family := bgp.RouteFamily(arg.Family) - var tbl *table.Table - var err error - var v []*table.Validation - switch arg.Type { - case Resource_LOCAL, Resource_GLOBAL: - tbl, v, err = s.bgpServer.GetRib(arg.Name, family, f()) - case Resource_ADJ_IN: - in = true - fallthrough - case Resource_ADJ_OUT: - tbl, v, err = s.bgpServer.GetAdjRib(arg.Name, family, in, f()) - case Resource_VRF: - tbl, err = s.bgpServer.GetVrfRib(arg.Name, family, []*table.LookupPrefix{}) - default: - return fmt.Errorf("unsupported resource type: %v", arg.Type) - } - if err != nil { - return err - } - - idx := 0 - return func() error { - for _, dst := range tbl.GetDestinations() { - for i, path := range dst.GetAllKnownPathList() { - p := ToPathApi(path, getValidation(v, idx)) - idx++ - if i == 0 && !table.SelectionOptions.DisableBestPathSelection { - switch arg.Type { - case Resource_LOCAL, Resource_GLOBAL: - p.Best = true - } - } - if err := stream.Send(p); err != nil { - return err - } - } - } - return nil - }() -} - -func (s *Server) MonitorRib(arg *MonitorRibRequest, stream GobgpApi_MonitorRibServer) error { - if arg == nil || arg.Table == nil { - return fmt.Errorf("invalid request") - } - t := arg.Table - w, err := func() (*server.Watcher, error) { - switch t.Type { - case Resource_GLOBAL: - return s.bgpServer.Watch(server.WatchBestPath(arg.Current)), nil - case Resource_ADJ_IN: - if t.PostPolicy { - return s.bgpServer.Watch(server.WatchPostUpdate(arg.Current)), nil - } - return s.bgpServer.Watch(server.WatchUpdate(arg.Current)), nil - default: - return nil, fmt.Errorf("unsupported resource type: %v", t.Type) - } - }() - if err != nil { - return nil - } - - return func() error { - defer func() { w.Stop() }() - - sendPath := func(pathList []*table.Path) error { - dsts := make(map[string]*Destination) - for _, path := range pathList { - if path == nil || (t.Family != 0 && bgp.RouteFamily(t.Family) != path.GetRouteFamily()) { - continue - } - if dst, y := dsts[path.GetNlri().String()]; y { - dst.Paths = append(dst.Paths, ToPathApi(path, nil)) - } else { - dsts[path.GetNlri().String()] = &Destination{ - Prefix: path.GetNlri().String(), - Paths: []*Path{ToPathApi(path, nil)}, - } - } - } - for _, dst := range dsts { - if err := stream.Send(dst); err != nil { - return err - } - } - return nil - } - - for ev := range w.Event() { - switch msg := ev.(type) { - case *server.WatchEventBestPath: - if err := sendPath(func() []*table.Path { - if len(msg.MultiPathList) > 0 { - l := make([]*table.Path, 0) - for _, p := range msg.MultiPathList { - l = append(l, p...) - } - return l - } else { - return msg.PathList - } - }()); err != nil { - return err - } - case *server.WatchEventUpdate: - if err := sendPath(msg.PathList); err != nil { - return err - } - } - } - return nil - }() -} - -func (s *Server) MonitorPeerState(arg *Arguments, stream GobgpApi_MonitorPeerStateServer) error { - if arg == nil { - return fmt.Errorf("invalid request") - } - return func() error { - w := s.bgpServer.Watch(server.WatchPeerState(arg.Current)) - defer func() { w.Stop() }() - - for ev := range w.Event() { - switch msg := ev.(type) { - case *server.WatchEventPeerState: - if len(arg.Name) > 0 && arg.Name != msg.PeerAddress.String() && arg.Name != msg.PeerInterface { - continue - } - if err := stream.Send(&Peer{ - Conf: &PeerConf{ - PeerAs: msg.PeerAS, - LocalAs: msg.LocalAS, - NeighborAddress: msg.PeerAddress.String(), - Id: msg.PeerID.String(), - NeighborInterface: msg.PeerInterface, - }, - Info: &PeerState{ - PeerAs: msg.PeerAS, - LocalAs: msg.LocalAS, - NeighborAddress: msg.PeerAddress.String(), - BgpState: msg.State.String(), - AdminState: PeerState_AdminState(msg.AdminState), - }, - Transport: &Transport{ - LocalAddress: msg.LocalAddress.String(), - LocalPort: uint32(msg.LocalPort), - RemotePort: uint32(msg.PeerPort), - }, - }); err != nil { - return err - } - } - } - return nil - }() -} - -func (s *Server) ResetNeighbor(ctx context.Context, arg *ResetNeighborRequest) (*ResetNeighborResponse, error) { - return &ResetNeighborResponse{}, s.bgpServer.ResetNeighbor(arg.Address, arg.Communication) -} - -func (s *Server) SoftResetNeighbor(ctx context.Context, arg *SoftResetNeighborRequest) (*SoftResetNeighborResponse, error) { - var err error - addr := arg.Address - if addr == "all" { - addr = "" - } - family := bgp.RouteFamily(0) - switch arg.Direction { - case SoftResetNeighborRequest_IN: - err = s.bgpServer.SoftResetIn(addr, family) - case SoftResetNeighborRequest_OUT: - err = s.bgpServer.SoftResetOut(addr, family) - default: - err = s.bgpServer.SoftReset(addr, family) - } - return &SoftResetNeighborResponse{}, err -} - -func (s *Server) ShutdownNeighbor(ctx context.Context, arg *ShutdownNeighborRequest) (*ShutdownNeighborResponse, error) { - return &ShutdownNeighborResponse{}, s.bgpServer.ShutdownNeighbor(arg.Address, arg.Communication) -} - -func (s *Server) EnableNeighbor(ctx context.Context, arg *EnableNeighborRequest) (*EnableNeighborResponse, error) { - return &EnableNeighborResponse{}, s.bgpServer.EnableNeighbor(arg.Address) -} - -func (s *Server) DisableNeighbor(ctx context.Context, arg *DisableNeighborRequest) (*DisableNeighborResponse, error) { - return &DisableNeighborResponse{}, s.bgpServer.DisableNeighbor(arg.Address, arg.Communication) -} - -func (s *Server) UpdatePolicy(ctx context.Context, arg *UpdatePolicyRequest) (*UpdatePolicyResponse, error) { - rp, err := NewRoutingPolicyFromApiStruct(arg) - if err != nil { - return nil, err - } - return &UpdatePolicyResponse{}, s.bgpServer.UpdatePolicy(*rp) -} - -func NewAPIRoutingPolicyFromConfigStruct(c *config.RoutingPolicy) (*RoutingPolicy, error) { - definedSets, err := NewAPIDefinedSetsFromConfigStruct(&c.DefinedSets) - if err != nil { - return nil, err - } - policies := make([]*Policy, 0, len(c.PolicyDefinitions)) - for _, policy := range c.PolicyDefinitions { - policies = append(policies, toPolicyApi(&policy)) - } - - return &RoutingPolicy{ - DefinedSet: definedSets, - PolicyDefinition: policies, - }, nil -} - -func NewRoutingPolicyFromApiStruct(arg *UpdatePolicyRequest) (*config.RoutingPolicy, error) { - policyDefinitions := make([]config.PolicyDefinition, 0, len(arg.Policies)) - for _, p := range arg.Policies { - pd, err := NewConfigPolicyFromApiStruct(p) - if err != nil { - return nil, err - } - policyDefinitions = append(policyDefinitions, *pd) - } - - definedSets, err := NewConfigDefinedSetsFromApiStruct(arg.Sets) - if err != nil { - return nil, err - } - - return &config.RoutingPolicy{ - DefinedSets: *definedSets, - PolicyDefinitions: policyDefinitions, - }, nil -} - -func (s *Server) api2PathList(resource Resource, ApiPathList []*Path) ([]*table.Path, error) { - var pi *table.PeerInfo - - pathList := make([]*table.Path, 0, len(ApiPathList)) - for _, path := range ApiPathList { - var nlri bgp.AddrPrefixInterface - var nexthop string - - if path.SourceAsn != 0 { - pi = &table.PeerInfo{ - AS: path.SourceAsn, - LocalID: net.ParseIP(path.SourceId), - } - } - - nlri, err := path.GetNativeNlri() - if err != nil { - return nil, err - } - nlri.SetPathIdentifier(path.Identifier) - - attrList, err := path.GetNativePathAttributes() - if err != nil { - return nil, err - } - - pattrs := make([]bgp.PathAttributeInterface, 0) - seen := make(map[bgp.BGPAttrType]struct{}) - for _, attr := range attrList { - attrType := attr.GetType() - if _, ok := seen[attrType]; !ok { - seen[attrType] = struct{}{} - } else { - return nil, fmt.Errorf("duplicated path attribute type: %d", attrType) - } - - switch a := attr.(type) { - case *bgp.PathAttributeNextHop: - nexthop = a.Value.String() - case *bgp.PathAttributeMpReachNLRI: - nlri = a.Value[0] - nexthop = a.Nexthop.String() - default: - pattrs = append(pattrs, attr) - } - } - - if nlri == nil { - return nil, fmt.Errorf("nlri not found") - } else if !path.IsWithdraw && nexthop == "" { - return nil, fmt.Errorf("nexthop not found") - } - - if resource != Resource_VRF && bgp.RouteFamily(path.Family) == bgp.RF_IPv4_UC && net.ParseIP(nexthop).To4() != nil { - pattrs = append(pattrs, bgp.NewPathAttributeNextHop(nexthop)) - } else { - pattrs = append(pattrs, bgp.NewPathAttributeMpReachNLRI(nexthop, []bgp.AddrPrefixInterface{nlri})) - } - - newPath := table.NewPath(pi, nlri, path.IsWithdraw, pattrs, time.Now(), path.NoImplicitWithdraw) - if !path.IsWithdraw { - total := bytes.NewBuffer(make([]byte, 0)) - for _, a := range newPath.GetPathAttrs() { - if a.GetType() == bgp.BGP_ATTR_TYPE_MP_REACH_NLRI { - continue - } - b, _ := a.Serialize() - total.Write(b) - } - newPath.SetHash(farm.Hash32(total.Bytes())) - } - newPath.SetIsFromExternal(path.IsFromExternal) - pathList = append(pathList, newPath) - } - return pathList, nil -} - -func (s *Server) AddPath(ctx context.Context, arg *AddPathRequest) (*AddPathResponse, error) { - pathList, err := s.api2PathList(arg.Resource, []*Path{arg.Path}) - var uuid []byte - if err == nil { - uuid, err = s.bgpServer.AddPath(arg.VrfId, pathList) - } - return &AddPathResponse{Uuid: uuid}, err -} - -func (s *Server) DeletePath(ctx context.Context, arg *DeletePathRequest) (*DeletePathResponse, error) { - pathList, err := func() ([]*table.Path, error) { - if arg.Path != nil { - arg.Path.IsWithdraw = true - return s.api2PathList(arg.Resource, []*Path{arg.Path}) - } - return []*table.Path{}, nil - }() - if err != nil { - return nil, err - } - return &DeletePathResponse{}, s.bgpServer.DeletePath(arg.Uuid, bgp.RouteFamily(arg.Family), arg.VrfId, pathList) -} - -func (s *Server) EnableMrt(ctx context.Context, arg *EnableMrtRequest) (*EnableMrtResponse, error) { - return &EnableMrtResponse{}, s.bgpServer.EnableMrt(&config.MrtConfig{ - RotationInterval: arg.Interval, - DumpType: config.IntToMrtTypeMap[int(arg.DumpType)], - FileName: arg.Filename, - }) -} - -func (s *Server) DisableMrt(ctx context.Context, arg *DisableMrtRequest) (*DisableMrtResponse, error) { - return &DisableMrtResponse{}, s.bgpServer.DisableMrt(&config.MrtConfig{}) -} - -func (s *Server) InjectMrt(stream GobgpApi_InjectMrtServer) error { - for { - arg, err := stream.Recv() - - if err == io.EOF { - break - } else if err != nil { - return err - } - - if arg.Resource != Resource_GLOBAL && arg.Resource != Resource_VRF { - return fmt.Errorf("unsupported resource: %s", arg.Resource) - } - - if pathList, err := s.api2PathList(arg.Resource, arg.Paths); err != nil { - return err - } else { - if _, err = s.bgpServer.AddPath("", pathList); err != nil { - return err - } - } - } - return stream.SendAndClose(&InjectMrtResponse{}) -} - -func (s *Server) AddBmp(ctx context.Context, arg *AddBmpRequest) (*AddBmpResponse, error) { - t, ok := config.IntToBmpRouteMonitoringPolicyTypeMap[int(arg.Type)] - if !ok { - return nil, fmt.Errorf("invalid bmp route monitoring policy: %d", arg.Type) - } - return &AddBmpResponse{}, s.bgpServer.AddBmp(&config.BmpServerConfig{ - Address: arg.Address, - Port: arg.Port, - RouteMonitoringPolicy: t, - }) -} - -func (s *Server) DeleteBmp(ctx context.Context, arg *DeleteBmpRequest) (*DeleteBmpResponse, error) { - return &DeleteBmpResponse{}, s.bgpServer.DeleteBmp(&config.BmpServerConfig{ - Address: arg.Address, - Port: arg.Port, - }) -} - -func (s *Server) ValidateRib(ctx context.Context, arg *ValidateRibRequest) (*ValidateRibResponse, error) { - return &ValidateRibResponse{}, nil -} - -func (s *Server) AddRpki(ctx context.Context, arg *AddRpkiRequest) (*AddRpkiResponse, error) { - return &AddRpkiResponse{}, s.bgpServer.AddRpki(&config.RpkiServerConfig{ - Address: arg.Address, - Port: arg.Port, - RecordLifetime: arg.Lifetime, - }) -} - -func (s *Server) DeleteRpki(ctx context.Context, arg *DeleteRpkiRequest) (*DeleteRpkiResponse, error) { - return &DeleteRpkiResponse{}, s.bgpServer.DeleteRpki(&config.RpkiServerConfig{ - Address: arg.Address, - Port: arg.Port, - }) -} - -func (s *Server) EnableRpki(ctx context.Context, arg *EnableRpkiRequest) (*EnableRpkiResponse, error) { - return &EnableRpkiResponse{}, s.bgpServer.EnableRpki(&config.RpkiServerConfig{ - Address: arg.Address, - }) -} - -func (s *Server) DisableRpki(ctx context.Context, arg *DisableRpkiRequest) (*DisableRpkiResponse, error) { - return &DisableRpkiResponse{}, s.bgpServer.DisableRpki(&config.RpkiServerConfig{ - Address: arg.Address, - }) -} - -func (s *Server) ResetRpki(ctx context.Context, arg *ResetRpkiRequest) (*ResetRpkiResponse, error) { - return &ResetRpkiResponse{}, s.bgpServer.ResetRpki(&config.RpkiServerConfig{ - Address: arg.Address, - }) -} - -func (s *Server) SoftResetRpki(ctx context.Context, arg *SoftResetRpkiRequest) (*SoftResetRpkiResponse, error) { - return &SoftResetRpkiResponse{}, s.bgpServer.SoftResetRpki(&config.RpkiServerConfig{ - Address: arg.Address, - }) -} - -func (s *Server) GetRpki(ctx context.Context, arg *GetRpkiRequest) (*GetRpkiResponse, error) { - servers, err := s.bgpServer.GetRpki() - if err != nil { - return nil, err - } - l := make([]*Rpki, 0, len(servers)) - for _, s := range servers { - received := &s.State.RpkiMessages.RpkiReceived - sent := &s.State.RpkiMessages.RpkiSent - rpki := &Rpki{ - Conf: &RPKIConf{ - Address: s.Config.Address, - RemotePort: strconv.Itoa(int(s.Config.Port)), - }, - State: &RPKIState{ - Uptime: s.State.Uptime, - Downtime: s.State.Downtime, - Up: s.State.Up, - RecordIpv4: s.State.RecordsV4, - RecordIpv6: s.State.RecordsV6, - PrefixIpv4: s.State.PrefixesV4, - PrefixIpv6: s.State.PrefixesV6, - Serial: s.State.SerialNumber, - ReceivedIpv4: received.Ipv4Prefix, - ReceivedIpv6: received.Ipv6Prefix, - SerialNotify: received.SerialNotify, - CacheReset: received.CacheReset, - CacheResponse: received.CacheResponse, - EndOfData: received.EndOfData, - Error: received.Error, - SerialQuery: sent.SerialQuery, - ResetQuery: sent.ResetQuery, - }, - } - l = append(l, rpki) - } - return &GetRpkiResponse{Servers: l}, nil -} - -func (s *Server) GetRoa(ctx context.Context, arg *GetRoaRequest) (*GetRoaResponse, error) { - roas, err := s.bgpServer.GetRoa(bgp.RouteFamily(arg.Family)) - if err != nil { - return nil, err - } - return &GetRoaResponse{Roas: NewRoaListFromTableStructList(roas)}, nil -} - -func (s *Server) EnableZebra(ctx context.Context, arg *EnableZebraRequest) (*EnableZebraResponse, error) { - for _, p := range arg.RouteTypes { - if _, err := zebra.RouteTypeFromString(p); err != nil { - return &EnableZebraResponse{}, err - } - } - return &EnableZebraResponse{}, s.bgpServer.StartZebraClient(&config.ZebraConfig{ - Url: arg.Url, - RedistributeRouteTypeList: arg.RouteTypes, - Version: uint8(arg.Version), - NexthopTriggerEnable: arg.NexthopTriggerEnable, - NexthopTriggerDelay: uint8(arg.NexthopTriggerDelay), - }) -} - -func (s *Server) GetVrf(ctx context.Context, arg *GetVrfRequest) (*GetVrfResponse, error) { - toApi := func(v *table.Vrf) *Vrf { - return &Vrf{ - Name: v.Name, - Rd: MarshalRD(v.Rd), - Id: v.Id, - ImportRt: MarshalRTs(v.ImportRt), - ExportRt: MarshalRTs(v.ExportRt), - } - } - vrfs := s.bgpServer.GetVrf() - l := make([]*Vrf, 0, len(vrfs)) - for _, v := range vrfs { - l = append(l, toApi(v)) - } - return &GetVrfResponse{Vrfs: l}, nil -} - -func (s *Server) AddVrf(ctx context.Context, arg *AddVrfRequest) (r *AddVrfResponse, err error) { - if arg == nil || arg.Vrf == nil { - return nil, fmt.Errorf("invalid request") - } - rd, err := UnmarshalRD(arg.Vrf.Rd) - if err != nil { - return nil, err - } - im, err := UnmarshalRTs(arg.Vrf.ImportRt) - if err != nil { - return nil, err - } - ex, err := UnmarshalRTs(arg.Vrf.ExportRt) - if err != nil { - return nil, err - } - return &AddVrfResponse{}, s.bgpServer.AddVrf(arg.Vrf.Name, arg.Vrf.Id, rd, im, ex) -} - -func (s *Server) DeleteVrf(ctx context.Context, arg *DeleteVrfRequest) (*DeleteVrfResponse, error) { - if arg == nil || arg.Vrf == nil { - return nil, fmt.Errorf("invalid request") - } - return &DeleteVrfResponse{}, s.bgpServer.DeleteVrf(arg.Vrf.Name) -} - -func ReadMpGracefulRestartFromAPIStruct(c *config.MpGracefulRestart, a *MpGracefulRestart) { - if c == nil || a == nil { - return - } - if a.Config != nil { - c.Config.Enabled = a.Config.Enabled - } -} - -func ReadAfiSafiConfigFromAPIStruct(c *config.AfiSafiConfig, a *AfiSafiConfig) { - if c == nil || a == nil { - return - } - c.AfiSafiName = config.AfiSafiType(bgp.RouteFamily(a.Family).String()) - c.Enabled = a.Enabled -} - -func ReadAfiSafiStateFromAPIStruct(s *config.AfiSafiState, a *AfiSafiConfig) { - if s == nil || a == nil { - return - } - // Store only address family value for the convenience - s.Family = bgp.RouteFamily(a.Family) -} - -func ReadPrefixLimitFromAPIStruct(c *config.PrefixLimit, a *PrefixLimit) { - if c == nil || a == nil { - return - } - c.Config.MaxPrefixes = a.MaxPrefixes - c.Config.ShutdownThresholdPct = config.Percentage(a.ShutdownThresholdPct) -} - -func ReadApplyPolicyFromAPIStruct(c *config.ApplyPolicy, a *ApplyPolicy) { - if c == nil || a == nil { - return - } - if a.ImportPolicy != nil { - c.Config.DefaultImportPolicy = config.IntToDefaultPolicyTypeMap[int(a.ImportPolicy.Default)] - for _, p := range a.ImportPolicy.Policies { - c.Config.ImportPolicyList = append(c.Config.ImportPolicyList, p.Name) - } - } - if a.ExportPolicy != nil { - c.Config.DefaultExportPolicy = config.IntToDefaultPolicyTypeMap[int(a.ExportPolicy.Default)] - for _, p := range a.ExportPolicy.Policies { - c.Config.ExportPolicyList = append(c.Config.ExportPolicyList, p.Name) - } - } - if a.InPolicy != nil { - c.Config.DefaultInPolicy = config.IntToDefaultPolicyTypeMap[int(a.InPolicy.Default)] - for _, p := range a.InPolicy.Policies { - c.Config.InPolicyList = append(c.Config.InPolicyList, p.Name) - } - } -} - -func ReadRouteSelectionOptionsFromAPIStruct(c *config.RouteSelectionOptions, a *RouteSelectionOptions) { - if c == nil || a == nil { - return - } - if a.Config != nil { - c.Config.AlwaysCompareMed = a.Config.AlwaysCompareMed - c.Config.IgnoreAsPathLength = a.Config.IgnoreAsPathLength - c.Config.ExternalCompareRouterId = a.Config.ExternalCompareRouterId - c.Config.AdvertiseInactiveRoutes = a.Config.AdvertiseInactiveRoutes - c.Config.EnableAigp = a.Config.EnableAigp - c.Config.IgnoreNextHopIgpMetric = a.Config.IgnoreNextHopIgpMetric - } -} - -func ReadUseMultiplePathsFromAPIStruct(c *config.UseMultiplePaths, a *UseMultiplePaths) { - if c == nil || a == nil { - return - } - if a.Config != nil { - c.Config.Enabled = a.Config.Enabled - } - if a.Ebgp != nil && a.Ebgp.Config != nil { - c.Ebgp = config.Ebgp{ - Config: config.EbgpConfig{ - AllowMultipleAs: a.Ebgp.Config.AllowMultipleAs, - MaximumPaths: a.Ebgp.Config.MaximumPaths, - }, - } - } - if a.Ibgp != nil && a.Ibgp.Config != nil { - c.Ibgp = config.Ibgp{ - Config: config.IbgpConfig{ - MaximumPaths: a.Ibgp.Config.MaximumPaths, - }, - } - } -} - -func ReadRouteTargetMembershipFromAPIStruct(c *config.RouteTargetMembership, a *RouteTargetMembership) { - if c == nil || a == nil { - return - } - if a.Config != nil { - c.Config.DeferralTime = uint16(a.Config.DeferralTime) - } -} - -func ReadLongLivedGracefulRestartFromAPIStruct(c *config.LongLivedGracefulRestart, a *LongLivedGracefulRestart) { - if c == nil || a == nil { - return - } - if a.Config != nil { - c.Config.Enabled = a.Config.Enabled - c.Config.RestartTime = a.Config.RestartTime - } -} - -func ReadAddPathsFromAPIStruct(c *config.AddPaths, a *AddPaths) { - if c == nil || a == nil { - return - } - if a.Config != nil { - c.Config.Receive = a.Config.Receive - c.Config.SendMax = uint8(a.Config.SendMax) - } -} - -func NewNeighborFromAPIStruct(a *Peer) (*config.Neighbor, error) { - pconf := &config.Neighbor{} - 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.PeerGroup = a.Conf.PeerGroup - pconf.Config.PeerType = config.IntToPeerTypeMap[int(a.Conf.PeerType)] - pconf.Config.NeighborAddress = a.Conf.NeighborAddress - pconf.Config.NeighborInterface = a.Conf.NeighborInterface - pconf.Config.Vrf = a.Conf.Vrf - pconf.AsPathOptions.Config.AllowOwnAs = uint8(a.Conf.AllowOwnAs) - pconf.AsPathOptions.Config.ReplacePeerAs = a.Conf.ReplacePeerAs - - switch a.Conf.RemovePrivateAs { - case PeerConf_ALL: - pconf.Config.RemovePrivateAs = config.REMOVE_PRIVATE_AS_OPTION_ALL - case PeerConf_REPLACE: - pconf.Config.RemovePrivateAs = config.REMOVE_PRIVATE_AS_OPTION_REPLACE - } - - localCaps, err := UnmarshalCapabilities(a.Conf.LocalCap) - if err != nil { - return nil, err - } - remoteCaps, err := UnmarshalCapabilities(a.Conf.RemoteCap) - if err != nil { - return nil, err - } - pconf.State.LocalCapabilityList = localCaps - pconf.State.RemoteCapabilityList = remoteCaps - - pconf.State.RemoteRouterId = a.Conf.Id - - 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, - }, - }) - } - } - // For the backward compatibility, we override AfiSafi configurations - // with Peer.Conf.PrefixLimits. - for _, prefixLimit := range a.Conf.PrefixLimits { - for _, afiSafi := range pconf.AfiSafis { - // If Peer.Conf.PrefixLimits contains the configuration for - // the same address family, we override AfiSafi.PrefixLimit. - if uint32(afiSafi.State.Family) == prefixLimit.Family { - ReadPrefixLimitFromAPIStruct(&afiSafi.PrefixLimit, prefixLimit) - } - } - } - } - - 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.SessionState = config.SessionState(a.Info.BgpState) - pconf.State.AdminState = config.IntToAdminStateMap[int(a.Info.AdminState)] - - pconf.State.AdjTable.Received = a.Info.Received - pconf.State.AdjTable.Accepted = a.Info.Accepted - pconf.State.AdjTable.Advertised = a.Info.Advertised - pconf.State.PeerAs = a.Info.PeerAs - pconf.State.PeerType = config.IntToPeerTypeMap[int(a.Info.PeerType)] - pconf.State.NeighborAddress = a.Info.NeighborAddress - - if a.Info.Messages != nil { - if a.Info.Messages.Sent != nil { - pconf.State.Messages.Sent.Update = a.Info.Messages.Sent.UPDATE - pconf.State.Messages.Sent.Notification = a.Info.Messages.Sent.NOTIFICATION - pconf.State.Messages.Sent.Open = a.Info.Messages.Sent.OPEN - pconf.State.Messages.Sent.Refresh = a.Info.Messages.Sent.REFRESH - pconf.State.Messages.Sent.Keepalive = a.Info.Messages.Sent.KEEPALIVE - pconf.State.Messages.Sent.Discarded = a.Info.Messages.Sent.DISCARDED - pconf.State.Messages.Sent.Total = a.Info.Messages.Sent.TOTAL - } - if a.Info.Messages.Received != nil { - pconf.State.Messages.Received.Update = a.Info.Messages.Received.UPDATE - pconf.State.Messages.Received.Open = a.Info.Messages.Received.OPEN - pconf.State.Messages.Received.Refresh = a.Info.Messages.Received.REFRESH - pconf.State.Messages.Received.Keepalive = a.Info.Messages.Received.KEEPALIVE - pconf.State.Messages.Received.Discarded = a.Info.Messages.Received.DISCARDED - pconf.State.Messages.Received.Total = a.Info.Messages.Received.TOTAL - } - } - } - ReadAddPathsFromAPIStruct(&pconf.AddPaths, a.AddPaths) - 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 { - return nil, err - } - return &AddNeighborResponse{}, s.bgpServer.AddNeighbor(c) -} - -func (s *Server) DeleteNeighbor(ctx context.Context, arg *DeleteNeighborRequest) (*DeleteNeighborResponse, error) { - return &DeleteNeighborResponse{}, s.bgpServer.DeleteNeighbor(&config.Neighbor{Config: config.NeighborConfig{ - NeighborAddress: arg.Peer.Conf.NeighborAddress, - NeighborInterface: arg.Peer.Conf.NeighborInterface, - }}) -} - -func (s *Server) UpdateNeighbor(ctx context.Context, arg *UpdateNeighborRequest) (*UpdateNeighborResponse, error) { - c, err := NewNeighborFromAPIStruct(arg.Peer) - if err != nil { - return nil, err - } - needsSoftResetIn, err := s.bgpServer.UpdateNeighbor(c) - if err != nil { - return nil, err - } - if arg.DoSoftResetIn && needsSoftResetIn { - return &UpdateNeighborResponse{NeedsSoftResetIn: false}, s.bgpServer.SoftResetIn("", bgp.RouteFamily(0)) - } - 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 { - return nil, err - } - rf := bgp.RF_IPv4_UC - if strings.Contains(a.IpPrefix, ":") { - rf = bgp.RF_IPv6_UC - } - return &table.Prefix{ - Prefix: prefix, - AddressFamily: rf, - MasklengthRangeMin: uint8(a.MaskLengthMin), - MasklengthRangeMax: uint8(a.MaskLengthMax), - }, nil -} - -func NewConfigPrefixFromAPIStruct(a *Prefix) (*config.Prefix, error) { - _, prefix, err := net.ParseCIDR(a.IpPrefix) - if err != nil { - return nil, err - } - return &config.Prefix{ - IpPrefix: prefix.String(), - MasklengthRange: fmt.Sprintf("%d..%d", a.MaskLengthMin, a.MaskLengthMax), - }, nil -} - -func NewAPIPrefixFromConfigStruct(c config.Prefix) (*Prefix, error) { - min, max, err := config.ParseMaskLength(c.IpPrefix, c.MasklengthRange) - if err != nil { - return nil, err - } - return &Prefix{ - IpPrefix: c.IpPrefix, - MaskLengthMin: uint32(min), - MaskLengthMax: uint32(max), - }, nil -} - -func NewAPIDefinedSetFromTableStruct(t table.DefinedSet) (*DefinedSet, error) { - a := &DefinedSet{ - Type: DefinedType(t.Type()), - Name: t.Name(), - } - switch t.Type() { - case table.DEFINED_TYPE_PREFIX: - s := t.(*table.PrefixSet) - c := s.ToConfig() - for _, p := range c.PrefixList { - ap, err := NewAPIPrefixFromConfigStruct(p) - if err != nil { - return nil, err - } - a.Prefixes = append(a.Prefixes, ap) - } - case table.DEFINED_TYPE_NEIGHBOR: - s := t.(*table.NeighborSet) - c := s.ToConfig() - a.List = append(a.List, c.NeighborInfoList...) - case table.DEFINED_TYPE_AS_PATH: - s := t.(*table.AsPathSet) - c := s.ToConfig() - a.List = append(a.List, c.AsPathList...) - case table.DEFINED_TYPE_COMMUNITY: - s := t.(*table.CommunitySet) - c := s.ToConfig() - a.List = append(a.List, c.CommunityList...) - case table.DEFINED_TYPE_EXT_COMMUNITY: - s := t.(*table.ExtCommunitySet) - c := s.ToConfig() - a.List = append(a.List, c.ExtCommunityList...) - case table.DEFINED_TYPE_LARGE_COMMUNITY: - s := t.(*table.LargeCommunitySet) - c := s.ToConfig() - a.List = append(a.List, c.LargeCommunityList...) - default: - return nil, fmt.Errorf("invalid defined type") - } - return a, nil -} - -func NewAPIDefinedSetsFromConfigStruct(t *config.DefinedSets) ([]*DefinedSet, error) { - definedSets := make([]*DefinedSet, 0) - - for _, ps := range t.PrefixSets { - prefixes := make([]*Prefix, 0) - for _, p := range ps.PrefixList { - ap, err := NewAPIPrefixFromConfigStruct(p) - if err != nil { - return nil, err - } - prefixes = append(prefixes, ap) - } - definedSets = append(definedSets, &DefinedSet{ - Type: DefinedType_PREFIX, - Name: ps.PrefixSetName, - Prefixes: prefixes, - }) - } - - for _, ns := range t.NeighborSets { - definedSets = append(definedSets, &DefinedSet{ - Type: DefinedType_NEIGHBOR, - Name: ns.NeighborSetName, - List: ns.NeighborInfoList, - }) - } - - bs := t.BgpDefinedSets - for _, cs := range bs.CommunitySets { - definedSets = append(definedSets, &DefinedSet{ - Type: DefinedType_COMMUNITY, - Name: cs.CommunitySetName, - List: cs.CommunityList, - }) - } - - for _, es := range bs.ExtCommunitySets { - definedSets = append(definedSets, &DefinedSet{ - Type: DefinedType_EXT_COMMUNITY, - Name: es.ExtCommunitySetName, - List: es.ExtCommunityList, - }) - } - - for _, ls := range bs.LargeCommunitySets { - definedSets = append(definedSets, &DefinedSet{ - Type: DefinedType_LARGE_COMMUNITY, - Name: ls.LargeCommunitySetName, - List: ls.LargeCommunityList, - }) - } - - for _, as := range bs.AsPathSets { - definedSets = append(definedSets, &DefinedSet{ - Type: DefinedType_AS_PATH, - Name: as.AsPathSetName, - List: as.AsPathList, - }) - } - - return definedSets, nil -} - -func NewConfigDefinedSetsFromApiStruct(a []*DefinedSet) (*config.DefinedSets, error) { - ps := make([]config.PrefixSet, 0) - ns := make([]config.NeighborSet, 0) - as := make([]config.AsPathSet, 0) - cs := make([]config.CommunitySet, 0) - es := make([]config.ExtCommunitySet, 0) - ls := make([]config.LargeCommunitySet, 0) - - for _, ds := range a { - if ds.Name == "" { - return nil, fmt.Errorf("empty neighbor set name") - } - switch table.DefinedType(ds.Type) { - case table.DEFINED_TYPE_PREFIX: - prefixes := make([]config.Prefix, 0, len(ds.Prefixes)) - for _, p := range ds.Prefixes { - prefix, err := NewConfigPrefixFromAPIStruct(p) - if err != nil { - return nil, err - } - prefixes = append(prefixes, *prefix) - } - ps = append(ps, config.PrefixSet{ - PrefixSetName: ds.Name, - PrefixList: prefixes, - }) - case table.DEFINED_TYPE_NEIGHBOR: - ns = append(ns, config.NeighborSet{ - NeighborSetName: ds.Name, - NeighborInfoList: ds.List, - }) - case table.DEFINED_TYPE_AS_PATH: - as = append(as, config.AsPathSet{ - AsPathSetName: ds.Name, - AsPathList: ds.List, - }) - case table.DEFINED_TYPE_COMMUNITY: - cs = append(cs, config.CommunitySet{ - CommunitySetName: ds.Name, - CommunityList: ds.List, - }) - case table.DEFINED_TYPE_EXT_COMMUNITY: - es = append(es, config.ExtCommunitySet{ - ExtCommunitySetName: ds.Name, - ExtCommunityList: ds.List, - }) - case table.DEFINED_TYPE_LARGE_COMMUNITY: - ls = append(ls, config.LargeCommunitySet{ - LargeCommunitySetName: ds.Name, - LargeCommunityList: ds.List, - }) - default: - return nil, fmt.Errorf("invalid defined type") - } - } - - return &config.DefinedSets{ - PrefixSets: ps, - NeighborSets: ns, - BgpDefinedSets: config.BgpDefinedSets{ - AsPathSets: as, - CommunitySets: cs, - ExtCommunitySets: es, - LargeCommunitySets: ls, - }, - }, nil -} - -func NewDefinedSetFromApiStruct(a *DefinedSet) (table.DefinedSet, error) { - if a.Name == "" { - return nil, fmt.Errorf("empty neighbor set name") - } - switch table.DefinedType(a.Type) { - case table.DEFINED_TYPE_PREFIX: - prefixes := make([]*table.Prefix, 0, len(a.Prefixes)) - for _, p := range a.Prefixes { - prefix, err := NewPrefixFromApiStruct(p) - if err != nil { - return nil, err - } - prefixes = append(prefixes, prefix) - } - return table.NewPrefixSetFromApiStruct(a.Name, prefixes) - case table.DEFINED_TYPE_NEIGHBOR: - list := make([]net.IPNet, 0, len(a.List)) - for _, x := range a.List { - _, addr, err := net.ParseCIDR(x) - if err != nil { - return nil, fmt.Errorf("invalid address or prefix: %s", x) - } - list = append(list, *addr) - } - return table.NewNeighborSetFromApiStruct(a.Name, list) - case table.DEFINED_TYPE_AS_PATH: - return table.NewAsPathSet(config.AsPathSet{ - AsPathSetName: a.Name, - AsPathList: a.List, - }) - case table.DEFINED_TYPE_COMMUNITY: - return table.NewCommunitySet(config.CommunitySet{ - CommunitySetName: a.Name, - CommunityList: a.List, - }) - case table.DEFINED_TYPE_EXT_COMMUNITY: - return table.NewExtCommunitySet(config.ExtCommunitySet{ - ExtCommunitySetName: a.Name, - ExtCommunityList: a.List, - }) - case table.DEFINED_TYPE_LARGE_COMMUNITY: - return table.NewLargeCommunitySet(config.LargeCommunitySet{ - LargeCommunitySetName: a.Name, - LargeCommunityList: a.List, - }) - default: - return nil, fmt.Errorf("invalid defined type") - } -} - -var _regexpPrefixMaskLengthRange = regexp.MustCompile(`(\d+)\.\.(\d+)`) - -func (s *Server) GetDefinedSet(ctx context.Context, arg *GetDefinedSetRequest) (*GetDefinedSetResponse, error) { - cd, err := s.bgpServer.GetDefinedSet(table.DefinedType(arg.Type), arg.Name) - if err != nil { - return nil, err - } - sets := make([]*DefinedSet, 0) - for _, cs := range cd.PrefixSets { - ad := &DefinedSet{ - Type: DefinedType_PREFIX, - Name: cs.PrefixSetName, - Prefixes: func() []*Prefix { - l := make([]*Prefix, 0, len(cs.PrefixList)) - for _, p := range cs.PrefixList { - elems := _regexpPrefixMaskLengthRange.FindStringSubmatch(p.MasklengthRange) - min, _ := strconv.ParseUint(elems[1], 10, 32) - max, _ := strconv.ParseUint(elems[2], 10, 32) - - l = append(l, &Prefix{IpPrefix: p.IpPrefix, MaskLengthMin: uint32(min), MaskLengthMax: uint32(max)}) - } - return l - }(), - } - sets = append(sets, ad) - - } - for _, cs := range cd.NeighborSets { - ad := &DefinedSet{ - Type: DefinedType_NEIGHBOR, - Name: cs.NeighborSetName, - List: cs.NeighborInfoList, - } - sets = append(sets, ad) - } - for _, cs := range cd.BgpDefinedSets.CommunitySets { - ad := &DefinedSet{ - Type: DefinedType_COMMUNITY, - Name: cs.CommunitySetName, - List: cs.CommunityList, - } - sets = append(sets, ad) - } - for _, cs := range cd.BgpDefinedSets.ExtCommunitySets { - ad := &DefinedSet{ - Type: DefinedType_EXT_COMMUNITY, - Name: cs.ExtCommunitySetName, - List: cs.ExtCommunityList, - } - sets = append(sets, ad) - } - for _, cs := range cd.BgpDefinedSets.LargeCommunitySets { - ad := &DefinedSet{ - Type: DefinedType_LARGE_COMMUNITY, - Name: cs.LargeCommunitySetName, - List: cs.LargeCommunityList, - } - sets = append(sets, ad) - } - for _, cs := range cd.BgpDefinedSets.AsPathSets { - ad := &DefinedSet{ - Type: DefinedType_AS_PATH, - Name: cs.AsPathSetName, - List: cs.AsPathList, - } - sets = append(sets, ad) - } - - return &GetDefinedSetResponse{Sets: sets}, nil -} - -func (s *Server) AddDefinedSet(ctx context.Context, arg *AddDefinedSetRequest) (*AddDefinedSetResponse, error) { - if arg == nil || arg.Set == nil { - return nil, fmt.Errorf("invalid request") - } - set, err := NewDefinedSetFromApiStruct(arg.Set) - if err != nil { - return nil, err - } - return &AddDefinedSetResponse{}, s.bgpServer.AddDefinedSet(set) -} - -func (s *Server) DeleteDefinedSet(ctx context.Context, arg *DeleteDefinedSetRequest) (*DeleteDefinedSetResponse, error) { - if arg == nil || arg.Set == nil { - return nil, fmt.Errorf("invalid request") - } - set, err := NewDefinedSetFromApiStruct(arg.Set) - if err != nil { - return nil, err - } - return &DeleteDefinedSetResponse{}, s.bgpServer.DeleteDefinedSet(set, arg.All) -} - -func (s *Server) ReplaceDefinedSet(ctx context.Context, arg *ReplaceDefinedSetRequest) (*ReplaceDefinedSetResponse, error) { - if arg == nil || arg.Set == nil { - return nil, fmt.Errorf("invalid request") - } - set, err := NewDefinedSetFromApiStruct(arg.Set) - if err != nil { - return nil, err - } - return &ReplaceDefinedSetResponse{}, s.bgpServer.ReplaceDefinedSet(set) -} - -func NewAPIStatementFromTableStruct(t *table.Statement) *Statement { - return toStatementApi(t.ToConfig()) -} - -var _regexpMedActionType = regexp.MustCompile(`([+-]?)(\d+)`) - -func toStatementApi(s *config.Statement) *Statement { - cs := &Conditions{} - if s.Conditions.MatchPrefixSet.PrefixSet != "" { - o, _ := table.NewMatchOption(s.Conditions.MatchPrefixSet.MatchSetOptions) - cs.PrefixSet = &MatchSet{ - Type: MatchType(o), - Name: s.Conditions.MatchPrefixSet.PrefixSet, - } - } - if s.Conditions.MatchNeighborSet.NeighborSet != "" { - o, _ := table.NewMatchOption(s.Conditions.MatchNeighborSet.MatchSetOptions) - cs.NeighborSet = &MatchSet{ - Type: MatchType(o), - Name: s.Conditions.MatchNeighborSet.NeighborSet, - } - } - if s.Conditions.BgpConditions.AsPathLength.Operator != "" { - cs.AsPathLength = &AsPathLength{ - Length: s.Conditions.BgpConditions.AsPathLength.Value, - Type: AsPathLengthType(s.Conditions.BgpConditions.AsPathLength.Operator.ToInt()), - } - } - if s.Conditions.BgpConditions.MatchAsPathSet.AsPathSet != "" { - cs.AsPathSet = &MatchSet{ - Type: MatchType(s.Conditions.BgpConditions.MatchAsPathSet.MatchSetOptions.ToInt()), - Name: s.Conditions.BgpConditions.MatchAsPathSet.AsPathSet, - } - } - if s.Conditions.BgpConditions.MatchCommunitySet.CommunitySet != "" { - cs.CommunitySet = &MatchSet{ - Type: MatchType(s.Conditions.BgpConditions.MatchCommunitySet.MatchSetOptions.ToInt()), - Name: s.Conditions.BgpConditions.MatchCommunitySet.CommunitySet, - } - } - if s.Conditions.BgpConditions.MatchExtCommunitySet.ExtCommunitySet != "" { - cs.ExtCommunitySet = &MatchSet{ - Type: MatchType(s.Conditions.BgpConditions.MatchExtCommunitySet.MatchSetOptions.ToInt()), - Name: s.Conditions.BgpConditions.MatchExtCommunitySet.ExtCommunitySet, - } - } - if s.Conditions.BgpConditions.MatchLargeCommunitySet.LargeCommunitySet != "" { - cs.LargeCommunitySet = &MatchSet{ - Type: MatchType(s.Conditions.BgpConditions.MatchLargeCommunitySet.MatchSetOptions.ToInt()), - Name: s.Conditions.BgpConditions.MatchLargeCommunitySet.LargeCommunitySet, - } - } - if s.Conditions.BgpConditions.RouteType != "" { - cs.RouteType = Conditions_RouteType(s.Conditions.BgpConditions.RouteType.ToInt()) - } - if len(s.Conditions.BgpConditions.NextHopInList) > 0 { - cs.NextHopInList = s.Conditions.BgpConditions.NextHopInList - } - if s.Conditions.BgpConditions.AfiSafiInList != nil { - afiSafiIn := make([]Family, 0) - for _, afiSafiType := range s.Conditions.BgpConditions.AfiSafiInList { - if mapped, ok := bgp.AddressFamilyValueMap[string(afiSafiType)]; ok { - afiSafiIn = append(afiSafiIn, Family(mapped)) - } - } - cs.AfiSafiIn = afiSafiIn - } - cs.RpkiResult = int32(s.Conditions.BgpConditions.RpkiValidationResult.ToInt()) - as := &Actions{ - RouteAction: func() RouteAction { - switch s.Actions.RouteDisposition { - case config.ROUTE_DISPOSITION_ACCEPT_ROUTE: - return RouteAction_ACCEPT - case config.ROUTE_DISPOSITION_REJECT_ROUTE: - return RouteAction_REJECT - } - return RouteAction_NONE - }(), - Community: func() *CommunityAction { - if len(s.Actions.BgpActions.SetCommunity.SetCommunityMethod.CommunitiesList) == 0 { - return nil - } - return &CommunityAction{ - Type: CommunityActionType(config.BgpSetCommunityOptionTypeToIntMap[config.BgpSetCommunityOptionType(s.Actions.BgpActions.SetCommunity.Options)]), - Communities: s.Actions.BgpActions.SetCommunity.SetCommunityMethod.CommunitiesList} - }(), - Med: func() *MedAction { - medStr := strings.TrimSpace(string(s.Actions.BgpActions.SetMed)) - if len(medStr) == 0 { - return nil - } - matches := _regexpMedActionType.FindStringSubmatch(medStr) - if len(matches) == 0 { - return nil - } - action := MedActionType_MED_REPLACE - switch matches[1] { - case "+", "-": - action = MedActionType_MED_MOD - } - value, err := strconv.ParseInt(matches[1]+matches[2], 10, 64) - if err != nil { - return nil - } - return &MedAction{ - Value: value, - Type: action, - } - }(), - AsPrepend: func() *AsPrependAction { - if len(s.Actions.BgpActions.SetAsPathPrepend.As) == 0 { - return nil - } - var asn uint64 - useleft := false - if s.Actions.BgpActions.SetAsPathPrepend.As != "last-as" { - asn, _ = strconv.ParseUint(s.Actions.BgpActions.SetAsPathPrepend.As, 10, 32) - } else { - useleft = true - } - return &AsPrependAction{ - Asn: uint32(asn), - Repeat: uint32(s.Actions.BgpActions.SetAsPathPrepend.RepeatN), - UseLeftMost: useleft, - } - }(), - ExtCommunity: func() *CommunityAction { - if len(s.Actions.BgpActions.SetExtCommunity.SetExtCommunityMethod.CommunitiesList) == 0 { - return nil - } - return &CommunityAction{ - Type: CommunityActionType(config.BgpSetCommunityOptionTypeToIntMap[config.BgpSetCommunityOptionType(s.Actions.BgpActions.SetExtCommunity.Options)]), - Communities: s.Actions.BgpActions.SetExtCommunity.SetExtCommunityMethod.CommunitiesList, - } - }(), - LargeCommunity: func() *CommunityAction { - if len(s.Actions.BgpActions.SetLargeCommunity.SetLargeCommunityMethod.CommunitiesList) == 0 { - return nil - } - return &CommunityAction{ - Type: CommunityActionType(config.BgpSetCommunityOptionTypeToIntMap[config.BgpSetCommunityOptionType(s.Actions.BgpActions.SetLargeCommunity.Options)]), - Communities: s.Actions.BgpActions.SetLargeCommunity.SetLargeCommunityMethod.CommunitiesList, - } - }(), - Nexthop: func() *NexthopAction { - if len(string(s.Actions.BgpActions.SetNextHop)) == 0 { - return nil - } - - if string(s.Actions.BgpActions.SetNextHop) == "self" { - return &NexthopAction{ - Self: true, - } - } - return &NexthopAction{ - Address: string(s.Actions.BgpActions.SetNextHop), - } - }(), - LocalPref: func() *LocalPrefAction { - if s.Actions.BgpActions.SetLocalPref == 0 { - return nil - } - return &LocalPrefAction{Value: s.Actions.BgpActions.SetLocalPref} - }(), - } - return &Statement{ - Name: s.Name, - Conditions: cs, - Actions: as, - } -} - -func toConfigMatchSetOption(a MatchType) (config.MatchSetOptionsType, error) { - var typ config.MatchSetOptionsType - switch a { - case MatchType_ANY: - typ = config.MATCH_SET_OPTIONS_TYPE_ANY - case MatchType_ALL: - typ = config.MATCH_SET_OPTIONS_TYPE_ALL - case MatchType_INVERT: - typ = config.MATCH_SET_OPTIONS_TYPE_INVERT - default: - return typ, fmt.Errorf("invalid match type") - } - return typ, nil -} - -func toConfigMatchSetOptionRestricted(a MatchType) (config.MatchSetOptionsRestrictedType, error) { - var typ config.MatchSetOptionsRestrictedType - switch a { - case MatchType_ANY: - typ = config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_ANY - case MatchType_INVERT: - typ = config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_INVERT - default: - return typ, fmt.Errorf("invalid match type") - } - return typ, nil -} - -func NewPrefixConditionFromApiStruct(a *MatchSet) (*table.PrefixCondition, error) { - if a == nil { - return nil, nil - } - typ, err := toConfigMatchSetOptionRestricted(a.Type) - if err != nil { - return nil, err - } - c := config.MatchPrefixSet{ - PrefixSet: a.Name, - MatchSetOptions: typ, - } - return table.NewPrefixCondition(c) -} - -func NewNeighborConditionFromApiStruct(a *MatchSet) (*table.NeighborCondition, error) { - if a == nil { - return nil, nil - } - typ, err := toConfigMatchSetOptionRestricted(a.Type) - if err != nil { - return nil, err - } - c := config.MatchNeighborSet{ - NeighborSet: a.Name, - MatchSetOptions: typ, - } - return table.NewNeighborCondition(c) -} - -func NewAsPathLengthConditionFromApiStruct(a *AsPathLength) (*table.AsPathLengthCondition, error) { - if a == nil { - return nil, nil - } - return table.NewAsPathLengthCondition(config.AsPathLength{ - Operator: config.IntToAttributeComparisonMap[int(a.Type)], - Value: a.Length, - }) -} - -func NewAsPathConditionFromApiStruct(a *MatchSet) (*table.AsPathCondition, error) { - if a == nil { - return nil, nil - } - typ, err := toConfigMatchSetOption(a.Type) - if err != nil { - return nil, err - } - c := config.MatchAsPathSet{ - AsPathSet: a.Name, - MatchSetOptions: typ, - } - return table.NewAsPathCondition(c) -} - -func NewRpkiValidationConditionFromApiStruct(a int32) (*table.RpkiValidationCondition, error) { - if a < 1 { - return nil, nil - } - return table.NewRpkiValidationCondition(config.IntToRpkiValidationResultTypeMap[int(a)]) -} - -func NewRouteTypeConditionFromApiStruct(a Conditions_RouteType) (*table.RouteTypeCondition, error) { - if a == 0 { - return nil, nil - } - typ, ok := config.IntToRouteTypeMap[int(a)] - if !ok { - return nil, fmt.Errorf("invalid route type: %d", a) - } - return table.NewRouteTypeCondition(typ) -} - -func NewCommunityConditionFromApiStruct(a *MatchSet) (*table.CommunityCondition, error) { - if a == nil { - return nil, nil - } - typ, err := toConfigMatchSetOption(a.Type) - if err != nil { - return nil, err - } - c := config.MatchCommunitySet{ - CommunitySet: a.Name, - MatchSetOptions: typ, - } - return table.NewCommunityCondition(c) -} - -func NewExtCommunityConditionFromApiStruct(a *MatchSet) (*table.ExtCommunityCondition, error) { - if a == nil { - return nil, nil - } - typ, err := toConfigMatchSetOption(a.Type) - if err != nil { - return nil, err - } - c := config.MatchExtCommunitySet{ - ExtCommunitySet: a.Name, - MatchSetOptions: typ, - } - return table.NewExtCommunityCondition(c) -} - -func NewLargeCommunityConditionFromApiStruct(a *MatchSet) (*table.LargeCommunityCondition, error) { - if a == nil { - return nil, nil - } - typ, err := toConfigMatchSetOption(a.Type) - if err != nil { - return nil, err - } - c := config.MatchLargeCommunitySet{ - LargeCommunitySet: a.Name, - MatchSetOptions: typ, - } - return table.NewLargeCommunityCondition(c) -} - -func NewNextHopConditionFromApiStruct(a []string) (*table.NextHopCondition, error) { - if a == nil { - return nil, nil - } - - return table.NewNextHopCondition(a) -} - -func NewAfiSafiInConditionFromApiStruct(a []Family) (*table.AfiSafiInCondition, error) { - if a == nil { - return nil, nil - } - afiSafiTypes := make([]config.AfiSafiType, 0, len(a)) - for _, aType := range a { - if configType, ok := bgp.AddressFamilyNameMap[bgp.RouteFamily(aType)]; ok { - afiSafiTypes = append(afiSafiTypes, config.AfiSafiType(configType)) - } else { - return nil, fmt.Errorf("unknown afi-safi-in type value: %d", aType) - } - } - return table.NewAfiSafiInCondition(afiSafiTypes) -} - -func NewRoutingActionFromApiStruct(a RouteAction) (*table.RoutingAction, error) { - if a == RouteAction_NONE { - return nil, nil - } - accept := false - if a == RouteAction_ACCEPT { - accept = true - } - return &table.RoutingAction{ - AcceptRoute: accept, - }, nil -} - -func NewCommunityActionFromApiStruct(a *CommunityAction) (*table.CommunityAction, error) { - if a == nil { - return nil, nil - } - return table.NewCommunityAction(config.SetCommunity{ - Options: string(config.IntToBgpSetCommunityOptionTypeMap[int(a.Type)]), - SetCommunityMethod: config.SetCommunityMethod{ - CommunitiesList: a.Communities, - }, - }) -} - -func NewExtCommunityActionFromApiStruct(a *CommunityAction) (*table.ExtCommunityAction, error) { - if a == nil { - return nil, nil - } - return table.NewExtCommunityAction(config.SetExtCommunity{ - Options: string(config.IntToBgpSetCommunityOptionTypeMap[int(a.Type)]), - SetExtCommunityMethod: config.SetExtCommunityMethod{ - CommunitiesList: a.Communities, - }, - }) -} - -func NewLargeCommunityActionFromApiStruct(a *CommunityAction) (*table.LargeCommunityAction, error) { - if a == nil { - return nil, nil - } - return table.NewLargeCommunityAction(config.SetLargeCommunity{ - Options: config.IntToBgpSetCommunityOptionTypeMap[int(a.Type)], - SetLargeCommunityMethod: config.SetLargeCommunityMethod{ - CommunitiesList: a.Communities, - }, - }) -} - -func NewMedActionFromApiStruct(a *MedAction) (*table.MedAction, error) { - if a == nil { - return nil, nil - } - return table.NewMedActionFromApiStruct(table.MedActionType(a.Type), a.Value), nil -} - -func NewLocalPrefActionFromApiStruct(a *LocalPrefAction) (*table.LocalPrefAction, error) { - if a == nil || a.Value == 0 { - return nil, nil - } - return table.NewLocalPrefAction(a.Value) -} - -func NewAsPathPrependActionFromApiStruct(a *AsPrependAction) (*table.AsPathPrependAction, error) { - if a == nil { - return nil, nil - } - return table.NewAsPathPrependAction(config.SetAsPathPrepend{ - RepeatN: uint8(a.Repeat), - As: func() string { - if a.UseLeftMost { - return "last-as" - } - return fmt.Sprintf("%d", a.Asn) - }(), - }) -} - -func NewNexthopActionFromApiStruct(a *NexthopAction) (*table.NexthopAction, error) { - if a == nil { - return nil, nil - } - return table.NewNexthopAction(config.BgpNextHopType( - func() string { - if a.Self { - return "self" - } - return a.Address - }(), - )) -} - -func NewStatementFromApiStruct(a *Statement) (*table.Statement, error) { - if a.Name == "" { - return nil, fmt.Errorf("empty statement name") - } - var ra table.Action - var as []table.Action - var cs []table.Condition - var err error - if a.Conditions != nil { - cfs := []func() (table.Condition, error){ - func() (table.Condition, error) { - return NewPrefixConditionFromApiStruct(a.Conditions.PrefixSet) - }, - func() (table.Condition, error) { - return NewNeighborConditionFromApiStruct(a.Conditions.NeighborSet) - }, - func() (table.Condition, error) { - return NewAsPathLengthConditionFromApiStruct(a.Conditions.AsPathLength) - }, - func() (table.Condition, error) { - return NewRpkiValidationConditionFromApiStruct(a.Conditions.RpkiResult) - }, - func() (table.Condition, error) { - return NewRouteTypeConditionFromApiStruct(a.Conditions.RouteType) - }, - func() (table.Condition, error) { - return NewAsPathConditionFromApiStruct(a.Conditions.AsPathSet) - }, - func() (table.Condition, error) { - return NewCommunityConditionFromApiStruct(a.Conditions.CommunitySet) - }, - func() (table.Condition, error) { - return NewExtCommunityConditionFromApiStruct(a.Conditions.ExtCommunitySet) - }, - func() (table.Condition, error) { - return NewLargeCommunityConditionFromApiStruct(a.Conditions.LargeCommunitySet) - }, - func() (table.Condition, error) { - return NewNextHopConditionFromApiStruct(a.Conditions.NextHopInList) - }, - func() (table.Condition, error) { - return NewAfiSafiInConditionFromApiStruct(a.Conditions.AfiSafiIn) - }, - } - cs = make([]table.Condition, 0, len(cfs)) - for _, f := range cfs { - c, err := f() - if err != nil { - return nil, err - } - if !reflect.ValueOf(c).IsNil() { - cs = append(cs, c) - } - } - } - if a.Actions != nil { - ra, err = NewRoutingActionFromApiStruct(a.Actions.RouteAction) - if err != nil { - return nil, err - } - afs := []func() (table.Action, error){ - func() (table.Action, error) { - return NewCommunityActionFromApiStruct(a.Actions.Community) - }, - func() (table.Action, error) { - return NewExtCommunityActionFromApiStruct(a.Actions.ExtCommunity) - }, - func() (table.Action, error) { - return NewLargeCommunityActionFromApiStruct(a.Actions.LargeCommunity) - }, - func() (table.Action, error) { - return NewMedActionFromApiStruct(a.Actions.Med) - }, - func() (table.Action, error) { - return NewLocalPrefActionFromApiStruct(a.Actions.LocalPref) - }, - func() (table.Action, error) { - return NewAsPathPrependActionFromApiStruct(a.Actions.AsPrepend) - }, - func() (table.Action, error) { - return NewNexthopActionFromApiStruct(a.Actions.Nexthop) - }, - } - as = make([]table.Action, 0, len(afs)) - for _, f := range afs { - a, err := f() - if err != nil { - return nil, err - } - if !reflect.ValueOf(a).IsNil() { - as = append(as, a) - } - } - } - return &table.Statement{ - Name: a.Name, - Conditions: cs, - RouteAction: ra, - ModActions: as, - }, nil -} - -func (s *Server) GetStatement(ctx context.Context, arg *GetStatementRequest) (*GetStatementResponse, error) { - l := make([]*Statement, 0) - for _, s := range s.bgpServer.GetStatement() { - l = append(l, toStatementApi(s)) - } - return &GetStatementResponse{Statements: l}, nil -} - -func (s *Server) AddStatement(ctx context.Context, arg *AddStatementRequest) (*AddStatementResponse, error) { - if arg == nil || arg.Statement == nil { - return nil, fmt.Errorf("invalid request") - } - st, err := NewStatementFromApiStruct(arg.Statement) - if err == nil { - err = s.bgpServer.AddStatement(st) - } - return &AddStatementResponse{}, err -} - -func (s *Server) DeleteStatement(ctx context.Context, arg *DeleteStatementRequest) (*DeleteStatementResponse, error) { - if arg == nil || arg.Statement == nil { - return nil, fmt.Errorf("invalid request") - } - st, err := NewStatementFromApiStruct(arg.Statement) - if err == nil { - err = s.bgpServer.DeleteStatement(st, arg.All) - } - return &DeleteStatementResponse{}, err -} - -func (s *Server) ReplaceStatement(ctx context.Context, arg *ReplaceStatementRequest) (*ReplaceStatementResponse, error) { - if arg == nil || arg.Statement == nil { - return nil, fmt.Errorf("invalid request") - } - st, err := NewStatementFromApiStruct(arg.Statement) - if err == nil { - err = s.bgpServer.ReplaceStatement(st) - } - return &ReplaceStatementResponse{}, err -} - -func NewAPIPolicyFromTableStruct(p *table.Policy) *Policy { - return toPolicyApi(p.ToConfig()) -} - -func toPolicyApi(p *config.PolicyDefinition) *Policy { - return &Policy{ - Name: p.Name, - Statements: func() []*Statement { - l := make([]*Statement, 0) - for _, s := range p.Statements { - l = append(l, toStatementApi(&s)) - } - return l - }(), - } -} - -func NewAPIPolicyAssignmentFromTableStruct(t *table.PolicyAssignment) *PolicyAssignment { - return &PolicyAssignment{ - Type: func() PolicyType { - switch t.Type { - case table.POLICY_DIRECTION_IMPORT: - return PolicyType_IMPORT - case table.POLICY_DIRECTION_EXPORT: - return PolicyType_EXPORT - } - log.Errorf("invalid policy-type: %s", t.Type) - return PolicyType(-1) - }(), - Default: func() RouteAction { - switch t.Default { - case table.ROUTE_TYPE_ACCEPT: - return RouteAction_ACCEPT - case table.ROUTE_TYPE_REJECT: - return RouteAction_REJECT - } - return RouteAction_NONE - }(), - Name: t.Name, - Resource: func() Resource { - if t.Name != "" { - return Resource_LOCAL - } - return Resource_GLOBAL - }(), - Policies: func() []*Policy { - l := make([]*Policy, 0) - for _, p := range t.Policies { - l = append(l, NewAPIPolicyFromTableStruct(p)) - } - return l - }(), - } -} - -func NewConfigPolicyFromApiStruct(a *Policy) (*config.PolicyDefinition, error) { - if a.Name == "" { - return nil, fmt.Errorf("empty policy name") - } - stmts := make([]config.Statement, 0, len(a.Statements)) - for idx, x := range a.Statements { - if x.Name == "" { - x.Name = fmt.Sprintf("%s_stmt%d", a.Name, idx) - } - y, err := NewStatementFromApiStruct(x) - if err != nil { - return nil, err - } - stmt := y.ToConfig() - stmts = append(stmts, *stmt) - } - return &config.PolicyDefinition{ - Name: a.Name, - Statements: stmts, - }, nil -} - -func NewPolicyFromApiStruct(a *Policy) (*table.Policy, error) { - if a.Name == "" { - return nil, fmt.Errorf("empty policy name") - } - stmts := make([]*table.Statement, 0, len(a.Statements)) - for idx, x := range a.Statements { - if x.Name == "" { - x.Name = fmt.Sprintf("%s_stmt%d", a.Name, idx) - } - y, err := NewStatementFromApiStruct(x) - if err != nil { - return nil, err - } - stmts = append(stmts, y) - } - return &table.Policy{ - Name: a.Name, - Statements: stmts, - }, nil -} - -func NewRoaListFromTableStructList(origin []*table.ROA) []*Roa { - l := make([]*Roa, 0) - for _, r := range origin { - host, port, _ := net.SplitHostPort(r.Src) - l = append(l, &Roa{ - As: r.AS, - Maxlen: uint32(r.MaxLen), - Prefixlen: uint32(r.Prefix.Length), - Prefix: r.Prefix.Prefix.String(), - Conf: &RPKIConf{ - Address: host, - RemotePort: port, - }, - }) - } - return l -} - -func (s *Server) GetPolicy(ctx context.Context, arg *GetPolicyRequest) (*GetPolicyResponse, error) { - l := make([]*Policy, 0) - for _, p := range s.bgpServer.GetPolicy() { - l = append(l, toPolicyApi(p)) - } - return &GetPolicyResponse{Policies: l}, nil -} - -func (s *Server) AddPolicy(ctx context.Context, arg *AddPolicyRequest) (*AddPolicyResponse, error) { - if arg == nil || arg.Policy == nil { - return nil, fmt.Errorf("invalid request") - } - x, err := NewPolicyFromApiStruct(arg.Policy) - if err != nil { - return nil, err - } - return &AddPolicyResponse{}, s.bgpServer.AddPolicy(x, arg.ReferExistingStatements) -} - -func (s *Server) DeletePolicy(ctx context.Context, arg *DeletePolicyRequest) (*DeletePolicyResponse, error) { - if arg == nil || arg.Policy == nil { - return nil, fmt.Errorf("invalid request") - } - x, err := NewPolicyFromApiStruct(arg.Policy) - if err != nil { - return nil, err - } - return &DeletePolicyResponse{}, s.bgpServer.DeletePolicy(x, arg.All, arg.PreserveStatements) -} - -func (s *Server) ReplacePolicy(ctx context.Context, arg *ReplacePolicyRequest) (*ReplacePolicyResponse, error) { - if arg == nil || arg.Policy == nil { - return nil, fmt.Errorf("invalid request") - } - x, err := NewPolicyFromApiStruct(arg.Policy) - if err != nil { - return nil, err - } - return &ReplacePolicyResponse{}, s.bgpServer.ReplacePolicy(x, arg.ReferExistingStatements, arg.PreserveStatements) -} - -func toPolicyAssignmentName(a *PolicyAssignment) (string, table.PolicyDirection, error) { - switch a.Resource { - case Resource_GLOBAL: - switch a.Type { - case PolicyType_IMPORT: - return "", table.POLICY_DIRECTION_IMPORT, nil - case PolicyType_EXPORT: - return "", table.POLICY_DIRECTION_EXPORT, nil - default: - return "", table.POLICY_DIRECTION_NONE, fmt.Errorf("invalid policy type") - } - case Resource_LOCAL: - switch a.Type { - case PolicyType_IMPORT: - return a.Name, table.POLICY_DIRECTION_IMPORT, nil - case PolicyType_EXPORT: - return a.Name, table.POLICY_DIRECTION_EXPORT, nil - default: - return "", table.POLICY_DIRECTION_NONE, fmt.Errorf("invalid policy type") - } - default: - return "", table.POLICY_DIRECTION_NONE, fmt.Errorf("invalid resource type") - } - -} - -func (s *Server) GetPolicyAssignment(ctx context.Context, arg *GetPolicyAssignmentRequest) (*GetPolicyAssignmentResponse, error) { - if arg == nil || arg.Assignment == nil { - return nil, fmt.Errorf("invalid request") - } - name, dir, err := toPolicyAssignmentName(arg.Assignment) - if err != nil { - return nil, err - } - def, pols, err := s.bgpServer.GetPolicyAssignment(name, dir) - if err != nil { - return nil, err - } - policies := make([]*table.Policy, 0, len(pols)) - for _, p := range pols { - t, err := table.NewPolicy(*p) - if err != nil { - return nil, err - } - policies = append(policies, t) - } - t := &table.PolicyAssignment{ - Name: name, - Type: dir, - Default: def, - Policies: policies, - } - return &GetPolicyAssignmentResponse{NewAPIPolicyAssignmentFromTableStruct(t)}, err -} - -func defaultRouteType(d RouteAction) table.RouteType { - switch d { - case RouteAction_ACCEPT: - return table.ROUTE_TYPE_ACCEPT - case RouteAction_REJECT: - return table.ROUTE_TYPE_REJECT - default: - return table.ROUTE_TYPE_NONE - } -} - -func toPolicyDefinition(policies []*Policy) []*config.PolicyDefinition { - l := make([]*config.PolicyDefinition, 0, len(policies)) - for _, p := range policies { - l = append(l, &config.PolicyDefinition{Name: p.Name}) - } - return l -} - -func (s *Server) AddPolicyAssignment(ctx context.Context, arg *AddPolicyAssignmentRequest) (*AddPolicyAssignmentResponse, error) { - if arg == nil || arg.Assignment == nil { - return nil, fmt.Errorf("invalid request") - } - name, dir, err := toPolicyAssignmentName(arg.Assignment) - if err != nil { - return nil, err - } - return &AddPolicyAssignmentResponse{}, s.bgpServer.AddPolicyAssignment(name, dir, toPolicyDefinition(arg.Assignment.Policies), defaultRouteType(arg.Assignment.Default)) -} - -func (s *Server) DeletePolicyAssignment(ctx context.Context, arg *DeletePolicyAssignmentRequest) (*DeletePolicyAssignmentResponse, error) { - if arg == nil || arg.Assignment == nil { - return nil, fmt.Errorf("invalid request") - } - name, dir, err := toPolicyAssignmentName(arg.Assignment) - if err != nil { - return nil, err - } - return &DeletePolicyAssignmentResponse{}, s.bgpServer.DeletePolicyAssignment(name, dir, toPolicyDefinition(arg.Assignment.Policies), arg.All) -} - -func (s *Server) ReplacePolicyAssignment(ctx context.Context, arg *ReplacePolicyAssignmentRequest) (*ReplacePolicyAssignmentResponse, error) { - if arg == nil || arg.Assignment == nil { - return nil, fmt.Errorf("invalid request") - } - name, dir, err := toPolicyAssignmentName(arg.Assignment) - if err != nil { - return nil, err - } - return &ReplacePolicyAssignmentResponse{}, s.bgpServer.ReplacePolicyAssignment(name, dir, toPolicyDefinition(arg.Assignment.Policies), defaultRouteType(arg.Assignment.Default)) -} - -func (s *Server) GetServer(ctx context.Context, arg *GetServerRequest) (*GetServerResponse, error) { - g := s.bgpServer.GetServer() - return &GetServerResponse{ - Global: &Global{ - As: g.Config.As, - RouterId: g.Config.RouterId, - ListenPort: g.Config.Port, - ListenAddresses: g.Config.LocalAddressList, - UseMultiplePaths: g.UseMultiplePaths.Config.Enabled, - }, - }, nil -} - -func NewGlobalFromAPIStruct(a *Global) *config.Global { - families := make([]config.AfiSafi, 0, len(a.Families)) - for _, f := range a.Families { - name := config.IntToAfiSafiTypeMap[int(f)] - rf, _ := bgp.GetRouteFamily(string(name)) - families = append(families, config.AfiSafi{ - Config: config.AfiSafiConfig{ - AfiSafiName: name, - Enabled: true, - }, - State: config.AfiSafiState{ - AfiSafiName: name, - Enabled: true, - Family: rf, - }, - }) - } - - applyPolicy := &config.ApplyPolicy{} - ReadApplyPolicyFromAPIStruct(applyPolicy, a.ApplyPolicy) - - global := &config.Global{ - Config: config.GlobalConfig{ - As: a.As, - RouterId: a.RouterId, - Port: a.ListenPort, - LocalAddressList: a.ListenAddresses, - }, - ApplyPolicy: *applyPolicy, - AfiSafis: families, - UseMultiplePaths: config.UseMultiplePaths{ - Config: config.UseMultiplePathsConfig{ - Enabled: a.UseMultiplePaths, - }, - }, - } - if a.RouteSelectionOptions != nil { - global.RouteSelectionOptions = config.RouteSelectionOptions{ - Config: config.RouteSelectionOptionsConfig{ - AlwaysCompareMed: a.RouteSelectionOptions.AlwaysCompareMed, - IgnoreAsPathLength: a.RouteSelectionOptions.IgnoreAsPathLength, - ExternalCompareRouterId: a.RouteSelectionOptions.ExternalCompareRouterId, - AdvertiseInactiveRoutes: a.RouteSelectionOptions.AdvertiseInactiveRoutes, - EnableAigp: a.RouteSelectionOptions.EnableAigp, - IgnoreNextHopIgpMetric: a.RouteSelectionOptions.IgnoreNextHopIgpMetric, - DisableBestPathSelection: a.RouteSelectionOptions.DisableBestPathSelection, - }, - } - } - if a.DefaultRouteDistance != nil { - global.DefaultRouteDistance = config.DefaultRouteDistance{ - Config: config.DefaultRouteDistanceConfig{ - ExternalRouteDistance: uint8(a.DefaultRouteDistance.ExternalRouteDistance), - InternalRouteDistance: uint8(a.DefaultRouteDistance.InternalRouteDistance), - }, - } - } - if a.Confederation != nil { - global.Confederation = config.Confederation{ - Config: config.ConfederationConfig{ - Enabled: a.Confederation.Enabled, - Identifier: a.Confederation.Identifier, - MemberAsList: a.Confederation.MemberAsList, - }, - } - } - if a.GracefulRestart != nil { - global.GracefulRestart = config.GracefulRestart{ - Config: config.GracefulRestartConfig{ - Enabled: a.GracefulRestart.Enabled, - RestartTime: uint16(a.GracefulRestart.RestartTime), - StaleRoutesTime: float64(a.GracefulRestart.StaleRoutesTime), - HelperOnly: a.GracefulRestart.HelperOnly, - DeferralTime: uint16(a.GracefulRestart.DeferralTime), - NotificationEnabled: a.GracefulRestart.NotificationEnabled, - LongLivedEnabled: a.GracefulRestart.LonglivedEnabled, - }, - } - } - return global -} - -func NewGlobalFromConfigStruct(c *config.Global) *Global { - families := make([]uint32, 0, len(c.AfiSafis)) - for _, f := range c.AfiSafis { - families = append(families, uint32(config.AfiSafiTypeToIntMap[f.Config.AfiSafiName])) - } - - applyPolicy := NewApplyPolicyFromConfigStruct(&c.ApplyPolicy) - - return &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: &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: &DefaultRouteDistance{ - ExternalRouteDistance: uint32(c.DefaultRouteDistance.Config.ExternalRouteDistance), - InternalRouteDistance: uint32(c.DefaultRouteDistance.Config.InternalRouteDistance), - }, - Confederation: &Confederation{ - Enabled: c.Confederation.Config.Enabled, - Identifier: c.Confederation.Config.Identifier, - MemberAsList: c.Confederation.Config.MemberAsList, - }, - GracefulRestart: &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, - } -} - -func (s *Server) StartServer(ctx context.Context, arg *StartServerRequest) (*StartServerResponse, error) { - if arg == nil || arg.Global == nil { - return nil, fmt.Errorf("invalid request") - } - g := arg.Global - if net.ParseIP(g.RouterId) == nil { - return nil, fmt.Errorf("invalid router-id format: %s", g.RouterId) - } - - global := NewGlobalFromAPIStruct(arg.Global) - - return &StartServerResponse{}, s.bgpServer.Start(global) -} - -func (s *Server) StopServer(ctx context.Context, arg *StopServerRequest) (*StopServerResponse, error) { - return &StopServerResponse{}, s.bgpServer.Stop() -} - -func (s *Server) GetRibInfo(ctx context.Context, arg *GetRibInfoRequest) (*GetRibInfoResponse, error) { - if arg == nil || arg.Info == nil { - return nil, fmt.Errorf("invalid request") - } - family := bgp.RouteFamily(arg.Info.Family) - var in bool - var err error - var info *table.TableInfo - switch arg.Info.Type { - case Resource_GLOBAL, Resource_LOCAL: - info, err = s.bgpServer.GetRibInfo(arg.Info.Name, family) - case Resource_ADJ_IN: - in = true - fallthrough - case Resource_ADJ_OUT: - info, err = s.bgpServer.GetAdjRibInfo(arg.Info.Name, family, in) - default: - return nil, fmt.Errorf("unsupported resource type: %s", arg.Info.Type) - } - - if err != nil { - return nil, err - } - - return &GetRibInfoResponse{ - Info: &TableInfo{ - Type: arg.Info.Type, - Family: arg.Info.Family, - Name: arg.Info.Name, - NumDestination: uint64(info.NumDestination), - NumPath: uint64(info.NumPath), - NumAccepted: uint64(info.NumAccepted), - }, - }, nil -} - -func (s *Server) AddCollector(ctx context.Context, arg *AddCollectorRequest) (*AddCollectorResponse, error) { - return &AddCollectorResponse{}, s.bgpServer.AddCollector(&config.CollectorConfig{ - Url: arg.Url, - DbName: arg.DbName, - TableDumpInterval: arg.TableDumpInterval, - }) -} - -func (s *Server) Shutdown(ctx context.Context, arg *ShutdownRequest) (*ShutdownResponse, error) { - s.bgpServer.Shutdown() - return &ShutdownResponse{}, nil -} diff --git a/api/util.go b/api/util.go index 9b7a389e..b77b35ec 100644 --- a/api/util.go +++ b/api/util.go @@ -20,7 +20,6 @@ import ( "net" "time" - "github.com/osrg/gobgp/config" "github.com/osrg/gobgp/packet/bgp" ) @@ -108,22 +107,3 @@ func (p *Path) GetNativePathAttributes() ([]bgp.PathAttributeInterface, error) { } return UnmarshalPathAttributes(p.AnyPattrs) } - -func extractFamilyFromConfigAfiSafi(c *config.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 -} |