Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Natively modify host route table #2615

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,070 changes: 2,065 additions & 2,005 deletions api/gobgp.pb.go

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions api/gobgp.proto
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ service GobgpApi {

rpc EnableZebra(EnableZebraRequest) returns(google.protobuf.Empty);

rpc EnableModifyHostFIB(EnableModifyHostFIBRequest) returns(google.protobuf.Empty);

rpc EnableMrt(EnableMrtRequest) returns(google.protobuf.Empty);
rpc DisableMrt(DisableMrtRequest) returns(google.protobuf.Empty);

Expand Down Expand Up @@ -403,6 +405,9 @@ message EnableZebraRequest {
string software_name = 7;
}

message EnableModifyHostFIBRequest {
}

message EnableMrtRequest {
enum DumpType { UPDATES = 0; TABLE = 1; }
DumpType type = 1;
Expand Down
36 changes: 36 additions & 0 deletions api/gobgp_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

112 changes: 112 additions & 0 deletions docs/sources/modify-host-fib.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# modify-host-fib

**WARNING: Experimental!**

`modify-host-fib` provides experimental functionality to inject learned routes into the
routing table of the host running GoBGP. i.e. it provides a subset of something like
Zebra's functionality without requiring the external dependency of Zebra.

This could be extended in the future to support bidirectional functionality but
currently only learning routes is supported.

This currently only works on Windows, with IPv4. The initial implementation goal was
only to get BGP working on Windows desktop OSs (Windows Server has native BGP support -
if you're here for Windows Server support you should probably use that).

**This is not supported by the core GoBGP team at all. Use at your own risk.**

## Users

Add this to your config:

```toml
[experimental]
[experimental.modify-host-fib]
[experimental.modify-host-fib.config]
enabled = true
```

## Developers

### Code flow

The implementation and flow mirrors the Zebra integration. The Zebra integration:

- `/tools/pyang_plugins/gobgp.yang` defines the user-facing configuration options for
Zebra in YANG format
- pyyang converts this into Go structures in `internal/config/bgp_configs.go`
- If Zebra is enabled, `InitialConfig()` in `pkg/config/config.go` calls `EnableZebra()`
- `EnableZebra()` in `pkg/server/server.go` calls `NewZebraClient()` to create a new
Zebra client and add it to the `BgpServer` singleton
- `NewZebraClient()` in `pkg/server/zclient.go` sets up the connection to Zebra and
kicks off `loop()` as a goroutine
- `loop()` in `pkg/server/zclient.go` watches for events from `BgpServer` and the Zebra
daemon and triggers a matching effect on the opposite side

Additionally a gprc request defined in `api/gobgp.proto` - rendered into `gobgp.pb.go`
and `gobgp_grpc.pb.go` by `tools/grpc/genproto.sh` - can be used to call
`EnableZebra()`.

This implementation:

- `/tools/pyang_plugins/gobgp.yang` defines the user-facing configuration options for
this feature in YANG format
- pyyang converts this into Go structures in `internal/config/bgp_configs.go`
- If this feature is enabled, `InitialConfig()` in `pkg/config/config.go` calls
`EnableModifyHostFIB()`
- `EnableModifyHostFIB()` in `pkg/server/server.go` calls `NewModifyHostFIBClient()` to
create a new client and add it to the `BgpServer` singleton
- `NewModifyHostFIBClient()` in `pkg/server/modify_host_fib.go` kicks off `loop()` as a
goroutine
- `loop()` in `pkg/server/modify_host_fib.go` watches for events from `BgpServer` and
updates the host's routing table to match
- Some external activity (e.g. CTRL+C) triggers `stopServer()` in `main.go`
- `stopServer()` calls `Stop()` on `bgpServer` in `server.go`
- `Stop()` calls `stop()` in `modify_host_fib.go`
- `stop()` stops `loop()`, waits for it to finish, then removes all BGP routes from the
host's routing table to clean up

Additionally a gprc request defined in `api/gobgp.proto` - rendered into `gobgp.pb.go`
and `gobgp_grpc.pb.go` by `tools/grpc/genproto.sh` - can be used to call
`EnableModifyHostFIB()`.

### Adding a new platform

To support multiple platforms this uses the `<filename>_<platform>.go` pattern used
elsewhere: each platform's specific implementation is in a separate file and Go `build:`
parameters are used to only include the correct files for each platform.

- Add a new `pkg/server/modify_host_fib_<platform>.go` file, e.g.
`pkg/server/modify_host_fib_linux.go`
- Set it to only build for that platform:

```go
//go:build <platform>
// +build <platform>
```

e.g.

```go
//go:build linux
// +build linux
```

- Exclude the default stub file `pkg/server/modify_host_fib_stub.go` from your platform

```go
//go:build <existing> && !<platform>
// +build <existing> && !<platform>
```

e.g.

```go
//go:build !windows && !linux
// +build !windows && !linux
```

- Copy the contents of `pkg/server/modify_host_fib_windows.go` and implement the
functions for your platform. The only required functions are
`newModifyHostFIBClient()` and `stop()` as these are called by other code in the
`server` package. The rest are implementation details.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ require (
github.com/vishvananda/netlink v1.2.1-beta.2
golang.org/x/net v0.4.0
golang.org/x/text v0.5.0
golang.zx2c4.com/wireguard/windows v0.5.3
google.golang.org/grpc v1.51.0
google.golang.org/protobuf v1.28.1
)
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE=
golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
Expand Down
69 changes: 68 additions & 1 deletion internal/pkg/config/bgp_configs.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions internal/pkg/config/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type BgpConfigSet struct {
Vrfs []Vrf `mapstructure:"vrfs"`
MrtDump []Mrt `mapstructure:"mrt-dump"`
Zebra Zebra `mapstructure:"zebra"`
Experimental Experimental `mapstructure:"experimental"`
Collector Collector `mapstructure:"collector"`
DefinedSets DefinedSets `mapstructure:"defined-sets"`
PolicyDefinitions []PolicyDefinition `mapstructure:"policy-definitions"`
Expand Down
7 changes: 7 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,13 @@ func InitialConfig(ctx context.Context, bgpServer *server.BgpServer, newConfig *
}
}

if newConfig.Experimental.ModifyHostFib.Config.Enabled {
if err := bgpServer.EnableModifyHostFIB(ctx, &api.EnableModifyHostFIBRequest{}); err != nil {
bgpServer.Log().Fatal("failed to enable ModifyHostFIB functionality",
log.Fields{"Topic": "config", "Error": err})
}
}

if len(newConfig.Collector.Config.Url) > 0 {
bgpServer.Log().Fatal("collector feature is not supported",
log.Fields{"Topic": "config"})
Expand Down
32 changes: 32 additions & 0 deletions pkg/server/modify_host_fib.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// bits of modify-host-fib functionality that should be included for all platforms.

package server

import (
"context"
"sync"
)

type modifyHostFIBClient struct {
// global parent struct
server *BgpServer
// called to stop the loop() goroutine when we shut down
stopLoop context.CancelFunc
// blocks until loop() is fully shut down after calling stopLoop
loopFinished *sync.WaitGroup
}
Loading