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 }