github.com/osrg/gobgp@v2.0.0+incompatible/pkg/server/grpc_server.go (about)

     1  // Copyright (C) 2014-2016 Nippon Telegraph and Telephone Corporation.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    12  // implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package server
    17  
    18  import (
    19  	"bytes"
    20  	"fmt"
    21  	"io"
    22  	"net"
    23  	"reflect"
    24  	"regexp"
    25  	"strconv"
    26  	"strings"
    27  	"sync"
    28  	"time"
    29  
    30  	farm "github.com/dgryski/go-farm"
    31  	"github.com/golang/protobuf/ptypes"
    32  	"github.com/golang/protobuf/ptypes/any"
    33  	"github.com/golang/protobuf/ptypes/empty"
    34  	log "github.com/sirupsen/logrus"
    35  	"golang.org/x/net/context"
    36  	"google.golang.org/grpc"
    37  
    38  	api "github.com/osrg/gobgp/api"
    39  	"github.com/osrg/gobgp/internal/pkg/apiutil"
    40  	"github.com/osrg/gobgp/internal/pkg/config"
    41  	"github.com/osrg/gobgp/internal/pkg/table"
    42  	"github.com/osrg/gobgp/pkg/packet/bgp"
    43  )
    44  
    45  type server struct {
    46  	bgpServer  *BgpServer
    47  	grpcServer *grpc.Server
    48  	hosts      string
    49  }
    50  
    51  func newAPIserver(b *BgpServer, g *grpc.Server, hosts string) *server {
    52  	grpc.EnableTracing = false
    53  	s := &server{
    54  		bgpServer:  b,
    55  		grpcServer: g,
    56  		hosts:      hosts,
    57  	}
    58  	api.RegisterGobgpApiServer(g, s)
    59  	return s
    60  }
    61  
    62  func (s *server) serve() error {
    63  	var wg sync.WaitGroup
    64  	l := strings.Split(s.hosts, ",")
    65  	wg.Add(len(l))
    66  
    67  	serve := func(host string) {
    68  		defer wg.Done()
    69  		lis, err := net.Listen("tcp", host)
    70  		if err != nil {
    71  			log.WithFields(log.Fields{
    72  				"Topic": "grpc",
    73  				"Key":   host,
    74  				"Error": err,
    75  			}).Warn("listen failed")
    76  			return
    77  		}
    78  		err = s.grpcServer.Serve(lis)
    79  		log.WithFields(log.Fields{
    80  			"Topic": "grpc",
    81  			"Key":   host,
    82  			"Error": err,
    83  		}).Warn("accept failed")
    84  	}
    85  
    86  	for _, host := range l {
    87  		go serve(host)
    88  	}
    89  	wg.Wait()
    90  	return nil
    91  }
    92  
    93  func (s *server) ListPeer(r *api.ListPeerRequest, stream api.GobgpApi_ListPeerServer) error {
    94  	ctx, cancel := context.WithCancel(context.Background())
    95  	defer cancel()
    96  	fn := func(p *api.Peer) {
    97  		if err := stream.Send(&api.ListPeerResponse{Peer: p}); err != nil {
    98  			cancel()
    99  			return
   100  		}
   101  	}
   102  	return s.bgpServer.ListPeer(ctx, r, fn)
   103  }
   104  
   105  func newValidationFromTableStruct(v *table.Validation) *api.Validation {
   106  	if v == nil {
   107  		return &api.Validation{}
   108  	}
   109  	return &api.Validation{
   110  		Reason:          api.Validation_Reason(v.Reason.ToInt()),
   111  		Matched:         newRoaListFromTableStructList(v.Matched),
   112  		UnmatchedAs:     newRoaListFromTableStructList(v.UnmatchedAs),
   113  		UnmatchedLength: newRoaListFromTableStructList(v.UnmatchedLength),
   114  	}
   115  }
   116  
   117  func toPathAPI(binNlri []byte, binPattrs [][]byte, anyNlri *any.Any, anyPattrs []*any.Any, path *table.Path, v *table.Validation) *api.Path {
   118  	nlri := path.GetNlri()
   119  	t, _ := ptypes.TimestampProto(path.GetTimestamp())
   120  	p := &api.Path{
   121  		Nlri:               anyNlri,
   122  		Pattrs:             anyPattrs,
   123  		Age:                t,
   124  		IsWithdraw:         path.IsWithdraw,
   125  		Validation:         newValidationFromTableStruct(v),
   126  		Family:             &api.Family{Afi: api.Family_Afi(nlri.AFI()), Safi: api.Family_Safi(nlri.SAFI())},
   127  		Stale:              path.IsStale(),
   128  		IsFromExternal:     path.IsFromExternal(),
   129  		NoImplicitWithdraw: path.NoImplicitWithdraw(),
   130  		IsNexthopInvalid:   path.IsNexthopInvalid,
   131  		Identifier:         nlri.PathIdentifier(),
   132  		LocalIdentifier:    nlri.PathLocalIdentifier(),
   133  		NlriBinary:         binNlri,
   134  		PattrsBinary:       binPattrs,
   135  	}
   136  	if s := path.GetSource(); s != nil {
   137  		p.SourceAsn = s.AS
   138  		p.SourceId = s.ID.String()
   139  		p.NeighborIp = s.Address.String()
   140  	}
   141  	return p
   142  }
   143  
   144  func toPathApi(path *table.Path, v *table.Validation) *api.Path {
   145  	nlri := path.GetNlri()
   146  	anyNlri := apiutil.MarshalNLRI(nlri)
   147  	anyPattrs := apiutil.MarshalPathAttributes(path.GetPathAttrs())
   148  	return toPathAPI(nil, nil, anyNlri, anyPattrs, path, v)
   149  }
   150  
   151  func getValidation(v []*table.Validation, i int) *table.Validation {
   152  	if v == nil {
   153  		return nil
   154  	} else {
   155  		return v[i]
   156  	}
   157  }
   158  
   159  func (s *server) ListPath(r *api.ListPathRequest, stream api.GobgpApi_ListPathServer) error {
   160  	ctx, cancel := context.WithCancel(context.Background())
   161  	defer cancel()
   162  	fn := func(d *api.Destination) {
   163  		if err := stream.Send(&api.ListPathResponse{Destination: d}); err != nil {
   164  			cancel()
   165  		}
   166  	}
   167  	return s.bgpServer.ListPath(ctx, r, fn)
   168  }
   169  
   170  func (s *server) MonitorTable(arg *api.MonitorTableRequest, stream api.GobgpApi_MonitorTableServer) error {
   171  	ctx, cancel := context.WithCancel(context.Background())
   172  	var err error
   173  	s.bgpServer.MonitorTable(ctx, arg, func(p *api.Path) {
   174  		if err = stream.Send(&api.MonitorTableResponse{
   175  			Path: p,
   176  		}); err != nil {
   177  			cancel()
   178  			return
   179  		}
   180  	})
   181  	<-ctx.Done()
   182  	return err
   183  }
   184  
   185  func (s *server) MonitorPeer(arg *api.MonitorPeerRequest, stream api.GobgpApi_MonitorPeerServer) error {
   186  	ctx, cancel := context.WithCancel(context.Background())
   187  	var err error
   188  	err = s.bgpServer.MonitorPeer(ctx, arg, func(p *api.Peer) {
   189  		if err = stream.Send(&api.MonitorPeerResponse{
   190  			Peer: p,
   191  		}); err != nil {
   192  			fmt.Println("try to cancel")
   193  			cancel()
   194  			return
   195  		}
   196  	})
   197  	<-ctx.Done()
   198  	return err
   199  }
   200  
   201  func (s *server) ResetPeer(ctx context.Context, r *api.ResetPeerRequest) (*empty.Empty, error) {
   202  	return &empty.Empty{}, s.bgpServer.ResetPeer(ctx, r)
   203  }
   204  
   205  func (s *server) ShutdownPeer(ctx context.Context, r *api.ShutdownPeerRequest) (*empty.Empty, error) {
   206  	return &empty.Empty{}, s.bgpServer.ShutdownPeer(ctx, r)
   207  }
   208  
   209  func (s *server) EnablePeer(ctx context.Context, r *api.EnablePeerRequest) (*empty.Empty, error) {
   210  	return &empty.Empty{}, s.bgpServer.EnablePeer(ctx, r)
   211  }
   212  
   213  func (s *server) DisablePeer(ctx context.Context, r *api.DisablePeerRequest) (*empty.Empty, error) {
   214  	return &empty.Empty{}, s.bgpServer.DisablePeer(ctx, r)
   215  }
   216  
   217  func (s *server) SetPolicies(ctx context.Context, r *api.SetPoliciesRequest) (*empty.Empty, error) {
   218  	return &empty.Empty{}, s.bgpServer.SetPolicies(ctx, r)
   219  }
   220  
   221  func newRoutingPolicyFromApiStruct(arg *api.SetPoliciesRequest) (*config.RoutingPolicy, error) {
   222  	policyDefinitions := make([]config.PolicyDefinition, 0, len(arg.Policies))
   223  	for _, p := range arg.Policies {
   224  		pd, err := newConfigPolicyFromApiStruct(p)
   225  		if err != nil {
   226  			return nil, err
   227  		}
   228  		policyDefinitions = append(policyDefinitions, *pd)
   229  	}
   230  
   231  	definedSets, err := newConfigDefinedSetsFromApiStruct(arg.DefinedSets)
   232  	if err != nil {
   233  		return nil, err
   234  	}
   235  
   236  	return &config.RoutingPolicy{
   237  		DefinedSets:       *definedSets,
   238  		PolicyDefinitions: policyDefinitions,
   239  	}, nil
   240  }
   241  
   242  func api2Path(resource api.TableType, path *api.Path, isWithdraw bool) (*table.Path, error) {
   243  	var pi *table.PeerInfo
   244  	var nlri bgp.AddrPrefixInterface
   245  	var nexthop string
   246  
   247  	if path.SourceAsn != 0 {
   248  		pi = &table.PeerInfo{
   249  			AS: path.SourceAsn,
   250  			ID: net.ParseIP(path.SourceId),
   251  		}
   252  	}
   253  
   254  	nlri, err := apiutil.GetNativeNlri(path)
   255  	if err != nil {
   256  		return nil, err
   257  	}
   258  	nlri.SetPathIdentifier(path.Identifier)
   259  
   260  	attrList, err := apiutil.GetNativePathAttributes(path)
   261  	if err != nil {
   262  		return nil, err
   263  	}
   264  
   265  	pattrs := make([]bgp.PathAttributeInterface, 0)
   266  	seen := make(map[bgp.BGPAttrType]struct{})
   267  	for _, attr := range attrList {
   268  		attrType := attr.GetType()
   269  		if _, ok := seen[attrType]; !ok {
   270  			seen[attrType] = struct{}{}
   271  		} else {
   272  			return nil, fmt.Errorf("duplicated path attribute type: %d", attrType)
   273  		}
   274  
   275  		switch a := attr.(type) {
   276  		case *bgp.PathAttributeNextHop:
   277  			nexthop = a.Value.String()
   278  		case *bgp.PathAttributeMpReachNLRI:
   279  			nlri = a.Value[0]
   280  			nexthop = a.Nexthop.String()
   281  		default:
   282  			pattrs = append(pattrs, attr)
   283  		}
   284  	}
   285  
   286  	if nlri == nil {
   287  		return nil, fmt.Errorf("nlri not found")
   288  	} else if !path.IsWithdraw && nexthop == "" {
   289  		return nil, fmt.Errorf("nexthop not found")
   290  	}
   291  	rf := bgp.AfiSafiToRouteFamily(uint16(path.Family.Afi), uint8(path.Family.Safi))
   292  	if resource != api.TableType_VRF && rf == bgp.RF_IPv4_UC && net.ParseIP(nexthop).To4() != nil {
   293  		pattrs = append(pattrs, bgp.NewPathAttributeNextHop(nexthop))
   294  	} else {
   295  		pattrs = append(pattrs, bgp.NewPathAttributeMpReachNLRI(nexthop, []bgp.AddrPrefixInterface{nlri}))
   296  	}
   297  
   298  	doWithdraw := (isWithdraw || path.IsWithdraw)
   299  	newPath := table.NewPath(pi, nlri, doWithdraw, pattrs, time.Now(), path.NoImplicitWithdraw)
   300  	if !doWithdraw {
   301  		total := bytes.NewBuffer(make([]byte, 0))
   302  		for _, a := range newPath.GetPathAttrs() {
   303  			if a.GetType() == bgp.BGP_ATTR_TYPE_MP_REACH_NLRI {
   304  				continue
   305  			}
   306  			b, _ := a.Serialize()
   307  			total.Write(b)
   308  		}
   309  		newPath.SetHash(farm.Hash32(total.Bytes()))
   310  	}
   311  	newPath.SetIsFromExternal(path.IsFromExternal)
   312  	return newPath, nil
   313  }
   314  
   315  func (s *server) AddPath(ctx context.Context, r *api.AddPathRequest) (*api.AddPathResponse, error) {
   316  	return s.bgpServer.AddPath(ctx, r)
   317  }
   318  
   319  func (s *server) DeletePath(ctx context.Context, r *api.DeletePathRequest) (*empty.Empty, error) {
   320  	return &empty.Empty{}, s.bgpServer.DeletePath(ctx, r)
   321  }
   322  
   323  func (s *server) EnableMrt(ctx context.Context, r *api.EnableMrtRequest) (*empty.Empty, error) {
   324  	return &empty.Empty{}, s.bgpServer.EnableMrt(ctx, r)
   325  }
   326  
   327  func (s *server) DisableMrt(ctx context.Context, r *api.DisableMrtRequest) (*empty.Empty, error) {
   328  	return &empty.Empty{}, s.bgpServer.DisableMrt(ctx, r)
   329  }
   330  
   331  func (s *server) AddPathStream(stream api.GobgpApi_AddPathStreamServer) error {
   332  	for {
   333  		arg, err := stream.Recv()
   334  		if err == io.EOF {
   335  			break
   336  		} else if err != nil {
   337  			return err
   338  		}
   339  
   340  		if arg.TableType != api.TableType_GLOBAL && arg.TableType != api.TableType_VRF {
   341  			return fmt.Errorf("unsupported resource: %s", arg.TableType)
   342  		}
   343  		pathList := make([]*table.Path, 0, len(arg.Paths))
   344  		for _, apiPath := range arg.Paths {
   345  			if path, err := api2Path(arg.TableType, apiPath, apiPath.IsWithdraw); err != nil {
   346  				return err
   347  			} else {
   348  				pathList = append(pathList, path)
   349  			}
   350  		}
   351  		err = s.bgpServer.addPathList(arg.VrfId, pathList)
   352  		if err != nil {
   353  			return err
   354  		}
   355  	}
   356  	return stream.SendAndClose(&empty.Empty{})
   357  }
   358  
   359  func (s *server) AddBmp(ctx context.Context, r *api.AddBmpRequest) (*empty.Empty, error) {
   360  	return &empty.Empty{}, s.bgpServer.AddBmp(ctx, r)
   361  }
   362  
   363  func (s *server) DeleteBmp(ctx context.Context, r *api.DeleteBmpRequest) (*empty.Empty, error) {
   364  	return &empty.Empty{}, s.bgpServer.DeleteBmp(ctx, r)
   365  }
   366  
   367  func (s *server) AddRpki(ctx context.Context, r *api.AddRpkiRequest) (*empty.Empty, error) {
   368  	return &empty.Empty{}, s.bgpServer.AddRpki(ctx, r)
   369  }
   370  
   371  func (s *server) DeleteRpki(ctx context.Context, r *api.DeleteRpkiRequest) (*empty.Empty, error) {
   372  	return &empty.Empty{}, s.bgpServer.DeleteRpki(ctx, r)
   373  }
   374  
   375  func (s *server) EnableRpki(ctx context.Context, r *api.EnableRpkiRequest) (*empty.Empty, error) {
   376  	return &empty.Empty{}, s.bgpServer.EnableRpki(ctx, r)
   377  }
   378  
   379  func (s *server) DisableRpki(ctx context.Context, r *api.DisableRpkiRequest) (*empty.Empty, error) {
   380  	return &empty.Empty{}, s.bgpServer.DisableRpki(ctx, r)
   381  }
   382  
   383  func (s *server) ResetRpki(ctx context.Context, r *api.ResetRpkiRequest) (*empty.Empty, error) {
   384  	return &empty.Empty{}, s.bgpServer.ResetRpki(ctx, r)
   385  }
   386  
   387  func (s *server) ListRpki(r *api.ListRpkiRequest, stream api.GobgpApi_ListRpkiServer) error {
   388  	ctx, cancel := context.WithCancel(context.Background())
   389  	defer cancel()
   390  	fn := func(r *api.Rpki) {
   391  		if err := stream.Send(&api.ListRpkiResponse{Server: r}); err != nil {
   392  			cancel()
   393  		}
   394  	}
   395  	return s.bgpServer.ListRpki(ctx, r, fn)
   396  }
   397  
   398  func (s *server) ListRpkiTable(r *api.ListRpkiTableRequest, stream api.GobgpApi_ListRpkiTableServer) error {
   399  	ctx, cancel := context.WithCancel(context.Background())
   400  	defer cancel()
   401  	fn := func(r *api.Roa) {
   402  		if err := stream.Send(&api.ListRpkiTableResponse{Roa: r}); err != nil {
   403  			cancel()
   404  		}
   405  	}
   406  	return s.bgpServer.ListRpkiTable(ctx, r, fn)
   407  }
   408  
   409  func (s *server) EnableZebra(ctx context.Context, r *api.EnableZebraRequest) (*empty.Empty, error) {
   410  	return &empty.Empty{}, s.bgpServer.EnableZebra(ctx, r)
   411  }
   412  
   413  func (s *server) ListVrf(r *api.ListVrfRequest, stream api.GobgpApi_ListVrfServer) error {
   414  	ctx, cancel := context.WithCancel(context.Background())
   415  	defer cancel()
   416  	fn := func(v *api.Vrf) {
   417  		if err := stream.Send(&api.ListVrfResponse{Vrf: v}); err != nil {
   418  			cancel()
   419  		}
   420  	}
   421  	return s.bgpServer.ListVrf(ctx, r, fn)
   422  }
   423  
   424  func (s *server) AddVrf(ctx context.Context, r *api.AddVrfRequest) (*empty.Empty, error) {
   425  	return &empty.Empty{}, s.bgpServer.AddVrf(ctx, r)
   426  }
   427  
   428  func (s *server) DeleteVrf(ctx context.Context, r *api.DeleteVrfRequest) (*empty.Empty, error) {
   429  	return &empty.Empty{}, s.bgpServer.DeleteVrf(ctx, r)
   430  }
   431  
   432  func readMpGracefulRestartFromAPIStruct(c *config.MpGracefulRestart, a *api.MpGracefulRestart) {
   433  	if c == nil || a == nil {
   434  		return
   435  	}
   436  	if a.Config != nil {
   437  		c.Config.Enabled = a.Config.Enabled
   438  	}
   439  }
   440  
   441  func readAfiSafiConfigFromAPIStruct(c *config.AfiSafiConfig, a *api.AfiSafiConfig) {
   442  	if c == nil || a == nil {
   443  		return
   444  	}
   445  	rf := bgp.AfiSafiToRouteFamily(uint16(a.Family.Afi), uint8(a.Family.Safi))
   446  	c.AfiSafiName = config.AfiSafiType(rf.String())
   447  	c.Enabled = a.Enabled
   448  }
   449  
   450  func readAfiSafiStateFromAPIStruct(s *config.AfiSafiState, a *api.AfiSafiConfig) {
   451  	if s == nil || a == nil {
   452  		return
   453  	}
   454  	// Store only address family value for the convenience
   455  	s.Family = bgp.AfiSafiToRouteFamily(uint16(a.Family.Afi), uint8(a.Family.Safi))
   456  }
   457  
   458  func readPrefixLimitFromAPIStruct(c *config.PrefixLimit, a *api.PrefixLimit) {
   459  	if c == nil || a == nil {
   460  		return
   461  	}
   462  	c.Config.MaxPrefixes = a.MaxPrefixes
   463  	c.Config.ShutdownThresholdPct = config.Percentage(a.ShutdownThresholdPct)
   464  }
   465  
   466  func readApplyPolicyFromAPIStruct(c *config.ApplyPolicy, a *api.ApplyPolicy) {
   467  	if c == nil || a == nil {
   468  		return
   469  	}
   470  	if a.ImportPolicy != nil {
   471  		c.Config.DefaultImportPolicy = config.IntToDefaultPolicyTypeMap[int(a.ImportPolicy.DefaultAction)]
   472  		for _, p := range a.ImportPolicy.Policies {
   473  			c.Config.ImportPolicyList = append(c.Config.ImportPolicyList, p.Name)
   474  		}
   475  	}
   476  	if a.ExportPolicy != nil {
   477  		c.Config.DefaultExportPolicy = config.IntToDefaultPolicyTypeMap[int(a.ExportPolicy.DefaultAction)]
   478  		for _, p := range a.ExportPolicy.Policies {
   479  			c.Config.ExportPolicyList = append(c.Config.ExportPolicyList, p.Name)
   480  		}
   481  	}
   482  	if a.InPolicy != nil {
   483  		c.Config.DefaultInPolicy = config.IntToDefaultPolicyTypeMap[int(a.InPolicy.DefaultAction)]
   484  		for _, p := range a.InPolicy.Policies {
   485  			c.Config.InPolicyList = append(c.Config.InPolicyList, p.Name)
   486  		}
   487  	}
   488  }
   489  
   490  func readRouteSelectionOptionsFromAPIStruct(c *config.RouteSelectionOptions, a *api.RouteSelectionOptions) {
   491  	if c == nil || a == nil {
   492  		return
   493  	}
   494  	if a.Config != nil {
   495  		c.Config.AlwaysCompareMed = a.Config.AlwaysCompareMed
   496  		c.Config.IgnoreAsPathLength = a.Config.IgnoreAsPathLength
   497  		c.Config.ExternalCompareRouterId = a.Config.ExternalCompareRouterId
   498  		c.Config.AdvertiseInactiveRoutes = a.Config.AdvertiseInactiveRoutes
   499  		c.Config.EnableAigp = a.Config.EnableAigp
   500  		c.Config.IgnoreNextHopIgpMetric = a.Config.IgnoreNextHopIgpMetric
   501  	}
   502  }
   503  
   504  func readUseMultiplePathsFromAPIStruct(c *config.UseMultiplePaths, a *api.UseMultiplePaths) {
   505  	if c == nil || a == nil {
   506  		return
   507  	}
   508  	if a.Config != nil {
   509  		c.Config.Enabled = a.Config.Enabled
   510  	}
   511  	if a.Ebgp != nil && a.Ebgp.Config != nil {
   512  		c.Ebgp = config.Ebgp{
   513  			Config: config.EbgpConfig{
   514  				AllowMultipleAs: a.Ebgp.Config.AllowMultipleAs,
   515  				MaximumPaths:    a.Ebgp.Config.MaximumPaths,
   516  			},
   517  		}
   518  	}
   519  	if a.Ibgp != nil && a.Ibgp.Config != nil {
   520  		c.Ibgp = config.Ibgp{
   521  			Config: config.IbgpConfig{
   522  				MaximumPaths: a.Ibgp.Config.MaximumPaths,
   523  			},
   524  		}
   525  	}
   526  }
   527  
   528  func readRouteTargetMembershipFromAPIStruct(c *config.RouteTargetMembership, a *api.RouteTargetMembership) {
   529  	if c == nil || a == nil {
   530  		return
   531  	}
   532  	if a.Config != nil {
   533  		c.Config.DeferralTime = uint16(a.Config.DeferralTime)
   534  	}
   535  }
   536  
   537  func readLongLivedGracefulRestartFromAPIStruct(c *config.LongLivedGracefulRestart, a *api.LongLivedGracefulRestart) {
   538  	if c == nil || a == nil {
   539  		return
   540  	}
   541  	if a.Config != nil {
   542  		c.Config.Enabled = a.Config.Enabled
   543  		c.Config.RestartTime = a.Config.RestartTime
   544  	}
   545  }
   546  
   547  func readAddPathsFromAPIStruct(c *config.AddPaths, a *api.AddPaths) {
   548  	if c == nil || a == nil {
   549  		return
   550  	}
   551  	if a.Config != nil {
   552  		c.Config.Receive = a.Config.Receive
   553  		c.Config.SendMax = uint8(a.Config.SendMax)
   554  	}
   555  }
   556  
   557  func newNeighborFromAPIStruct(a *api.Peer) (*config.Neighbor, error) {
   558  	pconf := &config.Neighbor{}
   559  	if a.Conf != nil {
   560  		pconf.Config.PeerAs = a.Conf.PeerAs
   561  		pconf.Config.LocalAs = a.Conf.LocalAs
   562  		pconf.Config.AuthPassword = a.Conf.AuthPassword
   563  		pconf.Config.RouteFlapDamping = a.Conf.RouteFlapDamping
   564  		pconf.Config.Description = a.Conf.Description
   565  		pconf.Config.PeerGroup = a.Conf.PeerGroup
   566  		pconf.Config.PeerType = config.IntToPeerTypeMap[int(a.Conf.PeerType)]
   567  		pconf.Config.NeighborAddress = a.Conf.NeighborAddress
   568  		pconf.Config.AdminDown = a.Conf.AdminDown
   569  		pconf.Config.NeighborInterface = a.Conf.NeighborInterface
   570  		pconf.Config.Vrf = a.Conf.Vrf
   571  		pconf.AsPathOptions.Config.AllowOwnAs = uint8(a.Conf.AllowOwnAs)
   572  		pconf.AsPathOptions.Config.ReplacePeerAs = a.Conf.ReplacePeerAs
   573  
   574  		switch a.Conf.RemovePrivateAs {
   575  		case api.PeerConf_ALL:
   576  			pconf.Config.RemovePrivateAs = config.REMOVE_PRIVATE_AS_OPTION_ALL
   577  		case api.PeerConf_REPLACE:
   578  			pconf.Config.RemovePrivateAs = config.REMOVE_PRIVATE_AS_OPTION_REPLACE
   579  		}
   580  
   581  		if a.State != nil {
   582  			localCaps, err := apiutil.UnmarshalCapabilities(a.State.LocalCap)
   583  			if err != nil {
   584  				return nil, err
   585  			}
   586  			remoteCaps, err := apiutil.UnmarshalCapabilities(a.State.RemoteCap)
   587  			if err != nil {
   588  				return nil, err
   589  			}
   590  			pconf.State.LocalCapabilityList = localCaps
   591  			pconf.State.RemoteCapabilityList = remoteCaps
   592  
   593  			pconf.State.RemoteRouterId = a.State.RouterId
   594  		}
   595  
   596  		for _, af := range a.AfiSafis {
   597  			afiSafi := config.AfiSafi{}
   598  			readMpGracefulRestartFromAPIStruct(&afiSafi.MpGracefulRestart, af.MpGracefulRestart)
   599  			readAfiSafiConfigFromAPIStruct(&afiSafi.Config, af.Config)
   600  			readAfiSafiStateFromAPIStruct(&afiSafi.State, af.Config)
   601  			readApplyPolicyFromAPIStruct(&afiSafi.ApplyPolicy, af.ApplyPolicy)
   602  			readRouteSelectionOptionsFromAPIStruct(&afiSafi.RouteSelectionOptions, af.RouteSelectionOptions)
   603  			readUseMultiplePathsFromAPIStruct(&afiSafi.UseMultiplePaths, af.UseMultiplePaths)
   604  			readPrefixLimitFromAPIStruct(&afiSafi.PrefixLimit, af.PrefixLimits)
   605  			readRouteTargetMembershipFromAPIStruct(&afiSafi.RouteTargetMembership, af.RouteTargetMembership)
   606  			readLongLivedGracefulRestartFromAPIStruct(&afiSafi.LongLivedGracefulRestart, af.LongLivedGracefulRestart)
   607  			readAddPathsFromAPIStruct(&afiSafi.AddPaths, af.AddPaths)
   608  			pconf.AfiSafis = append(pconf.AfiSafis, afiSafi)
   609  		}
   610  	}
   611  
   612  	if a.Timers != nil {
   613  		if a.Timers.Config != nil {
   614  			pconf.Timers.Config.ConnectRetry = float64(a.Timers.Config.ConnectRetry)
   615  			pconf.Timers.Config.HoldTime = float64(a.Timers.Config.HoldTime)
   616  			pconf.Timers.Config.KeepaliveInterval = float64(a.Timers.Config.KeepaliveInterval)
   617  			pconf.Timers.Config.MinimumAdvertisementInterval = float64(a.Timers.Config.MinimumAdvertisementInterval)
   618  		}
   619  		if a.Timers.State != nil {
   620  			pconf.Timers.State.KeepaliveInterval = float64(a.Timers.State.KeepaliveInterval)
   621  			pconf.Timers.State.NegotiatedHoldTime = float64(a.Timers.State.NegotiatedHoldTime)
   622  		}
   623  	}
   624  	if a.RouteReflector != nil {
   625  		pconf.RouteReflector.Config.RouteReflectorClusterId = config.RrClusterIdType(a.RouteReflector.RouteReflectorClusterId)
   626  		pconf.RouteReflector.Config.RouteReflectorClient = a.RouteReflector.RouteReflectorClient
   627  	}
   628  	if a.RouteServer != nil {
   629  		pconf.RouteServer.Config.RouteServerClient = a.RouteServer.RouteServerClient
   630  	}
   631  	if a.GracefulRestart != nil {
   632  		pconf.GracefulRestart.Config.Enabled = a.GracefulRestart.Enabled
   633  		pconf.GracefulRestart.Config.RestartTime = uint16(a.GracefulRestart.RestartTime)
   634  		pconf.GracefulRestart.Config.HelperOnly = a.GracefulRestart.HelperOnly
   635  		pconf.GracefulRestart.Config.DeferralTime = uint16(a.GracefulRestart.DeferralTime)
   636  		pconf.GracefulRestart.Config.NotificationEnabled = a.GracefulRestart.NotificationEnabled
   637  		pconf.GracefulRestart.Config.LongLivedEnabled = a.GracefulRestart.LonglivedEnabled
   638  		pconf.GracefulRestart.State.LocalRestarting = a.GracefulRestart.LocalRestarting
   639  	}
   640  	readApplyPolicyFromAPIStruct(&pconf.ApplyPolicy, a.ApplyPolicy)
   641  	if a.Transport != nil {
   642  		pconf.Transport.Config.LocalAddress = a.Transport.LocalAddress
   643  		pconf.Transport.Config.PassiveMode = a.Transport.PassiveMode
   644  		pconf.Transport.Config.RemotePort = uint16(a.Transport.RemotePort)
   645  	}
   646  	if a.EbgpMultihop != nil {
   647  		pconf.EbgpMultihop.Config.Enabled = a.EbgpMultihop.Enabled
   648  		pconf.EbgpMultihop.Config.MultihopTtl = uint8(a.EbgpMultihop.MultihopTtl)
   649  	}
   650  	if a.State != nil {
   651  		pconf.State.SessionState = config.SessionState(strings.ToUpper(string(a.State.SessionState)))
   652  		pconf.State.AdminState = config.IntToAdminStateMap[int(a.State.AdminState)]
   653  
   654  		pconf.State.PeerAs = a.State.PeerAs
   655  		pconf.State.PeerType = config.IntToPeerTypeMap[int(a.State.PeerType)]
   656  		pconf.State.NeighborAddress = a.State.NeighborAddress
   657  
   658  		if a.State.Messages != nil {
   659  			if a.State.Messages.Sent != nil {
   660  				pconf.State.Messages.Sent.Update = a.State.Messages.Sent.Update
   661  				pconf.State.Messages.Sent.Notification = a.State.Messages.Sent.Notification
   662  				pconf.State.Messages.Sent.Open = a.State.Messages.Sent.Open
   663  				pconf.State.Messages.Sent.Refresh = a.State.Messages.Sent.Refresh
   664  				pconf.State.Messages.Sent.Keepalive = a.State.Messages.Sent.Keepalive
   665  				pconf.State.Messages.Sent.Discarded = a.State.Messages.Sent.Discarded
   666  				pconf.State.Messages.Sent.Total = a.State.Messages.Sent.Total
   667  			}
   668  			if a.State.Messages.Received != nil {
   669  				pconf.State.Messages.Received.Update = a.State.Messages.Received.Update
   670  				pconf.State.Messages.Received.Open = a.State.Messages.Received.Open
   671  				pconf.State.Messages.Received.Refresh = a.State.Messages.Received.Refresh
   672  				pconf.State.Messages.Received.Keepalive = a.State.Messages.Received.Keepalive
   673  				pconf.State.Messages.Received.Discarded = a.State.Messages.Received.Discarded
   674  				pconf.State.Messages.Received.Total = a.State.Messages.Received.Total
   675  			}
   676  		}
   677  	}
   678  	return pconf, nil
   679  }
   680  
   681  func newPeerGroupFromAPIStruct(a *api.PeerGroup) (*config.PeerGroup, error) {
   682  	pconf := &config.PeerGroup{}
   683  	if a.Conf != nil {
   684  		pconf.Config.PeerAs = a.Conf.PeerAs
   685  		pconf.Config.LocalAs = a.Conf.LocalAs
   686  		pconf.Config.AuthPassword = a.Conf.AuthPassword
   687  		pconf.Config.RouteFlapDamping = a.Conf.RouteFlapDamping
   688  		pconf.Config.Description = a.Conf.Description
   689  		pconf.Config.PeerGroupName = a.Conf.PeerGroupName
   690  
   691  		switch a.Conf.RemovePrivateAs {
   692  		case api.PeerGroupConf_ALL:
   693  			pconf.Config.RemovePrivateAs = config.REMOVE_PRIVATE_AS_OPTION_ALL
   694  		case api.PeerGroupConf_REPLACE:
   695  			pconf.Config.RemovePrivateAs = config.REMOVE_PRIVATE_AS_OPTION_REPLACE
   696  		}
   697  
   698  		for _, af := range a.AfiSafis {
   699  			afiSafi := config.AfiSafi{}
   700  			readMpGracefulRestartFromAPIStruct(&afiSafi.MpGracefulRestart, af.MpGracefulRestart)
   701  			readAfiSafiConfigFromAPIStruct(&afiSafi.Config, af.Config)
   702  			readAfiSafiStateFromAPIStruct(&afiSafi.State, af.Config)
   703  			readApplyPolicyFromAPIStruct(&afiSafi.ApplyPolicy, af.ApplyPolicy)
   704  			readRouteSelectionOptionsFromAPIStruct(&afiSafi.RouteSelectionOptions, af.RouteSelectionOptions)
   705  			readUseMultiplePathsFromAPIStruct(&afiSafi.UseMultiplePaths, af.UseMultiplePaths)
   706  			readPrefixLimitFromAPIStruct(&afiSafi.PrefixLimit, af.PrefixLimits)
   707  			readRouteTargetMembershipFromAPIStruct(&afiSafi.RouteTargetMembership, af.RouteTargetMembership)
   708  			readLongLivedGracefulRestartFromAPIStruct(&afiSafi.LongLivedGracefulRestart, af.LongLivedGracefulRestart)
   709  			readAddPathsFromAPIStruct(&afiSafi.AddPaths, af.AddPaths)
   710  			pconf.AfiSafis = append(pconf.AfiSafis, afiSafi)
   711  		}
   712  	}
   713  
   714  	if a.Timers != nil {
   715  		if a.Timers.Config != nil {
   716  			pconf.Timers.Config.ConnectRetry = float64(a.Timers.Config.ConnectRetry)
   717  			pconf.Timers.Config.HoldTime = float64(a.Timers.Config.HoldTime)
   718  			pconf.Timers.Config.KeepaliveInterval = float64(a.Timers.Config.KeepaliveInterval)
   719  			pconf.Timers.Config.MinimumAdvertisementInterval = float64(a.Timers.Config.MinimumAdvertisementInterval)
   720  		}
   721  		if a.Timers.State != nil {
   722  			pconf.Timers.State.KeepaliveInterval = float64(a.Timers.State.KeepaliveInterval)
   723  			pconf.Timers.State.NegotiatedHoldTime = float64(a.Timers.State.NegotiatedHoldTime)
   724  		}
   725  	}
   726  	if a.RouteReflector != nil {
   727  		pconf.RouteReflector.Config.RouteReflectorClusterId = config.RrClusterIdType(a.RouteReflector.RouteReflectorClusterId)
   728  		pconf.RouteReflector.Config.RouteReflectorClient = a.RouteReflector.RouteReflectorClient
   729  	}
   730  	if a.RouteServer != nil {
   731  		pconf.RouteServer.Config.RouteServerClient = a.RouteServer.RouteServerClient
   732  	}
   733  	if a.GracefulRestart != nil {
   734  		pconf.GracefulRestart.Config.Enabled = a.GracefulRestart.Enabled
   735  		pconf.GracefulRestart.Config.RestartTime = uint16(a.GracefulRestart.RestartTime)
   736  		pconf.GracefulRestart.Config.HelperOnly = a.GracefulRestart.HelperOnly
   737  		pconf.GracefulRestart.Config.DeferralTime = uint16(a.GracefulRestart.DeferralTime)
   738  		pconf.GracefulRestart.Config.NotificationEnabled = a.GracefulRestart.NotificationEnabled
   739  		pconf.GracefulRestart.Config.LongLivedEnabled = a.GracefulRestart.LonglivedEnabled
   740  		pconf.GracefulRestart.State.LocalRestarting = a.GracefulRestart.LocalRestarting
   741  	}
   742  	readApplyPolicyFromAPIStruct(&pconf.ApplyPolicy, a.ApplyPolicy)
   743  	if a.Transport != nil {
   744  		pconf.Transport.Config.LocalAddress = a.Transport.LocalAddress
   745  		pconf.Transport.Config.PassiveMode = a.Transport.PassiveMode
   746  		pconf.Transport.Config.RemotePort = uint16(a.Transport.RemotePort)
   747  	}
   748  	if a.EbgpMultihop != nil {
   749  		pconf.EbgpMultihop.Config.Enabled = a.EbgpMultihop.Enabled
   750  		pconf.EbgpMultihop.Config.MultihopTtl = uint8(a.EbgpMultihop.MultihopTtl)
   751  	}
   752  	if a.Info != nil {
   753  		pconf.State.TotalPaths = a.Info.TotalPaths
   754  		pconf.State.TotalPrefixes = a.Info.TotalPrefixes
   755  		pconf.State.PeerAs = a.Info.PeerAs
   756  		pconf.State.PeerType = config.IntToPeerTypeMap[int(a.Info.PeerType)]
   757  	}
   758  	return pconf, nil
   759  }
   760  
   761  func (s *server) AddPeer(ctx context.Context, r *api.AddPeerRequest) (*empty.Empty, error) {
   762  	return &empty.Empty{}, s.bgpServer.AddPeer(ctx, r)
   763  }
   764  
   765  func (s *server) DeletePeer(ctx context.Context, r *api.DeletePeerRequest) (*empty.Empty, error) {
   766  	return &empty.Empty{}, s.bgpServer.DeletePeer(ctx, r)
   767  }
   768  
   769  func (s *server) UpdatePeer(ctx context.Context, r *api.UpdatePeerRequest) (*api.UpdatePeerResponse, error) {
   770  	return s.bgpServer.UpdatePeer(ctx, r)
   771  }
   772  
   773  func (s *server) AddPeerGroup(ctx context.Context, r *api.AddPeerGroupRequest) (*empty.Empty, error) {
   774  	return &empty.Empty{}, s.bgpServer.AddPeerGroup(ctx, r)
   775  }
   776  
   777  func (s *server) DeletePeerGroup(ctx context.Context, r *api.DeletePeerGroupRequest) (*empty.Empty, error) {
   778  	return &empty.Empty{}, s.bgpServer.DeletePeerGroup(ctx, r)
   779  }
   780  
   781  func (s *server) UpdatePeerGroup(ctx context.Context, r *api.UpdatePeerGroupRequest) (*api.UpdatePeerGroupResponse, error) {
   782  	return s.bgpServer.UpdatePeerGroup(ctx, r)
   783  }
   784  
   785  func (s *server) AddDynamicNeighbor(ctx context.Context, r *api.AddDynamicNeighborRequest) (*empty.Empty, error) {
   786  	return &empty.Empty{}, s.bgpServer.AddDynamicNeighbor(ctx, r)
   787  }
   788  
   789  func newPrefixFromApiStruct(a *api.Prefix) (*table.Prefix, error) {
   790  	_, prefix, err := net.ParseCIDR(a.IpPrefix)
   791  	if err != nil {
   792  		return nil, err
   793  	}
   794  	rf := bgp.RF_IPv4_UC
   795  	if strings.Contains(a.IpPrefix, ":") {
   796  		rf = bgp.RF_IPv6_UC
   797  	}
   798  	return &table.Prefix{
   799  		Prefix:             prefix,
   800  		AddressFamily:      rf,
   801  		MasklengthRangeMin: uint8(a.MaskLengthMin),
   802  		MasklengthRangeMax: uint8(a.MaskLengthMax),
   803  	}, nil
   804  }
   805  
   806  func newConfigPrefixFromAPIStruct(a *api.Prefix) (*config.Prefix, error) {
   807  	_, prefix, err := net.ParseCIDR(a.IpPrefix)
   808  	if err != nil {
   809  		return nil, err
   810  	}
   811  	return &config.Prefix{
   812  		IpPrefix:        prefix.String(),
   813  		MasklengthRange: fmt.Sprintf("%d..%d", a.MaskLengthMin, a.MaskLengthMax),
   814  	}, nil
   815  }
   816  
   817  func newConfigDefinedSetsFromApiStruct(a []*api.DefinedSet) (*config.DefinedSets, error) {
   818  	ps := make([]config.PrefixSet, 0)
   819  	ns := make([]config.NeighborSet, 0)
   820  	as := make([]config.AsPathSet, 0)
   821  	cs := make([]config.CommunitySet, 0)
   822  	es := make([]config.ExtCommunitySet, 0)
   823  	ls := make([]config.LargeCommunitySet, 0)
   824  
   825  	for _, ds := range a {
   826  		if ds.Name == "" {
   827  			return nil, fmt.Errorf("empty neighbor set name")
   828  		}
   829  		switch table.DefinedType(ds.DefinedType) {
   830  		case table.DEFINED_TYPE_PREFIX:
   831  			prefixes := make([]config.Prefix, 0, len(ds.Prefixes))
   832  			for _, p := range ds.Prefixes {
   833  				prefix, err := newConfigPrefixFromAPIStruct(p)
   834  				if err != nil {
   835  					return nil, err
   836  				}
   837  				prefixes = append(prefixes, *prefix)
   838  			}
   839  			ps = append(ps, config.PrefixSet{
   840  				PrefixSetName: ds.Name,
   841  				PrefixList:    prefixes,
   842  			})
   843  		case table.DEFINED_TYPE_NEIGHBOR:
   844  			ns = append(ns, config.NeighborSet{
   845  				NeighborSetName:  ds.Name,
   846  				NeighborInfoList: ds.List,
   847  			})
   848  		case table.DEFINED_TYPE_AS_PATH:
   849  			as = append(as, config.AsPathSet{
   850  				AsPathSetName: ds.Name,
   851  				AsPathList:    ds.List,
   852  			})
   853  		case table.DEFINED_TYPE_COMMUNITY:
   854  			cs = append(cs, config.CommunitySet{
   855  				CommunitySetName: ds.Name,
   856  				CommunityList:    ds.List,
   857  			})
   858  		case table.DEFINED_TYPE_EXT_COMMUNITY:
   859  			es = append(es, config.ExtCommunitySet{
   860  				ExtCommunitySetName: ds.Name,
   861  				ExtCommunityList:    ds.List,
   862  			})
   863  		case table.DEFINED_TYPE_LARGE_COMMUNITY:
   864  			ls = append(ls, config.LargeCommunitySet{
   865  				LargeCommunitySetName: ds.Name,
   866  				LargeCommunityList:    ds.List,
   867  			})
   868  		default:
   869  			return nil, fmt.Errorf("invalid defined type")
   870  		}
   871  	}
   872  
   873  	return &config.DefinedSets{
   874  		PrefixSets:   ps,
   875  		NeighborSets: ns,
   876  		BgpDefinedSets: config.BgpDefinedSets{
   877  			AsPathSets:         as,
   878  			CommunitySets:      cs,
   879  			ExtCommunitySets:   es,
   880  			LargeCommunitySets: ls,
   881  		},
   882  	}, nil
   883  }
   884  
   885  func newDefinedSetFromApiStruct(a *api.DefinedSet) (table.DefinedSet, error) {
   886  	if a.Name == "" {
   887  		return nil, fmt.Errorf("empty neighbor set name")
   888  	}
   889  	switch table.DefinedType(a.DefinedType) {
   890  	case table.DEFINED_TYPE_PREFIX:
   891  		prefixes := make([]*table.Prefix, 0, len(a.Prefixes))
   892  		for _, p := range a.Prefixes {
   893  			prefix, err := newPrefixFromApiStruct(p)
   894  			if err != nil {
   895  				return nil, err
   896  			}
   897  			prefixes = append(prefixes, prefix)
   898  		}
   899  		return table.NewPrefixSetFromApiStruct(a.Name, prefixes)
   900  	case table.DEFINED_TYPE_NEIGHBOR:
   901  		list := make([]net.IPNet, 0, len(a.List))
   902  		for _, x := range a.List {
   903  			_, addr, err := net.ParseCIDR(x)
   904  			if err != nil {
   905  				return nil, fmt.Errorf("invalid address or prefix: %s", x)
   906  			}
   907  			list = append(list, *addr)
   908  		}
   909  		return table.NewNeighborSetFromApiStruct(a.Name, list)
   910  	case table.DEFINED_TYPE_AS_PATH:
   911  		return table.NewAsPathSet(config.AsPathSet{
   912  			AsPathSetName: a.Name,
   913  			AsPathList:    a.List,
   914  		})
   915  	case table.DEFINED_TYPE_COMMUNITY:
   916  		return table.NewCommunitySet(config.CommunitySet{
   917  			CommunitySetName: a.Name,
   918  			CommunityList:    a.List,
   919  		})
   920  	case table.DEFINED_TYPE_EXT_COMMUNITY:
   921  		return table.NewExtCommunitySet(config.ExtCommunitySet{
   922  			ExtCommunitySetName: a.Name,
   923  			ExtCommunityList:    a.List,
   924  		})
   925  	case table.DEFINED_TYPE_LARGE_COMMUNITY:
   926  		return table.NewLargeCommunitySet(config.LargeCommunitySet{
   927  			LargeCommunitySetName: a.Name,
   928  			LargeCommunityList:    a.List,
   929  		})
   930  	default:
   931  		return nil, fmt.Errorf("invalid defined type")
   932  	}
   933  }
   934  
   935  var _regexpPrefixMaskLengthRange = regexp.MustCompile(`(\d+)\.\.(\d+)`)
   936  
   937  func (s *server) ListDefinedSet(r *api.ListDefinedSetRequest, stream api.GobgpApi_ListDefinedSetServer) error {
   938  	ctx, cancel := context.WithCancel(context.Background())
   939  	defer cancel()
   940  	fn := func(d *api.DefinedSet) {
   941  		if err := stream.Send(&api.ListDefinedSetResponse{DefinedSet: d}); err != nil {
   942  			cancel()
   943  		}
   944  	}
   945  	return s.bgpServer.ListDefinedSet(ctx, r, fn)
   946  }
   947  
   948  func (s *server) AddDefinedSet(ctx context.Context, r *api.AddDefinedSetRequest) (*empty.Empty, error) {
   949  	return &empty.Empty{}, s.bgpServer.AddDefinedSet(ctx, r)
   950  }
   951  
   952  func (s *server) DeleteDefinedSet(ctx context.Context, r *api.DeleteDefinedSetRequest) (*empty.Empty, error) {
   953  	return &empty.Empty{}, s.bgpServer.DeleteDefinedSet(ctx, r)
   954  }
   955  
   956  var _regexpMedActionType = regexp.MustCompile(`([+-]?)(\d+)`)
   957  
   958  func matchSetOptionsRestrictedTypeToAPI(t config.MatchSetOptionsRestrictedType) api.MatchType {
   959  	t = t.DefaultAsNeeded()
   960  	switch t {
   961  	case config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_ANY:
   962  		return api.MatchType_ANY
   963  	case config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_INVERT:
   964  		return api.MatchType_INVERT
   965  	}
   966  	return api.MatchType_ANY
   967  }
   968  
   969  func toStatementApi(s *config.Statement) *api.Statement {
   970  	cs := &api.Conditions{}
   971  	if s.Conditions.MatchPrefixSet.PrefixSet != "" {
   972  		cs.PrefixSet = &api.MatchSet{
   973  			MatchType: matchSetOptionsRestrictedTypeToAPI(s.Conditions.MatchPrefixSet.MatchSetOptions),
   974  			Name:      s.Conditions.MatchPrefixSet.PrefixSet,
   975  		}
   976  	}
   977  	if s.Conditions.MatchNeighborSet.NeighborSet != "" {
   978  		cs.NeighborSet = &api.MatchSet{
   979  			MatchType: matchSetOptionsRestrictedTypeToAPI(s.Conditions.MatchNeighborSet.MatchSetOptions),
   980  			Name:      s.Conditions.MatchNeighborSet.NeighborSet,
   981  		}
   982  	}
   983  	if s.Conditions.BgpConditions.AsPathLength.Operator != "" {
   984  		cs.AsPathLength = &api.AsPathLength{
   985  			Length:     s.Conditions.BgpConditions.AsPathLength.Value,
   986  			LengthType: api.AsPathLengthType(s.Conditions.BgpConditions.AsPathLength.Operator.ToInt()),
   987  		}
   988  	}
   989  	if s.Conditions.BgpConditions.MatchAsPathSet.AsPathSet != "" {
   990  		cs.AsPathSet = &api.MatchSet{
   991  			MatchType: api.MatchType(s.Conditions.BgpConditions.MatchAsPathSet.MatchSetOptions.ToInt()),
   992  			Name:      s.Conditions.BgpConditions.MatchAsPathSet.AsPathSet,
   993  		}
   994  	}
   995  	if s.Conditions.BgpConditions.MatchCommunitySet.CommunitySet != "" {
   996  		cs.CommunitySet = &api.MatchSet{
   997  			MatchType: api.MatchType(s.Conditions.BgpConditions.MatchCommunitySet.MatchSetOptions.ToInt()),
   998  			Name:      s.Conditions.BgpConditions.MatchCommunitySet.CommunitySet,
   999  		}
  1000  	}
  1001  	if s.Conditions.BgpConditions.MatchExtCommunitySet.ExtCommunitySet != "" {
  1002  		cs.ExtCommunitySet = &api.MatchSet{
  1003  			MatchType: api.MatchType(s.Conditions.BgpConditions.MatchExtCommunitySet.MatchSetOptions.ToInt()),
  1004  			Name:      s.Conditions.BgpConditions.MatchExtCommunitySet.ExtCommunitySet,
  1005  		}
  1006  	}
  1007  	if s.Conditions.BgpConditions.MatchLargeCommunitySet.LargeCommunitySet != "" {
  1008  		cs.LargeCommunitySet = &api.MatchSet{
  1009  			MatchType: api.MatchType(s.Conditions.BgpConditions.MatchLargeCommunitySet.MatchSetOptions.ToInt()),
  1010  			Name:      s.Conditions.BgpConditions.MatchLargeCommunitySet.LargeCommunitySet,
  1011  		}
  1012  	}
  1013  	if s.Conditions.BgpConditions.RouteType != "" {
  1014  		cs.RouteType = api.Conditions_RouteType(s.Conditions.BgpConditions.RouteType.ToInt())
  1015  	}
  1016  	if len(s.Conditions.BgpConditions.NextHopInList) > 0 {
  1017  		cs.NextHopInList = s.Conditions.BgpConditions.NextHopInList
  1018  	}
  1019  	if s.Conditions.BgpConditions.AfiSafiInList != nil {
  1020  		afiSafiIn := make([]*api.Family, 0)
  1021  		for _, afiSafiType := range s.Conditions.BgpConditions.AfiSafiInList {
  1022  			if mapped, ok := bgp.AddressFamilyValueMap[string(afiSafiType)]; ok {
  1023  				afi, safi := bgp.RouteFamilyToAfiSafi(mapped)
  1024  				afiSafiIn = append(afiSafiIn, &api.Family{Afi: api.Family_Afi(afi), Safi: api.Family_Safi(safi)})
  1025  			}
  1026  		}
  1027  		cs.AfiSafiIn = afiSafiIn
  1028  	}
  1029  	cs.RpkiResult = int32(s.Conditions.BgpConditions.RpkiValidationResult.ToInt())
  1030  	as := &api.Actions{
  1031  		RouteAction: func() api.RouteAction {
  1032  			switch s.Actions.RouteDisposition {
  1033  			case config.ROUTE_DISPOSITION_ACCEPT_ROUTE:
  1034  				return api.RouteAction_ACCEPT
  1035  			case config.ROUTE_DISPOSITION_REJECT_ROUTE:
  1036  				return api.RouteAction_REJECT
  1037  			}
  1038  			return api.RouteAction_NONE
  1039  		}(),
  1040  		Community: func() *api.CommunityAction {
  1041  			if len(s.Actions.BgpActions.SetCommunity.SetCommunityMethod.CommunitiesList) == 0 {
  1042  				return nil
  1043  			}
  1044  			return &api.CommunityAction{
  1045  				ActionType:  api.CommunityActionType(config.BgpSetCommunityOptionTypeToIntMap[config.BgpSetCommunityOptionType(s.Actions.BgpActions.SetCommunity.Options)]),
  1046  				Communities: s.Actions.BgpActions.SetCommunity.SetCommunityMethod.CommunitiesList}
  1047  		}(),
  1048  		Med: func() *api.MedAction {
  1049  			medStr := strings.TrimSpace(string(s.Actions.BgpActions.SetMed))
  1050  			if len(medStr) == 0 {
  1051  				return nil
  1052  			}
  1053  			matches := _regexpMedActionType.FindStringSubmatch(medStr)
  1054  			if len(matches) == 0 {
  1055  				return nil
  1056  			}
  1057  			action := api.MedActionType_MED_REPLACE
  1058  			switch matches[1] {
  1059  			case "+", "-":
  1060  				action = api.MedActionType_MED_MOD
  1061  			}
  1062  			value, err := strconv.ParseInt(matches[1]+matches[2], 10, 64)
  1063  			if err != nil {
  1064  				return nil
  1065  			}
  1066  			return &api.MedAction{
  1067  				Value:      value,
  1068  				ActionType: action,
  1069  			}
  1070  		}(),
  1071  		AsPrepend: func() *api.AsPrependAction {
  1072  			if len(s.Actions.BgpActions.SetAsPathPrepend.As) == 0 {
  1073  				return nil
  1074  			}
  1075  			var asn uint64
  1076  			useleft := false
  1077  			if s.Actions.BgpActions.SetAsPathPrepend.As != "last-as" {
  1078  				asn, _ = strconv.ParseUint(s.Actions.BgpActions.SetAsPathPrepend.As, 10, 32)
  1079  			} else {
  1080  				useleft = true
  1081  			}
  1082  			return &api.AsPrependAction{
  1083  				Asn:         uint32(asn),
  1084  				Repeat:      uint32(s.Actions.BgpActions.SetAsPathPrepend.RepeatN),
  1085  				UseLeftMost: useleft,
  1086  			}
  1087  		}(),
  1088  		ExtCommunity: func() *api.CommunityAction {
  1089  			if len(s.Actions.BgpActions.SetExtCommunity.SetExtCommunityMethod.CommunitiesList) == 0 {
  1090  				return nil
  1091  			}
  1092  			return &api.CommunityAction{
  1093  				ActionType:  api.CommunityActionType(config.BgpSetCommunityOptionTypeToIntMap[config.BgpSetCommunityOptionType(s.Actions.BgpActions.SetExtCommunity.Options)]),
  1094  				Communities: s.Actions.BgpActions.SetExtCommunity.SetExtCommunityMethod.CommunitiesList,
  1095  			}
  1096  		}(),
  1097  		LargeCommunity: func() *api.CommunityAction {
  1098  			if len(s.Actions.BgpActions.SetLargeCommunity.SetLargeCommunityMethod.CommunitiesList) == 0 {
  1099  				return nil
  1100  			}
  1101  			return &api.CommunityAction{
  1102  				ActionType:  api.CommunityActionType(config.BgpSetCommunityOptionTypeToIntMap[config.BgpSetCommunityOptionType(s.Actions.BgpActions.SetLargeCommunity.Options)]),
  1103  				Communities: s.Actions.BgpActions.SetLargeCommunity.SetLargeCommunityMethod.CommunitiesList,
  1104  			}
  1105  		}(),
  1106  		Nexthop: func() *api.NexthopAction {
  1107  			if len(string(s.Actions.BgpActions.SetNextHop)) == 0 {
  1108  				return nil
  1109  			}
  1110  
  1111  			if string(s.Actions.BgpActions.SetNextHop) == "self" {
  1112  				return &api.NexthopAction{
  1113  					Self: true,
  1114  				}
  1115  			}
  1116  			return &api.NexthopAction{
  1117  				Address: string(s.Actions.BgpActions.SetNextHop),
  1118  			}
  1119  		}(),
  1120  		LocalPref: func() *api.LocalPrefAction {
  1121  			if s.Actions.BgpActions.SetLocalPref == 0 {
  1122  				return nil
  1123  			}
  1124  			return &api.LocalPrefAction{Value: s.Actions.BgpActions.SetLocalPref}
  1125  		}(),
  1126  	}
  1127  	return &api.Statement{
  1128  		Name:       s.Name,
  1129  		Conditions: cs,
  1130  		Actions:    as,
  1131  	}
  1132  }
  1133  
  1134  func toConfigMatchSetOption(a api.MatchType) (config.MatchSetOptionsType, error) {
  1135  	var typ config.MatchSetOptionsType
  1136  	switch a {
  1137  	case api.MatchType_ANY:
  1138  		typ = config.MATCH_SET_OPTIONS_TYPE_ANY
  1139  	case api.MatchType_ALL:
  1140  		typ = config.MATCH_SET_OPTIONS_TYPE_ALL
  1141  	case api.MatchType_INVERT:
  1142  		typ = config.MATCH_SET_OPTIONS_TYPE_INVERT
  1143  	default:
  1144  		return typ, fmt.Errorf("invalid match type")
  1145  	}
  1146  	return typ, nil
  1147  }
  1148  
  1149  func toConfigMatchSetOptionRestricted(a api.MatchType) (config.MatchSetOptionsRestrictedType, error) {
  1150  	var typ config.MatchSetOptionsRestrictedType
  1151  	switch a {
  1152  	case api.MatchType_ANY:
  1153  		typ = config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_ANY
  1154  	case api.MatchType_INVERT:
  1155  		typ = config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_INVERT
  1156  	default:
  1157  		return typ, fmt.Errorf("invalid match type")
  1158  	}
  1159  	return typ, nil
  1160  }
  1161  
  1162  func newPrefixConditionFromApiStruct(a *api.MatchSet) (*table.PrefixCondition, error) {
  1163  	if a == nil {
  1164  		return nil, nil
  1165  	}
  1166  	typ, err := toConfigMatchSetOptionRestricted(a.MatchType)
  1167  	if err != nil {
  1168  		return nil, err
  1169  	}
  1170  	c := config.MatchPrefixSet{
  1171  		PrefixSet:       a.Name,
  1172  		MatchSetOptions: typ,
  1173  	}
  1174  	return table.NewPrefixCondition(c)
  1175  }
  1176  
  1177  func newNeighborConditionFromApiStruct(a *api.MatchSet) (*table.NeighborCondition, error) {
  1178  	if a == nil {
  1179  		return nil, nil
  1180  	}
  1181  	typ, err := toConfigMatchSetOptionRestricted(a.MatchType)
  1182  	if err != nil {
  1183  		return nil, err
  1184  	}
  1185  	c := config.MatchNeighborSet{
  1186  		NeighborSet:     a.Name,
  1187  		MatchSetOptions: typ,
  1188  	}
  1189  	return table.NewNeighborCondition(c)
  1190  }
  1191  
  1192  func newAsPathLengthConditionFromApiStruct(a *api.AsPathLength) (*table.AsPathLengthCondition, error) {
  1193  	if a == nil {
  1194  		return nil, nil
  1195  	}
  1196  	return table.NewAsPathLengthCondition(config.AsPathLength{
  1197  		Operator: config.IntToAttributeComparisonMap[int(a.LengthType)],
  1198  		Value:    a.Length,
  1199  	})
  1200  }
  1201  
  1202  func newAsPathConditionFromApiStruct(a *api.MatchSet) (*table.AsPathCondition, error) {
  1203  	if a == nil {
  1204  		return nil, nil
  1205  	}
  1206  	typ, err := toConfigMatchSetOption(a.MatchType)
  1207  	if err != nil {
  1208  		return nil, err
  1209  	}
  1210  	c := config.MatchAsPathSet{
  1211  		AsPathSet:       a.Name,
  1212  		MatchSetOptions: typ,
  1213  	}
  1214  	return table.NewAsPathCondition(c)
  1215  }
  1216  
  1217  func newRpkiValidationConditionFromApiStruct(a int32) (*table.RpkiValidationCondition, error) {
  1218  	if a < 1 {
  1219  		return nil, nil
  1220  	}
  1221  	return table.NewRpkiValidationCondition(config.IntToRpkiValidationResultTypeMap[int(a)])
  1222  }
  1223  
  1224  func newRouteTypeConditionFromApiStruct(a api.Conditions_RouteType) (*table.RouteTypeCondition, error) {
  1225  	if a == 0 {
  1226  		return nil, nil
  1227  	}
  1228  	typ, ok := config.IntToRouteTypeMap[int(a)]
  1229  	if !ok {
  1230  		return nil, fmt.Errorf("invalid route type: %d", a)
  1231  	}
  1232  	return table.NewRouteTypeCondition(typ)
  1233  }
  1234  
  1235  func newCommunityConditionFromApiStruct(a *api.MatchSet) (*table.CommunityCondition, error) {
  1236  	if a == nil {
  1237  		return nil, nil
  1238  	}
  1239  	typ, err := toConfigMatchSetOption(a.MatchType)
  1240  	if err != nil {
  1241  		return nil, err
  1242  	}
  1243  	c := config.MatchCommunitySet{
  1244  		CommunitySet:    a.Name,
  1245  		MatchSetOptions: typ,
  1246  	}
  1247  	return table.NewCommunityCondition(c)
  1248  }
  1249  
  1250  func newExtCommunityConditionFromApiStruct(a *api.MatchSet) (*table.ExtCommunityCondition, error) {
  1251  	if a == nil {
  1252  		return nil, nil
  1253  	}
  1254  	typ, err := toConfigMatchSetOption(a.MatchType)
  1255  	if err != nil {
  1256  		return nil, err
  1257  	}
  1258  	c := config.MatchExtCommunitySet{
  1259  		ExtCommunitySet: a.Name,
  1260  		MatchSetOptions: typ,
  1261  	}
  1262  	return table.NewExtCommunityCondition(c)
  1263  }
  1264  
  1265  func newLargeCommunityConditionFromApiStruct(a *api.MatchSet) (*table.LargeCommunityCondition, error) {
  1266  	if a == nil {
  1267  		return nil, nil
  1268  	}
  1269  	typ, err := toConfigMatchSetOption(a.MatchType)
  1270  	if err != nil {
  1271  		return nil, err
  1272  	}
  1273  	c := config.MatchLargeCommunitySet{
  1274  		LargeCommunitySet: a.Name,
  1275  		MatchSetOptions:   typ,
  1276  	}
  1277  	return table.NewLargeCommunityCondition(c)
  1278  }
  1279  
  1280  func newNextHopConditionFromApiStruct(a []string) (*table.NextHopCondition, error) {
  1281  	if a == nil {
  1282  		return nil, nil
  1283  	}
  1284  
  1285  	return table.NewNextHopCondition(a)
  1286  }
  1287  
  1288  func newAfiSafiInConditionFromApiStruct(a []*api.Family) (*table.AfiSafiInCondition, error) {
  1289  	if a == nil {
  1290  		return nil, nil
  1291  	}
  1292  	afiSafiTypes := make([]config.AfiSafiType, 0, len(a))
  1293  	for _, aType := range a {
  1294  		rf := bgp.AfiSafiToRouteFamily(uint16(aType.Afi), uint8(aType.Safi))
  1295  		if configType, ok := bgp.AddressFamilyNameMap[bgp.RouteFamily(rf)]; ok {
  1296  			afiSafiTypes = append(afiSafiTypes, config.AfiSafiType(configType))
  1297  		} else {
  1298  			return nil, fmt.Errorf("unknown afi-safi-in type value: %d", aType)
  1299  		}
  1300  	}
  1301  	return table.NewAfiSafiInCondition(afiSafiTypes)
  1302  }
  1303  
  1304  func newRoutingActionFromApiStruct(a api.RouteAction) (*table.RoutingAction, error) {
  1305  	if a == api.RouteAction_NONE {
  1306  		return nil, nil
  1307  	}
  1308  	accept := false
  1309  	if a == api.RouteAction_ACCEPT {
  1310  		accept = true
  1311  	}
  1312  	return &table.RoutingAction{
  1313  		AcceptRoute: accept,
  1314  	}, nil
  1315  }
  1316  
  1317  func newCommunityActionFromApiStruct(a *api.CommunityAction) (*table.CommunityAction, error) {
  1318  	if a == nil {
  1319  		return nil, nil
  1320  	}
  1321  	return table.NewCommunityAction(config.SetCommunity{
  1322  		Options: string(config.IntToBgpSetCommunityOptionTypeMap[int(a.ActionType)]),
  1323  		SetCommunityMethod: config.SetCommunityMethod{
  1324  			CommunitiesList: a.Communities,
  1325  		},
  1326  	})
  1327  }
  1328  
  1329  func newExtCommunityActionFromApiStruct(a *api.CommunityAction) (*table.ExtCommunityAction, error) {
  1330  	if a == nil {
  1331  		return nil, nil
  1332  	}
  1333  	return table.NewExtCommunityAction(config.SetExtCommunity{
  1334  		Options: string(config.IntToBgpSetCommunityOptionTypeMap[int(a.ActionType)]),
  1335  		SetExtCommunityMethod: config.SetExtCommunityMethod{
  1336  			CommunitiesList: a.Communities,
  1337  		},
  1338  	})
  1339  }
  1340  
  1341  func newLargeCommunityActionFromApiStruct(a *api.CommunityAction) (*table.LargeCommunityAction, error) {
  1342  	if a == nil {
  1343  		return nil, nil
  1344  	}
  1345  	return table.NewLargeCommunityAction(config.SetLargeCommunity{
  1346  		Options: config.IntToBgpSetCommunityOptionTypeMap[int(a.ActionType)],
  1347  		SetLargeCommunityMethod: config.SetLargeCommunityMethod{
  1348  			CommunitiesList: a.Communities,
  1349  		},
  1350  	})
  1351  }
  1352  
  1353  func newMedActionFromApiStruct(a *api.MedAction) (*table.MedAction, error) {
  1354  	if a == nil {
  1355  		return nil, nil
  1356  	}
  1357  	return table.NewMedActionFromApiStruct(table.MedActionType(a.ActionType), a.Value), nil
  1358  }
  1359  
  1360  func newLocalPrefActionFromApiStruct(a *api.LocalPrefAction) (*table.LocalPrefAction, error) {
  1361  	if a == nil || a.Value == 0 {
  1362  		return nil, nil
  1363  	}
  1364  	return table.NewLocalPrefAction(a.Value)
  1365  }
  1366  
  1367  func newAsPathPrependActionFromApiStruct(a *api.AsPrependAction) (*table.AsPathPrependAction, error) {
  1368  	if a == nil {
  1369  		return nil, nil
  1370  	}
  1371  	return table.NewAsPathPrependAction(config.SetAsPathPrepend{
  1372  		RepeatN: uint8(a.Repeat),
  1373  		As: func() string {
  1374  			if a.UseLeftMost {
  1375  				return "last-as"
  1376  			}
  1377  			return fmt.Sprintf("%d", a.Asn)
  1378  		}(),
  1379  	})
  1380  }
  1381  
  1382  func newNexthopActionFromApiStruct(a *api.NexthopAction) (*table.NexthopAction, error) {
  1383  	if a == nil {
  1384  		return nil, nil
  1385  	}
  1386  	return table.NewNexthopAction(config.BgpNextHopType(
  1387  		func() string {
  1388  			if a.Self {
  1389  				return "self"
  1390  			}
  1391  			return a.Address
  1392  		}(),
  1393  	))
  1394  }
  1395  
  1396  func newStatementFromApiStruct(a *api.Statement) (*table.Statement, error) {
  1397  	if a.Name == "" {
  1398  		return nil, fmt.Errorf("empty statement name")
  1399  	}
  1400  	var ra table.Action
  1401  	var as []table.Action
  1402  	var cs []table.Condition
  1403  	var err error
  1404  	if a.Conditions != nil {
  1405  		cfs := []func() (table.Condition, error){
  1406  			func() (table.Condition, error) {
  1407  				return newPrefixConditionFromApiStruct(a.Conditions.PrefixSet)
  1408  			},
  1409  			func() (table.Condition, error) {
  1410  				return newNeighborConditionFromApiStruct(a.Conditions.NeighborSet)
  1411  			},
  1412  			func() (table.Condition, error) {
  1413  				return newAsPathLengthConditionFromApiStruct(a.Conditions.AsPathLength)
  1414  			},
  1415  			func() (table.Condition, error) {
  1416  				return newRpkiValidationConditionFromApiStruct(a.Conditions.RpkiResult)
  1417  			},
  1418  			func() (table.Condition, error) {
  1419  				return newRouteTypeConditionFromApiStruct(a.Conditions.RouteType)
  1420  			},
  1421  			func() (table.Condition, error) {
  1422  				return newAsPathConditionFromApiStruct(a.Conditions.AsPathSet)
  1423  			},
  1424  			func() (table.Condition, error) {
  1425  				return newCommunityConditionFromApiStruct(a.Conditions.CommunitySet)
  1426  			},
  1427  			func() (table.Condition, error) {
  1428  				return newExtCommunityConditionFromApiStruct(a.Conditions.ExtCommunitySet)
  1429  			},
  1430  			func() (table.Condition, error) {
  1431  				return newLargeCommunityConditionFromApiStruct(a.Conditions.LargeCommunitySet)
  1432  			},
  1433  			func() (table.Condition, error) {
  1434  				return newNextHopConditionFromApiStruct(a.Conditions.NextHopInList)
  1435  			},
  1436  			func() (table.Condition, error) {
  1437  				return newAfiSafiInConditionFromApiStruct(a.Conditions.AfiSafiIn)
  1438  			},
  1439  		}
  1440  		cs = make([]table.Condition, 0, len(cfs))
  1441  		for _, f := range cfs {
  1442  			c, err := f()
  1443  			if err != nil {
  1444  				return nil, err
  1445  			}
  1446  			if !reflect.ValueOf(c).IsNil() {
  1447  				cs = append(cs, c)
  1448  			}
  1449  		}
  1450  	}
  1451  	if a.Actions != nil {
  1452  		ra, err = newRoutingActionFromApiStruct(a.Actions.RouteAction)
  1453  		if err != nil {
  1454  			return nil, err
  1455  		}
  1456  		afs := []func() (table.Action, error){
  1457  			func() (table.Action, error) {
  1458  				return newCommunityActionFromApiStruct(a.Actions.Community)
  1459  			},
  1460  			func() (table.Action, error) {
  1461  				return newExtCommunityActionFromApiStruct(a.Actions.ExtCommunity)
  1462  			},
  1463  			func() (table.Action, error) {
  1464  				return newLargeCommunityActionFromApiStruct(a.Actions.LargeCommunity)
  1465  			},
  1466  			func() (table.Action, error) {
  1467  				return newMedActionFromApiStruct(a.Actions.Med)
  1468  			},
  1469  			func() (table.Action, error) {
  1470  				return newLocalPrefActionFromApiStruct(a.Actions.LocalPref)
  1471  			},
  1472  			func() (table.Action, error) {
  1473  				return newAsPathPrependActionFromApiStruct(a.Actions.AsPrepend)
  1474  			},
  1475  			func() (table.Action, error) {
  1476  				return newNexthopActionFromApiStruct(a.Actions.Nexthop)
  1477  			},
  1478  		}
  1479  		as = make([]table.Action, 0, len(afs))
  1480  		for _, f := range afs {
  1481  			a, err := f()
  1482  			if err != nil {
  1483  				return nil, err
  1484  			}
  1485  			if !reflect.ValueOf(a).IsNil() {
  1486  				as = append(as, a)
  1487  			}
  1488  		}
  1489  	}
  1490  	return &table.Statement{
  1491  		Name:        a.Name,
  1492  		Conditions:  cs,
  1493  		RouteAction: ra,
  1494  		ModActions:  as,
  1495  	}, nil
  1496  }
  1497  
  1498  func (s *server) ListStatement(r *api.ListStatementRequest, stream api.GobgpApi_ListStatementServer) error {
  1499  	ctx, cancel := context.WithCancel(context.Background())
  1500  	defer cancel()
  1501  	fn := func(s *api.Statement) {
  1502  		if err := stream.Send(&api.ListStatementResponse{Statement: s}); err != nil {
  1503  			cancel()
  1504  		}
  1505  	}
  1506  	return s.bgpServer.ListStatement(ctx, r, fn)
  1507  }
  1508  
  1509  func (s *server) AddStatement(ctx context.Context, r *api.AddStatementRequest) (*empty.Empty, error) {
  1510  	return &empty.Empty{}, s.bgpServer.AddStatement(ctx, r)
  1511  }
  1512  
  1513  func (s *server) DeleteStatement(ctx context.Context, r *api.DeleteStatementRequest) (*empty.Empty, error) {
  1514  	return &empty.Empty{}, s.bgpServer.DeleteStatement(ctx, r)
  1515  }
  1516  
  1517  func newConfigPolicyFromApiStruct(a *api.Policy) (*config.PolicyDefinition, error) {
  1518  	if a.Name == "" {
  1519  		return nil, fmt.Errorf("empty policy name")
  1520  	}
  1521  	stmts := make([]config.Statement, 0, len(a.Statements))
  1522  	for idx, x := range a.Statements {
  1523  		if x.Name == "" {
  1524  			x.Name = fmt.Sprintf("%s_stmt%d", a.Name, idx)
  1525  		}
  1526  		y, err := newStatementFromApiStruct(x)
  1527  		if err != nil {
  1528  			return nil, err
  1529  		}
  1530  		stmt := y.ToConfig()
  1531  		stmts = append(stmts, *stmt)
  1532  	}
  1533  	return &config.PolicyDefinition{
  1534  		Name:       a.Name,
  1535  		Statements: stmts,
  1536  	}, nil
  1537  }
  1538  
  1539  func newPolicyFromApiStruct(a *api.Policy) (*table.Policy, error) {
  1540  	if a.Name == "" {
  1541  		return nil, fmt.Errorf("empty policy name")
  1542  	}
  1543  	stmts := make([]*table.Statement, 0, len(a.Statements))
  1544  	for idx, x := range a.Statements {
  1545  		if x.Name == "" {
  1546  			x.Name = fmt.Sprintf("%s_stmt%d", a.Name, idx)
  1547  		}
  1548  		y, err := newStatementFromApiStruct(x)
  1549  		if err != nil {
  1550  			return nil, err
  1551  		}
  1552  		stmts = append(stmts, y)
  1553  	}
  1554  	return &table.Policy{
  1555  		Name:       a.Name,
  1556  		Statements: stmts,
  1557  	}, nil
  1558  }
  1559  
  1560  func newRoaListFromTableStructList(origin []*table.ROA) []*api.Roa {
  1561  	l := make([]*api.Roa, 0)
  1562  	for _, r := range origin {
  1563  		host, portStr, _ := net.SplitHostPort(r.Src)
  1564  		port, _ := strconv.ParseUint(portStr, 10, 32)
  1565  		l = append(l, &api.Roa{
  1566  			As:        r.AS,
  1567  			Maxlen:    uint32(r.MaxLen),
  1568  			Prefixlen: uint32(r.Prefix.Length),
  1569  			Prefix:    r.Prefix.Prefix.String(),
  1570  			Conf: &api.RPKIConf{
  1571  				Address:    host,
  1572  				RemotePort: uint32(port),
  1573  			},
  1574  		})
  1575  	}
  1576  	return l
  1577  }
  1578  
  1579  func (s *server) ListPolicy(r *api.ListPolicyRequest, stream api.GobgpApi_ListPolicyServer) error {
  1580  	ctx, cancel := context.WithCancel(context.Background())
  1581  	defer cancel()
  1582  	fn := func(p *api.Policy) {
  1583  		if err := stream.Send(&api.ListPolicyResponse{Policy: p}); err != nil {
  1584  			cancel()
  1585  		}
  1586  	}
  1587  	return s.bgpServer.ListPolicy(ctx, r, fn)
  1588  }
  1589  
  1590  func (s *server) AddPolicy(ctx context.Context, r *api.AddPolicyRequest) (*empty.Empty, error) {
  1591  	return &empty.Empty{}, s.bgpServer.AddPolicy(ctx, r)
  1592  }
  1593  
  1594  func (s *server) DeletePolicy(ctx context.Context, r *api.DeletePolicyRequest) (*empty.Empty, error) {
  1595  	return &empty.Empty{}, s.bgpServer.DeletePolicy(ctx, r)
  1596  }
  1597  
  1598  func (s *server) ListPolicyAssignment(r *api.ListPolicyAssignmentRequest, stream api.GobgpApi_ListPolicyAssignmentServer) error {
  1599  	ctx, cancel := context.WithCancel(context.Background())
  1600  	defer cancel()
  1601  	fn := func(a *api.PolicyAssignment) {
  1602  		if err := stream.Send(&api.ListPolicyAssignmentResponse{Assignment: a}); err != nil {
  1603  			cancel()
  1604  		}
  1605  	}
  1606  	return s.bgpServer.ListPolicyAssignment(ctx, r, fn)
  1607  }
  1608  
  1609  func defaultRouteType(d api.RouteAction) table.RouteType {
  1610  	switch d {
  1611  	case api.RouteAction_ACCEPT:
  1612  		return table.ROUTE_TYPE_ACCEPT
  1613  	case api.RouteAction_REJECT:
  1614  		return table.ROUTE_TYPE_REJECT
  1615  	default:
  1616  		return table.ROUTE_TYPE_NONE
  1617  	}
  1618  }
  1619  
  1620  func toPolicyDefinition(policies []*api.Policy) []*config.PolicyDefinition {
  1621  	l := make([]*config.PolicyDefinition, 0, len(policies))
  1622  	for _, p := range policies {
  1623  		l = append(l, &config.PolicyDefinition{Name: p.Name})
  1624  	}
  1625  	return l
  1626  }
  1627  
  1628  func (s *server) AddPolicyAssignment(ctx context.Context, r *api.AddPolicyAssignmentRequest) (*empty.Empty, error) {
  1629  	return &empty.Empty{}, s.bgpServer.AddPolicyAssignment(ctx, r)
  1630  }
  1631  
  1632  func (s *server) DeletePolicyAssignment(ctx context.Context, r *api.DeletePolicyAssignmentRequest) (*empty.Empty, error) {
  1633  	return &empty.Empty{}, s.bgpServer.DeletePolicyAssignment(ctx, r)
  1634  }
  1635  
  1636  func (s *server) SetPolicyAssignment(ctx context.Context, r *api.SetPolicyAssignmentRequest) (*empty.Empty, error) {
  1637  	return &empty.Empty{}, s.bgpServer.SetPolicyAssignment(ctx, r)
  1638  }
  1639  
  1640  func (s *server) GetBgp(ctx context.Context, r *api.GetBgpRequest) (*api.GetBgpResponse, error) {
  1641  	return s.bgpServer.GetBgp(ctx, r)
  1642  }
  1643  
  1644  func newGlobalFromAPIStruct(a *api.Global) *config.Global {
  1645  	families := make([]config.AfiSafi, 0, len(a.Families))
  1646  	for _, f := range a.Families {
  1647  		name := config.IntToAfiSafiTypeMap[int(f)]
  1648  		rf, _ := bgp.GetRouteFamily(string(name))
  1649  		families = append(families, config.AfiSafi{
  1650  			Config: config.AfiSafiConfig{
  1651  				AfiSafiName: name,
  1652  				Enabled:     true,
  1653  			},
  1654  			State: config.AfiSafiState{
  1655  				AfiSafiName: name,
  1656  				Enabled:     true,
  1657  				Family:      rf,
  1658  			},
  1659  		})
  1660  	}
  1661  
  1662  	applyPolicy := &config.ApplyPolicy{}
  1663  	readApplyPolicyFromAPIStruct(applyPolicy, a.ApplyPolicy)
  1664  
  1665  	global := &config.Global{
  1666  		Config: config.GlobalConfig{
  1667  			As:               a.As,
  1668  			RouterId:         a.RouterId,
  1669  			Port:             a.ListenPort,
  1670  			LocalAddressList: a.ListenAddresses,
  1671  		},
  1672  		ApplyPolicy: *applyPolicy,
  1673  		AfiSafis:    families,
  1674  		UseMultiplePaths: config.UseMultiplePaths{
  1675  			Config: config.UseMultiplePathsConfig{
  1676  				Enabled: a.UseMultiplePaths,
  1677  			},
  1678  		},
  1679  	}
  1680  	if a.RouteSelectionOptions != nil {
  1681  		global.RouteSelectionOptions = config.RouteSelectionOptions{
  1682  			Config: config.RouteSelectionOptionsConfig{
  1683  				AlwaysCompareMed:         a.RouteSelectionOptions.AlwaysCompareMed,
  1684  				IgnoreAsPathLength:       a.RouteSelectionOptions.IgnoreAsPathLength,
  1685  				ExternalCompareRouterId:  a.RouteSelectionOptions.ExternalCompareRouterId,
  1686  				AdvertiseInactiveRoutes:  a.RouteSelectionOptions.AdvertiseInactiveRoutes,
  1687  				EnableAigp:               a.RouteSelectionOptions.EnableAigp,
  1688  				IgnoreNextHopIgpMetric:   a.RouteSelectionOptions.IgnoreNextHopIgpMetric,
  1689  				DisableBestPathSelection: a.RouteSelectionOptions.DisableBestPathSelection,
  1690  			},
  1691  		}
  1692  	}
  1693  	if a.DefaultRouteDistance != nil {
  1694  		global.DefaultRouteDistance = config.DefaultRouteDistance{
  1695  			Config: config.DefaultRouteDistanceConfig{
  1696  				ExternalRouteDistance: uint8(a.DefaultRouteDistance.ExternalRouteDistance),
  1697  				InternalRouteDistance: uint8(a.DefaultRouteDistance.InternalRouteDistance),
  1698  			},
  1699  		}
  1700  	}
  1701  	if a.Confederation != nil {
  1702  		global.Confederation = config.Confederation{
  1703  			Config: config.ConfederationConfig{
  1704  				Enabled:      a.Confederation.Enabled,
  1705  				Identifier:   a.Confederation.Identifier,
  1706  				MemberAsList: a.Confederation.MemberAsList,
  1707  			},
  1708  		}
  1709  	}
  1710  	if a.GracefulRestart != nil {
  1711  		global.GracefulRestart = config.GracefulRestart{
  1712  			Config: config.GracefulRestartConfig{
  1713  				Enabled:             a.GracefulRestart.Enabled,
  1714  				RestartTime:         uint16(a.GracefulRestart.RestartTime),
  1715  				StaleRoutesTime:     float64(a.GracefulRestart.StaleRoutesTime),
  1716  				HelperOnly:          a.GracefulRestart.HelperOnly,
  1717  				DeferralTime:        uint16(a.GracefulRestart.DeferralTime),
  1718  				NotificationEnabled: a.GracefulRestart.NotificationEnabled,
  1719  				LongLivedEnabled:    a.GracefulRestart.LonglivedEnabled,
  1720  			},
  1721  		}
  1722  	}
  1723  	return global
  1724  }
  1725  
  1726  func (s *server) StartBgp(ctx context.Context, r *api.StartBgpRequest) (*empty.Empty, error) {
  1727  	return &empty.Empty{}, s.bgpServer.StartBgp(ctx, r)
  1728  }
  1729  
  1730  func (s *server) StopBgp(ctx context.Context, r *api.StopBgpRequest) (*empty.Empty, error) {
  1731  	return &empty.Empty{}, s.bgpServer.StopBgp(ctx, r)
  1732  }
  1733  
  1734  func (s *server) GetTable(ctx context.Context, r *api.GetTableRequest) (*api.GetTableResponse, error) {
  1735  	return s.bgpServer.GetTable(ctx, r)
  1736  }