From 458349ea72f6ca55ea5a9253cc34ec97dd47bd29 Mon Sep 17 00:00:00 2001 From: Christian Giese Date: Thu, 15 Dec 2022 13:01:38 +0000 Subject: [PATCH] LDP minor enhancements --- code/bngblaster/src/ldp/ldp_ctrl.c | 11 ++++-- code/bngblaster/src/ldp/ldp_def.h | 6 ++++ code/bngblaster/src/ldp/ldp_hello.c | 8 +++-- code/bngblaster/src/ldp/ldp_receive.c | 51 +++++++++++++++++++++++++-- code/bngblaster/src/ldp/ldp_session.c | 3 ++ code/common/src/utils.h | 2 +- 6 files changed, 72 insertions(+), 9 deletions(-) diff --git a/code/bngblaster/src/ldp/ldp_ctrl.c b/code/bngblaster/src/ldp/ldp_ctrl.c index 5cd21d73..b43cee65 100644 --- a/code/bngblaster/src/ldp/ldp_ctrl.c +++ b/code/bngblaster/src/ldp/ldp_ctrl.c @@ -49,10 +49,14 @@ ldp_ctrl_adjacencies(int fd, uint32_t session_id __attribute__((unused)), json_t } ldp_adjacency = ldp_instance->adjacencies; while(ldp_adjacency) { - adjacency = json_pack("{si ss ss}", + adjacency = json_pack("{si ss ss si si si si}", "ldp-instance-id", ldp_adjacency->instance->config->id, "interface", ldp_adjacency->interface->name, - "state", ldp_adjacency->state == LDP_ADJACENCY_STATE_UP ? "up" : "down"); + "state", ldp_adjacency->state == LDP_ADJACENCY_STATE_UP ? "up" : "down", + "state-transitions", ldp_adjacency->state_transitions, + "rx-discovery", ldp_adjacency->interface->stats.ldp_udp_rx, + "rx-discovery-error", ldp_adjacency->interface->stats.ldp_udp_rx_error, + "tx-discovery", ldp_adjacency->interface->stats.ldp_udp_tx); if(adjacency) { json_array_append(adjacencies, adjacency); } @@ -103,7 +107,7 @@ ldp_ctrl_session_json(ldp_session_s *session) return NULL; } - root = json_pack("{si ss ss ss ss ss ss ss* ss* so*}", + root = json_pack("{si ss ss ss ss ss ss si ss* ss* so*}", "ldp-instance-id", session->instance->config->id, "interface", session->interface->name, "local-address", format_ipv4_address(&session->local.ipv4_address), @@ -111,6 +115,7 @@ ldp_ctrl_session_json(ldp_session_s *session) "peer-address", format_ipv4_address(&session->peer.ipv4_address), "peer-identifier", ldp_id_to_str(session->peer.lsr_id, session->peer.label_space_id), "state", ldp_session_state_string(session->state), + "state-transitions", session->state_transitions, "raw-update-state", raw_update_state(session), "raw-update-file", raw_update_file, "stats", stats); diff --git a/code/bngblaster/src/ldp/ldp_def.h b/code/bngblaster/src/ldp/ldp_def.h index 154b9e34..e563bef0 100644 --- a/code/bngblaster/src/ldp/ldp_def.h +++ b/code/bngblaster/src/ldp/ldp_def.h @@ -52,11 +52,15 @@ #define LDP_TLV_LEN_MIN 4 #define LDP_FEC_LEN_MIN 4 #define LDP_FEC_ELEMENT_TYPE_PREFIX 2 +#define LDP_STATUS_LEN_MIN 10 #define LDP_STATUS_SUCCESS 0x00000000 #define LDP_STATUS_BAD_IDENTIFIER 0x00000001 #define LDP_STATUS_BAD_VERSION 0x00000002 +#define LDP_STATUS_BAD_PDU_LEN 0x00000003 +#define LDP_STATUS_UNKNOWN_MSG_TYPE 0x00000004 #define LDP_STATUS_BAD_MSG_LEN 0x00000005 +#define LDP_STATUS_UNKNOWN_TLV_TYPE 0x00000006 #define LDP_STATUS_BAD_TLV_LEN 0x00000007 #define LDP_STATUS_BAD_TLV_VALUE 0x00000008 #define LDP_STATUS_HOLD_TIMER_EXPIRED 0x00000009 @@ -177,6 +181,7 @@ typedef struct ldp_session_ { bool decode_error; bool active; ldp_state_t state; + uint32_t state_transitions; uint16_t max_pdu_len; uint16_t keepalive_time; @@ -233,6 +238,7 @@ typedef struct ldp_adjacency_ { uint16_t hold_time; ldp_adjacency_state state; + uint32_t state_transitions; /* Pointer to next adjacency of * corresponding instance with. */ diff --git a/code/bngblaster/src/ldp/ldp_hello.c b/code/bngblaster/src/ldp/ldp_hello.c index ead76564..efac5d6f 100644 --- a/code/bngblaster/src/ldp/ldp_hello.c +++ b/code/bngblaster/src/ldp/ldp_hello.c @@ -90,7 +90,7 @@ ldp_hello_hold_timeout_job(timer_s *timer) if(adjacency->state == LDP_ADJACENCY_STATE_DOWN) { return; } - + adjacency->state_transitions++; adjacency->state = LDP_ADJACENCY_STATE_DOWN; LOG(LDP, "LDP hold timeout on interface %s\n", adjacency->interface->name); } @@ -98,7 +98,11 @@ ldp_hello_hold_timeout_job(timer_s *timer) static void ldp_hello_restart_hold_timeout(ldp_adjacency_s *adjacency) { - adjacency->state = LDP_ADJACENCY_STATE_UP; + if(adjacency->state == LDP_ADJACENCY_STATE_DOWN) { + adjacency->state_transitions++; + adjacency->state = LDP_ADJACENCY_STATE_UP; + LOG(LDP, "LDP adjacency on interface %s\n", adjacency->interface->name); + } timer_add(&g_ctx->timer_root, &adjacency->hold_timer, "LDP HOLD TIMEOUT", adjacency->hold_time, 0, adjacency, &ldp_hello_hold_timeout_job); } diff --git a/code/bngblaster/src/ldp/ldp_receive.c b/code/bngblaster/src/ldp/ldp_receive.c index 11162d3d..e873c6d7 100644 --- a/code/bngblaster/src/ldp/ldp_receive.c +++ b/code/bngblaster/src/ldp/ldp_receive.c @@ -24,6 +24,23 @@ struct keyval_ ldp_msg_names[] = { { 0, NULL} }; +struct keyval_ ldp_status_names[] = { + { LDP_STATUS_SUCCESS, "success" }, + { LDP_STATUS_BAD_IDENTIFIER, "bad LDP identifier" }, + { LDP_STATUS_BAD_VERSION, "bad protocol version" }, + { LDP_STATUS_BAD_PDU_LEN, "bad PDU length" }, + { LDP_STATUS_UNKNOWN_MSG_TYPE, "unknown message type" }, + { LDP_STATUS_BAD_MSG_LEN, "bad message length" }, + { LDP_STATUS_UNKNOWN_TLV_TYPE, "unknown TLV type" }, + { LDP_STATUS_BAD_TLV_LEN, "bad TLV length" }, + { LDP_STATUS_BAD_TLV_VALUE, "bad TLV value" }, + { LDP_STATUS_HOLD_TIMER_EXPIRED, "hold timer expired" }, + { LDP_STATUS_KEEPALIVE_TIMER_EXPIRED, "keepalive timer expired" }, + { LDP_STATUS_SHUTDOWN, "shutdown" }, + { LDP_STATUS_INTERNAL_ERROR, "internal error" }, + { 0, NULL} +}; + static void ldp_decode_error(ldp_session_s *session) { @@ -41,9 +58,37 @@ ldp_decode_error(ldp_session_s *session) static bool ldp_notification(ldp_session_s *session, uint8_t *start, uint16_t length) { - UNUSED(session); - UNUSED(start); - UNUSED(length); + uint8_t *tlv_start = start; + uint16_t tlv_type; + uint16_t tlv_length; + uint32_t status_code = UINT32_MAX; + + /* Read all TLV's. */ + while(length >= LDP_TLV_LEN_MIN) { + tlv_type = read_be_uint(tlv_start, 2) & 0x3FFF; + tlv_length = read_be_uint(tlv_start+2, 2); + if(tlv_length+LDP_TLV_LEN_MIN > length) { + return false; + } + switch(tlv_type) { + case LDP_TLV_TYPE_STATUS: + if(tlv_length < LDP_STATUS_LEN_MIN) { + return false; + } + status_code = read_be_uint(tlv_start+LDP_TLV_LEN_MIN, 4); + break; + default: + break; + } + length -= (tlv_length+LDP_TLV_LEN_MIN); + tlv_start += (tlv_length+LDP_TLV_LEN_MIN); + } + + LOG(LDP, "LDP (%s - %s) received notification with status code %u (%s)\n", + ldp_id_to_str(session->local.lsr_id, session->local.label_space_id), + ldp_id_to_str(session->peer.lsr_id, session->peer.label_space_id), + status_code, keyval_get_key(ldp_status_names, status_code)); + return true; } diff --git a/code/bngblaster/src/ldp/ldp_session.c b/code/bngblaster/src/ldp/ldp_session.c index 56e288e0..bdb2df35 100644 --- a/code/bngblaster/src/ldp/ldp_session.c +++ b/code/bngblaster/src/ldp/ldp_session.c @@ -32,6 +32,9 @@ static void ldp_session_state_change(ldp_session_s *session, ldp_state_t new_state) { if(session->state != new_state) { + if(session->state == LDP_OPERATIONAL || new_state == LDP_OPERATIONAL) { + session->state_transitions++; + } LOG(LDP, "LDP (%s - %s) state changed from %s -> %s\n", ldp_id_to_str(session->local.lsr_id, session->local.label_space_id), ldp_id_to_str(session->peer.lsr_id, session->peer.label_space_id), diff --git a/code/common/src/utils.h b/code/common/src/utils.h index 926cfa2e..3ae13ccf 100644 --- a/code/common/src/utils.h +++ b/code/common/src/utils.h @@ -23,7 +23,7 @@ bool push_le_uint(struct io_buffer_ *buffer, uint32_t length, uint64_t value); const char *val2key(struct keyval_ *keyval, uint32_t val); uint32_t key2val(struct keyval_ *ptr, const char *key); -const char *keyval_get_key (struct keyval_ *keyval, uint32_t val); +const char *keyval_get_key(struct keyval_ *keyval, uint32_t val); char *format_mac_address(uint8_t *mac); char *format_ipv4_address(uint32_t *addr4);