ISIS enhancements

This commit is contained in:
Christian Giese
2023-05-08 23:18:42 +02:00
committed by Christian Giese
parent 86c1cae2b3
commit ce7f04706e
14 changed files with 286 additions and 151 deletions
+1
View File
@@ -221,6 +221,7 @@ bbl_smear_job(timer_s *timer)
UNUSED(timer);
/* LCP Keepalive Interval */
if(g_ctx->config.lcp_keepalive_interval) {
/* Adding 1 nanoseconds to enforce a dedicated timer bucket. */
timer_smear_bucket(&g_ctx->timer_root, g_ctx->config.lcp_keepalive_interval, 1);
}
}
+3 -3
View File
@@ -410,12 +410,12 @@ bbl_access_igmp_initial_join(timer_s *timer)
session->zapping_count = rand() % g_ctx->config.igmp_zap_count;
}
/* Adding 1 nanosecond to enforce a dedicated timer bucket for zapping. */
timer_add_periodic(&g_ctx->timer_root, &session->timer_zapping, "IGMP Zapping", g_ctx->config.igmp_zap_interval, 1, session, &bbl_access_igmp_zapping);
/* Adding 2 nanoseconds to enforce a dedicated timer bucket for zapping. */
timer_add_periodic(&g_ctx->timer_root, &session->timer_zapping, "IGMP Zapping", g_ctx->config.igmp_zap_interval, 2, session, &bbl_access_igmp_zapping);
LOG(IGMP, "IGMP (ID: %u) ZAPPING start zapping with interval %u\n",
session->session_id, g_ctx->config.igmp_zap_interval);
timer_smear_bucket(&g_ctx->timer_root, g_ctx->config.igmp_zap_interval, 1);
timer_smear_bucket(&g_ctx->timer_root, g_ctx->config.igmp_zap_interval, 2);
}
}
+50 -9
View File
@@ -1315,7 +1315,8 @@ json_parse_isis_config(json_t *isis, isis_config_s *isis_config)
json_t *sub, *con, *c, *value = NULL;
const char *s = NULL;
int i, size;
double number;
isis_external_connection_s *connection = NULL;
const char *schema[] = {
@@ -1447,7 +1448,12 @@ json_parse_isis_config(json_t *isis, isis_config_s *isis_config)
value = json_object_get(isis, "hello-interval");
if(json_is_number(value)) {
isis_config->hello_interval = json_number_value(value);
number = json_number_value(value);
if(number < 1 || number > UINT16_MAX) {
fprintf(stderr, "JSON config error: Invalid value for isis->hello-interval (1 - 65535)\n");
return false;
}
isis_config->hello_interval = number;
} else {
isis_config->hello_interval = ISIS_DEFAULT_HELLO_INTERVAL;
}
@@ -1459,49 +1465,84 @@ json_parse_isis_config(json_t *isis, isis_config_s *isis_config)
value = json_object_get(isis, "hold-time");
if(json_is_number(value)) {
isis_config->hold_time = json_number_value(value);
number = json_number_value(value);
if(number < 1 || number > UINT16_MAX) {
fprintf(stderr, "JSON config error: Invalid value for isis->hold-time (1 - 65535)\n");
return false;
}
isis_config->hold_time = number;
} else {
isis_config->hold_time = ISIS_DEFAULT_HOLD_TIME;
}
value = json_object_get(isis, "lsp-lifetime");
if(json_is_number(value)) {
isis_config->lsp_lifetime = json_number_value(value);
number = json_number_value(value);
if(number < ISIS_DEFAULT_LSP_LIFETIME_MIN || number > ISIS_DEFAULT_LSP_LIFETIME) {
fprintf(stderr, "JSON config error: Invalid value for isis->lsp-lifetime (330 - 65535)\n");
return false;
}
isis_config->lsp_lifetime = number;
} else {
isis_config->lsp_lifetime = ISIS_DEFAULT_LSP_LIFETIME;
}
value = json_object_get(isis, "lsp-refresh-interval");
if(json_is_number(value)) {
isis_config->lsp_refresh_interval = json_number_value(value);
number = json_number_value(value);
if(number < 1 || number > UINT16_MAX) {
fprintf(stderr, "JSON config error: Invalid value for isis->lsp-refresh-interval (1 - 65535)\n");
return false;
}
isis_config->lsp_refresh_interval = number;
} else {
isis_config->lsp_refresh_interval = ISIS_DEFAULT_LSP_REFRESH_IVL;
}
value = json_object_get(isis, "lsp-retry-interval");
if(json_is_number(value)) {
isis_config->lsp_retry_interval = json_number_value(value);
number = json_number_value(value);
if(number < 1 || number > UINT16_MAX) {
fprintf(stderr, "JSON config error: Invalid value for isis->lsp-retry-interval (1 - 65535)\n");
return false;
}
isis_config->lsp_retry_interval = number;
} else {
isis_config->lsp_retry_interval = ISIS_DEFAULT_LSP_RETRY_IVL;
}
value = json_object_get(isis, "lsp-tx-interval");
if(json_is_number(value)) {
isis_config->lsp_tx_interval = json_number_value(value);
number = json_number_value(value);
if(number < 1 || number > UINT16_MAX) {
fprintf(stderr, "JSON config error: Invalid value for isis->lsp-tx-interval (1 - 65535)\n");
return false;
}
isis_config->lsp_tx_interval = number;
} else {
isis_config->lsp_tx_interval = ISIS_DEFAULT_LSP_TX_IVL_MS;
}
value = json_object_get(isis, "lsp-tx-window-size");
if(json_is_number(value)) {
isis_config->lsp_tx_window_size = json_number_value(value);
number = json_number_value(value);
if(number < 1 || number > UINT16_MAX) {
fprintf(stderr, "JSON config error: Invalid value for isis->lsp-tx-window-size (1 - 65535)\n");
return false;
}
isis_config->lsp_tx_window_size = number;
} else {
isis_config->lsp_tx_window_size = ISIS_DEFAULT_LSP_WINDOWS_SIZE;
}
value = json_object_get(isis, "csnp-interval");
if(json_is_number(value)) {
isis_config->csnp_interval = json_number_value(value);
number = json_number_value(value);
if(number < 1 || number > UINT16_MAX) {
fprintf(stderr, "JSON config error: Invalid value for isis->csnp-interval (1 - 65535)\n");
return false;
}
isis_config->csnp_interval = number;
} else {
isis_config->csnp_interval = ISIS_DEFAULT_CSNP_INTERVAL;
}
+1 -1
View File
@@ -76,7 +76,7 @@ isis_init() {
}
if(config->external_mrt_file) {
if(!isis_mrt_load(instance, config->external_mrt_file)) {
if(!isis_mrt_load(instance, config->external_mrt_file, true)) {
LOG(ISIS, "Failed to load MRT file %s\n", config->external_mrt_file);
return false;
}
+46 -31
View File
@@ -78,37 +78,52 @@ isis_csnp_job(timer_s *timer)
while(next) {
lsp = *hb_itor_datum(itor);
/* Calculate remaining lifetime and ignore if already expired. */
timespec_sub(&ago, &now, &lsp->timestamp);
if(ago.tv_sec < lsp->lifetime) {
remaining_lifetime = lsp->lifetime - ago.tv_sec;
if(tlv->len > UINT8_MAX-ISIS_LSP_ENTRY_LEN) {
/* Open next LSP entry TLV */
if(pdu.pdu_len+sizeof(isis_tlv_s)+ISIS_LSP_ENTRY_LEN > ISIS_MAX_PDU_LEN) {
adjacency->csnp_start = lsp->id;
break;
}
tlv = (isis_tlv_s *)PDU_CURSOR(&pdu);
tlv->type = ISIS_TLV_LSP_ENTRIES;
tlv->len = 0;
PDU_BUMP_WRITE_BUFFER(&pdu, sizeof(isis_tlv_s));
} else {
if(pdu.pdu_len+ISIS_LSP_ENTRY_LEN > ISIS_MAX_PDU_LEN) {
/* All entries do not fit into single CSNP. */
adjacency->csnp_start = lsp->id;
break;
}
}
tlv->len+=sizeof(isis_lsp_entry_s);
entry = (isis_lsp_entry_s *)PDU_CURSOR(&pdu);
entry->lifetime = htobe16(remaining_lifetime);
entry->lsp_id = htobe64(lsp->id);
entry->seq = htobe32(lsp->seq);
entry->checksum = *(uint16_t*)PDU_OFFSET(&lsp->pdu, ISIS_OFFSET_LSP_CHECKSUM);
PDU_BUMP_WRITE_BUFFER(&pdu, sizeof(isis_lsp_entry_s));
entries++;
if(lsp->deleted) {
/* Ignore deleted LSP. */
next = hb_itor_next(itor);
continue;
}
/* Calculate remaining lifetime. */
timespec_sub(&ago, &now, &lsp->timestamp);
if(lsp->expired || ago.tv_sec >= lsp->lifetime) {
/* Expired! */
remaining_lifetime = 0;
} else {
remaining_lifetime = lsp->lifetime - ago.tv_sec;
}
if(tlv->len > UINT8_MAX-ISIS_LSP_ENTRY_LEN) {
/* Open next LSP entry TLV. */
if(pdu.pdu_len+sizeof(isis_tlv_s)+ISIS_LSP_ENTRY_LEN > ISIS_MAX_PDU_LEN) {
adjacency->csnp_start = lsp->id;
break;
}
tlv = (isis_tlv_s *)PDU_CURSOR(&pdu);
tlv->type = ISIS_TLV_LSP_ENTRIES;
tlv->len = 0;
PDU_BUMP_WRITE_BUFFER(&pdu, sizeof(isis_tlv_s));
} else {
if(pdu.pdu_len+ISIS_LSP_ENTRY_LEN > ISIS_MAX_PDU_LEN) {
/* All entries do not fit into single CSNP. */
adjacency->csnp_start = lsp->id;
break;
}
}
tlv->len+=sizeof(isis_lsp_entry_s);
entry = (isis_lsp_entry_s *)PDU_CURSOR(&pdu);
entry->lsp_id = htobe64(lsp->id);
entry->seq = htobe32(lsp->seq);
if(remaining_lifetime) {
entry->lifetime = htobe16(remaining_lifetime);
entry->checksum = *(uint16_t*)PDU_OFFSET(&lsp->pdu, ISIS_OFFSET_LSP_CHECKSUM);
} else {
entry->lifetime = 0;
entry->checksum = 0;
}
PDU_BUMP_WRITE_BUFFER(&pdu, sizeof(isis_lsp_entry_s));
entries++;
next = hb_itor_next(itor);
}
hb_itor_free(itor);
@@ -127,7 +142,7 @@ isis_csnp_job(timer_s *timer)
}
if(!entries) {
/* Do not send empty PSNP. */
/* Do not send empty CSNP. */
return;
}
+11 -4
View File
@@ -135,11 +135,18 @@ isis_ctrl_database_entries(hb_tree *lsdb)
database = json_array();
while(next) {
lsp = *hb_itor_datum(itor);
if(lsp->deleted) {
/* Ignore deleted LSP. */
next = hb_itor_next(itor);
continue;
}
timespec_sub(&ago, &now, &lsp->timestamp);
if(ago.tv_sec < lsp->lifetime) {
remaining_lifetime = lsp->lifetime - ago.tv_sec;
} else {
if(lsp->expired || ago.tv_sec >= lsp->lifetime) {
remaining_lifetime = 0;
} else {
remaining_lifetime = lsp->lifetime - ago.tv_sec;
}
if(lsp->source.adjacency) {
@@ -253,7 +260,7 @@ isis_ctrl_load_mrt(int fd, uint32_t session_id __attribute__((unused)), json_t *
return bbl_ctrl_status(fd, "error", 404, "ISIS instance not found");
}
if(!isis_mrt_load(instance, file_path)) {
if(!isis_mrt_load(instance, file_path, false)) {
return bbl_ctrl_status(fd, "error", 500, "failed to load ISIS MRT file");
}
return bbl_ctrl_status(fd, "ok", 200, NULL);
+2 -1
View File
@@ -63,6 +63,7 @@
#define ISIS_DEFAULT_HELLO_INTERVAL 10
#define ISIS_DEFAULT_CSNP_INTERVAL 30
#define ISIS_DEFAULT_HOLD_TIME 30
#define ISIS_DEFAULT_LSP_LIFETIME_MIN 330
#define ISIS_DEFAULT_LSP_LIFETIME 65535
#define ISIS_DEFAULT_LSP_RETRY_IVL 5
#define ISIS_DEFAULT_LSP_REFRESH_IVL 300
@@ -70,7 +71,6 @@
#define ISIS_DEFAULT_LSP_WINDOWS_SIZE 1
#define ISIS_DEFAULT_TEARDOWN_TIME 5
#define ISIS_DEFAULT_PURGE_LIFETIME 0
#define ISIS_LSP_GC_INTERVAL 30
@@ -364,6 +364,7 @@ typedef struct isis_lsp_ {
uint32_t refcount;
bool expired;
bool deleted;
uint32_t seq; /* Sequence number */
uint16_t lifetime; /* Remaining lifetime */
+90 -44
View File
@@ -207,6 +207,45 @@ isis_lsp_retry_job(timer_s *timer)
}
}
void
isis_lsp_purge_job(timer_s *timer)
{
isis_lsp_s *lsp = timer->data;
lsp->expired = true;
lsp->deleted = true;
}
void
isis_lsp_lifetime_job(timer_s *timer)
{
isis_lsp_s *lsp = timer->data;
lsp->expired = true;
LOG(ISIS, "ISIS %s-LSP %s (source %s seq %u) lifetime expired (%us)\n",
isis_level_string(lsp->level),
isis_lsp_id_to_str(&lsp->id),
isis_source_string(lsp->source.type),
lsp->seq, lsp->lifetime);
}
void
isis_lsp_lifetime(isis_lsp_s *lsp)
{
timer_del(lsp->timer_refresh);
if(lsp->lifetime > 0) {
timer_add(&g_ctx->timer_root,
&lsp->timer_lifetime,
"ISIS LIFETIME", lsp->lifetime, 0, lsp,
&isis_lsp_lifetime_job);
} else {
timer_add(&g_ctx->timer_root,
&lsp->timer_lifetime,
"ISIS PURGE", 60, 0, lsp,
&isis_lsp_purge_job);
}
timer_no_smear(lsp->timer_lifetime);
}
void
isis_lsp_refresh(isis_lsp_s *lsp)
{
@@ -214,11 +253,6 @@ isis_lsp_refresh(isis_lsp_s *lsp)
lsp->seq++;
lsp->expired = false;
timer_add(&g_ctx->timer_root,
&lsp->timer_lifetime,
"ISIS LIFETIME", lsp->lifetime, 0, lsp,
&isis_lsp_lifetime_job);
timer_no_smear(lsp->timer_lifetime);
*(uint32_t*)PDU_OFFSET(&lsp->pdu, ISIS_OFFSET_LSP_SEQ) = htobe32(lsp->seq);
clock_gettime(CLOCK_MONOTONIC, &lsp->timestamp);
@@ -236,19 +270,6 @@ isis_lsp_refresh_job(timer_s *timer)
isis_lsp_refresh(lsp);
}
void
isis_lsp_lifetime_job(timer_s *timer)
{
isis_lsp_s *lsp = timer->data;
LOG(ISIS, "ISIS %s-LSP %s (seq %u) lifetime expired\n",
isis_level_string(lsp->level),
isis_lsp_id_to_str(&lsp->id),
lsp->seq);
lsp->expired = true;
}
void
isis_lsp_sx_job(timer_s *timer)
{
@@ -336,7 +357,9 @@ isis_lsp_final(isis_lsp_s *lsp)
isis_pdu_update_len(pdu);
isis_pdu_update_auth(pdu, lsp->auth_key);
isis_pdu_update_lifetime(pdu, lsp->lifetime);
isis_pdu_update_checksum(pdu);
if(lsp->lifetime > 0) {
isis_pdu_update_checksum(pdu);
}
}
static isis_lsp_s *
@@ -348,6 +371,7 @@ isis_lsp_fragment(isis_instance_s *instance, uint8_t level, uint8_t fragment, bo
isis_pdu_s *pdu = NULL;
uint64_t lsp_id = htobe64(fragment);
uint16_t refresh_interval = 0;
hb_tree *lsdb;
void **search = NULL;
@@ -384,12 +408,17 @@ isis_lsp_fragment(isis_instance_s *instance, uint8_t level, uint8_t fragment, bo
clock_gettime(CLOCK_MONOTONIC, &lsp->timestamp);
if(purge || instance->teardown) {
lsp->lifetime = ISIS_DEFAULT_PURGE_LIFETIME;
timer_del(lsp->timer_refresh);
lsp->lifetime = 0;
isis_lsp_lifetime(lsp);
} else {
lsp->lifetime = config->lsp_lifetime;
refresh_interval = lsp->lifetime - 300;
if(config->lsp_refresh_interval < refresh_interval) {
refresh_interval = config->lsp_refresh_interval;
}
timer_del(lsp->timer_lifetime);
timer_add_periodic(&g_ctx->timer_root, &lsp->timer_refresh,
"ISIS LSP refresh", config->lsp_refresh_interval, 0, lsp,
"ISIS LSP REFRESH", refresh_interval, 3, lsp,
&isis_lsp_refresh_job);
}
@@ -609,6 +638,8 @@ isis_lsp_handler_rx(bbl_network_interface_s *interface, isis_pdu_s *pdu, uint8_t
/* Per default we will not overwrite
* external LSP. */
if(config->external_auto_refresh) {
/* With external-auto-refresh enabled,
* the sequence number will be increased. */
lsp->seq = seq;
isis_lsp_refresh(lsp);
}
@@ -647,12 +678,7 @@ isis_lsp_handler_rx(bbl_network_interface_s *interface, isis_pdu_s *pdu, uint8_t
PDU_CURSOR_RST(pdu);
memcpy(&lsp->pdu, pdu, sizeof(isis_pdu_s));
timer_add(&g_ctx->timer_root,
&lsp->timer_lifetime,
"ISIS LIFETIME", lsp->lifetime, 0, lsp,
&isis_lsp_lifetime_job);
timer_no_smear(lsp->timer_lifetime);
isis_lsp_lifetime(lsp);
isis_lsp_flood(lsp);
ACK:
@@ -704,10 +730,12 @@ isis_lsp_purge_external(isis_instance_s *instance, uint8_t level)
lsp = *hb_itor_datum(itor);
if(lsp && lsp->source.type == ISIS_SOURCE_EXTERNAL) {
lsp->seq++;
lsp->lifetime = ISIS_DEFAULT_PURGE_LIFETIME;
lsp->timestamp.tv_sec = now.tv_sec;
lsp->timestamp.tv_nsec = now.tv_nsec;
timer_del(lsp->timer_refresh);
lsp->lifetime = 0;
lsp->expired = true;
isis_lsp_lifetime(lsp);
/* Build PDU */
pdu = &lsp->pdu;
@@ -721,7 +749,7 @@ isis_lsp_purge_external(isis_instance_s *instance, uint8_t level)
lsp->auth_key = config->level2_key;
}
/* PDU header */
/* PDU header. */
isis_pdu_add_u16(pdu, 0);
isis_pdu_add_u16(pdu, 0);
isis_pdu_add_u64(pdu, lsp->id);
@@ -729,14 +757,17 @@ isis_lsp_purge_external(isis_instance_s *instance, uint8_t level)
isis_pdu_add_u16(pdu, 0);
isis_pdu_add_u8(pdu, 0x03);
/* TLV section */
/* TLV section. */
isis_pdu_add_tlv_auth(pdu, auth_type, lsp->auth_key);
/* Update checksum... */
/* Update length and authentication. */
isis_pdu_update_len(pdu);
isis_pdu_update_auth(pdu, lsp->auth_key);
isis_pdu_update_lifetime(pdu, lsp->lifetime);
isis_pdu_update_checksum(pdu);
/* Set checksum and lifetime to zero. */
*(uint16_t*)PDU_OFFSET(pdu, ISIS_OFFSET_LSP_LIFETIME) = 0;
*(uint16_t*)PDU_OFFSET(pdu, ISIS_OFFSET_LSP_CHECKSUM) = 0;
isis_lsp_flood(lsp);
}
next = hb_itor_next(itor);
@@ -752,10 +783,12 @@ isis_lsp_purge_external(isis_instance_s *instance, uint8_t level)
bool
isis_lsp_update_external(isis_instance_s *instance, isis_pdu_s *pdu)
{
uint8_t level;
isis_lsp_s *lsp = NULL;
uint64_t lsp_id;
uint32_t seq;
uint8_t level;
uint64_t lsp_id;
uint32_t seq;
uint16_t refresh_interval = 0;
hb_tree *lsdb;
void **search = NULL;
@@ -772,7 +805,7 @@ isis_lsp_update_external(isis_instance_s *instance, isis_pdu_s *pdu)
lsp_id = be64toh(*(uint64_t*)PDU_OFFSET(pdu, ISIS_OFFSET_LSP_ID));
seq = be32toh(*(uint32_t*)PDU_OFFSET(pdu, ISIS_OFFSET_LSP_SEQ));
LOG(DEBUG, "ISIS UPDATE %s-LSP %s (seq %u) from command\n",
LOG(ISIS, "ISIS UPDATE %s-LSP %s (seq %u) from command\n",
isis_level_string(level),
isis_lsp_id_to_str(&lsp_id),
seq);
@@ -807,11 +840,24 @@ isis_lsp_update_external(isis_instance_s *instance, isis_pdu_s *pdu)
PDU_CURSOR_RST(pdu);
memcpy(&lsp->pdu, pdu, sizeof(isis_pdu_s));
timer_add(&g_ctx->timer_root,
&lsp->timer_lifetime,
"ISIS LIFETIME", lsp->lifetime, 0, lsp,
&isis_lsp_lifetime_job);
timer_no_smear(lsp->timer_lifetime);
if(lsp->lifetime > 0 && instance->config->external_auto_refresh) {
if(level == ISIS_LEVEL_1) {
lsp->auth_key = instance->config->level1_key;
} else {
lsp->auth_key = instance->config->level2_key;
}
if(lsp->lifetime < ISIS_DEFAULT_LSP_LIFETIME_MIN) {
/* Increase ISIS lifetime. */
lsp->lifetime = ISIS_DEFAULT_LSP_LIFETIME_MIN;
isis_lsp_refresh(lsp);
}
refresh_interval = lsp->lifetime - 300;
timer_add_periodic(&g_ctx->timer_root, &lsp->timer_refresh,
"ISIS LSP REFRESH", refresh_interval, 3, lsp,
&isis_lsp_refresh_job);
} else {
isis_lsp_lifetime(lsp);
}
isis_lsp_flood(lsp);
return true;
+4 -1
View File
@@ -24,11 +24,14 @@ isis_lsp_gc_job(timer_s *timer);
void
isis_lsp_retry_job(timer_s *timer);
void
isis_lsp_refresh(isis_lsp_s *lsp);
void
isis_lsp_refresh_job(timer_s *timer);
void
isis_lsp_lifetime_job(timer_s *timer);
isis_lsp_lifetime(isis_lsp_s *lsp);
void
isis_lsp_sx_job(timer_s *timer);
+17 -11
View File
@@ -9,7 +9,7 @@
#include "isis.h"
bool
isis_mrt_load(isis_instance_s *instance, char *file_path)
isis_mrt_load(isis_instance_s *instance, char *file_path, bool startup)
{
FILE *mrt_file;
@@ -21,6 +21,7 @@ isis_mrt_load(isis_instance_s *instance, char *file_path)
isis_lsp_s *lsp = NULL;
uint64_t lsp_id;
uint32_t seq;
uint16_t refresh_interval = 0;
hb_tree *lsdb;
void **search = NULL;
@@ -117,26 +118,31 @@ isis_mrt_load(isis_instance_s *instance, char *file_path)
PDU_CURSOR_RST(&pdu);
memcpy(&lsp->pdu, &pdu, sizeof(isis_pdu_s));
if(instance->config->external_auto_refresh) {
if(lsp->lifetime > 0 && instance->config->external_auto_refresh) {
if(level == ISIS_LEVEL_1) {
lsp->auth_key = instance->config->level1_key;
} else {
lsp->auth_key = instance->config->level2_key;
}
if(lsp->lifetime < 330) {
lsp->lifetime = 300;
if(lsp->lifetime < ISIS_DEFAULT_LSP_LIFETIME_MIN) {
/* Increase ISIS lifetime. */
lsp->lifetime = ISIS_DEFAULT_LSP_LIFETIME_MIN;
isis_lsp_refresh(lsp);
}
refresh_interval = lsp->lifetime - 300;
timer_add_periodic(&g_ctx->timer_root, &lsp->timer_refresh,
"ISIS LSP refresh", lsp->lifetime - 300, 0, lsp,
"ISIS LSP REFRESH", refresh_interval, 3, lsp,
&isis_lsp_refresh_job);
} else {
isis_lsp_lifetime(lsp);
}
timer_add(&g_ctx->timer_root,
&lsp->timer_lifetime,
"ISIS LIFETIME", lsp->lifetime, 0, lsp,
&isis_lsp_lifetime_job);
timer_no_smear(lsp->timer_lifetime);
}
if(startup && refresh_interval) {
/* Adding 3 nanoseconds to enforce a dedicated timer bucket. */
timer_smear_bucket(&g_ctx->timer_root, refresh_interval, 3);
}
fclose(mrt_file);
return true;
}
+1 -1
View File
@@ -19,6 +19,6 @@ typedef struct isis_mrt_hdr_ {
} __attribute__ ((__packed__)) isis_mrt_hdr_t;
bool
isis_mrt_load(isis_instance_s *instance, char *file_path);
isis_mrt_load(isis_instance_s *instance, char *file_path, bool startup);
#endif
+9 -6
View File
@@ -207,13 +207,16 @@ isis_p2p_hello_handler_rx(bbl_network_interface_s *interface, isis_pdu_s *pdu)
}
}
if(adjacency->state != new_state && new_state == ISIS_P2P_ADJACENCY_STATE_UP) {
for(int i=0; i<ISIS_LEVELS; i++) {
if(interface->isis_adjacency[i]) {
isis_adjacency_up(interface->isis_adjacency[i]);
isis_lsp_self_update(adjacency->instance, i+1);
if(adjacency->state != new_state) {
interface->send_requests |= BBL_IF_SEND_ISIS_P2P_HELLO;
if(new_state == ISIS_P2P_ADJACENCY_STATE_UP) {
for(int i=0; i<ISIS_LEVELS; i++) {
if(interface->isis_adjacency[i]) {
isis_adjacency_up(interface->isis_adjacency[i]);
isis_lsp_self_update(adjacency->instance, i+1);
}
}
}
adjacency->state = new_state;
}
adjacency->state = new_state;
}
+9 -7
View File
@@ -231,17 +231,19 @@ isis_pdu_update_auth(isis_pdu_s *pdu, char *key)
bool
isis_pdu_validate_checksum(isis_pdu_s *pdu)
{
uint16_t checksum;
uint16_t checksum_orig;
uint16_t checksum = 0;
uint16_t checksum_orig = 0;
switch (pdu->pdu_type) {
switch(pdu->pdu_type) {
case ISIS_PDU_L1_LSP:
case ISIS_PDU_L2_LSP:
checksum_orig = *(uint16_t*)PDU_OFFSET(pdu, ISIS_OFFSET_LSP_CHECKSUM);
checksum = isis_checksum_fletcher16(
pdu->pdu+ISIS_OFFSET_LSP_ID,
pdu->pdu_len-ISIS_OFFSET_LSP_ID,
ISIS_OFFSET_LSP_CHECKSUM-ISIS_OFFSET_LSP_ID);
if(checksum_orig > 0) {
checksum = isis_checksum_fletcher16(
pdu->pdu+ISIS_OFFSET_LSP_ID,
pdu->pdu_len-ISIS_OFFSET_LSP_ID,
ISIS_OFFSET_LSP_CHECKSUM-ISIS_OFFSET_LSP_ID);
}
break;
default:
return true;
+42 -32
View File
@@ -70,39 +70,49 @@ isis_psnp_job (timer_s *timer)
lsp = *search;
hb_tree_remove(adjacency->psnp_tree, &lsp->id);
/* Calculate remaining lifetime and ignore if already expired. */
timespec_sub(&ago, &now, &lsp->timestamp);
if(ago.tv_sec < lsp->lifetime) {
remaining_lifetime = lsp->lifetime - ago.tv_sec;
if(tlv->len > UINT8_MAX-ISIS_LSP_ENTRY_LEN) {
/* Open next LSP entry TLV */
if(pdu.pdu_len+sizeof(isis_tlv_s)+ISIS_LSP_ENTRY_LEN > ISIS_MAX_PDU_LEN) {
adjacency->csnp_start = lsp->id;
break;
}
tlv = (isis_tlv_s *)PDU_CURSOR(&pdu);
tlv->type = ISIS_TLV_LSP_ENTRIES;
tlv->len = 0;
PDU_BUMP_WRITE_BUFFER(&pdu, sizeof(isis_tlv_s));
} else {
if(pdu.pdu_len+ISIS_LSP_ENTRY_LEN > ISIS_MAX_PDU_LEN) {
/* All entries do not fit into single PSNP. */
adjacency->timer_psnp_started = true;
timer_add(&g_ctx->timer_root, &adjacency->timer_psnp_next,
"ISIS PSNP", 0, 10*MSEC, adjacency, &isis_psnp_job);
break;
}
}
tlv->len+=sizeof(isis_lsp_entry_s);
entry = (isis_lsp_entry_s *)PDU_CURSOR(&pdu);
entry->lifetime = htobe16(remaining_lifetime);
entry->lsp_id = htobe64(lsp->id);
entry->seq = htobe32(lsp->seq);
entry->checksum = *(uint16_t*)PDU_OFFSET(&lsp->pdu, ISIS_OFFSET_LSP_CHECKSUM);
PDU_BUMP_WRITE_BUFFER(&pdu, sizeof(isis_lsp_entry_s));
entries++;
if(lsp->deleted) {
/* Ignore deleted LSP. */
search = hb_tree_search_gt(adjacency->psnp_tree, &lsp_id_zero);
continue;
}
/* Calculate remaining lifetime. */
timespec_sub(&ago, &now, &lsp->timestamp);
if(lsp->expired || ago.tv_sec >= lsp->lifetime) {
/* Expired! */
remaining_lifetime = 0;
} else {
remaining_lifetime = lsp->lifetime - ago.tv_sec;
}
if(tlv->len > UINT8_MAX-ISIS_LSP_ENTRY_LEN) {
/* Open next LSP entry TLV. */
if(pdu.pdu_len+sizeof(isis_tlv_s)+ISIS_LSP_ENTRY_LEN > ISIS_MAX_PDU_LEN) {
adjacency->csnp_start = lsp->id;
break;
}
tlv = (isis_tlv_s *)PDU_CURSOR(&pdu);
tlv->type = ISIS_TLV_LSP_ENTRIES;
tlv->len = 0;
PDU_BUMP_WRITE_BUFFER(&pdu, sizeof(isis_tlv_s));
} else {
if(pdu.pdu_len+ISIS_LSP_ENTRY_LEN > ISIS_MAX_PDU_LEN) {
/* All entries do not fit into single PSNP. */
adjacency->timer_psnp_started = true;
timer_add(&g_ctx->timer_root, &adjacency->timer_psnp_next,
"ISIS PSNP", 0, 10*MSEC, adjacency, &isis_psnp_job);
break;
}
}
tlv->len+=sizeof(isis_lsp_entry_s);
entry = (isis_lsp_entry_s *)PDU_CURSOR(&pdu);
entry->lifetime = htobe16(remaining_lifetime);
entry->lsp_id = htobe64(lsp->id);
entry->seq = htobe32(lsp->seq);
entry->checksum = *(uint16_t*)PDU_OFFSET(&lsp->pdu, ISIS_OFFSET_LSP_CHECKSUM);
PDU_BUMP_WRITE_BUFFER(&pdu, sizeof(isis_lsp_entry_s));
entries++;
search = hb_tree_search_gt(adjacency->psnp_tree, &lsp_id_zero);
}
isis_pdu_update_len(&pdu);