BGP Initial (WIP)

This commit is contained in:
Christian Giese
2022-03-09 13:45:10 +01:00
parent 2e3fe1fa1d
commit 15e17ecc70
21 changed files with 754 additions and 108 deletions
+9
View File
@@ -564,6 +564,15 @@ main(int argc, char *argv[])
exit(1);
}
/* Init TCP. */
bbl_tcp_init(ctx);
/* Init BGP sessions. */
if(!bgp_init(ctx)) {
fprintf(stderr, "Error: Failed to init BGP\n");
exit(1);
}
/* Start curses. */
if (interactive) {
bbl_init_curses(ctx);
+2
View File
@@ -30,6 +30,7 @@
#include "bbl_def.h"
#include "bbl_protocols.h"
#include "bgp/bgp_def.h"
#include "isis/isis_def.h"
#include "bbl_stats.h"
@@ -43,6 +44,7 @@
#include "bbl_a10nsp.h"
#include "bbl_li.h"
#include "bbl_tcp.h"
#include "bgp/bgp.h"
#include "isis/isis.h"
WINDOW *log_win;
+104
View File
@@ -282,6 +282,18 @@ json_parse_network_interface(bbl_ctx_s *ctx, json_t *network_interface, bbl_netw
network_config->vlan &= 4095;
}
value = json_object_get(network_interface, "mtu");
if (json_is_number(value)) {
network_config->mtu = json_number_value(value);
} else {
network_config->mtu = 1500;
}
if(network_config->mtu < 64 || network_config->mtu > 9000) {
fprintf(stderr, "JSON config error: Invalid value for network->mtu\n");
return false;
}
value = json_object_get(network_interface, "gateway-resolve-wait");
if (json_is_boolean(value)) {
network_config->gateway_resolve_wait = json_boolean_value(value);
@@ -679,6 +691,69 @@ json_parse_a10nsp_interface(bbl_ctx_s *ctx, json_t *a10nsp_interface, bbl_a10nsp
return true;
}
static bool
json_parse_bgp_config(bbl_ctx_s *ctx, json_t *bgp, bgp_config_t *bgp_config) {
json_t *value = NULL;
const char *s = NULL;
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}", "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");
return false;
}
} else {
fprintf(stderr, "JSON config error: Missing value for bgp->destination-ipv4-address\n");
return false;
}
value = json_object_get(bgp, "local-as");
if (value) {
bgp_config->local_as = json_number_value(value);
} else {
bgp_config->local_as = BGP_DEFAULT_AS;
}
value = json_object_get(bgp, "peer-as");
if (value) {
bgp_config->peer_as = json_number_value(value);
} else {
bgp_config->peer_as = bgp_config->local_as;
}
value = json_object_get(bgp, "holdtime");
if (value) {
bgp_config->holdtime = json_number_value(value);
} else {
bgp_config->holdtime = BGP_DEFAULT_HOLDTIME;
}
bgp_config->id = htobe32(0x01020304);
if (json_unpack(bgp, "{s:s}", "id", &s) == 0) {
if (!inet_pton(AF_INET, s, &bgp_config->id)) {
fprintf(stderr, "JSON config error: Invalid value for bgp->id\n");
return false;
}
} else {
}
if (json_unpack(bgp, "{s:s}", "mrt-file", &s) == 0) {
bgp_config->mrt_file = strdup(s);
}
return true;
}
static bool
json_parse_isis_config(bbl_ctx_s *ctx, json_t *isis, isis_config_t *isis_config) {
json_t *sub, *con, *c, *value = NULL;
@@ -1181,6 +1256,7 @@ json_parse_config(json_t *root, bbl_ctx_s *ctx) {
bbl_access_config_s *access_config = NULL;
bbl_a10nsp_config_s *a10nsp_config = NULL;
bgp_config_t *bgp_config = NULL;
isis_config_t *isis_config = NULL;
if (json_typeof(root) != JSON_OBJECT) {
@@ -1581,6 +1657,34 @@ json_parse_config(json_t *root, bbl_ctx_s *ctx) {
}
}
/* BGP Configuration */
sub = json_object_get(root, "bgp");
if (json_is_array(sub)) {
/* Config is provided as array (multiple bgp sessions) */
size = json_array_size(sub);
for (i = 0; i < size; i++) {
if (!bgp_config) {
ctx->config.bgp_config = calloc(1, sizeof(bgp_config_t));
bgp_config = ctx->config.bgp_config;
} else {
bgp_config->next = calloc(1, sizeof(bgp_config_t));
bgp_config = bgp_config->next;
}
if (!json_parse_bgp_config(ctx, json_array_get(sub, i), bgp_config)) {
return false;
}
}
} else if (json_is_object(sub)) {
/* Config is provided as object (single bgp session) */
bgp_config = calloc(1, sizeof(bgp_config_t));
if (!ctx->config.bgp_config) {
ctx->config.bgp_config = bgp_config;
}
if (!json_parse_bgp_config(ctx, sub, bgp_config)) {
return false;
}
}
/* IS-IS Configuration */
sub = json_object_get(root, "isis");
if (json_is_array(sub)) {
+2 -1
View File
@@ -87,7 +87,8 @@ typedef struct bbl_network_config_
uint8_t gateway_mac[ETH_ADDR_LEN];
bool gateway_resolve_wait;
uint16_t vlan;
uint16_t mtu;
ipv4_prefix ip;
ipv4addr_t gateway;
+3 -6
View File
@@ -21,7 +21,7 @@ bbl_compare_key32 (void *key1, void *key2)
}
uint32_t
bbl_key32_hash (const void* k)
bbl_key32_hash(const void* k)
{
uint32_t hash = 2166136261U;
hash ^= *(uint32_t *)k;
@@ -29,7 +29,7 @@ bbl_key32_hash (const void* k)
}
int
bbl_compare_key64 (void *key1, void *key2)
bbl_compare_key64(void *key1, void *key2)
{
const uint64_t a = *(const uint64_t*)key1;
const uint64_t b = *(const uint64_t*)key2;
@@ -37,7 +37,7 @@ bbl_compare_key64 (void *key1, void *key2)
}
uint32_t
bbl_key64_hash (const void* k)
bbl_key64_hash(const void* k)
{
uint32_t hash = 2166136261U;
@@ -85,9 +85,6 @@ bbl_ctx_add (void)
ctx->li_flow_dict = hashtable_dict_new((dict_compare_func)bbl_compare_key32, bbl_key32_hash, BBL_LI_HASHTABLE_SIZE);
ctx->stream_flow_dict = hashtable_dict_new((dict_compare_func)bbl_compare_key64, bbl_key64_hash, BBL_STREAM_FLOW_HASHTABLE_SIZE);
/* Initialize TCP. */
bbl_tcp_init(ctx);
return ctx;
}
+18
View File
@@ -84,6 +84,8 @@ typedef struct bbl_ctx_
void *stream_thread; /* single linked list of threads */
bool tcp;
/* Interfaces */
struct {
uint8_t count;
@@ -99,6 +101,7 @@ typedef struct bbl_ctx_
struct bbl_interface_ *a10nsp_if[BBL_MAX_INTERFACES];
} interfaces;
bgp_session_t *bgp_sessions;
isis_instance_t *isis_instances;
/* Scratchpad memory */
@@ -171,6 +174,9 @@ typedef struct bbl_ctx_
/* Traffic Streams */
void *stream_config;
/* BGP Instances */
bgp_config_t *bgp_config;
/* ISIS Instances */
isis_config_t *isis_config;
@@ -301,6 +307,18 @@ typedef struct bbl_ctx_
} config;
} bbl_ctx_s;
int
bbl_compare_key32 (void *key1, void *key2);
uint
bbl_key32_hash(const void* k);
int
bbl_compare_key64(void *key1, void *key2);
uint
bbl_key64_hash(const void* k);
bbl_ctx_s *
bbl_ctx_add(void);
+1
View File
@@ -173,5 +173,6 @@ typedef struct bbl_a10nsp_session_ bbl_a10nsp_session_t;
typedef struct bbl_stream_thread_ bbl_stream_thread;
typedef struct bbl_stream_config_ bbl_stream_config;
typedef struct bbl_stream_ bbl_stream;
typedef struct bbl_tcp_ctx_ bbl_tcp_ctx_t;
#endif
+1
View File
@@ -86,6 +86,7 @@ typedef struct bbl_interface_
uint16_t mc_packet_cursor;
struct netif netif; /* LwIP network interface */
dict *tcp_connections; /* hashtable for tcp_connections */
isis_adjacency_p2p_t *isis_adjacency_p2p;
isis_adjacency_t *isis_adjacency[ISIS_LEVELS];
+36
View File
@@ -2555,6 +2555,35 @@ decode_udp(uint8_t *buf, uint16_t len,
return ret_val;
}
/*
* decode_tcp
*/
protocol_error_t
decode_tcp(uint8_t *buf, uint16_t len,
uint8_t *sp, uint16_t sp_len,
bbl_tcp_t **_tcp) {
protocol_error_t ret_val = PROTOCOL_SUCCESS;
bbl_tcp_t *tcp;
if(len < 20 || sp_len < sizeof(bbl_tcp_t)) {
return DECODE_ERROR;
}
/* Init UDP header */
tcp = (bbl_tcp_t*)sp; BUMP_BUFFER(sp, sp_len, sizeof(bbl_tcp_t));
tcp->src = be16toh(*(uint16_t*)buf);
BUMP_BUFFER(buf, len, sizeof(uint16_t));
tcp->dst = be16toh(*(uint16_t*)buf);
BUMP_BUFFER(buf, len, sizeof(uint16_t));
*_tcp = tcp;
return ret_val;
}
/*
* decode_ipv6
*/
@@ -2607,6 +2636,9 @@ decode_ipv6(uint8_t *buf, uint16_t len,
case IPV6_NEXT_HEADER_UDP:
ret_val = decode_udp(buf, len, sp, sp_len, (bbl_udp_t**)&ipv6->next);
break;
case IPV6_NEXT_HEADER_TCP:
ret_val = decode_tcp(buf, len, sp, sp_len, (bbl_tcp_t**)&ipv6->next);
break;
default:
ipv6->next = NULL;
break;
@@ -2703,6 +2735,10 @@ decode_ipv4(uint8_t *buf, uint16_t len,
case PROTOCOL_IPV4_UDP:
ret_val = decode_udp(buf, len, sp, sp_len, (bbl_udp_t**)&ipv4->next);
break;
case PROTOCOL_IPV4_TCP:
ret_val = decode_tcp(buf, len, sp, sp_len, (bbl_tcp_t**)&ipv4->next);
break;
default:
ipv4->next = NULL;
break;
+10
View File
@@ -675,6 +675,16 @@ typedef struct bbl_udp_ {
uint16_t payload_len; /* UDP payload length */
} bbl_udp_t;
/*
* TCP Structure
*/
typedef struct bbl_tcp_ {
uint16_t src;
uint16_t dst;
uint16_t len; /* TCP total length */
uint8_t *hdr; /* TCP header start */
} bbl_tcp_t;
/*
* IGMP Structure
*/
-14
View File
@@ -1781,27 +1781,13 @@ bbl_rx_handler_access(bbl_ethernet_header_t *eth, bbl_interface_s *interface) {
}
}
static void
bbl_rx_test_tcp(bbl_interface_s *interface) {
static uint8_t test_packet[1024] = {0};
LOG(TCP, "START TCP SESSION on interface %s\n", interface->name);
bbl_tcp_t *tcp = bbl_tcp_ipv4_connect(interface, &interface->ip.address, &interface->gateway, 179);
if(tcp) {
bbl_tcp_send(tcp, test_packet, sizeof(test_packet));
}
}
static void
bbl_rx_network_arp(bbl_ethernet_header_t *eth, bbl_interface_s *interface) {
bbl_secondary_ip_s *secondary_ip;
bbl_arp_t *arp = (bbl_arp_t*)eth->next;
if(arp->sender_ip == interface->gateway) {
if(!interface->arp_resolved) {
bbl_rx_test_tcp(interface);
}
interface->arp_resolved = true;
if(*(uint32_t*)interface->gateway_mac == 0) {
memcpy(interface->gateway_mac, arp->sender, ETH_ADDR_LEN);
}
+1 -1
View File
@@ -185,7 +185,7 @@ typedef struct isis_external_connection_ {
} isis_external_connection_t;
/*
* IS-IS Instance
* IS-IS Instance Configuration
*/
typedef struct isis_config_ {