diff --git a/code/bngblaster/CMakeLists.txt b/code/bngblaster/CMakeLists.txt index c4834c34..c8ecab55 100644 --- a/code/bngblaster/CMakeLists.txt +++ b/code/bngblaster/CMakeLists.txt @@ -1,4 +1,4 @@ -FILE(GLOB BBL_SOURCES src/*.c src/io/*.c src/isis/*.c src/bgp/*.c) +FILE(GLOB BBL_SOURCES src/*.c src/io/*.c src/isis/*.c src/ldp/*.c src/bgp/*.c) list(SORT BBL_SOURCES) # Deterministic randomness for symbol name creation diff --git a/code/bngblaster/src/bbl.c b/code/bngblaster/src/bbl.c index c5bd3870..bd0ecc78 100644 --- a/code/bngblaster/src/bbl.c +++ b/code/bngblaster/src/bbl.c @@ -23,16 +23,15 @@ bbl_ctx_s *g_ctx = NULL; /* Global Variables */ -bool g_interactive = false; /* interactive mode using ncurses */ - -uint8_t g_log_buf_cur = 0; -char *g_log_buf = NULL; - +bool g_interactive = false; /* interactive mode using ncurses */ bool g_init_phase = true; bool g_traffic = true; bool g_banner = true; bool g_monkey = true; +uint8_t g_log_buf_cur = 0; +char *g_log_buf = NULL; + extern char *g_log_file; volatile bool g_teardown = false; volatile bool g_teardown_request = false; @@ -152,6 +151,7 @@ struct keyval_ log_names[] = { { L2TP, "l2tp" }, { DHCP, "dhcp" }, { ISIS, "isis" }, + { LDP, "ldp" }, { BGP, "bgp" }, { TCP, "tcp" }, { LAG, "lag" }, @@ -293,6 +293,7 @@ bbl_ctrl_job(timer_s *timer) } /* Teardown routing protocols. */ isis_teardown(); + ldp_teardown(); bgp_teardown(); g_teardown_request = false; } else { @@ -549,6 +550,12 @@ main(int argc, char *argv[]) goto CLEANUP; } + /* Init LDP instances. */ + if(!ldp_init()) { + fprintf(stderr, "Error: Failed to init LDP\n"); + goto CLEANUP; + } + /* Init interfaces. */ if(!bbl_interface_init()) { fprintf(stderr, "Error: Failed to init interfaces\n"); diff --git a/code/bngblaster/src/bbl.h b/code/bngblaster/src/bbl.h index 082b7160..4d32822a 100644 --- a/code/bngblaster/src/bbl.h +++ b/code/bngblaster/src/bbl.h @@ -27,6 +27,7 @@ #include "io/io_def.h" #include "bgp/bgp_def.h" #include "isis/isis_def.h" +#include "ldp/ldp_def.h" #include "bbl_ctrl.h" #include "bbl_stats.h" @@ -49,6 +50,7 @@ #include "io/io.h" #include "bgp/bgp.h" #include "isis/isis.h" +#include "ldp/ldp.h" extern bbl_ctx_s *g_ctx; extern WINDOW *log_win; diff --git a/code/bngblaster/src/bbl_config.c b/code/bngblaster/src/bbl_config.c index 86775843..f2bb2aba 100644 --- a/code/bngblaster/src/bbl_config.c +++ b/code/bngblaster/src/bbl_config.c @@ -635,6 +635,13 @@ json_parse_network_interface(json_t *network_interface, bbl_network_config_s *ne network_config->isis_l2_metric = 10; } } + + /* LDP interface configuration */ + value = json_object_get(network_interface, "ldp-instance-id"); + if(json_is_number(value)) { + network_config->ldp_instance_id = json_number_value(value); + } + return true; } @@ -1068,11 +1075,11 @@ json_parse_bgp_config(json_t *bgp, bgp_config_s *bgp_config) bgp_config->peer_as = bgp_config->local_as; } - value = json_object_get(bgp, "holdtime"); + value = json_object_get(bgp, "hold-time"); if(value) { - bgp_config->holdtime = json_number_value(value); + bgp_config->hold_time = json_number_value(value); } else { - bgp_config->holdtime = BGP_DEFAULT_HOLDTIME; + bgp_config->hold_time = BGP_DEFAULT_HOLD_TIME; } bgp_config->id = htobe32(0x01020304); @@ -1191,11 +1198,11 @@ json_parse_isis_config(json_t *isis, isis_config_s *isis_config) isis_config->hello_padding = json_boolean_value(value); } - value = json_object_get(isis, "holding-time"); + value = json_object_get(isis, "hold-time"); if(json_is_number(value)) { - isis_config->holding_time = json_number_value(value); + isis_config->hold_time = json_number_value(value); } else { - isis_config->holding_time = ISIS_DEFAULT_HOLDING_TIME; + isis_config->hold_time = ISIS_DEFAULT_HOLD_TIME; } value = json_object_get(isis, "lsp-lifetime"); @@ -1358,6 +1365,72 @@ json_parse_isis_config(json_t *isis, isis_config_s *isis_config) return true; } +static bool +json_parse_ldp_config(json_t *ldp, ldp_config_s *ldp_config) +{ + json_t *value = NULL; + const char *s = NULL; + + value = json_object_get(ldp, "instance-id"); + if(value) { + ldp_config->id = json_number_value(value); + } else { + fprintf(stderr, "JSON config error: Missing value for ldp->instance-id\n"); + return false; + } + + value = json_object_get(ldp, "overload"); + if(json_is_boolean(value)) { + ldp_config->overload = json_boolean_value(value); + } + + value = json_object_get(ldp, "hello-interval"); + if(json_is_number(value)) { + ldp_config->hello_interval = json_number_value(value); + } else { + ldp_config->hello_interval = LDP_DEFAULT_HELLO_INTERVAL; + } + + value = json_object_get(ldp, "hold-time"); + if(json_is_number(value)) { + ldp_config->hold_time = json_number_value(value); + } else { + ldp_config->hold_time = LDP_DEFAULT_HOLD_TIME; + } + + value = json_object_get(ldp, "teardown-time"); + if(json_is_number(value)) { + ldp_config->teardown_time = json_number_value(value); + } else { + ldp_config->teardown_time = LDP_DEFAULT_TEARDOWN_TIME; + } + + if(json_unpack(ldp, "{s:s}", "hostname", &s) == 0) { + ldp_config->hostname = strdup(s); + } else { + ldp_config->hostname = g_default_hostname; + } + + if(json_unpack(ldp, "{s:s}", "lsr-id", &s) == 0) { + ldp_config->lsr_id_str = strdup(s); + } else { + ldp_config->lsr_id_str = g_default_router_id; + } + if(!inet_pton(AF_INET, ldp_config->lsr_id_str, &ldp_config->lsr_id)) { + fprintf(stderr, "JSON config error: Invalid value for ldp->lsr-id\n"); + return false; + } + if(json_unpack(ldp, "{s:s}", "ipv4-transport-address", &s) == 0) { + if(!inet_pton(AF_INET, s, &ldp_config->ipv4_transport_address)) { + fprintf(stderr, "JSON config error: Invalid value for ldp->ipv4-transport-address\n"); + return false; + } + } else { + ldp_config->ipv4_transport_address = ldp_config->lsr_id; + } + return true; +} + static bool json_parse_stream(json_t *stream, bbl_stream_config_s *stream_config) { @@ -1642,6 +1715,7 @@ json_parse_config(json_t *root) bgp_config_s *bgp_config = NULL; isis_config_s *isis_config = NULL; + ldp_config_s *ldp_config = NULL; if(json_typeof(root) != JSON_OBJECT) { fprintf(stderr, "JSON config error: Configuration root element must object\n"); @@ -2167,7 +2241,7 @@ json_parse_config(json_t *root) /* BGP Configuration */ sub = json_object_get(root, "bgp"); if(json_is_array(sub)) { - /* Config is provided as array (multiple bgp sessions) */ + /* Config is provided as array (multiple BGP sessions) */ size = json_array_size(sub); for(i = 0; i < size; i++) { if(!bgp_config) { @@ -2182,7 +2256,7 @@ json_parse_config(json_t *root) } } } else if(json_is_object(sub)) { - /* Config is provided as object (single bgp session) */ + /* Config is provided as object (single BGP session) */ bgp_config = calloc(1, sizeof(bgp_config_s)); if(!g_ctx->config.bgp_config) { g_ctx->config.bgp_config = bgp_config; @@ -2209,7 +2283,7 @@ json_parse_config(json_t *root) /* IS-IS Configuration */ sub = json_object_get(root, "isis"); if(json_is_array(sub)) { - /* Config is provided as array (multiple isis instances) */ + /* Config is provided as array (multiple IS-IS instances) */ size = json_array_size(sub); for(i = 0; i < size; i++) { if(!isis_config) { @@ -2224,7 +2298,7 @@ json_parse_config(json_t *root) } } } else if(json_is_object(sub)) { - /* Config is provided as object (single isis instance) */ + /* Config is provided as object (single IS-IS instance) */ isis_config = calloc(1, sizeof(isis_config_s)); if(!g_ctx->config.isis_config) { g_ctx->config.isis_config = isis_config; @@ -2234,6 +2308,34 @@ json_parse_config(json_t *root) } } + /* LDP Configuration */ + sub = json_object_get(root, "ldp"); + if(json_is_array(sub)) { + /* Config is provided as array (multiple LDP instances) */ + size = json_array_size(sub); + for(i = 0; i < size; i++) { + if(!ldp_config) { + g_ctx->config.ldp_config = calloc(1, sizeof(ldp_config_s)); + ldp_config = g_ctx->config.ldp_config; + } else { + ldp_config->next = calloc(1, sizeof(ldp_config_s)); + ldp_config = ldp_config->next; + } + if(!json_parse_ldp_config(json_array_get(sub, i), ldp_config)) { + return false; + } + } + } else if(json_is_object(sub)) { + /* Config is provided as object (single LDP instance) */ + ldp_config = calloc(1, sizeof(ldp_config_s)); + if(!g_ctx->config.ldp_config) { + g_ctx->config.ldp_config = ldp_config; + } + if(!json_parse_ldp_config(sub, ldp_config)) { + return false; + } + } + /* Interface Configuration */ section = json_object_get(root, "interfaces"); if(json_is_object(section)) { diff --git a/code/bngblaster/src/bbl_config.h b/code/bngblaster/src/bbl_config.h index 1e1d1f09..b54e88e0 100644 --- a/code/bngblaster/src/bbl_config.h +++ b/code/bngblaster/src/bbl_config.h @@ -106,6 +106,8 @@ typedef struct bbl_network_config_ uint32_t isis_l1_metric; uint32_t isis_l2_metric; + uint16_t ldp_instance_id; + void *next; /* pointer to next network config element */ bbl_network_interface_s *network_interface; } bbl_network_config_s; diff --git a/code/bngblaster/src/bbl_ctx.h b/code/bngblaster/src/bbl_ctx.h index 0facf2e5..414e1c9e 100644 --- a/code/bngblaster/src/bbl_ctx.h +++ b/code/bngblaster/src/bbl_ctx.h @@ -95,6 +95,7 @@ typedef struct bbl_ctx_ bgp_session_s *bgp_sessions; bgp_raw_update_s *bgp_raw_updates; isis_instance_s *isis_instances; + ldp_instance_s *ldp_instances; /* Scratchpad memory */ uint8_t *sp; @@ -191,6 +192,9 @@ typedef struct bbl_ctx_ /* ISIS Instances */ isis_config_s *isis_config; + /* LDP Instances */ + ldp_config_s *ldp_config; + /* Global Session Settings */ uint32_t sessions; uint32_t sessions_max_outstanding; diff --git a/code/bngblaster/src/bbl_def.h b/code/bngblaster/src/bbl_def.h index e86f129d..0a4aa792 100644 --- a/code/bngblaster/src/bbl_def.h +++ b/code/bngblaster/src/bbl_def.h @@ -90,6 +90,7 @@ #define BBL_IF_SEND_ARP_REQUEST 0x00000001 #define BBL_IF_SEND_ICMPV6_NS 0x00000002 #define BBL_IF_SEND_ISIS_P2P_HELLO 0x00000004 +#define BBL_IF_SEND_LDP_HELLO 0x00000008 #define DUID_LEN 10 diff --git a/code/bngblaster/src/bbl_network.c b/code/bngblaster/src/bbl_network.c index 3d23e93c..c2737ce1 100644 --- a/code/bngblaster/src/bbl_network.c +++ b/code/bngblaster/src/bbl_network.c @@ -42,7 +42,8 @@ bbl_network_interfaces_add() bbl_network_interface_s *network_interface; bbl_interface_s *interface; isis_instance_s *isis; - bool isis_result; + ldp_instance_s *ldp; + bool result; char ifname[SUB_STR_LEN]; @@ -142,12 +143,12 @@ bbl_network_interfaces_add() /* Init routing protocols */ if(network_config->isis_instance_id) { - isis_result = false; + result = false; isis = g_ctx->isis_instances; - while (isis) { + while(isis) { if(isis->config->id == network_config->isis_instance_id) { - isis_result = isis_adjacency_init(network_interface, network_config, isis); - if(!isis_result) { + result = isis_adjacency_init(network_interface, network_config, isis); + if(!result) { LOG(ERROR, "Failed to enable IS-IS for network interface %s (adjacency init failed)\n", ifname); return false; } @@ -155,11 +156,30 @@ bbl_network_interfaces_add() } isis = isis->next; } - if(!isis_result) { + if(!result) { LOG(ERROR, "Failed to enable IS-IS for network interface %s (instance not found)\n", ifname); return false; } } + if(network_config->ldp_instance_id) { + result = false; + ldp = g_ctx->ldp_instances; + while(ldp) { + if(ldp->config->id == network_config->ldp_instance_id) { + result = ldp_interface_init(network_interface, network_config, ldp); + if(!result) { + LOG(ERROR, "Failed to enable LDP for network interface %s (adjacency init failed)\n", ifname); + return false; + } + break; + } + ldp = ldp->next; + } + if(!result) { + LOG(ERROR, "Failed to enable LDP for network interface %s (instance not found)\n", ifname); + return false; + } + } /* TX list init */ CIRCLEQ_INIT(&network_interface->l2tp_tx_qhead); @@ -386,25 +406,39 @@ bbl_network_rx_handler(bbl_network_interface_s *interface, bbl_network_rx_arp(interface, eth); return; case ETH_TYPE_IPV4: - if(memcmp(interface->mac, eth->dst, ETH_ADDR_LEN) != 0) { - /* Drop wrong MAC */ - return; - } ipv4 = (bbl_ipv4_s*)eth->next; if(ipv4->protocol == PROTOCOL_IPV4_UDP) { udp = (bbl_udp_s*)ipv4->next; + /* LDP hello is send to all routers multicast address and therefore + * processed before check on local MAC address. */ + if(udp->protocol == UDP_PROTOCOL_LDP) { + ldp_hello_rx(interface, eth, ipv4, (bbl_ldp_hello_s*)udp->next); + return; + } + if(memcmp(interface->mac, eth->dst, ETH_ADDR_LEN) != 0) { + /* Drop wrong MAC */ + return; + } if(udp->protocol == UDP_PROTOCOL_QMX_LI) { bbl_qmx_li_handler_rx(interface, eth, (bbl_qmx_li_s*)udp->next); return; } else if(udp->protocol == UDP_PROTOCOL_L2TP) { bbl_l2tp_handler_rx(interface, eth, (bbl_l2tp_s*)udp->next); return; - } + } } else if(ipv4->protocol == PROTOCOL_IPV4_ICMP) { + if(memcmp(interface->mac, eth->dst, ETH_ADDR_LEN) != 0) { + /* Drop wrong MAC */ + return; + } interface->stats.icmp_rx++; bbl_network_rx_icmp(interface, eth, ipv4); return; } else if(ipv4->protocol == PROTOCOL_IPV4_TCP) { + if(memcmp(interface->mac, eth->dst, ETH_ADDR_LEN) != 0) { + /* Drop wrong MAC */ + return; + } interface->stats.tcp_rx++; bbl_tcp_ipv4_rx(interface, eth, ipv4); return; diff --git a/code/bngblaster/src/bbl_network.h b/code/bngblaster/src/bbl_network.h index 3b69503c..422ccb97 100644 --- a/code/bngblaster/src/bbl_network.h +++ b/code/bngblaster/src/bbl_network.h @@ -56,6 +56,7 @@ typedef struct bbl_network_interface_ isis_adjacency_p2p_s *isis_adjacency_p2p; isis_adjacency_s *isis_adjacency[ISIS_LEVELS]; + ldp_adjacency_s *ldp_adjacency; struct { uint64_t packets_tx; @@ -108,6 +109,10 @@ typedef struct bbl_network_interface_ uint32_t isis_tx; uint32_t isis_rx_error; + uint32_t ldp_udp_rx; + uint32_t ldp_udp_tx; + uint32_t ldp_udp_rx_error; + /* Rate Stats */ bbl_rate_s rate_packets_tx; diff --git a/code/bngblaster/src/bbl_protocols.c b/code/bngblaster/src/bbl_protocols.c index a2375401..c9f4ec50 100644 --- a/code/bngblaster/src/bbl_protocols.c +++ b/code/bngblaster/src/bbl_protocols.c @@ -10,6 +10,7 @@ #include "bbl_protocols.h" #include "bbl_access_line.h" #include "isis/isis_def.h" +#include "ldp/ldp_def.h" static protocol_error_t decode_l2tp(uint8_t *buf, uint16_t len, uint8_t *sp, uint16_t sp_len, bbl_ethernet_header_s *eth, bbl_l2tp_s **_l2tp); static protocol_error_t encode_l2tp(uint8_t *buf, uint16_t *len, bbl_l2tp_s *l2tp); @@ -551,6 +552,55 @@ encode_dhcp(uint8_t *buf, uint16_t *len, return PROTOCOL_SUCCESS; } +/* + * encode_ldp_hello + */ +static protocol_error_t +encode_ldp_hello(uint8_t *buf, uint16_t *len, bbl_ldp_hello_s *ldp) +{ + /* PDU version and length */ + *(uint16_t*)buf = htobe16(1); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t)); + *(uint16_t*)buf = htobe16(30); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t)); + + /* LDP identifier (LSR ID + label space) */ + *(uint32_t*)buf = htobe32(ldp->lsr_id); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + *(uint16_t*)buf = htobe16(ldp->label_space_id); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t)); + + /* LDP message type and length */ + *(uint16_t*)buf = htobe16(LDP_MESSAGE_TYPE_HELLO); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t)); + *(uint16_t*)buf = htobe16(20); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t)); + + /* LDP message ID */ + *(uint32_t*)buf = htobe32(ldp->msg_id); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + + /* Common hello parameters TLV */ + *(uint16_t*)buf = htobe16(LDP_TLV_TYPE_COMMON_HELLO_PARAMETERS); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t)); + *(uint16_t*)buf = htobe16(4); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t)); + *(uint16_t*)buf = htobe16(ldp->hold_time); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t)); + *(uint16_t*)buf = 0; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t)); + + /* IPv4 transport address TLV */ + *(uint16_t*)buf = htobe16(LDP_TLV_TYPE_IPV4_TRANSPORT_ADDRESS); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t)); + *(uint16_t*)buf = htobe16(4); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t)); + *(uint32_t*)buf = htobe32(ldp->ipv4_transport_address); + BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); + + return PROTOCOL_SUCCESS; +} + /* * encode_bbl */ @@ -628,6 +678,9 @@ encode_udp(uint8_t *buf, uint16_t *len, case UDP_PROTOCOL_DHCP: result = encode_dhcp(buf, len, (bbl_dhcp_s*)udp->next); break; + case UDP_PROTOCOL_LDP: + result = encode_ldp_hello(buf, len, (bbl_ldp_hello_s*)udp->next); + break; default: result = PROTOCOL_SUCCESS; break; @@ -2746,6 +2799,106 @@ decode_qmx_li(uint8_t *buf, uint16_t len, return decode_ethernet(buf, len, sp, sp_len, (bbl_ethernet_header_s**)&qmx_li->next); } +/* + * decode_ldp_hello + */ +static protocol_error_t +decode_ldp_hello(uint8_t *buf, uint16_t len, + uint8_t *sp, uint16_t sp_len, + bbl_ldp_hello_s **_ldp) +{ + bbl_ldp_hello_s *ldp; + + uint16_t pdu_version; + uint16_t pdu_len; + uint16_t msg_type; + uint16_t msg_len; + uint16_t tlv_type; + uint16_t tlv_len; + + if(len < 10 || sp_len < sizeof(bbl_ldp_hello_s)) { + return DECODE_ERROR; + } + + /* Init LDP structure */ + ldp = (bbl_ldp_hello_s*)sp; BUMP_BUFFER(sp, sp_len, sizeof(bbl_ldp_hello_s)); + memset(ldp, 0x0, sizeof(bbl_ldp_hello_s)); + + /* PDU version and length */ + pdu_version = be16toh(*(uint16_t*)buf) & 0x7FFF; + BUMP_BUFFER(buf, len, sizeof(uint16_t)); + pdu_len = be16toh(*(uint16_t*)buf); + BUMP_BUFFER(buf, len, sizeof(uint16_t)); + + if(pdu_version != 1) { + return UNKNOWN_PROTOCOL; + } + + /* The PDU length is defined as two octet integer specifying + * the total length of the PDU in octets, excluding the version + * and PDU length fields. */ + if(pdu_len > len) { + return UNKNOWN_PROTOCOL; + } + len = pdu_len; + + /* LDP identifier (LSR ID + label space) */ + ldp->lsr_id = be32toh(*(uint32_t*)buf); + BUMP_BUFFER(buf, len, sizeof(uint16_t)); + ldp->label_space_id = be16toh(*(uint16_t*)buf); + BUMP_BUFFER(buf, len, sizeof(uint16_t)); + + /* LDP message type and length */ + if(len < 4) { + return DECODE_ERROR; + } + msg_type = be16toh(*(uint16_t*)buf); + BUMP_BUFFER(buf, len, sizeof(uint16_t)); + msg_len = be16toh(*(uint16_t*)buf); + BUMP_BUFFER(buf, len, sizeof(uint16_t)); + + if(msg_len > len || msg_len < 4 || + msg_type != LDP_MESSAGE_TYPE_HELLO) { + return DECODE_ERROR; + } + len = msg_len; + + /* LDP message ID */ + ldp->msg_id = be32toh(*(uint32_t*)buf); + BUMP_BUFFER(buf, len, sizeof(uint32_t)); + + /* LDP TLV's */ + while(len >= LDP_TLV_LEN_MIN) { + tlv_type = be16toh(*(uint16_t*)buf); + BUMP_BUFFER(buf, len, sizeof(uint16_t)); + tlv_len = be16toh(*(uint16_t*)buf); + BUMP_BUFFER(buf, len, sizeof(uint16_t)); + if(tlv_len > len) { + return DECODE_ERROR; + } + switch(tlv_type) { + case LDP_TLV_TYPE_COMMON_HELLO_PARAMETERS: + if(tlv_len != 4) { + return DECODE_ERROR; + } + ldp->hold_time = be16toh(*(uint16_t*)buf); + break; + case LDP_TLV_TYPE_IPV4_TRANSPORT_ADDRESS: + if(tlv_len != 4) { + return DECODE_ERROR; + } + ldp->ipv4_transport_address = be32toh(*(uint16_t*)buf); + break; + default: + break; + } + BUMP_BUFFER(buf, len, tlv_len); + } + + *_ldp = ldp; + return PROTOCOL_SUCCESS; +} + /* * decode_udp */ @@ -2755,7 +2908,7 @@ decode_udp(uint8_t *buf, uint16_t len, bbl_ethernet_header_s *eth, bbl_udp_s **_udp) { - protocol_error_t ret_val = PROTOCOL_SUCCESS; + protocol_error_t ret_val = UNKNOWN_PROTOCOL; bbl_udp_s *udp; @@ -2791,8 +2944,10 @@ decode_udp(uint8_t *buf, uint16_t len, eth->bbl = udp->next; break; case L2TP_UDP_PORT: - udp->protocol = UDP_PROTOCOL_L2TP; - ret_val = decode_l2tp(buf, len, sp, sp_len, eth, (bbl_l2tp_s**)&udp->next); + if(udp->src == L2TP_UDP_PORT) { + udp->protocol = UDP_PROTOCOL_L2TP; + ret_val = decode_l2tp(buf, len, sp, sp_len, eth, (bbl_l2tp_s**)&udp->next); + } break; case DHCP_UDP_CLIENT: case DHCP_UDP_SERVER: @@ -2803,23 +2958,34 @@ decode_udp(uint8_t *buf, uint16_t len, udp->protocol = UDP_PROTOCOL_QMX_LI; ret_val = decode_qmx_li(buf, len, sp, sp_len, (bbl_qmx_li_s**)&udp->next); break; - default: - if(udp->src == QMX_LI_UDP_PORT) { - udp->protocol = UDP_PROTOCOL_QMX_LI; - ret_val = decode_qmx_li(buf, len, sp, sp_len, (bbl_qmx_li_s**)&udp->next); - } else { - /* Try if payload could be decoded as BBL! - * This fails fast if the 64 bit magic number - * is not found on the expected position. */ - if(decode_bbl(buf, len, sp, sp_len, (bbl_bbl_s**)&udp->next) == PROTOCOL_SUCCESS) { - udp->protocol = UDP_PROTOCOL_BBL; - eth->bbl = udp->next; - } else { - udp->protocol = 0; - udp->next = NULL; - } + case LDP_PORT: + if(udp->src == LDP_PORT) { + udp->protocol = UDP_PROTOCOL_LDP; + ret_val = decode_ldp_hello(buf, len, sp, sp_len, (bbl_ldp_hello_s**)&udp->next); } break; + default: + break; + } + + if(ret_val == UNKNOWN_PROTOCOL) { + if(udp->src == QMX_LI_UDP_PORT) { + udp->protocol = UDP_PROTOCOL_QMX_LI; + ret_val = decode_qmx_li(buf, len, sp, sp_len, (bbl_qmx_li_s**)&udp->next); + } else { + /* Try if payload could be decoded as BBL! + * This fails fast if the 64 bit magic number + * is not found on the expected position. */ + ret_val = decode_bbl(buf, len, sp, sp_len, (bbl_bbl_s**)&udp->next); + if(ret_val == PROTOCOL_SUCCESS) { + udp->protocol = UDP_PROTOCOL_BBL; + eth->bbl = udp->next; + } else { + ret_val = PROTOCOL_SUCCESS; + udp->protocol = 0; + udp->next = NULL; + } + } } *_udp = udp; diff --git a/code/bngblaster/src/bbl_protocols.h b/code/bngblaster/src/bbl_protocols.h index af4fcb40..86a50283 100644 --- a/code/bngblaster/src/bbl_protocols.h +++ b/code/bngblaster/src/bbl_protocols.h @@ -202,6 +202,7 @@ #define UDP_PROTOCOL_L2TP 3 #define UDP_PROTOCOL_QMX_LI 4 #define UDP_PROTOCOL_DHCP 5 +#define UDP_PROTOCOL_LDP 6 #define IPV6_NEXT_HEADER_TCP 6 #define IPV6_NEXT_HEADER_UDP 17 @@ -285,6 +286,8 @@ static const ipv6addr_t ipv6_solicited_node_multicast = {0xFF, 0x02, 0x00, 0x00, /* MAC Addresses */ static const uint8_t broadcast_mac[ETH_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; static const uint8_t slow_mac[ETH_ADDR_LEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x02}; +static const uint8_t all_hosts_mac[ETH_ADDR_LEN] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0x01}; +static const uint8_t all_routers_mac[ETH_ADDR_LEN] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0x02}; typedef enum protocol_error_ { PROTOCOL_SUCCESS = 0, @@ -530,12 +533,20 @@ typedef struct bbl_mpls_ { /* * ISIS PDU */ -typedef struct bbl_isis_s { +typedef struct bbl_isis_ { uint8_t type; uint8_t *pdu; uint16_t pdu_len; } bbl_isis_s; +typedef struct bbl_ldp_hello_ { + uint32_t lsr_id; + uint16_t label_space_id; + uint32_t msg_id; + uint32_t ipv4_transport_address; + uint16_t hold_time; +} bbl_ldp_hello_s; + typedef struct bbl_bbl_ { uint16_t padding; uint8_t type; diff --git a/code/bngblaster/src/bbl_tx.c b/code/bngblaster/src/bbl_tx.c index b8e0bcf0..016d8cd2 100644 --- a/code/bngblaster/src/bbl_tx.c +++ b/code/bngblaster/src/bbl_tx.c @@ -1421,6 +1421,9 @@ bbl_tx_encode_network_packet(bbl_network_interface_s *interface, uint8_t *buf, u } else if(interface->send_requests & BBL_IF_SEND_ISIS_P2P_HELLO) { interface->send_requests &= ~BBL_IF_SEND_ISIS_P2P_HELLO; result = isis_p2p_hello_encode(interface, buf, len, ð); + } else if(interface->send_requests & BBL_IF_SEND_LDP_HELLO) { + interface->send_requests &= ~BBL_IF_SEND_LDP_HELLO; + result = ldp_hello_encode(interface, buf, len, ð); } else { interface->send_requests = 0; } diff --git a/code/bngblaster/src/bgp/bgp_ctrl.c b/code/bngblaster/src/bgp/bgp_ctrl.c index 98d304e1..30a2c722 100644 --- a/code/bngblaster/src/bgp/bgp_ctrl.c +++ b/code/bngblaster/src/bgp/bgp_ctrl.c @@ -60,11 +60,11 @@ bgp_ctrl_session_json(bgp_session_s *session) "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, + "local-hold-time", session->config->hold_time, "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, + "peer-hold-time", session->peer.hold_time, "state", bgp_session_state_string(session->state), "raw-update-state", raw_update_state(session), "raw-update-file", raw_update_file, diff --git a/code/bngblaster/src/bgp/bgp_def.h b/code/bngblaster/src/bgp/bgp_def.h index 7ea4418f..ad4bfdf2 100644 --- a/code/bngblaster/src/bgp/bgp_def.h +++ b/code/bngblaster/src/bgp/bgp_def.h @@ -16,7 +16,7 @@ #define BGP_MAX_MESSAGE_SIZE 4096U #define BGP_BUF_SIZE 256*1024 #define BGP_DEFAULT_AS 65000 -#define BGP_DEFAULT_HOLDTIME 90 +#define BGP_DEFAULT_HOLD_TIME 90 #define BGP_DEFAULT_TEARDOWN_TIME 5 #define BGP_MSG_OPEN 1 @@ -58,7 +58,7 @@ typedef struct bgp_config_ { uint32_t id; uint32_t local_as; uint32_t peer_as; - uint16_t holdtime; + uint16_t hold_time; uint16_t teardown_time; bool reconnect; @@ -101,7 +101,7 @@ typedef struct bgp_session_ { struct { uint32_t as; uint32_t id; - uint16_t holdtime; + uint16_t hold_time; } peer; struct { diff --git a/code/bngblaster/src/bgp/bgp_message.c b/code/bngblaster/src/bgp/bgp_message.c index f9e7e620..4904f197 100644 --- a/code/bngblaster/src/bgp/bgp_message.c +++ b/code/bngblaster/src/bgp/bgp_message.c @@ -69,7 +69,7 @@ bgp_push_open_message(bgp_session_s *session) } else { push_be_uint(buffer, 2, session->config->local_as); } - push_be_uint(buffer, 2, session->config->holdtime); /* holdtime */ + push_be_uint(buffer, 2, session->config->hold_time); /* hold-time */ push_data(buffer, (uint8_t*)&session->config->id, 4); /* BGP ID */ /* Optional parameters */ diff --git a/code/bngblaster/src/bgp/bgp_receive.c b/code/bngblaster/src/bgp/bgp_receive.c index dd1d9187..5441d1ba 100644 --- a/code/bngblaster/src/bgp/bgp_receive.c +++ b/code/bngblaster/src/bgp/bgp_receive.c @@ -92,14 +92,14 @@ bgp_open(bgp_session_s *session, uint8_t *start, uint16_t length) return; } session->peer.as = read_be_uint(start+20, 2); - session->peer.holdtime = read_be_uint(start+22, 2); + session->peer.hold_time = read_be_uint(start+22, 2); session->peer.id = read_be_uint(start+24, 4); - LOG(BGP, "BGP (%s %s - %s) open message received with peer AS: %u, holdtime: %us\n", + LOG(BGP, "BGP (%s %s - %s) open message received with peer AS: %u, hold-time: %us\n", session->interface->name, format_ipv4_address(&session->ipv4_local_address), format_ipv4_address(&session->ipv4_peer_address), - session->peer.as, session->peer.holdtime); + session->peer.as, session->peer.hold_time); bgp_session_state_change(session, BGP_OPENCONFIRM); return; @@ -185,7 +185,7 @@ bgp_rebase_read_buffer(bgp_session_s *session) } static void -bpg_read(bgp_session_s *session) +bgp_read(bgp_session_s *session) { uint32_t size; uint16_t length; @@ -223,7 +223,7 @@ bpg_read(bgp_session_s *session) format_ipv4_address(&session->ipv4_peer_address), keyval_get_key(bgp_msg_names, type)); - switch (type) { + switch(type) { case BGP_MSG_OPEN: bgp_open(session, start, length); break; @@ -244,7 +244,7 @@ bpg_read(bgp_session_s *session) } /* Reset hold timer */ - bgp_restart_hold_timer(session, session->config->holdtime); + bgp_restart_hold_timer(session, session->config->hold_time); /* Progress pointer to next BGP message */ buffer->start_idx += length; @@ -274,6 +274,6 @@ bgp_receive_cb(void *arg, uint8_t *buf, uint16_t len) memcpy(buffer->data+buffer->idx, buf, len); buffer->idx+=len; } else { - bpg_read(session); + bgp_read(session); } } \ No newline at end of file diff --git a/code/bngblaster/src/bgp/bgp_session.c b/code/bngblaster/src/bgp/bgp_session.c index a203357f..f8702bae 100644 --- a/code/bngblaster/src/bgp/bgp_session.c +++ b/code/bngblaster/src/bgp/bgp_session.c @@ -176,10 +176,10 @@ bgp_session_state_established(bgp_session_s *session) clock_gettime(CLOCK_MONOTONIC, &session->established_timestamp); /* Start BGP keepalive */ - if(session->peer.holdtime < session->config->holdtime) { - keepalive_interval = session->peer.holdtime/2U; + if(session->peer.hold_time < session->config->hold_time) { + keepalive_interval = session->peer.hold_time/2U; } else { - keepalive_interval = session->config->holdtime/2U; + keepalive_interval = session->config->hold_time/2U; } if(!keepalive_interval) { keepalive_interval = 1; @@ -320,7 +320,7 @@ bgp_session_connect(bgp_session_s *session, time_t delay) session->peer.as = 0; session->peer.id = 0; - session->peer.holdtime = 0; + session->peer.hold_time = 0; session->stats.message_rx = 0; session->stats.message_tx = 0; diff --git a/code/bngblaster/src/isis/isis.c b/code/bngblaster/src/isis/isis.c index ce907306..d40ccab1 100644 --- a/code/bngblaster/src/isis/isis.c +++ b/code/bngblaster/src/isis/isis.c @@ -111,20 +111,20 @@ isis_handler_rx(bbl_network_interface_s *interface, bbl_ethernet_header_s *eth) result = isis_pdu_load(&pdu, isis->pdu, isis->pdu_len); if(result != PROTOCOL_SUCCESS) { LOG(ISIS, "ISIS RX %s PDU decode error on interface %s\n", - isis_pdu_sype_string(pdu.pdu_type), interface->name); + isis_pdu_type_string(pdu.pdu_type), interface->name); interface->stats.isis_rx_error++; return; } if(!isis_pdu_validate_checksum(&pdu)) { LOG(ISIS, "ISIS RX %s PDU checksum error on interface %s\n", - isis_pdu_sype_string(pdu.pdu_type), interface->name); + isis_pdu_type_string(pdu.pdu_type), interface->name); interface->stats.isis_rx_error++; return; } LOG(DEBUG, "ISIS RX %s on interface %s\n", - isis_pdu_sype_string(pdu.pdu_type), interface->name); + isis_pdu_type_string(pdu.pdu_type), interface->name); switch (pdu.pdu_type) { case ISIS_PDU_P2P_HELLO: diff --git a/code/bngblaster/src/isis/isis_adjacency.c b/code/bngblaster/src/isis/isis_adjacency.c index 31582c66..aa965415 100644 --- a/code/bngblaster/src/isis/isis_adjacency.c +++ b/code/bngblaster/src/isis/isis_adjacency.c @@ -140,7 +140,7 @@ isis_adjacency_down(isis_adjacency_s *adjacency) timer_del(adjacency->timer_retry); timer_del(adjacency->timer_csnp); timer_del(adjacency->timer_csnp_next); - timer_del(adjacency->timer_holding); + timer_del(adjacency->timer_hold); if(g_ctx->routing_sessions) g_ctx->routing_sessions--; } \ No newline at end of file diff --git a/code/bngblaster/src/isis/isis_csnp.c b/code/bngblaster/src/isis/isis_csnp.c index 26b59ea4..185b1199 100644 --- a/code/bngblaster/src/isis/isis_csnp.c +++ b/code/bngblaster/src/isis/isis_csnp.c @@ -147,8 +147,9 @@ isis_csnp_job(timer_s *timer) isis.pdu_len = pdu.pdu_len; if(bbl_txq_to_buffer(adjacency->interface->txq, ð) == BBL_TXQ_OK) { LOG(DEBUG, "ISIS TX %s on interface %s\n", - isis_pdu_sype_string(isis.type), adjacency->interface->name); + isis_pdu_type_string(isis.type), adjacency->interface->name); adjacency->stats.csnp_tx++; + adjacency->interface->stats.isis_tx++; /* Clear PSNP tree after CSNP was send */ hb_tree_clear(adjacency->psnp_tree, isis_psnp_free); timer_del(adjacency->timer_psnp_next); diff --git a/code/bngblaster/src/isis/isis_ctrl.c b/code/bngblaster/src/isis/isis_ctrl.c index 3305850e..d32d4737 100644 --- a/code/bngblaster/src/isis/isis_ctrl.c +++ b/code/bngblaster/src/isis/isis_ctrl.c @@ -21,7 +21,7 @@ isis_ctrl_adjacency(isis_adjacency_s *adjacency) peer = json_pack("{ss si}", "system-id", isis_system_id_to_str(adjacency->peer->system_id), - "holding-timer", adjacency->peer->holding_time); + "hold-timer", adjacency->peer->hold_time); root = json_pack("{ss ss ss si ss so}", "interface", adjacency->interface->name, @@ -50,7 +50,7 @@ isis_ctrl_adjacency_p2p(isis_adjacency_p2p_s *adjacency) peer = json_pack("{ss si}", "system-id", isis_system_id_to_str(adjacency->peer->system_id), - "holding-timer", adjacency->peer->holding_time); + "hold-timer", adjacency->peer->hold_time); root = json_pack("{ss ss, ss si ss so}", "interface", adjacency->interface->name, diff --git a/code/bngblaster/src/isis/isis_def.h b/code/bngblaster/src/isis/isis_def.h index 3c3d3593..698beb7d 100644 --- a/code/bngblaster/src/isis/isis_def.h +++ b/code/bngblaster/src/isis/isis_def.h @@ -62,7 +62,7 @@ #define ISIS_DEFAULT_HELLO_INTERVAL 10 #define ISIS_DEFAULT_CSNP_INTERVAL 30 -#define ISIS_DEFAULT_HOLDING_TIME 30 +#define ISIS_DEFAULT_HOLD_TIME 30 #define ISIS_DEFAULT_LSP_LIFETIME 65535 #define ISIS_DEFAULT_LSP_RETRY_IVL 5 #define ISIS_DEFAULT_LSP_REFRESH_IVL 300 @@ -130,7 +130,7 @@ typedef enum isis_pdu_type_ { /* IS-IS TLV Codepoints * https://www.iana.org/assignments/isis-tlv-codepoints/isis-tlv-codepoints.xhtml */ -typedef enum isis_tlv_sype_ { +typedef enum isis_tlv_type_ { ISIS_TLV_AREA_ADDRESSES = 1, ISIS_TLV_PADDING = 8, ISIS_TLV_LSP_ENTRIES = 9, @@ -145,7 +145,7 @@ typedef enum isis_tlv_sype_ { ISIS_TLV_IPV6_REACHABILITY = 236, ISIS_TLV_P2P_ADJACENCY_STATE = 240, ISIS_TLV_ROUTER_CAPABILITY = 242 -} isis_tlv_sype; +} isis_tlv_type; /* STRUCTURES ... */ @@ -203,7 +203,7 @@ typedef struct isis_config_ { uint16_t lsp_refresh_interval; uint16_t lsp_lifetime; uint16_t hello_interval; - uint16_t holding_time; + uint16_t hold_time; uint16_t teardown_time; const char *hostname; @@ -238,7 +238,7 @@ typedef struct isis_config_ { typedef struct isis_peer_ { uint8_t level; uint8_t system_id[ISIS_SYSTEM_ID_LEN]; - uint16_t holding_time; + uint16_t hold_time; char *hostname; } isis_peer_s; @@ -260,7 +260,7 @@ typedef struct isis_adjacency_ { struct timer_ *timer_csnp; struct timer_ *timer_csnp_next; struct timer_ *timer_psnp_next; - struct timer_ *timer_holding; + struct timer_ *timer_hold; bool timer_psnp_started; diff --git a/code/bngblaster/src/isis/isis_lsp.c b/code/bngblaster/src/isis/isis_lsp.c index aee22e9c..79230e88 100644 --- a/code/bngblaster/src/isis/isis_lsp.c +++ b/code/bngblaster/src/isis/isis_lsp.c @@ -291,6 +291,7 @@ isis_lsp_sx_job(timer_s *timer) entry->tx_timestamp.tv_sec = now.tv_sec; entry->tx_timestamp.tv_nsec = now.tv_nsec; adjacency->stats.lsp_tx++; + adjacency->interface->stats.isis_tx++; if(window) window--; if(window == 0) break; } diff --git a/code/bngblaster/src/isis/isis_p2p_hello.c b/code/bngblaster/src/isis/isis_p2p_hello.c index ab059f0f..cc0024ae 100644 --- a/code/bngblaster/src/isis/isis_p2p_hello.c +++ b/code/bngblaster/src/isis/isis_p2p_hello.c @@ -16,7 +16,7 @@ isis_p2p_hello_timeout(timer_s *timer) } void -isis_p2p_holding_timeout(timer_s *timer) +isis_p2p_hold_timeout(timer_s *timer) { isis_adjacency_s *adjacency = timer->data; @@ -24,7 +24,7 @@ isis_p2p_holding_timeout(timer_s *timer) return; } - LOG(ISIS, "ISIS %s holding timeout to %s on interface %s\n", + LOG(ISIS, "ISIS %s hold timeout to %s on interface %s\n", isis_level_string(adjacency->level), isis_system_id_to_str(adjacency->peer->system_id), adjacency->interface->name); @@ -36,16 +36,16 @@ isis_p2p_holding_timeout(timer_s *timer) } static void -isis_p2p_restart_holding_timers(bbl_network_interface_s *interface) +isis_p2p_restart_hold_timers(bbl_network_interface_s *interface) { isis_adjacency_s *adjacency; for(int i=0; iisis_adjacency[i]; if(adjacency) { - timer_add(&g_ctx->timer_root, &adjacency->timer_holding, - "ISIS holding", adjacency->peer->holding_time, 0, adjacency, - &isis_p2p_holding_timeout); + timer_add(&g_ctx->timer_root, &adjacency->timer_hold, + "ISIS Hold", adjacency->peer->hold_time, 0, adjacency, + &isis_p2p_hold_timeout); } } } @@ -77,7 +77,7 @@ isis_p2p_hello_encode(bbl_network_interface_s *interface, /* Start next timer ... */ timer_add(&g_ctx->timer_root, &interface->timer_isis_hello, - "ISIS hello", config->hello_interval, 0, interface, + "ISIS Hello", config->hello_interval, 0, interface, &isis_p2p_hello_timeout); if(config->level1_auth && config->level1_key) { @@ -93,7 +93,7 @@ isis_p2p_hello_encode(bbl_network_interface_s *interface, /* PDU header */ isis_pdu_add_u8(&pdu, adjacency->level); isis_pdu_add_bytes(&pdu, config->system_id, ISIS_SYSTEM_ID_LEN); - isis_pdu_add_u16(&pdu, config->holding_time); + isis_pdu_add_u16(&pdu, config->hold_time); isis_pdu_add_u16(&pdu, 0); isis_pdu_add_u8(&pdu, 0x1); /* TLV section */ @@ -118,8 +118,9 @@ isis_p2p_hello_encode(bbl_network_interface_s *interface, result = encode_ethernet(buf, len, eth); if(result == PROTOCOL_SUCCESS) { LOG(DEBUG, "ISIS TX %s on interface %s\n", - isis_pdu_sype_string(isis.type), interface->name); + isis_pdu_type_string(isis.type), interface->name); adjacency->stats.hello_tx++; + adjacency->interface->stats.isis_tx++; } return result; } @@ -170,9 +171,9 @@ isis_p2p_hello_handler_rx(bbl_network_interface_s *interface, isis_pdu_s *pdu) peer = adjacency->peer; peer->level = *PDU_OFFSET(pdu, ISIS_OFFSET_P2P_HELLO_LEVEL) & 0x03; memcpy(peer->system_id, PDU_OFFSET(pdu, ISIS_OFFSET_P2P_HELLO_SYSTEM_ID), ISIS_SYSTEM_ID_LEN); - peer->holding_time = be16toh(*(uint16_t*)PDU_OFFSET(pdu, ISIS_OFFSET_P2P_HELLO_HOLD_TIME)); + peer->hold_time = be16toh(*(uint16_t*)PDU_OFFSET(pdu, ISIS_OFFSET_P2P_HELLO_HOLD_TIME)); - isis_p2p_restart_holding_timers(interface); + isis_p2p_restart_hold_timers(interface); tlv = isis_pdu_first_tlv(pdu); while(tlv) { diff --git a/code/bngblaster/src/isis/isis_psnp.c b/code/bngblaster/src/isis/isis_psnp.c index 11fa2f5a..3bfd02ab 100644 --- a/code/bngblaster/src/isis/isis_psnp.c +++ b/code/bngblaster/src/isis/isis_psnp.c @@ -129,8 +129,9 @@ isis_psnp_job (timer_s *timer) isis.pdu_len = pdu.pdu_len; if(bbl_txq_to_buffer(adjacency->interface->txq, ð) == BBL_TXQ_OK) { LOG(DEBUG, "ISIS TX %s on interface %s\n", - isis_pdu_sype_string(isis.type), adjacency->interface->name); + isis_pdu_type_string(isis.type), adjacency->interface->name); adjacency->stats.psnp_tx++; + adjacency->interface->stats.isis_tx++; } return; } diff --git a/code/bngblaster/src/isis/isis_utils.c b/code/bngblaster/src/isis/isis_utils.c index b410be3a..5c17fac5 100644 --- a/code/bngblaster/src/isis/isis_utils.c +++ b/code/bngblaster/src/isis/isis_utils.c @@ -52,7 +52,7 @@ isis_adjacency_state_string(uint8_t state) } const char * -isis_pdu_sype_string(uint8_t type) +isis_pdu_type_string(uint8_t type) { switch(type) { case ISIS_PDU_L1_HELLO: return "L1-Hello"; diff --git a/code/bngblaster/src/isis/isis_utils.h b/code/bngblaster/src/isis/isis_utils.h index 703ba443..697c7a24 100644 --- a/code/bngblaster/src/isis/isis_utils.h +++ b/code/bngblaster/src/isis/isis_utils.h @@ -22,7 +22,7 @@ const char * isis_adjacency_state_string(uint8_t state); const char * -isis_pdu_sype_string(uint8_t type); +isis_pdu_type_string(uint8_t type); bool isis_str_to_area(const char *str, isis_area_s *area); diff --git a/code/bngblaster/src/ldp/ldp.c b/code/bngblaster/src/ldp/ldp.c new file mode 100644 index 00000000..3273286d --- /dev/null +++ b/code/bngblaster/src/ldp/ldp.c @@ -0,0 +1,63 @@ +/* + * BNG Blaster (BBL) - LDP Functions + * + * Christian Giese, November 2022 + * + * Copyright (C) 2020-2022, RtBrick, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "ldp.h" + +/** + * ldp_init + * + * This function inits all LDP sessions. + */ +bool +ldp_init() +{ + ldp_config_s *config = g_ctx->config.ldp_config; + ldp_instance_s *instance = NULL; + + while(config) { + LOG(LDP, "Init LDP instance %u\n", config->id); + if(instance) { + instance->next = calloc(1, sizeof(ldp_instance_s)); + instance = instance->next; + } else { + instance = calloc(1, sizeof(ldp_instance_s)); + g_ctx->ldp_instances = instance; + } + instance->config = config; + + config = config->next; + } + return true; +} + +void +ldp_teardown_job(timer_s *timer) { + ldp_instance_s *instance = timer->data; + UNUSED(instance); +} + +/** + * ldp_teardown + * + * This function stops all LDP sessions. + */ +void +ldp_teardown() +{ + ldp_instance_s *instance = g_ctx->ldp_instances; + while(instance) { + if(!instance->teardown) { + LOG(LDP, "Teardown LDP instance %u\n", instance->config->id); + instance->teardown = true; + timer_add(&g_ctx->timer_root, &instance->teardown_timer, + "LDP TEARDOWN", instance->config->teardown_time, 0, instance, + &ldp_teardown_job); + } + instance = instance->next; + } +} \ No newline at end of file diff --git a/code/bngblaster/src/ldp/ldp.h b/code/bngblaster/src/ldp/ldp.h new file mode 100644 index 00000000..8ebebe70 --- /dev/null +++ b/code/bngblaster/src/ldp/ldp.h @@ -0,0 +1,24 @@ +/* + * BNG Blaster (BBL) - LDP Main + * + * Christian Giese, November 2022 + * + * Copyright (C) 2020-2022, RtBrick, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef __BBL_LDP_H__ +#define __BBL_LDP_H__ + +#include "../bbl.h" +#include "ldp_def.h" +#include "ldp_pdu.h" +#include "ldp_hello.h" +#include "ldp_interface.h" + +bool +ldp_init(); + +void +ldp_teardown(); + +#endif \ No newline at end of file diff --git a/code/bngblaster/src/ldp/ldp_def.h b/code/bngblaster/src/ldp/ldp_def.h new file mode 100644 index 00000000..633ec129 --- /dev/null +++ b/code/bngblaster/src/ldp/ldp_def.h @@ -0,0 +1,201 @@ +/* + * BNG Blaster (BBL) - LDP Definitions + * + * Christian Giese, November 2022 + * + * Copyright (C) 2020-2022, RtBrick, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef __BBL_LDP_DEF_H__ +#define __BBL_LDP_DEF_H__ + +/* DEFINITIONS ... */ + +#define LDP_PORT 646 +#define LDP_IDENTIFIER_LEN 6U +#define LDP_MAX_PDU_LEN_INIT 4096U + +#define LDP_MESSAGE_TYPE_NOTIFICATION 0x0001 +#define LDP_MESSAGE_TYPE_HELLO 0x0100 +#define LDP_MESSAGE_TYPE_INITIALIZATION 0x0200 +#define LDP_MESSAGE_TYPE_KEEPALIVE 0x0201 +#define LDP_MESSAGE_TYPE_ADDRESS 0x0300 +#define LDP_MESSAGE_TYPE_ADDRESS_WITHDRAW 0x0301 +#define LDP_MESSAGE_TYPE_LABEL_MAPPING 0x0400 +#define LDP_MESSAGE_TYPE_LABEL_REQUEST 0x0401 +#define LDP_MESSAGE_TYPE_LABEL_WITHDRAW 0x0402 +#define LDP_MESSAGE_TYPE_LABEL_RELEASE 0x0403 +#define LDP_MESSAGE_TYPE_ABORT_REQUEST 0x0404 + +#define LDP_TLV_TYPE_FEC 0x0100 +#define LDP_TLV_TYPE_ADDRESS_LIST 0x0101 +#define LDP_TLV_TYPE_HOP_COUNT 0x0103 +#define LDP_TLV_TYPE_PATH_VECTOR 0x0104 +#define LDP_TLV_TYPE_GENERIC_LABEL 0x0200 +#define LDP_TLV_TYPE_STATUS 0x0300 +#define LDP_TLV_TYPE_EXTENDED_STATUS 0x0301 +#define LDP_TLV_TYPE_RETURNED_PDU 0x0302 +#define LDP_TLV_TYPE_RETURNED_MESSAGE 0x0303 +#define LDP_TLV_TYPE_COMMON_HELLO_PARAMETERS 0x0400 +#define LDP_TLV_TYPE_IPV4_TRANSPORT_ADDRESS 0x0401 +#define LDP_TLV_TYPE_CONFIG_SEQ_NUMBER 0x0402 +#define LDP_TLV_TYPE_IPV6_TRANSPORT_ADDRESS 0x0403 +#define LDP_TLV_TYPE_COMMON_SESSION_PARAMETERS 0x0500 +#define LDP_TLV_TYPE_LABEL_REQUEST_ID 0x0600 + +#define LDP_TLV_LEN_MIN 4 + +#define LDP_DEFAULT_HELLO_INTERVAL 10 +#define LDP_DEFAULT_HOLD_TIME 30 +#define LDP_DEFAULT_TEARDOWN_TIME 5 + +typedef enum ldp_state_ { + LDP_NON_EXISTENT, + LDP_INITIALIZED, + LDP_OPENREC, + LDP_OPENSENT, + LDP_OPERATIONAL, +} ldp_state_t; + +typedef struct ldp_instance_ ldp_instance_s; +typedef struct ldp_session_ ldp_session_s; +typedef struct ldp_adjacency_ ldp_adjacency_s; + +/* + * LDP Type-Length-Value (TLV). + */ +typedef struct ldp_tlv_ { + bool u_bit; /* Unknown TLV bit. */ + bool f_bit; /* Forward unknown TLV bit. */ + uint16_t type; + uint16_t len; + uint8_t *value; + struct ldp_tlv_ *next; +} ldp_tlv_s; + +/* + * LDP Message which contains + * one or more LDP TLV. + */ +typedef struct ldp_message_ { + bool u_bit; /* Unknown message bit. */ + uint16_t type; + uint32_t msg_id; + ldp_tlv_s *tlv; + struct ldp_message_ *next; +} ldp_message_s; + +/* + * LDP Protocol Data Unit (PDU) which contains + * one or more LDP messages. + */ +typedef struct ldp_pdu_ { + uint16_t version; + uint16_t len; + uint32_t lsr_id; + uint16_t label_space_id; + ldp_message_s *message; +} ldp_pdu_s; + +/* + * LDP Instance Configuration. + */ +typedef struct ldp_config_ { + + uint16_t id; /* LDP instance identifier */ + uint32_t lsr_id; + uint32_t ipv4_transport_address; + const char *lsr_id_str; + const char *hostname; + + bool overload; + + uint16_t hello_interval; + uint16_t hold_time; + uint16_t teardown_time; + + /* Pointer to next instance. */ + struct ldp_config_ *next; +} ldp_config_s; + +/* + * LDP Session. + */ +typedef struct ldp_session_ { + struct { + uint32_t ipv4_address; + uint32_t lsr_id; + uint16_t label_space_id; + uint16_t hold_time; + } local; + + struct { + uint32_t ipv4_address; + uint32_t lsr_id; + uint16_t label_space_id; + uint16_t hold_time; + } peer; + + struct { + uint32_t message_rx; + uint32_t message_tx; + uint32_t keepalive_rx; + uint32_t keepalive_tx; + } stats; + + struct { + bool e_bit; /* Fatal error bit. */ + bool f_bit; /* Forward bit. */ + uint32_t code; + uint16_t msg_type; + } status; + + uint16_t max_pdu_len; + + ldp_instance_s *instance; + ldp_state_t state; + + io_buffer_t read_buf; + io_buffer_t write_buf; + + /* Pointer to next peer of + * corresponding instance. */ + struct ldp_session_ *next; +} ldp_session_s; + +/* + * LDP Adjacency. + */ +typedef struct ldp_adjacency_ { + bbl_network_interface_s *interface; + ldp_instance_s *instance; + ldp_session_s *session; + + struct timer_ *hello_timer; + + /* Pointer to next adjacency of + * corresponding instance with. */ + struct ldp_adjacency_ *next; +} ldp_adjacency_s; + +/* + * LDP Instance + */ +typedef struct ldp_instance_ { + ldp_config_s *config; + + bool overload; + bool teardown; + + struct timer_ *teardown_timer; + + ldp_adjacency_s *adjacencies; + ldp_session_s *sessions; + + hb_tree *ldb; /* Label database. */ + + /* Pointer to next instance. */ + struct ldp_instance_ *next; +} ldp_instance_s; + +#endif \ No newline at end of file diff --git a/code/bngblaster/src/ldp/ldp_hello.c b/code/bngblaster/src/ldp/ldp_hello.c new file mode 100644 index 00000000..bd466840 --- /dev/null +++ b/code/bngblaster/src/ldp/ldp_hello.c @@ -0,0 +1,106 @@ +/* + * BNG Blaster (BBL) - LDP Hello + * + * Christian Giese, November 2022 + * + * Copyright (C) 2020-2022, RtBrick, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "ldp.h" + +void +ldp_hello_job(timer_s *timer) +{ + ldp_adjacency_s *adjacency = timer->data; + bbl_network_interface_s *interface = adjacency->interface; + interface->send_requests |= BBL_IF_SEND_LDP_HELLO; +} + +/** + * ldp_hello_start + * + * @param config LDP configuration + * @param adjacency LDP adjacency + */ +void +ldp_hello_start(ldp_config_s *config, ldp_adjacency_s *adjacency) +{ + timer_add_periodic(&g_ctx->timer_root, &adjacency->hello_timer, + "LDP Hello", config->hello_interval, 0, adjacency, + &ldp_hello_job); +} + +/** + * ldp_hello_encode + * + * @param interface send interface + * @param buf send buffer + * @param len send buffer length + * @param eth send ethernet parent structure + * @return PROTOCOL_SUCCESS on success + */ +protocol_error_t +ldp_hello_encode(bbl_network_interface_s *interface, + uint8_t *buf, uint16_t *len, + bbl_ethernet_header_s *eth) +{ + protocol_error_t result; + + bbl_ipv4_s ipv4 = {0}; + bbl_udp_s udp = {0}; + bbl_ldp_hello_s ldp = {0}; + + ldp_adjacency_s *adjacency = interface->ldp_adjacency; + ldp_instance_s *instance = adjacency->instance; + ldp_config_s *config = instance->config; + + /* Build packet ... */ + eth->type = ETH_TYPE_IPV4; + eth->next = &ipv4; + eth->dst = (uint8_t*)all_routers_mac; + + ipv4.dst = IPV4_MC_ALL_ROUTERS; + ipv4.src = interface->ip.address; + ipv4.ttl = 1; + ipv4.protocol = PROTOCOL_IPV4_UDP; + ipv4.router_alert_option = true; + ipv4.next = &udp; + udp.src = LDP_PORT; + udp.dst = LDP_PORT; + udp.protocol = UDP_PROTOCOL_LDP; + udp.next = &ldp; + ldp.lsr_id = config->lsr_id; + ldp.hold_time = config->hold_time; + ldp.ipv4_transport_address = config->ipv4_transport_address; + result = encode_ethernet(buf, len, eth); + if(result == PROTOCOL_SUCCESS) { + LOG(DEBUG, "LDP TX hello on interface %s\n", interface->name); + adjacency->interface->stats.ldp_udp_tx++; + } + return result; +} + +/** + * ldp_hello_rx + * + * This function handles all received LDP hello packets. + * + * @param interface receiving interface + * @param eth received ethernet header + * @param ipv4 received ipv4 header + * @param ldp LDP header of received packet + */ +void +ldp_hello_rx(bbl_network_interface_s *interface, + bbl_ethernet_header_s *eth, + bbl_ipv4_s *ipv4, + bbl_ldp_hello_s *ldp) +{ + ldp_adjacency_s *adjacency = interface->ldp_adjacency; + + UNUSED(adjacency); + UNUSED(eth); + UNUSED(ipv4); + UNUSED(ldp); + +} \ No newline at end of file diff --git a/code/bngblaster/src/ldp/ldp_hello.h b/code/bngblaster/src/ldp/ldp_hello.h new file mode 100644 index 00000000..a2079192 --- /dev/null +++ b/code/bngblaster/src/ldp/ldp_hello.h @@ -0,0 +1,26 @@ +/* + * BNG Blaster (BBL) - LDP Hello + * + * Christian Giese, November 2022 + * + * Copyright (C) 2020-2022, RtBrick, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef __BBL_LDP_HELLO_H__ +#define __BBL_LDP_HELLO_H__ + +void +ldp_hello_start(ldp_config_s *config, ldp_adjacency_s *adjacency); + +protocol_error_t +ldp_hello_encode(bbl_network_interface_s *interface, + uint8_t *buf, uint16_t *len, + bbl_ethernet_header_s *eth); + +void +ldp_hello_rx(bbl_network_interface_s *interface, + bbl_ethernet_header_s *eth, + bbl_ipv4_s *ipv4, + bbl_ldp_hello_s *ldp); + +#endif \ No newline at end of file diff --git a/code/bngblaster/src/ldp/ldp_interface.c b/code/bngblaster/src/ldp/ldp_interface.c new file mode 100644 index 00000000..ce4a610a --- /dev/null +++ b/code/bngblaster/src/ldp/ldp_interface.c @@ -0,0 +1,49 @@ +/* + * BNG Blaster (BBL) - LDP Interface + * + * Christian Giese, November 2022 + * + * Copyright (C) 2020-2022, RtBrick, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "ldp.h" + +void +ldp_interface_hello_job(timer_s *timer) +{ + ldp_adjacency_s *adjacency = timer->data; + bbl_network_interface_s *interface = adjacency->interface; + + interface->send_requests |= BBL_IF_SEND_LDP_HELLO; +} + +/** + * ldp_interface_init + * + * This function inits the LDP interface. + * + * @param interface network interface + * @param config network interface configuration + * @param instance LDP instance + */ +bool +ldp_interface_init(bbl_network_interface_s *interface, + bbl_network_config_s *interface_config, + ldp_instance_s *instance) +{ + ldp_config_s *config = instance->config; + ldp_adjacency_s *adjacency; + + LOG(LDP, "Add network interface %s to LDP instance %u\n", + interface->name, interface_config->ldp_instance_id); + + adjacency = calloc(1, sizeof(ldp_adjacency_s)); + adjacency->next = instance->adjacencies; + instance->adjacencies = adjacency; + adjacency->instance = instance; + adjacency->interface = interface; + interface->ldp_adjacency = adjacency; + + ldp_hello_start(config, adjacency); + return true; +} \ No newline at end of file diff --git a/code/bngblaster/src/ldp/ldp_interface.h b/code/bngblaster/src/ldp/ldp_interface.h new file mode 100644 index 00000000..8711bf4c --- /dev/null +++ b/code/bngblaster/src/ldp/ldp_interface.h @@ -0,0 +1,17 @@ +/* + * BNG Blaster (BBL) - LDP Interface + * + * Christian Giese, November 2022 + * + * Copyright (C) 2020-2022, RtBrick, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef __BBL_LDP_INTERFACE_H__ +#define __BBL_LDP_INTERFACE_H__ + +bool +ldp_interface_init(bbl_network_interface_s *interface, + bbl_network_config_s *interface_config, + ldp_instance_s *instance); + +#endif \ No newline at end of file diff --git a/code/bngblaster/src/ldp/ldp_pdu.c b/code/bngblaster/src/ldp/ldp_pdu.c new file mode 100644 index 00000000..00c1b1ba --- /dev/null +++ b/code/bngblaster/src/ldp/ldp_pdu.c @@ -0,0 +1,9 @@ +/* + * BNG Blaster (BBL) - LDP PDU + * + * Christian Giese, November 2022 + * + * Copyright (C) 2020-2022, RtBrick, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "ldp.h" diff --git a/code/bngblaster/src/ldp/ldp_pdu.h b/code/bngblaster/src/ldp/ldp_pdu.h new file mode 100644 index 00000000..aedfa4be --- /dev/null +++ b/code/bngblaster/src/ldp/ldp_pdu.h @@ -0,0 +1,12 @@ +/* + * BNG Blaster (BBL) - LDP PDU + * + * Christian Giese, November 2022 + * + * Copyright (C) 2020-2022, RtBrick, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef __BBL_LDP_PDU_H__ +#define __BBL_LDP_PDU_H__ + +#endif \ No newline at end of file diff --git a/code/bngblaster/src/ldp/ldp_receive.c b/code/bngblaster/src/ldp/ldp_receive.c new file mode 100644 index 00000000..963657c3 --- /dev/null +++ b/code/bngblaster/src/ldp/ldp_receive.c @@ -0,0 +1,176 @@ + +/* + * BNG Blaster (BBL) - LDP Message Receive Functions + * + * Christian Giese, March 2022 + * + * Copyright (C) 2020-2022, RtBrick, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "ldp.h" + +struct keyval_ ldp_msg_names[] = { + { LDP_MESSAGE_TYPE_NOTIFICATION, "notification" }, + { LDP_MESSAGE_TYPE_HELLO, "hello" }, + { LDP_MESSAGE_TYPE_INITIALIZATION, "initialization" }, + { LDP_MESSAGE_TYPE_KEEPALIVE, "keepalive" }, + { LDP_MESSAGE_TYPE_ADDRESS, "address" }, + { LDP_MESSAGE_TYPE_ADDRESS_WITHDRAW, "address-withdraw" }, + { LDP_MESSAGE_TYPE_LABEL_MAPPING, "label-mapping" }, + { LDP_MESSAGE_TYPE_LABEL_REQUEST, "label-request" }, + { LDP_MESSAGE_TYPE_LABEL_WITHDRAW, "label-withdraw" }, + { LDP_MESSAGE_TYPE_LABEL_RELEASE, "label-release" }, + { LDP_MESSAGE_TYPE_ABORT_REQUEST, "abort-request" }, + { 0, NULL} +}; + +/* + * When there is only little data left and + * the buffer start is close to buffer end, + * then 'rebase' the buffer by copying + * the tail data to the buffer head. + */ +static void +ldp_rebase_buffer(io_buffer_t *buffer) +{ + uint32_t size; + + size = buffer->idx - buffer->start_idx; + if(size) { + /* Copy what is left to the buffer start. */ + memcpy(buffer->data, buffer->data+buffer->start_idx, size); + } + buffer->start_idx = 0; + buffer->idx = size; +} + +static void +ldp_read(ldp_session_s *session) +{ + uint32_t size; + uint16_t length; + + io_buffer_t *buffer = &session->read_buf; + + uint32_t lsr_id; + uint16_t label_space_id; + + uint8_t *pdu_start; + uint16_t pdu_version; + uint16_t pdu_length; + + uint8_t *msg_start; + uint16_t msg_type; + uint16_t msg_length; + + while(true) { + pdu_start = buffer->data+buffer->start_idx; + size = buffer->idx - buffer->start_idx; + + /* Minimum PDU size */ + if(size < 4) { + break; + } + + pdu_version = read_be_uint(pdu_start, 2); + pdu_length = read_be_uint(pdu_start+2, 2); + + /* The PDU length is defined as two octet integer specifying + * the total length of the PDU in octets, excluding the version + * and PDU length fields. */ + + if(pdu_version != 1 || + pdu_length < LDP_IDENTIFIER_LEN || + pdu_length > session->max_pdu_len) { + //ldp_decode_error(session); + break; + } + + length = pdu_length+4; + + /* Full message on the wire to consume? */ + if(length > size) { + break; + } + + /* Read LDP Identifier. */ + lsr_id = read_be_uint(pdu_start+4, 4); + label_space_id = read_be_uint(pdu_start+8, 2); + + if(lsr_id != session->peer.lsr_id || + label_space_id != session->peer.label_space_id) { + /* TODO: INVALID MESSAGE!!!! */ + break; + } + + pdu_length -= LDP_IDENTIFIER_LEN; + msg_start = pdu_start+10; + while(pdu_length >= 4) { + msg_type = read_be_uint(msg_start, 2); + msg_length = read_be_uint(msg_start+2, 2); + + UNUSED(msg_length); + + LOG(DEBUG, "LDP (%s - %s) read %s message\n", + format_ipv4_address(&session->local.ipv4_address), + format_ipv4_address(&session->peer.ipv4_address), + keyval_get_key(ldp_msg_names, msg_type)); + + session->stats.message_rx++; + switch(msg_type) { + case LDP_MESSAGE_TYPE_NOTIFICATION: + break; + case LDP_MESSAGE_TYPE_INITIALIZATION: + break; + case LDP_MESSAGE_TYPE_KEEPALIVE: + session->stats.keepalive_rx++; + break; + case LDP_MESSAGE_TYPE_ADDRESS: + case LDP_MESSAGE_TYPE_ADDRESS_WITHDRAW: + case LDP_MESSAGE_TYPE_LABEL_MAPPING: + case LDP_MESSAGE_TYPE_LABEL_REQUEST: + case LDP_MESSAGE_TYPE_LABEL_WITHDRAW: + case LDP_MESSAGE_TYPE_LABEL_RELEASE: + case LDP_MESSAGE_TYPE_ABORT_REQUEST: + break; + default: + break; + } + } + + /* Reset hold timer */ + //ldp_restart_hold_timer(session, session->instance->config->hold_time); + + /* Progress pointer to next LDP PDU. */ + buffer->start_idx += length; + } + ldp_rebase_buffer(buffer); +} + +void +ldp_receive_cb(void *arg, uint8_t *buf, uint16_t len) +{ + ldp_session_s *session = (ldp_session_s*)arg; + io_buffer_t *buffer = &session->read_buf; + if(buf) { + if(buffer->idx+len > buffer->size) { + LOG(ERROR, "LDP (%s - %s) receive error (read buffer exhausted)\n", + format_ipv4_address(&session->local.ipv4_address), + format_ipv4_address(&session->peer.ipv4_address)); + +#if 0 + if(!session->status_code) { + peer->status_code = 0x00000019; /* Cease */ + session->error_subcode = 8; /* Out of resources */ + } +#endif + //ldp_session_close(session); + return; + } + memcpy(buffer->data+buffer->idx, buf, len); + buffer->idx+=len; + } else { + ldp_read(session); + } +} + diff --git a/code/common/src/logging.h b/code/common/src/logging.h index 4cfc588a..41e5838a 100644 --- a/code/common/src/logging.h +++ b/code/common/src/logging.h @@ -36,6 +36,7 @@ enum { L2TP, DHCP, ISIS, + LDP, BGP, TCP, LSDB, diff --git a/docsrc/sources/configuration/bgp.rst b/docsrc/sources/configuration/bgp.rst index 584080c8..16aa5fdf 100644 --- a/docsrc/sources/configuration/bgp.rst +++ b/docsrc/sources/configuration/bgp.rst @@ -25,8 +25,8 @@ * - `peer-as` - BGP peer AS - local AS - * - `holdtime` - - BGP holdtime in seconds + * - `hold-time` + - BGP hold-time in seconds - 90 * - `id` - BGP identifier diff --git a/docsrc/sources/configuration/isis.rst b/docsrc/sources/configuration/isis.rst index 85341a4b..adde659a 100644 --- a/docsrc/sources/configuration/isis.rst +++ b/docsrc/sources/configuration/isis.rst @@ -43,8 +43,8 @@ * - `hello-padding` - ISIS hello padding - false - * - `holding-time` - - ISIS holding time in seconds + * - `hold-time` + - ISIS hold time in seconds - 30 * - `lsp-lifetime` - ISIS LSP lifetime in seconds diff --git a/docsrc/sources/configuration/ldp.rst b/docsrc/sources/configuration/ldp.rst new file mode 100644 index 00000000..83e69a37 --- /dev/null +++ b/docsrc/sources/configuration/ldp.rst @@ -0,0 +1,33 @@ +.. code-block:: json + + { "ldp": {} } + + +.. list-table:: + :widths: 25 50 25 + :header-rows: 1 + + * - Attribute + - Description + - Default + * - `instance-id` + - LDP instance identifier + - + * - `overload` + - LDP overload + - false + * - `hello-interval` + - LDP hello interval in seconds + - 10 + * - `hold-time` + - LDP hold time in seconds + - 30 + * - `hostname` + - LDP hostname + - bngblaster + * - `router-id` + - LDP router identifier + - 10.10.10.10 + * - `teardown-time` + - LDP teardown time in seconds + - 5 \ No newline at end of file diff --git a/docsrc/sources/quickstart.rst b/docsrc/sources/quickstart.rst index 160f7bba..bac45f87 100644 --- a/docsrc/sources/quickstart.rst +++ b/docsrc/sources/quickstart.rst @@ -519,7 +519,7 @@ Finally, start the BNG Blaster in another terminal window. Apr 08 14:53:52.904389 All network interfaces resolved Apr 08 14:53:53.904448 BGP (veth1.2 192.168.92.2 - 192.168.92.1) state changed from idle -> connect Apr 08 14:53:53.905659 BGP (veth1.2 192.168.92.2 - 192.168.92.1) state changed from connect -> opensent - Apr 08 14:53:53.907888 BGP (veth1.2 192.168.92.2 - 192.168.92.1) open message received with peer AS: 65001, holdtime: 90s + Apr 08 14:53:53.907888 BGP (veth1.2 192.168.92.2 - 192.168.92.1) open message received with peer AS: 65001, hold-time: 90s Apr 08 14:53:53.907903 BGP (veth1.2 192.168.92.2 - 192.168.92.1) state changed from opensent -> openconfirm Apr 08 14:53:53.907917 BGP (veth1.2 192.168.92.2 - 192.168.92.1) state changed from openconfirm -> established Apr 08 14:53:54.907989 BGP (veth1.2 192.168.92.2 - 192.168.92.1) raw update start @@ -544,11 +544,11 @@ from where you started the BNG Blaster and enter the following command. "local-address": "192.168.92.2", "local-id": "1.2.3.4", "local-as": 65001, - "local-holdtime": 90, + "local-hold-time": 90, "peer-address": "192.168.92.1", "peer-id": "1.92.168.192", "peer-as": 65001, - "peer-holdtime": 90, + "peer-hold-time": 90, "state": "established", "raw-update-state": "done", "raw-update-file": "out.bgp", diff --git a/docsrc/sources/routing/index.rst b/docsrc/sources/routing/index.rst index bfc7e839..79827a8f 100644 --- a/docsrc/sources/routing/index.rst +++ b/docsrc/sources/routing/index.rst @@ -9,5 +9,6 @@ router testing. :maxdepth: 1 isis.rst - bgp.rst + ldp.rst mpls.rst + bgp.rst diff --git a/docsrc/sources/routing/ldp.rst b/docsrc/sources/routing/ldp.rst new file mode 100644 index 00000000..3e3ef8ed --- /dev/null +++ b/docsrc/sources/routing/ldp.rst @@ -0,0 +1,62 @@ +.. _ldp: + +LDP +--- + +The Label Distribution Protocol (LDP) is a protocol defined for +distributing labels. + +Configuration +~~~~~~~~~~~~~ + +Following an example LDP configuration with one instance +attached to two network interfaces. + +.. code-block:: json + + { + "interfaces": { + "network": [ + { + "interface": "eth1", + "address": "10.0.1.2/24", + "gateway": "10.0.1.1", + "address-ipv6": "fc66:1337:7331:1::2/64", + "gateway-ipv6": "fc66:1337:7331:1::1", + "ldp-instance-id": 1, + }, + { + "interface": "eth2", + "address": "10.0.2.2/24", + "gateway": "10.0.2.1", + "address-ipv6": "fc66:1337:7331:2::2/64", + "gateway-ipv6": "fc66:1337:7331:2::1", + "ldp-instance-id": 1 + } + ] + }, + "ldp": [ + { + "instance-id": 1, + "lsr-id": "10.10.10.10", + "hostname": "R1", + } + ] + } + +.. include:: ../configuration/ldp.rst + +The support for multiple instances allows different use cases. One example might +be to create two instances connected to the device or network under test. Now +inject an LSP on one instance and check if learned over the tested network on +the other instance. + +Peers +~~~~~ + +Database +~~~~~~~~ + +Limitations +~~~~~~~~~~~ +