BGP service daemon built in Rust
Peers and their config are defined in TOML
format; see an example here.
Details of config values:
``toml
router_id = "1.1.1.1" # Default Router ID for the service
default_as = 65000 # Used as the local-as if
localas` is not defined for a peer
bgpsocket = "127.0.0.1:1179" # BGP address & port
api_socket = "0.0.0.0:8080" # API address & port [Listen on all interfaces (IPv4 & IPv6)]
[[peers]] remote_ip = "127.0.0.2" # This can also be an IPv6 address, see next peer
remoteas = 65000 passive = true # If passive, bgpd won't attempt outbound connections routerid = "127.0.0.1" # Can override local Router ID for this peer holdtimer = 90 # Set the hold timer for the peer, defaults to 180 seconds families = [ # Define the families this session should support "ipv4 unicast", "ipv6 unicast", ] [[peers.staticroutes]] # Add static routes (advertised at session start) prefix = "9.9.9.0/24" nexthop = "127.0.0.1" [[peers.staticroutes]] prefix = "3001:100::/64" nexthop = "3001:1::1" [[peers.staticflows]] # Add static Flowspec rules too! afi = 2 action = "traffic-rate 24000" matches= [ "source 3001:100::/56", "destination-port >8000 <=8080", "packet-length >100", ] as_path = ["65000", "500"] communities = ["101", "202", "65000:99"]
[[peers]] remoteip = "::2" enabled = false # Peer is essentially de-configured remoteas = 100 local_as = 200 families = [ "ipv6 unicast", ] ```
You can send the BGPd process a SIGHUP
[E.g. pkill -HUP bgpd$
] to reload and update peer configs. The following items can be updated:
*Supported Families
- When not in an active session only, since these are negotiated in the OPEN
BGPd offers an JSON RCP API that can be queried to view operational info like neighbors and routes:
Neighbor uptime & prefixes received
sh
$ curl localhost:8080 -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"show_peers","params":null,"id":0}' | jq '.result[] | {peer: .peer, uptime: .uptime, prefixes_received: .prefixes_received}'
{
"peer": "127.0.0.2",
"uptime": "00:31:13",
"prefixes_received": 4
}
{
"peer": "127.0.0.3",
"uptime": null,
"prefixes_received": null
}
{
"peer": "172.16.20.2",
"uptime": "00:31:20",
"prefixes_received": 2
}
Learned routes (with attributes)
sh
$ curl localhost:8080 -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"show_routes_learned","params": {"from_peer": "172.16.20.2"},"id":0}' | jq '.result[]'
{
"afi": "IPv6",
"age": "00:00:38",
"as_path": "",
"communities": [],
"local_pref": 100,
"multi_exit_disc": null,
"next_hop": "::ffff:172.16.20.2",
"origin": "IGP",
"prefix": "3001:172:16:20::/64",
"received_at": 1572898659,
"safi": "Unicast",
"source": "172.16.20.2"
}
{
"afi": "IPv4",
"age": "00:00:38",
"as_path": "",
"communities": [],
"local_pref": 100,
"multi_exit_disc": null,
"next_hop": "172.16.20.2",
"origin": "IGP",
"prefix": "172.16.20.0/24",
"received_at": 1572898659,
"safi": "Unicast",
"source": "172.16.20.2"
}
The bgpd
CLI can also be used to view peer & route information via the BGPd API (and announce routes too!)
I'm currently using ExaBGP (Python) and GoBGP (Go) to act as my BGP peers for testing. - Here's an intro article about installing & getting started with ExaBGP.
With ExaBGP installed, you can use a config from the examples/exabgp
dir:
conf_127.0.0.2.ini ```ini neighbor 127.0.0.1 { router-id 2.2.2.2; local-address 127.0.0.2; # Our local update-source local-as 65000; # Our local AS peer-as 65000; # Peer's AS
announce {
ipv4 {
unicast 2.100.0.0/24 next-hop self med 500 extended-community [ target:65000:1.1.1.1 ];
unicast 2.200.0.0/24 next-hop self as-path [ 100 200 ];
unicast 2.10.0.0/24 next-hop self med 10 community [404 65000:10];
}
}
} ```
Running the exabgp service with the command:
sh
$ env exabgp.tcp.port=1179 exabgp.tcp.bind="127.0.0.2" exabgp ./conf_127.0.0.2.ini --once
--once only attempts a single connection, auto-quits when session ends
With GoBGP installed, you can use a config from the examples/gobgp
dir:
gobgpd.toml ```toml [global.config] as = 65000 router-id = "4.4.4.4" port = 1179 local-address-list = ["127.0.0.4"]
[[neighbors]] [neighbors.config] neighbor-address = "127.0.0.1" peer-as = 65000 [neighbors.transport.config] passive-mode = false local-address = "127.0.0.4" remote-port = 1179 [neighbors.timers.config] connect-retry = 5 hold-time = 30 keepalive-interval = 10 ```
Running the gobgpd service with the command:
sh
$ gobgpd -f ./examples/gobgp/gobgpd.toml
And then running bgpd
as follows:
Using IPv6
sh
$ cargo run -- run --address "::1" --port 1179 ./examples/config.toml -vv
or IPv4 (defaults to 127.0.0.1)
sh
$ cargo run -- run --port 1179 ./examples/config.toml -vv
You may notice that I'm using TCP port 1179 for testing, if you want/need to use TCP 179 for testing with a peer that can't change the port (coughCiscocough), you need to run bgpd with sudo permissions:
sh
$ cargo build --release
$ sudo ./targets/release/bgpd run ./examples/config.toml -vv