mirror of
https://github.com/rtbrick/bngblaster.git
synced 2024-05-06 15:54:57 +00:00
BGP Initial (WIP)
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ typedef struct isis_external_connection_ {
|
||||
} isis_external_connection_t;
|
||||
|
||||
/*
|
||||
* IS-IS Instance
|
||||
* IS-IS Instance Configuration
|
||||
*/
|
||||
typedef struct isis_config_ {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user