github.com/osrg/gobgp/v3@v3.30.0/pkg/server/grpc_server.go (about)

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