Feature request: GoBGP plugins
Hi, first of all thank you for the great tool.
I'd like to propose a plugin feature using pkg.go.dev/plugin package.
Plugin main purpose is to inject/withdraw routes or react to incoming route events according to some logic.
Examples of possible plugins:
- Plugin which conditionally advertises VIP address according to service healthiness
- Plugin to "redistribute" the routes of one family into another family and vice versa (e.g. IPv4 inside a VRF and BGP VPNv4)
Plugin vs API
I know that GoBGP has very nice API which allows to do the things I described. Despite this, the plugin has a number of advantages comparing it to GoBGP + separate route injector instance both communicating via GRPC. Arguments for the plugin:
- From operational point of view one process (gobgp+plugin) is better than 2 separate processes . One process is definitely easier to monitor and likely easier to deploy.
- One shared config file (e.g. with separate "plugins" section for plugin config) is more convenient than 2 separate ones.
- Likely better performance due to lack of API communication delay
Plugin vs Write Your Own GO App
I understand that everyone can just write their own go app and use gobgp as a library. Although this approach is feasible, it has some important drawbacks:
- Developer of the app will have to reimplement all the startup stuff (located inside cmd folder) implemented in gobgp: reading config, starting server, reaction to OS signals, and so on.
- If there were 2 open source tools using this separate app approach, the users of these tools would not have an option to combine them inside one gobgp instance (e.g. combine two examples I mentioned earlier inside one app).
Implementation details
- Plugin should be distributed as
.sobinary and be pluggable to the main app using--pluginkeyword. Example:
gobgpd -f config.toml --plugin plugin_1.so --plugin plugin_2.so
- Plugin interface is required and must be implemented by every plugin. Something like:
type BgpServer interface {
// here are the methods to add/remove path and to subscribe to events
}
type Plugin interface {
GetName() string
GetVersion() string
Start(server BgpServer, config *oc.BgpConfigSet)
Stop(server BgpServer, config *oc.BgpConfigSet)
}
- Plugin-specific config should be stored under
[[plugins]]top key of the gobgp config file.
type PluginConfig struct {
Name string
config: []byte // arbitrary struct, should be parsed later by the plugin itself
}
type BgpConfigSet struct {
// rest of the fields here
plugins []PluginConfig
}
I can work on this further, provide more details and finally the PR itself if you agree with the general idea of plugins.