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