BGP ctrl commands, config, docu ...

This commit is contained in:
Christian Giese
2022-03-15 15:13:19 +01:00
parent ff16b44532
commit 4e341fc354
14 changed files with 221 additions and 71 deletions
+14 -10
View File
@@ -698,21 +698,25 @@ json_parse_bgp_config(bbl_ctx_s *ctx, json_t *bgp, bgp_config_t *bgp_config) {
ctx->tcp = true;
if (json_unpack(bgp, "{s:s}", "source-ipv4-address", &s) == 0) {
if (!inet_pton(AF_INET, s, &bgp_config->ipv4_src_address)) {
fprintf(stderr, "JSON config error: Invalid value for bgp->source-ipv4-address\n");
return false;
}
add_secondary_ipv4(ctx, bgp_config->ipv4_src_address);
if (json_unpack(bgp, "{s:s}", "network-interface", &s) == 0) {
bgp_config->network_interface = strdup(s);
}
if (json_unpack(bgp, "{s:s}", "destination-ipv4-address", &s) == 0) {
if (!inet_pton(AF_INET, s, &bgp_config->ipv4_dst_address)) {
fprintf(stderr, "JSON config error: Invalid value for bgp->destination-ipv4-address\n");
if (json_unpack(bgp, "{s:s}", "local-ipv4-address", &s) == 0) {
if (!inet_pton(AF_INET, s, &bgp_config->ipv4_local_address)) {
fprintf(stderr, "JSON config error: Invalid value for bgp->local-ipv4-address\n");
return false;
}
add_secondary_ipv4(ctx, bgp_config->ipv4_local_address);
}
if (json_unpack(bgp, "{s:s}", "peer-ipv4-address", &s) == 0) {
if (!inet_pton(AF_INET, s, &bgp_config->ipv4_peer_address)) {
fprintf(stderr, "JSON config error: Invalid value for bgp->peer-ipv4-address\n");
return false;
}
} else {
fprintf(stderr, "JSON config error: Missing value for bgp->destination-ipv4-address\n");
fprintf(stderr, "JSON config error: Missing value for bgp->peer-ipv4-address\n");
return false;
}
+31
View File
@@ -1433,6 +1433,36 @@ bbl_ctrl_isis_lsp_update(int fd, bbl_ctx_s *ctx, uint32_t session_id __attribute
return bbl_ctrl_status(fd, "ok", 200, NULL);
}
ssize_t
bbl_ctrl_bgp_sessions(int fd, bbl_ctx_s *ctx, uint32_t session_id __attribute__((unused)), json_t* arguments __attribute__((unused))) {
ssize_t result = 0;
json_t *root, *sessions, *session;
bgp_session_t *bgp_session = ctx->bgp_sessions;
sessions = json_array();
while(bgp_session) {
session = bgp_ctrl_session(bgp_session);
if(session) {
json_array_append(sessions, session);
}
bgp_session = bgp_session->next;
}
root = json_pack("{ss si so}",
"status", "ok",
"code", 200,
"bgp-sessions", sessions);
if(root) {
result = json_dumpfd(root, fd, 0);
json_decref(root);
} else {
result = bbl_ctrl_status(fd, "error", 500, "internal error");
json_decref(sessions);
}
return result;
}
struct action {
char *name;
callback_function *fn;
@@ -1481,6 +1511,7 @@ struct action actions[] = {
{"isis-database", bbl_ctrl_isis_database},
{"isis-load-mrt", bbl_ctrl_isis_load_mrt},
{"isis-lsp-update", bbl_ctrl_isis_lsp_update},
{"bgp-sessions", bbl_ctrl_bgp_sessions},
{NULL, NULL},
};
+8 -8
View File
@@ -82,12 +82,12 @@ bgp_init(bbl_ctx_s *ctx) {
session->config = config;
session->interface = network_if;
if(config->ipv4_src_address) {
session->ipv4_src_address = config->ipv4_src_address;
if(config->ipv4_local_address) {
session->ipv4_local_address = config->ipv4_local_address;
} else {
session->ipv4_src_address = network_if->ip.address;
session->ipv4_local_address = network_if->ip.address;
}
session->ipv4_dst_address = config->ipv4_dst_address;
session->ipv4_peer_address = config->ipv4_peer_address;
/* Init read/write buffer */
session->read_buf.data = malloc(BGP_BUF_SIZE);
@@ -114,8 +114,8 @@ bgp_init(bbl_ctx_s *ctx) {
LOG(BGP, "BGP (%s %s - %s) init session\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address));
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address));
bgp_session_connect(session, 1);
ctx->routing_sessions++;
@@ -148,8 +148,8 @@ bgp_teardown(bbl_ctx_s *ctx) {
if(!session->teardown) {
LOG(BGP, "BGP (%s %s - %s) teardown session\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address));
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address));
session->teardown = true;
if(!session->error_code) {
+1
View File
@@ -15,6 +15,7 @@
#include "bgp_message.h"
#include "bgp_receive.h"
#include "bgp_mrt.h"
#include "bgp_ctrl.h"
bool
bgp_init(bbl_ctx_s *ctx);
+32
View File
@@ -0,0 +1,32 @@
/*
* BNG Blaster (BBL) - BGP CTRL (Control Commands)
*
* Christian Giese, March 2022
*
* Copyright (C) 2020-2022, RtBrick, Inc.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "bgp.h"
json_t *
bgp_ctrl_session(bgp_session_t *session) {
json_t *root = NULL;
if(!session) {
return NULL;
}
root = json_pack("{ss ss ss si si ss ss si si ss }",
"interface", session->interface->name,
"local-address", format_ipv4_address(&session->ipv4_local_address),
"local-id", format_ipv4_address(&session->config->id),
"local-as", session->config->local_as,
"local-holdtime", session->config->holdtime,
"peer-address", format_ipv4_address(&session->ipv4_peer_address),
"peer-id", format_ipv4_address(&session->peer.id),
"peer-as", session->peer.as,
"peer-holdtime", session->peer.holdtime,
"state", bgp_session_state_string(session->state));
return root;
}
+15
View File
@@ -0,0 +1,15 @@
/*
* BNG Blaster (BBL) - BGP CTRL (Control Commands)
*
* Christian Giese, March 2022
*
* Copyright (C) 2020-2022, RtBrick, Inc.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __BBL_BGP_CTRL_H__
#define __BBL_BGP_CTRL_H__
json_t *
bgp_ctrl_session(bgp_session_t *session);
#endif
+4 -4
View File
@@ -52,8 +52,8 @@ typedef struct bgp_raw_update_ {
* BGP Configuration
*/
typedef struct bgp_config_ {
uint32_t ipv4_src_address;
uint32_t ipv4_dst_address;
uint32_t ipv4_local_address;
uint32_t ipv4_peer_address;
uint32_t id;
uint32_t local_as;
uint32_t peer_as;
@@ -76,8 +76,8 @@ typedef struct bgp_config_ {
typedef struct bgp_session_ {
struct bbl_ctx_ *ctx; /* parent */
uint32_t ipv4_src_address;
uint32_t ipv4_dst_address;
uint32_t ipv4_local_address;
uint32_t ipv4_peer_address;
bgp_config_t *config;
bbl_interface_s *interface;
+20 -20
View File
@@ -80,8 +80,8 @@ bgp_open(bgp_session_t *session, uint8_t *start, uint16_t length) {
LOG(BGP, "BGP (%s %s - %s) open message received with peer AS: %u, holdtime: %us\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address),
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address),
session->peer.as, session->peer.holdtime);
bgp_session_state_change(session, BGP_OPENCONFIRM);
@@ -90,8 +90,8 @@ bgp_open(bgp_session_t *session, uint8_t *start, uint16_t length) {
ERROR:
LOG(BGP, "BGP (%s %s - %s) invalid open message received\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address));
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address));
if(!session->error_code) {
session->error_code = 1; /* Message header error */
@@ -114,40 +114,40 @@ bgp_notification(bgp_session_t *session, uint8_t *start, uint16_t length) {
case 1: /* Message Header Error */
LOG(BGP, "BGP (%s %s - %s) notification received with error: %s (%u), %s (%u)\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address),
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address),
keyval_get_key(bgp_notification_error_values, error_code), error_code,
keyval_get_key(bgp_notification_msg_hdr_error_values, error_subcode), error_subcode);
break;
case 2: /* OPEN Message Error */
LOG(BGP, "BGP (%s %s - %s) notification received with error: %s (%u), %s (%u)\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address),
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address),
keyval_get_key(bgp_notification_error_values, error_code), error_code,
keyval_get_key(bgp_notification_open_error_values, error_subcode), error_subcode);
break;
case 3: /* Update Message Error */
LOG(BGP, "BGP (%s %s - %s) notification received with error: %s (%u), %s (%u)\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address),
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address),
keyval_get_key(bgp_notification_error_values, error_code), error_code,
keyval_get_key(bgp_notification_update_error_values, error_subcode), error_subcode);
break;
case 6: /* Cease */
LOG(BGP, "BGP (%s %s - %s) notification received with error: %s (%u), %s (%u)\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address),
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address),
keyval_get_key(bgp_notification_error_values, error_code), error_code,
keyval_get_key(bgp_notification_cease_error_values, error_subcode), error_subcode);
break;
default:
LOG(BGP, "BGP (%s %s - %s) notification received with error: %s (%u), subcode %u\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address),
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address),
keyval_get_key(bgp_notification_error_values, error_code), error_code, error_subcode);
break;
}
@@ -158,8 +158,8 @@ bgp_notification(bgp_session_t *session, uint8_t *start, uint16_t length) {
ERROR:
LOG(BGP, "BGP (%s %s - %s) invalid notification message received\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address));
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address));
if(!session->error_code) {
session->error_code = 1; /* Message header error */
@@ -215,8 +215,8 @@ bpg_read(bgp_session_t *session) {
LOG(DEBUG, "BGP (%s %s - %s) read %s message\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address),
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address),
keyval_get_key(bgp_msg_names, type));
switch (type) {
@@ -256,8 +256,8 @@ bgp_receive_cb(void *arg, uint8_t *buf, uint16_t len) {
if(buffer->idx+len > buffer->size) {
LOG(ERROR, "BGP (%s %s - %s) receive error (read buffer exhausted)\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address));
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address));
if(!session->error_code) {
session->error_code = 6; /* Cease */
+30 -28
View File
@@ -10,18 +10,20 @@
extern bool g_init_phase;
extern volatile bool g_teardown;
struct keyval_ bgp_fsm_state_names[] = {
{ BGP_CLOSED, "closed" },
{ BGP_IDLE, "idle" },
{ BGP_CONNECT, "connect" },
{ BGP_ACTIVE, "active" },
{ BGP_OPENSENT, "opensent" },
{ BGP_OPENCONFIRM, "openconfirm" },
{ BGP_ESTABLISHED, "established" },
{ BGP_CLOSING, "closing" },
{ 0, NULL}
};
const char *
bgp_session_state_string(bgp_state_t state) {
switch(state) {
case BGP_CLOSED: return "closed";
case BGP_IDLE: return "idle";
case BGP_CONNECT: return "connect";
case BGP_ACTIVE: return "active";
case BGP_OPENSENT: return "opensent";
case BGP_OPENCONFIRM: return "openconfirm";
case BGP_ESTABLISHED: return "established";
case BGP_CLOSING: return "closing";
default: return "unknown";
}
}
/**
* bgp_session_reset_read_buffer
@@ -151,10 +153,10 @@ bgp_session_state_change(bgp_session_t *session, bgp_state_t new_state) {
LOG(BGP, "BGP (%s %s - %s) state changed from %s -> %s\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address),
keyval_get_key(bgp_fsm_state_names, session->state),
keyval_get_key(bgp_fsm_state_names, new_state));
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address),
bgp_session_state_string(session->state),
bgp_session_state_string(new_state));
session->state = new_state;
@@ -185,8 +187,8 @@ bgp_error_cb(void *arg, err_t err) {
LOG(BGP, "BGP (%s %s - %s) TCP error %d (%s)\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address),
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address),
err, tcp_err_string(err));
session->error_code = 0;
@@ -206,8 +208,8 @@ bgp_session_connect_job(timer_s *timer) {
/* Connect TCP session */
session->tcpc = bbl_tcp_ipv4_connect(
session->interface,
&session->ipv4_src_address,
&session->ipv4_dst_address,
&session->ipv4_local_address,
&session->ipv4_peer_address,
BGP_PORT);
if(session->tcpc) {
@@ -221,8 +223,8 @@ bgp_session_connect_job(timer_s *timer) {
} else {
LOG(BGP, "BGP (%s %s - %s) TCP connect failed\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address));
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address));
}
} else if(session->state == BGP_ESTABLISHED) {
timer->periodic = false;
@@ -230,8 +232,8 @@ bgp_session_connect_job(timer_s *timer) {
} else {
LOG(BGP, "BGP (%s %s - %s) connect timeout\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address));
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address));
bgp_session_close(session);
timer->periodic = false;
@@ -309,8 +311,8 @@ bgp_session_close(bgp_session_t *session) {
/* Send notification messages */
LOG(BGP, "BGP (%s %s - %s) send notification message (error code %u sub-code %u)\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address),
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address),
session->error_code, session->error_subcode);
bgp_session_reset_write_buffer(session);
bgp_push_notification_message(session);
@@ -330,8 +332,8 @@ bgp_session_hold_timer_job(timer_s *timer) {
LOG(BGP, "BGP (%s %s - %s) session timeout\n",
session->interface->name,
format_ipv4_address(&session->ipv4_src_address),
format_ipv4_address(&session->ipv4_dst_address));
format_ipv4_address(&session->ipv4_local_address),
format_ipv4_address(&session->ipv4_peer_address));
if(!session->error_code) {
session->error_code = 4; /* hold timer expired */
+3
View File
@@ -9,6 +9,9 @@
#ifndef __BBL_BGP_SESSION_H__
#define __BBL_BGP_SESSION_H__
const char *
bgp_session_state_string(bgp_state_t state);
void
bgp_session_state_change(bgp_session_t *session, bgp_state_t new_state);
-1
View File
@@ -31,7 +31,6 @@ isis_ctrl_adjacency_p2p(isis_adjacency_p2p_t *adjacency) {
if(!root) {
if(peer) json_decref(peer);
}
return root;
}
+45
View File
@@ -0,0 +1,45 @@
# BGP
The Border Gateway Protocol (BGP) is a standardized exterior gateway protocol
designed to exchange routing and reachability information among autonomous systems
(AS) on the internet. BGP is classified as a path-vector routing protocol, and it
makes routing decisions based on paths, network policies, or rule-sets configured
by a network administrator.
Following an example ISIS configuration with one instance
attached to two network interfaces.
```json
{
"interfaces": {
"network": [
{
"interface": "eth1",
"address": "10.0.1.2/24",
"gateway": "10.0.1.1"
}
]
},
"bgp": [
{
"local-ipv4-address": "10.0.1.2",
"peer-ipv4-address": "10.0.1.1",
"raw-update-file": "test.bgp",
"local-as": 65001,
"peer-as": 65001
}
]
}
```
## Limitations
Currently only IPv4 sessions are supported.
## RAW Update Files
The BNG Blaster is able to inject BGP update messages
from a pre-compiled RAW update file into the defined
session.
+17
View File
@@ -915,3 +915,20 @@ Attribute | Description | Default
]
}
```
## BGP
This section describes all attributes of the `bgp` hierarchy.
Attribute | Description | Default
--------- | ----------- | -------
`network-interface` | BGP local interface (source-interface) | first network interface
`local-ipv4-address` | BGP local IPv4 address (source-address) | network interface address
`local-as` | BGP local AS | 65000
`peer-ipv4-address` | BGP peer address |
`peer-as` | BGP peer AS | local AS
`holdtime` | BGP holdtime in seconds | 90
`id` | BGP identifier | 1.2.3.4
`reconnect` | BGP reconnect | true
`teardown-time` | BGP teardown time in seconds | 5
`raw-update-file` | BGP RAW update file |
+1
View File
@@ -14,6 +14,7 @@
- [Legal Interception](li)
- [A10NSP](a10nsp)
- [ISIS](isis)
- [BGP](bgp)
The BNG Blaster is an open source network test tool which is able to simulate more
than hundred thousand PPPoE and IPoE subscribers including IPTV, L2TPv2, QoS, forwarding