From 86fdbe5f1342dcc2261689ddcf314dadeb82f19c Mon Sep 17 00:00:00 2001 From: Christian Giese Date: Mon, 12 Dec 2022 22:00:52 +0000 Subject: [PATCH] LDP commands --- code/bngblaster/src/bbl_config.c | 27 +- code/bngblaster/src/bbl_ctrl.c | 6 + code/bngblaster/src/bbl_ctx.h | 1 + code/bngblaster/src/bbl_session.c | 2 +- code/bngblaster/src/bgp/bgp_def.h | 1 - code/bngblaster/src/ldp/ldp.h | 6 +- code/bngblaster/src/ldp/ldp_ctrl.c | 407 +++++++++++++++++++++++ code/bngblaster/src/ldp/ldp_ctrl.h | 30 ++ code/bngblaster/src/ldp/ldp_def.h | 6 +- code/bngblaster/src/ldp/ldp_raw_update.c | 123 +++++++ code/bngblaster/src/ldp/ldp_raw_update.h | 15 + code/bngblaster/src/ldp/ldp_receive.c | 2 +- code/bngblaster/src/ldp/ldp_session.c | 11 +- code/bngblaster/src/ldp/ldp_session.h | 6 + 14 files changed, 629 insertions(+), 14 deletions(-) create mode 100644 code/bngblaster/src/ldp/ldp_ctrl.c create mode 100644 code/bngblaster/src/ldp/ldp_ctrl.h create mode 100644 code/bngblaster/src/ldp/ldp_raw_update.c create mode 100644 code/bngblaster/src/ldp/ldp_raw_update.h diff --git a/code/bngblaster/src/bbl_config.c b/code/bngblaster/src/bbl_config.c index e931cd97..3ce0ae62 100644 --- a/code/bngblaster/src/bbl_config.c +++ b/code/bngblaster/src/bbl_config.c @@ -1381,11 +1381,11 @@ json_parse_ldp_config(json_t *ldp, ldp_config_s *ldp_config) return false; } - value = json_object_get(ldp, "keepalive-interval"); + value = json_object_get(ldp, "keepalive-time"); if(json_is_number(value)) { - ldp_config->keepalive_interval = json_number_value(value); + ldp_config->keepalive_time = json_number_value(value); } else { - ldp_config->keepalive_interval = LDP_DEFAULT_KEEPALIVE_INTERVAL; + ldp_config->keepalive_time = LDP_DEFAULT_KEEPALIVE_TIME; } value = json_object_get(ldp, "hold-time"); @@ -1425,6 +1425,13 @@ json_parse_ldp_config(json_t *ldp, ldp_config_s *ldp_config) } else { ldp_config->ipv4_transport_address = ldp_config->lsr_id; } + + if(json_unpack(ldp, "{s:s}", "raw-update-file", &s) == 0) { + ldp_config->raw_update_file = strdup(s); + if(!ldp_raw_update_load(ldp_config->raw_update_file, true)) { + return false; + } + } return true; } @@ -2333,6 +2340,20 @@ json_parse_config(json_t *root) } } + /* Pre-Load LDP RAW update files */ + sub = json_object_get(root, "ldp-raw-update-files"); + if(json_is_array(sub)) { + size = json_array_size(sub); + for(i = 0; i < size; i++) { + s = json_string_value(json_array_get(sub, i)); + if(s) { + if(!ldp_raw_update_load(s, true)) { + return false; + } + } + } + } + /* Interface Configuration */ section = json_object_get(root, "interfaces"); if(json_is_object(section)) { diff --git a/code/bngblaster/src/bbl_ctrl.c b/code/bngblaster/src/bbl_ctrl.c index 378346fe..17ae1b4a 100644 --- a/code/bngblaster/src/bbl_ctrl.c +++ b/code/bngblaster/src/bbl_ctrl.c @@ -156,6 +156,12 @@ struct action actions[] = { {"bgp-teardown", bgp_ctrl_teardown, true}, {"bgp-raw-update-list", bgp_ctrl_raw_update_list, true}, {"bgp-raw-update", bgp_ctrl_raw_update, false}, + {"ldp-adjacencies", ldp_ctrl_adjacencies, true}, + {"ldp-sessions", ldp_ctrl_sessions, true}, + {"ldp-disconnect", ldp_ctrl_disconnect, false}, + {"ldp-teardown", ldp_ctrl_teardown, true}, + {"ldp-raw-update-list", ldp_ctrl_raw_update_list, true}, + {"ldp-raw-update", ldp_ctrl_raw_update, false}, {"monkey-start", bbl_session_ctrl_monkey_start, false}, {"monkey-stop", bbl_session_ctrl_monkey_stop, false}, {"lag-info", bbl_lag_ctrl_info, true}, diff --git a/code/bngblaster/src/bbl_ctx.h b/code/bngblaster/src/bbl_ctx.h index 414e1c9e..a9d16ca8 100644 --- a/code/bngblaster/src/bbl_ctx.h +++ b/code/bngblaster/src/bbl_ctx.h @@ -96,6 +96,7 @@ typedef struct bbl_ctx_ bgp_raw_update_s *bgp_raw_updates; isis_instance_s *isis_instances; ldp_instance_s *ldp_instances; + ldp_raw_update_s *ldp_raw_updates; /* Scratchpad memory */ uint8_t *sp; diff --git a/code/bngblaster/src/bbl_session.c b/code/bngblaster/src/bbl_session.c index 2452ef7b..9d087524 100644 --- a/code/bngblaster/src/bbl_session.c +++ b/code/bngblaster/src/bbl_session.c @@ -1384,7 +1384,7 @@ bbl_session_ctrl_terminate(int fd, uint32_t session_id, json_t *arguments) /* Terminate single matching session ... */ session = bbl_session_get(session_id); if(session) { - json_unpack(arguments, "{s:i}", "reconnect-delay", &session->reconnect_delay); + json_unpack(arguments, "{s:i}", "reconnect-delay", &reconnect_delay); if(reconnect_delay > 0) { session->reconnect_delay = reconnect_delay; } diff --git a/code/bngblaster/src/bgp/bgp_def.h b/code/bngblaster/src/bgp/bgp_def.h index c1c67d2b..ab905c2c 100644 --- a/code/bngblaster/src/bgp/bgp_def.h +++ b/code/bngblaster/src/bgp/bgp_def.h @@ -65,7 +65,6 @@ typedef struct bgp_config_ { bool start_traffic; char *network_interface; - char *mrt_file; char *raw_update_file; /* Pointer to next instance */ diff --git a/code/bngblaster/src/ldp/ldp.h b/code/bngblaster/src/ldp/ldp.h index 801327f0..38dafc7f 100644 --- a/code/bngblaster/src/ldp/ldp.h +++ b/code/bngblaster/src/ldp/ldp.h @@ -11,11 +11,13 @@ #include "../bbl.h" #include "ldp_def.h" -#include "ldp_message.h" #include "ldp_hello.h" #include "ldp_interface.h" -#include "ldp_receive.h" #include "ldp_session.h" +#include "ldp_message.h" +#include "ldp_receive.h" +#include "ldp_raw_update.h" +#include "ldp_ctrl.h" bool ldp_init(); diff --git a/code/bngblaster/src/ldp/ldp_ctrl.c b/code/bngblaster/src/ldp/ldp_ctrl.c new file mode 100644 index 00000000..ce2ee2c8 --- /dev/null +++ b/code/bngblaster/src/ldp/ldp_ctrl.c @@ -0,0 +1,407 @@ +/* + * BNG Blaster (BBL) - LDP CTRL (Control Commands) + * + * Christian Giese, November 2022 + * + * Copyright (C) 2020-2022, RtBrick, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "ldp.h" +#include "../bbl_ctrl.h" + +static const char * +raw_update_state(ldp_session_s *session) +{ + if(session->raw_update) { + if(session->update_start_timestamp.tv_sec) { + if(session->raw_update_sending) { + return "sending"; + } + if(session->update_stop_timestamp.tv_sec) { + return "done"; + } + } else { + return "wait"; + } + } + return NULL; +} + +int +ldp_ctrl_adjacencies(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments) +{ + int result = 0; + json_t *root, *adjacencies, *adjacency; + + ldp_instance_s *ldp_instance = g_ctx->ldp_instances; + ldp_adjacency_s *ldp_adjacency; + + int ldp_instance_id = 0; + + /* Unpack further arguments */ + json_unpack(arguments, "{s:i}", "ldp-instance-id", &ldp_instance_id); + + adjacencies = json_array(); + while(ldp_instance) { + if(ldp_instance_id > 0 && ldp_instance_id != ldp_instance->config->id) { + ldp_instance = ldp_instance->next; + continue; + } + ldp_adjacency = ldp_instance->adjacencies; + while(ldp_adjacency) { + adjacency = json_pack("{si ss ss}", + "ldp-instance-id", ldp_adjacency->instance->config->id, + "interface", ldp_adjacency->interface->name, + "state", ldp_adjacency->state == LDP_ADJACENCY_STATE_UP ? "up" : "down"); + if(adjacency) { + json_array_append(adjacencies, adjacency); + } + ldp_adjacency = ldp_adjacency->next; + } + ldp_instance = ldp_instance->next; + } + + root = json_pack("{ss si so}", + "status", "ok", + "code", 200, + "ldp-adjacencies", adjacencies); + if(root) { + result = json_dumpfd(root, fd, 0); + json_decref(root); + } else { + result = bbl_ctrl_status(fd, "error", 500, "internal error"); + json_decref(adjacencies); + } + return result; +} + +static json_t * +ldp_ctrl_session_json(ldp_session_s *session) +{ + json_t *root = NULL; + json_t *stats = NULL; + + const char *raw_update_file = NULL; + + if(!session) { + return NULL; + } + + if(session->raw_update) { + raw_update_file = session->raw_update->file; + } + + stats = json_pack("{si si si si si si}", + "pdu-rx", session->stats.pdu_rx, + "pdu-tx", session->stats.pdu_tx, + "messages-rx", session->stats.message_rx, + "messages-tx", session->stats.message_tx, + "keepalive-rx", session->stats.keepalive_rx, + "keepalive-tx", session->stats.keepalive_tx); + + if(!stats) { + return NULL; + } + + root = json_pack("{si ss ss ss si ss ss si ss ss* ss* so*}", + "ldp-instance-id", session->instance->config->id, + "interface", session->interface->name, + "local-address", format_ipv4_address(&session->local.ipv4_address), + "local-lsr-id", format_ipv4_address(&session->local.lsr_id), + "local-label-space-id", session->local.label_space_id, + "peer-address", format_ipv4_address(&session->peer.ipv4_address), + "peer-lsr-id", format_ipv4_address(&session->peer.lsr_id), + "peer-label-space-id", session->peer.label_space_id, + "state", ldp_session_state_string(session->state), + "raw-update-state", raw_update_state(session), + "raw-update-file", raw_update_file, + "stats", stats); + + if(!root) { + if(stats) json_decref(stats); + } + return root; +} + +int +ldp_ctrl_sessions(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments) +{ + int result = 0; + json_t *root, *sessions, *session; + + ldp_instance_s *ldp_instance = g_ctx->ldp_instances; + ldp_session_s *ldp_session; + + const char *s; + uint32_t ipv4_local_address = 0; + uint32_t ipv4_peer_address = 0; + int ldp_instance_id = 0; + + /* Unpack further arguments */ + json_unpack(arguments, "{s:i}", "ldp-instance-id", &ldp_instance_id); + if(json_unpack(arguments, "{s:s}", "local-ipv4-address", &s) == 0) { + if(!inet_pton(AF_INET, s, &ipv4_local_address)) { + return bbl_ctrl_status(fd, "error", 400, "invalid local-ipv4-address"); + } + } + if(json_unpack(arguments, "{s:s}", "peer-ipv4-address", &s) == 0) { + if(!inet_pton(AF_INET, s, &ipv4_peer_address)) { + return bbl_ctrl_status(fd, "error", 400, "invalid peer-ipv4-address"); + } + } + + sessions = json_array(); + while(ldp_instance) { + if(ldp_instance_id > 0 && ldp_instance_id != ldp_instance->config->id) { + ldp_instance = ldp_instance->next; + continue; + } + ldp_session = ldp_instance->sessions; + while(ldp_session) { + if(ipv4_local_address && ldp_session->local.ipv4_address != ipv4_local_address) { + ldp_session = ldp_session->next; + continue; + } + if(ipv4_peer_address && ldp_session->peer.ipv4_address != ipv4_peer_address) { + ldp_session = ldp_session->next; + continue; + } + session = ldp_ctrl_session_json(ldp_session); + if(session) { + json_array_append(sessions, session); + } + ldp_session = ldp_session->next; + } + ldp_instance = ldp_instance->next; + } + + root = json_pack("{ss si so}", + "status", "ok", + "code", 200, + "ldp-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; +} + +int +ldp_ctrl_teardown(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments __attribute__((unused))) +{ + ldp_teardown(); + return bbl_ctrl_status(fd, "ok", 200, NULL); +} + +int +ldp_ctrl_raw_update(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments) +{ + int result = 0; + json_t *root; + + ldp_instance_s *ldp_instance = g_ctx->ldp_instances; + ldp_session_s *ldp_session; + ldp_raw_update_s *raw_update; + + const char *s; + const char *file_path; + + uint16_t started = 0; + uint16_t skipped = 0; + uint16_t filtered = 0; + + uint32_t ipv4_local_address = 0; + uint32_t ipv4_peer_address = 0; + int ldp_instance_id = 0; + + /* Unpack further arguments */ + if(json_unpack(arguments, "{s:s}", "file", &file_path) != 0) { + return bbl_ctrl_status(fd, "error", 400, "missing argument file"); + } + json_unpack(arguments, "{s:i}", "ldp-instance-id", &ldp_instance_id); + if(json_unpack(arguments, "{s:s}", "local-ipv4-address", &s) == 0) { + if(!inet_pton(AF_INET, s, &ipv4_local_address)) { + return bbl_ctrl_status(fd, "error", 400, "invalid local-ipv4-address"); + } + } + if(json_unpack(arguments, "{s:s}", "peer-ipv4-address", &s) == 0) { + if(!inet_pton(AF_INET, s, &ipv4_peer_address)) { + return bbl_ctrl_status(fd, "error", 400, "invalid peer-ipv4-address"); + } + } + + /* Load file. */ + raw_update = ldp_raw_update_load(file_path, true); + if(!raw_update) { + return bbl_ctrl_status(fd, "error", 400, "failed to load file"); + } + + while(ldp_instance) { + ldp_session = ldp_instance->sessions; + while(ldp_session) { + if(ldp_instance_id > 0 && ldp_instance_id != ldp_instance->config->id) { + ldp_session = ldp_session->next; + filtered++; + continue; + } + if(ipv4_local_address && ldp_session->local.ipv4_address != ipv4_local_address) { + ldp_session = ldp_session->next; + filtered++; + continue; + } + if(ipv4_peer_address && ldp_session->peer.ipv4_address != ipv4_peer_address) { + ldp_session = ldp_session->next; + filtered++; + continue; + } + if(ldp_session->raw_update_sending) { + ldp_session = ldp_session->next; + skipped++; + continue; + } + ldp_session->raw_update = raw_update; + timer_add(&g_ctx->timer_root, &ldp_session->update_timer, + "LDP UPDATE", 0, 0, ldp_session, + &ldp_session_update_job); + + started++; + ldp_session = ldp_session->next; + } + ldp_instance = ldp_instance->next; + } + + root = json_pack("{ss si s{si si si}}", + "status", "ok", + "code", 200, + "ldp-raw-update", + "started", started, + "skipped", skipped, + "filtered", filtered); + + if(root) { + result = json_dumpfd(root, fd, 0); + json_decref(root); + } else { + result = bbl_ctrl_status(fd, "error", 500, "internal error"); + } + return result; +} + +int +ldp_ctrl_raw_update_list(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments __attribute__((unused))) +{ + int result = 0; + ldp_raw_update_s *raw_update = g_ctx->ldp_raw_updates; + json_t *root, *updates, *update; + + updates = json_array(); + + while(raw_update){ + update = json_pack("{ss* si si si}", + "file", raw_update->file, + "len", raw_update->len, + "pdu", raw_update->pdu, + "messages", raw_update->messages); + if(update) { + json_array_append(updates, update); + } + raw_update = raw_update->next; + } + root = json_pack("{ss si so}", + "status", "ok", + "code", 200, + "ldp-raw-update-list", updates); + if(root) { + result = json_dumpfd(root, fd, 0); + json_decref(root); + } else { + result = bbl_ctrl_status(fd, "error", 500, "internal error"); + json_decref(updates); + } + return result; +} + +int +ldp_ctrl_disconnect(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments) +{ + int result = 0; + json_t *root; + + ldp_instance_s *ldp_instance = g_ctx->ldp_instances; + ldp_session_s *ldp_session; + + const char *s; + + uint16_t disconnected = 0; + uint16_t skipped = 0; + uint16_t filtered = 0; + + uint32_t ipv4_local_address = 0; + uint32_t ipv4_peer_address = 0; + int ldp_instance_id = 0; + + /* Unpack further arguments */ + json_unpack(arguments, "{s:i}", "ldp-instance-id", &ldp_instance_id); + if(json_unpack(arguments, "{s:s}", "local-ipv4-address", &s) == 0) { + if(!inet_pton(AF_INET, s, &ipv4_local_address)) { + return bbl_ctrl_status(fd, "error", 400, "invalid local-ipv4-address"); + } + } + if(json_unpack(arguments, "{s:s}", "peer-ipv4-address", &s) == 0) { + if(!inet_pton(AF_INET, s, &ipv4_peer_address)) { + return bbl_ctrl_status(fd, "error", 400, "invalid peer-ipv4-address"); + } + } + + while(ldp_instance) { + ldp_session = ldp_instance->sessions; + while(ldp_session) { + if(ldp_instance_id > 0 && ldp_instance_id != ldp_instance->config->id) { + ldp_session = ldp_session->next; + filtered++; + continue; + } + if(ipv4_local_address && ldp_session->local.ipv4_address != ipv4_local_address) { + ldp_session = ldp_session->next; + filtered++; + continue; + } + if(ipv4_peer_address && ldp_session->peer.ipv4_address != ipv4_peer_address) { + ldp_session = ldp_session->next; + filtered++; + continue; + } + if(ldp_session->state == LDP_CLOSED || ldp_session->state == LDP_CLOSING) { + ldp_session = ldp_session->next; + skipped++; + continue; + } + if(!ldp_session->error_code) { + ldp_session->error_code = LDP_STATUS_SHUTDOWN; + } + ldp_session_close(ldp_session); + disconnected++; + ldp_session = ldp_session->next; + } + ldp_instance = ldp_instance->next; + } + + root = json_pack("{ss si s{si si si}}", + "status", "ok", + "code", 200, + "ldp-disconnect", + "disconnected", disconnected, + "skipped", skipped, + "filtered", filtered); + + if(root) { + result = json_dumpfd(root, fd, 0); + json_decref(root); + } else { + result = bbl_ctrl_status(fd, "error", 500, "internal error"); + } + return result; +} \ No newline at end of file diff --git a/code/bngblaster/src/ldp/ldp_ctrl.h b/code/bngblaster/src/ldp/ldp_ctrl.h new file mode 100644 index 00000000..96e0a43a --- /dev/null +++ b/code/bngblaster/src/ldp/ldp_ctrl.h @@ -0,0 +1,30 @@ +/* + * BNG Blaster (BBL) - LDP CTRL (Control Commands) + * + * Christian Giese, November 2022 + * + * Copyright (C) 2020-2022, RtBrick, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef __BBL_LDP_CTRL_H__ +#define __BBL_LDP_CTRL_H__ + +int +ldp_ctrl_adjacencies(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments); + +int +ldp_ctrl_sessions(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments __attribute__((unused))); + +int +ldp_ctrl_teardown(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments __attribute__((unused))); + +int +ldp_ctrl_raw_update(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments); + +int +ldp_ctrl_raw_update_list(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments __attribute__((unused))); + +int +ldp_ctrl_disconnect(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments); + +#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 index b9641952..58162c2b 100644 --- a/code/bngblaster/src/ldp/ldp_def.h +++ b/code/bngblaster/src/ldp/ldp_def.h @@ -62,7 +62,7 @@ #define LDP_STATUS_SHUTDOWN 0x0000000A #define LDP_STATUS_INTERNAL_ERROR 0x00000019 -#define LDP_DEFAULT_KEEPALIVE_INTERVAL 15 +#define LDP_DEFAULT_KEEPALIVE_TIME 15 #define LDP_DEFAULT_HOLD_TIME 15 #define LDP_DEFAULT_TEARDOWN_TIME 5 @@ -120,10 +120,12 @@ typedef struct ldp_config_ { const char *lsr_id_str; const char *hostname; - uint16_t keepalive_interval; + uint16_t keepalive_time; uint16_t hold_time; uint16_t teardown_time; + char *raw_update_file; + /* Pointer to next instance. */ struct ldp_config_ *next; } ldp_config_s; diff --git a/code/bngblaster/src/ldp/ldp_raw_update.c b/code/bngblaster/src/ldp/ldp_raw_update.c new file mode 100644 index 00000000..d8d8a020 --- /dev/null +++ b/code/bngblaster/src/ldp/ldp_raw_update.c @@ -0,0 +1,123 @@ +/* + * BNG Blaster (BBL) - LDP RAW Update Functions + * + * Christian Giese, November 2022 + * + * Copyright (C) 2020-2022, RtBrick, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "ldp.h" + +static ldp_raw_update_s * +ldp_raw_update_load_file(const char *file, bool decode_file) +{ + ldp_raw_update_s *raw_update = NULL; + long fsize; + double fsize_kb; + + uint8_t *buf = NULL; + uint32_t len = 0; + + uint16_t pdu_length; + uint16_t msg_len; + + /* Open file */ + FILE *f = fopen(file, "rb"); + if(f == NULL) { + LOG(ERROR, "Failed to open LDP RAW update file %s\n", file); + return NULL; + } + + /* Get file size */ + fseek(f, 0, SEEK_END); + fsize = ftell(f); + fsize_kb = fsize/1024.0; + fseek(f, 0, SEEK_SET); + + /* Load file into memory */ + raw_update = calloc(1, sizeof(ldp_raw_update_s)); + raw_update->file = strdup(file); + raw_update->buf = malloc(fsize); + raw_update->len = fsize; + if(fread(raw_update->buf, fsize, 1, f) != 1) { + fclose(f); + LOG(ERROR, "Failed to read LDP RAW update file %s\n", file); + goto ERROR; + } + fclose(f); + + if(decode_file) { + /* Decode update stream */ + buf = raw_update->buf; + len = raw_update->len; + while(len) { + if(len < LDP_MIN_PDU_LEN) { + goto DECODE_ERROR; + } + raw_update->pdu++; + + BUMP_BUFFER(buf, len, sizeof(uint16_t)); + pdu_length = be16toh(*(uint16_t*)buf); + BUMP_BUFFER(buf, len, sizeof(uint16_t)); + if(pdu_length > len) { + goto DECODE_ERROR; + } + BUMP_BUFFER(buf, len, LDP_IDENTIFIER_LEN); + while(pdu_length > LDP_MIN_MSG_LEN) { + BUMP_BUFFER(buf, len, sizeof(uint16_t)); + msg_len = be16toh(*(uint16_t*)buf); + BUMP_BUFFER(buf, len, sizeof(uint16_t)); + pdu_length -= 4; + if(msg_len > pdu_length) { + goto DECODE_ERROR; + } + BUMP_BUFFER(buf, len, msg_len); + pdu_length -= msg_len; + raw_update->messages++; + } + } + } + LOG(INFO, "Loaded LDP RAW update file %s (%.2f KB, %u pdu, %u messages)\n", + file, fsize_kb, raw_update->pdu, raw_update->messages); + return raw_update; + +DECODE_ERROR: + LOG(ERROR, "Failed to decode LDP RAW update file %s\n", file); +ERROR: + if(raw_update) { + if(raw_update->buf) { + free(raw_update->buf); + } + free(raw_update); + } + return NULL; +} + +/** + * ldp_raw_update_load + * + * @param file update file + * @param decode_file decode/parse file content if true + * @return LDP RAW update structure + */ +ldp_raw_update_s * +ldp_raw_update_load(const char *file, bool decode_file) +{ + ldp_raw_update_s *raw_update = g_ctx->ldp_raw_updates; + + /* Check if file is already loaded */ + while(raw_update){ + if(strcmp(file, raw_update->file) == 0) { + return raw_update; + } + raw_update = raw_update->next; + } + raw_update = ldp_raw_update_load_file(file, decode_file); + if(raw_update) { + raw_update->next = g_ctx->ldp_raw_updates; + g_ctx->ldp_raw_updates = raw_update; + return raw_update; + } else { + return NULL; + } +} \ No newline at end of file diff --git a/code/bngblaster/src/ldp/ldp_raw_update.h b/code/bngblaster/src/ldp/ldp_raw_update.h new file mode 100644 index 00000000..91883951 --- /dev/null +++ b/code/bngblaster/src/ldp/ldp_raw_update.h @@ -0,0 +1,15 @@ +/* + * BNG Blaster (BBL) - LDP RAW Update Functions + * + * Christian Giese, November 2022 + * + * Copyright (C) 2020-2022, RtBrick, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef __BBL_LDP_RAW_UPDATE_H__ +#define __BBL_LDP_RAW_UPDATE_H__ + +ldp_raw_update_s * +ldp_raw_update_load(const char *file, bool decode_file); + +#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 index cde3ded2..8b96ba10 100644 --- a/code/bngblaster/src/ldp/ldp_receive.c +++ b/code/bngblaster/src/ldp/ldp_receive.c @@ -2,7 +2,7 @@ /* * BNG Blaster (BBL) - LDP Receive Functions * - * Christian Giese, March 2022 + * Christian Giese, November 2022 * * Copyright (C) 2020-2022, RtBrick, Inc. * SPDX-License-Identifier: BSD-3-Clause diff --git a/code/bngblaster/src/ldp/ldp_session.c b/code/bngblaster/src/ldp/ldp_session.c index 221b6d3f..5bc430c8 100644 --- a/code/bngblaster/src/ldp/ldp_session.c +++ b/code/bngblaster/src/ldp/ldp_session.c @@ -241,7 +241,8 @@ ldp_session_fsm(ldp_session_s *session, ldp_event_t event) ldp_push_init_message(session, true); if(ldp_session_send(session)) { session->stats.pdu_tx++; - session->stats.message_tx++; + session->stats.message_tx += 2; + session->stats.keepalive_tx++; ldp_session_state_change(session, LDP_OPENREC); } } else if(session->state == LDP_OPENSENT) { @@ -250,6 +251,7 @@ ldp_session_fsm(ldp_session_s *session, ldp_event_t event) if(ldp_session_send(session)) { session->stats.pdu_tx++; session->stats.message_tx++; + session->stats.keepalive_tx++; ldp_session_state_change(session, LDP_OPENREC); } } else { @@ -449,13 +451,14 @@ ldp_session_init(ldp_session_s *session, ldp_adjacency_s *adjacency, if(!session) { session = calloc(1, sizeof(ldp_session_s)); - session->next = instance->sessions; - instance->sessions = session; + session->instance = instance; session->local.ipv4_address = config->ipv4_transport_address; session->local.lsr_id = config->lsr_id; session->local.label_space_id = 0; - session->local.keepalive_time = config->keepalive_interval; + session->local.keepalive_time = config->keepalive_time; session->local.max_pdu_len = LDP_MAX_PDU_LEN_INIT; + session->next = instance->sessions; + instance->sessions = session; } session->interface = adjacency->interface; session->max_pdu_len = session->local.max_pdu_len; diff --git a/code/bngblaster/src/ldp/ldp_session.h b/code/bngblaster/src/ldp/ldp_session.h index c920f702..e97232bf 100644 --- a/code/bngblaster/src/ldp/ldp_session.h +++ b/code/bngblaster/src/ldp/ldp_session.h @@ -9,6 +9,12 @@ #ifndef __BBL_LDP_SESSION_H__ #define __BBL_LDP_SESSION_H__ +const char * +ldp_session_state_string(ldp_state_t state); + +void +ldp_session_update_job(timer_s *timer); + void ldp_session_restart_keepalive_timeout(ldp_session_s *session);