summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--cmd/gobgpd/main.go18
-rw-r--r--pkg/config/config.go21
-rw-r--r--pkg/config/config_test.go68
3 files changed, 101 insertions, 6 deletions
diff --git a/cmd/gobgpd/main.go b/cmd/gobgpd/main.go
index 597a7df9..48eb43ac 100644
--- a/cmd/gobgpd/main.go
+++ b/cmd/gobgpd/main.go
@@ -181,7 +181,14 @@ func main() {
"Topic": "Config",
}).Info("Finished reading the config file")
- currentConfig := config.ApplyInitialConfig(context.Background(), bgpServer, initialConfig, opts.GracefulRestart)
+ currentConfig, err := config.InitialConfig(context.Background(), bgpServer, initialConfig, opts.GracefulRestart)
+ if err != nil {
+ log.WithFields(log.Fields{
+ "Topic": "Config",
+ "Error": err,
+ }).Fatalf("Failed to apply initial configuration %s", opts.ConfigFile)
+ }
+
for sig := range sigCh {
if sig != syscall.SIGHUP {
stopServer(bgpServer, opts.UseSdNotify)
@@ -200,7 +207,14 @@ func main() {
continue
}
- currentConfig = config.UpdateConfig(context.Background(), bgpServer, currentConfig, newConfig)
+ currentConfig, err = config.UpdateConfig(context.Background(), bgpServer, currentConfig, newConfig)
+ if err != nil {
+ log.WithFields(log.Fields{
+ "Topic": "Config",
+ "Error": err,
+ }).Warningf("Failed to update config %s", opts.ConfigFile)
+ continue
+ }
}
}
diff --git a/pkg/config/config.go b/pkg/config/config.go
index ba205ce8..5e315094 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -13,6 +13,8 @@ import (
"github.com/osrg/gobgp/pkg/server"
)
+// ReadConfigFile parses a config file into a BgpConfigSet which can be applied
+// using InitialConfig and UpdateConfig.
func ReadConfigFile(configFile, configType string) (*config.BgpConfigSet, error) {
return config.ReadConfigfile(configFile, configType)
}
@@ -160,7 +162,12 @@ func updateNeighbors(ctx context.Context, bgpServer *server.BgpServer, updated [
return false
}
-func ApplyInitialConfig(ctx context.Context, bgpServer *server.BgpServer, newConfig *config.BgpConfigSet, isGracefulRestart bool) *config.BgpConfigSet {
+// InitialConfig applies initial configuration to a pristine gobgp instance. It
+// can only be called once for an instance. Subsequent changes to the
+// configuration can be applied using UpdateConfig. The BgpConfigSet can be
+// obtained by calling ReadConfigFile. If graceful restart behavior is desired,
+// pass true for isGracefulRestart. Otherwise, pass false.
+func InitialConfig(ctx context.Context, bgpServer *server.BgpServer, newConfig *config.BgpConfigSet, isGracefulRestart bool) (*config.BgpConfigSet, error) {
if err := bgpServer.StartBgp(ctx, &api.StartBgpRequest{
Global: config.NewGlobalFromConfigStruct(&newConfig.Global),
}); err != nil {
@@ -277,10 +284,16 @@ func ApplyInitialConfig(ctx context.Context, bgpServer *server.BgpServer, newCon
addPeerGroups(ctx, bgpServer, addedPg)
addDynamicNeighbors(ctx, bgpServer, newConfig.DynamicNeighbors)
addNeighbors(ctx, bgpServer, added)
- return newConfig
+ return newConfig, nil
}
-func UpdateConfig(ctx context.Context, bgpServer *server.BgpServer, c, newConfig *config.BgpConfigSet) *config.BgpConfigSet {
+// UpdateConfig updates the configuration of a running gobgp instance.
+// InitialConfig must have been called once before this can be called for
+// subsequent changes to config. The differences are that this call 1) does not
+// hangle graceful restart and 2) requires a BgpConfigSet for the previous
+// configuration so that it can compute the delta between it and the new
+// config. The new BgpConfigSet can be obtained using ReadConfigFile.
+func UpdateConfig(ctx context.Context, bgpServer *server.BgpServer, c, newConfig *config.BgpConfigSet) (*config.BgpConfigSet, error) {
addedPg, deletedPg, updatedPg := config.UpdatePeerGroupConfig(c, newConfig)
added, deleted, updated := config.UpdateNeighborConfig(c, newConfig)
updatePolicy := config.CheckPolicyDifference(config.ConfigSetToRoutingPolicy(c), config.ConfigSetToRoutingPolicy(newConfig))
@@ -323,5 +336,5 @@ func UpdateConfig(ctx context.Context, bgpServer *server.BgpServer, c, newConfig
log.Warn(err)
}
}
- return newConfig
+ return newConfig, nil
}
diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go
new file mode 100644
index 00000000..67ffa5e7
--- /dev/null
+++ b/pkg/config/config_test.go
@@ -0,0 +1,68 @@
+package config
+
+import (
+ "context"
+ "os"
+ "os/signal"
+ "syscall"
+
+ "github.com/osrg/gobgp/pkg/server"
+)
+
+// ExampleUpdateConfig shows how InitialConfig can be used without UpdateConfig
+func ExampleInitialConfig() {
+ bgpServer := server.NewBgpServer()
+ go bgpServer.Serve()
+
+ initialConfig, err := ReadConfigFile("gobgp.conf", "toml")
+ if err != nil {
+ // Handle error
+ return
+ }
+
+ isGracefulRestart := true
+ _, err = InitialConfig(context.Background(), bgpServer, initialConfig, isGracefulRestart)
+
+ if err != nil {
+ // Handle error
+ return
+ }
+}
+
+// ExampleUpdateConfig shows how UpdateConfig is used in conjuction with
+// InitialConfig.
+func ExampleUpdateConfig() {
+ bgpServer := server.NewBgpServer()
+ go bgpServer.Serve()
+
+ initialConfig, err := ReadConfigFile("gobgp.conf", "toml")
+ if err != nil {
+ // Handle error
+ return
+ }
+
+ isGracefulRestart := true
+ currentConfig, err := InitialConfig(context.Background(), bgpServer, initialConfig, isGracefulRestart)
+
+ if err != nil {
+ // Handle error
+ return
+ }
+
+ sigCh := make(chan os.Signal, 1)
+ signal.Notify(sigCh, syscall.SIGHUP)
+
+ for range sigCh {
+ newConfig, err := ReadConfigFile("gobgp.conf", "toml")
+ if err != nil {
+ // Handle error
+ continue
+ }
+
+ currentConfig, err = UpdateConfig(context.Background(), bgpServer, currentConfig, newConfig)
+ if err != nil {
+ // Handle error
+ continue
+ }
+ }
+}