mirror of
https://github.com/rtbrick/bngblaster.git
synced 2024-05-06 15:54:57 +00:00
ISIS LSP flapping
This commit is contained in:
@@ -222,6 +222,8 @@ struct action actions[] = {
|
||||
{"isis-database", isis_ctrl_database, true},
|
||||
{"isis-load-mrt", isis_ctrl_load_mrt, false},
|
||||
{"isis-lsp-update", isis_ctrl_lsp_update, false},
|
||||
{"isis-lsp-purge", isis_ctrl_lsp_purge, false},
|
||||
{"isis-lsp-flap", isis_ctrl_lsp_flap, false},
|
||||
{"isis-teardown", isis_ctrl_teardown, false},
|
||||
{"bgp-sessions", bgp_ctrl_sessions, true},
|
||||
{"bgp-disconnect", bgp_ctrl_disconnect, false},
|
||||
|
||||
@@ -183,7 +183,7 @@ isis_teardown()
|
||||
for(int i=0; i<ISIS_LEVELS; i++) {
|
||||
if(instance->level[i].adjacency) {
|
||||
isis_lsp_self_update(instance, i+1);
|
||||
isis_lsp_purge_external(instance, i+1);
|
||||
isis_lsp_purge_all_external(instance, i+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ isis_adjacency_up(isis_adjacency_s *adjacency)
|
||||
adjacency->state = ISIS_ADJACENCY_STATE_UP;
|
||||
|
||||
timer_add_periodic(&g_ctx->timer_root, &adjacency->timer_tx,
|
||||
"ISIS TX", 0, config->lsp_tx_interval * MSEC, adjacency, &isis_lsp_sx_job);
|
||||
"ISIS TX", 0, config->lsp_tx_interval * MSEC, adjacency, &isis_lsp_tx_job);
|
||||
|
||||
timer_add_periodic(&g_ctx->timer_root, &adjacency->timer_retry,
|
||||
"ISIS RETRY", config->lsp_retry_interval, 0, adjacency, &isis_lsp_retry_job);
|
||||
|
||||
@@ -9,6 +9,37 @@
|
||||
#include "isis.h"
|
||||
#include "../bbl_ctrl.h"
|
||||
|
||||
isis_lsp_flap_s *g_isis_lsp_flap = NULL;
|
||||
|
||||
|
||||
#define ISIS_CTRL_ARG_INSTANCE(_arguments, _fd, _instance_id, _instance) \
|
||||
do { \
|
||||
if(json_unpack(_arguments, "{s:i}", "instance", &_instance_id) != 0) { \
|
||||
return bbl_ctrl_status(_fd, "error", 400, "missing ISIS instance"); \
|
||||
} \
|
||||
/* Search for matching instance */ \
|
||||
_instance = g_ctx->isis_instances; \
|
||||
while(_instance) { \
|
||||
if(_instance->config->id == _instance_id) { \
|
||||
break; \
|
||||
} \
|
||||
_instance = _instance->next; \
|
||||
} \
|
||||
if(!_instance) { \
|
||||
return bbl_ctrl_status(_fd, "error", 404, "ISIS instance not found"); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define ISIS_CTRL_ARG_LEVEL(_arguments, _fd, _level) \
|
||||
do { \
|
||||
if(json_unpack(_arguments, "{s:i}", "level", &_level) != 0) { \
|
||||
return bbl_ctrl_status(_fd, "error", 400, "missing ISIS level"); \
|
||||
} \
|
||||
if(!(_level == ISIS_LEVEL_1 || _level == ISIS_LEVEL_2)) { \
|
||||
return bbl_ctrl_status(_fd, "error", 400, "invalid ISIS level"); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
static json_t *
|
||||
isis_ctrl_adjacency(isis_adjacency_s *adjacency)
|
||||
{
|
||||
@@ -180,36 +211,15 @@ isis_ctrl_database(int fd, uint32_t session_id __attribute__((unused)), json_t *
|
||||
json_t *root = NULL;
|
||||
json_t *database = NULL;
|
||||
isis_instance_s *instance = NULL;
|
||||
|
||||
int instance_id = 0;
|
||||
int level = 0;
|
||||
|
||||
/* Unpack further arguments */
|
||||
if(json_unpack(arguments, "{s:i}", "instance", &instance_id) != 0) {
|
||||
return bbl_ctrl_status(fd, "error", 400, "missing ISIS instance");
|
||||
}
|
||||
if(json_unpack(arguments, "{s:i}", "level", &level) != 0) {
|
||||
return bbl_ctrl_status(fd, "error", 400, "missing ISIS level");
|
||||
}
|
||||
if(!(level == ISIS_LEVEL_1 || level == ISIS_LEVEL_2)) {
|
||||
return bbl_ctrl_status(fd, "error", 400, "invalid ISIS level");
|
||||
}
|
||||
|
||||
/* Search for matching instance */
|
||||
instance = g_ctx->isis_instances;
|
||||
while(instance) {
|
||||
if(instance->config->id == instance_id) {
|
||||
break;
|
||||
}
|
||||
instance = instance->next;
|
||||
}
|
||||
|
||||
if(!instance) {
|
||||
return bbl_ctrl_status(fd, "error", 400, "ISIS instance not found");
|
||||
}
|
||||
ISIS_CTRL_ARG_INSTANCE(arguments, fd, instance_id, instance);
|
||||
ISIS_CTRL_ARG_LEVEL(arguments, fd, level);
|
||||
|
||||
if(!instance->level[level-1].lsdb) {
|
||||
return bbl_ctrl_status(fd, "error", 400, "ISIS database not found");
|
||||
return bbl_ctrl_status(fd, "error", 404, "ISIS database not found");
|
||||
}
|
||||
|
||||
database = isis_ctrl_database_entries(instance->level[level-1].lsdb);
|
||||
@@ -235,31 +245,15 @@ int
|
||||
isis_ctrl_load_mrt(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments)
|
||||
{
|
||||
char *file_path;
|
||||
isis_instance_s *instance = NULL;
|
||||
int instance_id = 0;
|
||||
|
||||
isis_instance_s *instance = NULL;
|
||||
|
||||
/* Unpack further arguments */
|
||||
ISIS_CTRL_ARG_INSTANCE(arguments, fd, instance_id, instance);
|
||||
|
||||
if(json_unpack(arguments, "{s:s}", "file", &file_path) != 0) {
|
||||
return bbl_ctrl_status(fd, "error", 400, "missing MRT file");
|
||||
}
|
||||
if(json_unpack(arguments, "{s:i}", "instance", &instance_id) != 0) {
|
||||
return bbl_ctrl_status(fd, "error", 400, "missing ISIS instance");
|
||||
}
|
||||
|
||||
/* Search for matching instance */
|
||||
instance = g_ctx->isis_instances;
|
||||
while(instance) {
|
||||
if(instance->config->id == instance_id) {
|
||||
break;
|
||||
}
|
||||
instance = instance->next;
|
||||
}
|
||||
|
||||
if(!instance) {
|
||||
return bbl_ctrl_status(fd, "error", 404, "ISIS instance not found");
|
||||
}
|
||||
|
||||
if(!isis_mrt_load(instance, file_path, false)) {
|
||||
return bbl_ctrl_status(fd, "error", 500, "failed to load ISIS MRT file");
|
||||
}
|
||||
@@ -274,35 +268,19 @@ isis_ctrl_lsp_update(int fd, uint32_t session_id __attribute__((unused)), json_t
|
||||
json_t *value;
|
||||
size_t pdu_count;
|
||||
|
||||
int instance_id = 0;
|
||||
isis_instance_s *instance = NULL;
|
||||
|
||||
isis_pdu_s pdu = {0};
|
||||
|
||||
const char *pdu_string;
|
||||
uint16_t pdu_string_len;
|
||||
|
||||
uint8_t buf[ISIS_MAX_PDU_LEN];
|
||||
uint16_t len;
|
||||
|
||||
isis_instance_s *instance = NULL;
|
||||
int instance_id = 0;
|
||||
|
||||
/* Unpack further arguments */
|
||||
if(json_unpack(arguments, "{s:i}", "instance", &instance_id) != 0) {
|
||||
return bbl_ctrl_status(fd, "error", 400, "missing ISIS instance");
|
||||
}
|
||||
|
||||
/* Search for matching instance */
|
||||
instance = g_ctx->isis_instances;
|
||||
while(instance) {
|
||||
if(instance->config->id == instance_id) {
|
||||
break;
|
||||
}
|
||||
instance = instance->next;
|
||||
}
|
||||
|
||||
if(!instance) {
|
||||
return bbl_ctrl_status(fd, "error", 404, "ISIS instance not found");
|
||||
}
|
||||
ISIS_CTRL_ARG_INSTANCE(arguments, fd, instance_id, instance);
|
||||
|
||||
/* Process PDU array */
|
||||
value = json_object_get(arguments, "pdu");
|
||||
@@ -323,7 +301,7 @@ isis_ctrl_lsp_update(int fd, uint32_t session_id __attribute__((unused)), json_t
|
||||
return bbl_ctrl_status(fd, "error", 500, "failed to decode ISIS PDU");
|
||||
}
|
||||
/* Update external LSP */
|
||||
if(!isis_lsp_update_external(instance, &pdu)) {
|
||||
if(!isis_lsp_update_external(instance, &pdu, false)) {
|
||||
return bbl_ctrl_status(fd, "error", 500, "failed to update ISIS LSP");
|
||||
}
|
||||
}
|
||||
@@ -333,6 +311,151 @@ isis_ctrl_lsp_update(int fd, uint32_t session_id __attribute__((unused)), json_t
|
||||
return bbl_ctrl_status(fd, "ok", 200, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
isis_ctrl_lsp_purge(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments)
|
||||
{
|
||||
json_t *value;
|
||||
|
||||
isis_lsp_s *lsp = NULL;
|
||||
uint64_t lsp_id;
|
||||
|
||||
hb_tree *lsdb;
|
||||
void **search = NULL;
|
||||
|
||||
isis_instance_s *instance = NULL;
|
||||
int instance_id = 0;
|
||||
int level = 0;
|
||||
|
||||
/* Unpack further arguments */
|
||||
ISIS_CTRL_ARG_INSTANCE(arguments, fd, instance_id, instance);
|
||||
ISIS_CTRL_ARG_LEVEL(arguments, fd, level);
|
||||
|
||||
if(!instance->level[level-1].lsdb) {
|
||||
return bbl_ctrl_status(fd, "error", 404, "ISIS database not found");
|
||||
}
|
||||
|
||||
value = json_object_get(arguments, "id");
|
||||
if(json_is_string(value)) {
|
||||
if(!isis_str_to_lsp_id(json_string_value(value), &lsp_id)) {
|
||||
return bbl_ctrl_status(fd, "error", 400, "invalid ISIS LSP identifier");
|
||||
}
|
||||
lsdb = instance->level[level-1].lsdb;
|
||||
search = hb_tree_search(lsdb, &lsp_id);
|
||||
if(search) {
|
||||
lsp = *search;
|
||||
if(lsp && lsp->source.type == ISIS_SOURCE_EXTERNAL) {
|
||||
isis_lsp_purge(lsp);
|
||||
} else {
|
||||
return bbl_ctrl_status(fd, "error", 500, "failed to purge ISIS LSP");
|
||||
}
|
||||
} else {
|
||||
return bbl_ctrl_status(fd, "error", 404, "ISIS LSP not found");
|
||||
}
|
||||
} else {
|
||||
return bbl_ctrl_status(fd, "error", 400, "missing ISIS LSP identifier");
|
||||
}
|
||||
return bbl_ctrl_status(fd, "ok", 200, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
isis_ctrl_lsp_flap_job(timer_s *timer)
|
||||
{
|
||||
isis_lsp_flap_s *flap = timer->data;
|
||||
uint32_t seq;
|
||||
|
||||
if(flap) {
|
||||
seq = be32toh(*(uint32_t*)PDU_OFFSET(&flap->pdu, ISIS_OFFSET_LSP_SEQ));
|
||||
*(uint32_t*)PDU_OFFSET(&flap->pdu, ISIS_OFFSET_LSP_SEQ) = htobe32(++seq);
|
||||
|
||||
if(!isis_lsp_update_external(flap->instance, &flap->pdu, true)) {
|
||||
LOG(ISIS, "Failed to flap ISIS LSP %s\n", isis_lsp_id_to_str(&flap->id));
|
||||
}
|
||||
flap->free = true;
|
||||
}
|
||||
}
|
||||
|
||||
static isis_lsp_flap_s *
|
||||
isis_ctrl_lsp_flap_new(isis_lsp_s *lsp)
|
||||
{
|
||||
isis_lsp_flap_s *flap = g_isis_lsp_flap;
|
||||
|
||||
while(flap) {
|
||||
if(flap->free) {
|
||||
break;
|
||||
}
|
||||
flap = flap->next;
|
||||
}
|
||||
if(!flap) {
|
||||
flap = calloc(1, sizeof(isis_lsp_flap_s));
|
||||
flap->next = g_isis_lsp_flap;
|
||||
g_isis_lsp_flap = flap;
|
||||
}
|
||||
|
||||
flap->free = false;
|
||||
flap->timer = NULL;
|
||||
flap->id = lsp->id;
|
||||
flap->instance = lsp->instance;
|
||||
memcpy(&flap->pdu, &lsp->pdu, sizeof(isis_pdu_s));
|
||||
|
||||
return flap;
|
||||
}
|
||||
|
||||
int
|
||||
isis_ctrl_lsp_flap(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments)
|
||||
{
|
||||
json_t *value;
|
||||
|
||||
isis_lsp_s *lsp = NULL;
|
||||
uint64_t lsp_id;
|
||||
|
||||
time_t timer = 30;
|
||||
hb_tree *lsdb;
|
||||
void **search = NULL;
|
||||
|
||||
isis_lsp_flap_s *flap;
|
||||
|
||||
isis_instance_s *instance = NULL;
|
||||
int instance_id = 0;
|
||||
int level = 0;
|
||||
|
||||
/* Unpack further arguments */
|
||||
ISIS_CTRL_ARG_INSTANCE(arguments, fd, instance_id, instance);
|
||||
ISIS_CTRL_ARG_LEVEL(arguments, fd, level);
|
||||
|
||||
if(!instance->level[level-1].lsdb) {
|
||||
return bbl_ctrl_status(fd, "error", 404, "ISIS database not found");
|
||||
}
|
||||
|
||||
value = json_object_get(arguments, "timer");
|
||||
if(json_is_number(value)) {
|
||||
timer = json_number_value(value);
|
||||
}
|
||||
|
||||
value = json_object_get(arguments, "id");
|
||||
if(json_is_string(value)) {
|
||||
if(!isis_str_to_lsp_id(json_string_value(value), &lsp_id)) {
|
||||
return bbl_ctrl_status(fd, "error", 400, "invalid ISIS LSP identifier");
|
||||
}
|
||||
lsdb = instance->level[level-1].lsdb;
|
||||
search = hb_tree_search(lsdb, &lsp_id);
|
||||
if(search) {
|
||||
lsp = *search;
|
||||
if(lsp && lsp->source.type == ISIS_SOURCE_EXTERNAL) {
|
||||
flap = isis_ctrl_lsp_flap_new(lsp);
|
||||
timer_add(&g_ctx->timer_root, &flap->timer, "ISIS FLAP", timer, 0, flap, &isis_ctrl_lsp_flap_job);
|
||||
isis_lsp_purge(lsp);
|
||||
} else {
|
||||
return bbl_ctrl_status(fd, "error", 500, "failed to flap ISIS LSP");
|
||||
}
|
||||
} else {
|
||||
return bbl_ctrl_status(fd, "error", 404, "ISIS LSP not found");
|
||||
}
|
||||
} else {
|
||||
return bbl_ctrl_status(fd, "error", 400, "missing ISIS LSP identifier");
|
||||
}
|
||||
return bbl_ctrl_status(fd, "ok", 200, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
isis_ctrl_teardown(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments __attribute__((unused)))
|
||||
{
|
||||
|
||||
@@ -21,6 +21,12 @@ isis_ctrl_load_mrt(int fd, uint32_t session_id __attribute__((unused)), json_t *
|
||||
int
|
||||
isis_ctrl_lsp_update(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments);
|
||||
|
||||
int
|
||||
isis_ctrl_lsp_purge(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments);
|
||||
|
||||
int
|
||||
isis_ctrl_lsp_flap(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments);
|
||||
|
||||
int
|
||||
isis_ctrl_teardown(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments __attribute__((unused)));
|
||||
|
||||
|
||||
@@ -382,4 +382,16 @@ typedef struct isis_flood_entry_ {
|
||||
struct timespec tx_timestamp;
|
||||
} isis_flood_entry_s;
|
||||
|
||||
typedef struct isis_lsp_flap_ {
|
||||
uint64_t id; /* LSP-ID */
|
||||
|
||||
isis_instance_s *instance;
|
||||
isis_pdu_s pdu;
|
||||
|
||||
bool free;
|
||||
struct timer_ *timer;
|
||||
|
||||
struct isis_lsp_flap_ *next;
|
||||
} isis_lsp_flap_s;
|
||||
|
||||
#endif
|
||||
@@ -148,7 +148,6 @@ void
|
||||
isis_lsp_gc_job(timer_s *timer)
|
||||
{
|
||||
isis_instance_s *instance = timer->data;
|
||||
|
||||
isis_lsp_s *lsp;
|
||||
hb_itor *itor;
|
||||
bool next;
|
||||
@@ -277,7 +276,7 @@ isis_lsp_refresh_job(timer_s *timer)
|
||||
}
|
||||
|
||||
void
|
||||
isis_lsp_sx_job(timer_s *timer)
|
||||
isis_lsp_tx_job(timer_s *timer)
|
||||
{
|
||||
isis_adjacency_s *adjacency = timer->data;
|
||||
isis_flood_entry_s *entry;
|
||||
@@ -703,77 +702,87 @@ ACK:
|
||||
}
|
||||
|
||||
/**
|
||||
* isis_lsp_purge_external
|
||||
* isis_lsp_purge
|
||||
*
|
||||
* @param lsp ISIS LSP
|
||||
*/
|
||||
void
|
||||
isis_lsp_purge(isis_lsp_s *lsp)
|
||||
{
|
||||
isis_pdu_s *pdu;
|
||||
isis_auth_type auth_type = ISIS_AUTH_NONE;
|
||||
|
||||
isis_config_s *config = lsp->instance->config;
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
lsp->seq++;
|
||||
lsp->timestamp.tv_sec = now.tv_sec;
|
||||
lsp->timestamp.tv_nsec = now.tv_nsec;
|
||||
|
||||
lsp->lifetime = 0;
|
||||
isis_lsp_lifetime(lsp);
|
||||
|
||||
/* Build PDU */
|
||||
pdu = &lsp->pdu;
|
||||
if(lsp->level == ISIS_LEVEL_1) {
|
||||
isis_pdu_init(pdu, ISIS_PDU_L1_LSP);
|
||||
auth_type = config->level1_auth;
|
||||
lsp->auth_key = config->level1_key;
|
||||
} else {
|
||||
isis_pdu_init(pdu, ISIS_PDU_L2_LSP);
|
||||
auth_type = config->level2_auth;
|
||||
lsp->auth_key = config->level2_key;
|
||||
}
|
||||
|
||||
/* PDU header. */
|
||||
isis_pdu_add_u16(pdu, 0);
|
||||
isis_pdu_add_u16(pdu, 0);
|
||||
isis_pdu_add_u64(pdu, lsp->id);
|
||||
isis_pdu_add_u32(pdu, lsp->seq);
|
||||
isis_pdu_add_u16(pdu, 0);
|
||||
isis_pdu_add_u8(pdu, 0x03);
|
||||
|
||||
/* TLV section. */
|
||||
isis_pdu_add_tlv_auth(pdu, auth_type, lsp->auth_key);
|
||||
|
||||
/* Update length and authentication. */
|
||||
isis_pdu_update_len(pdu);
|
||||
isis_pdu_update_auth(pdu, lsp->auth_key);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* isis_lsp_purge_all_external
|
||||
*
|
||||
* @param instance ISIS instance
|
||||
* @param level ISIS level
|
||||
*/
|
||||
void
|
||||
isis_lsp_purge_external(isis_instance_s *instance, uint8_t level)
|
||||
isis_lsp_purge_all_external(isis_instance_s *instance, uint8_t level)
|
||||
{
|
||||
isis_config_s *config = instance->config;
|
||||
hb_tree *lsdb = instance->level[level-1].lsdb;
|
||||
|
||||
isis_lsp_s *lsp;
|
||||
hb_itor *itor;
|
||||
bool next;
|
||||
|
||||
isis_pdu_s *pdu;
|
||||
isis_auth_type auth_type = ISIS_AUTH_NONE;
|
||||
|
||||
struct timespec now;
|
||||
|
||||
if(!lsdb) {
|
||||
return;
|
||||
}
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
itor = hb_itor_new(lsdb);
|
||||
next = hb_itor_first(itor);
|
||||
|
||||
while(next) {
|
||||
lsp = *hb_itor_datum(itor);
|
||||
if(lsp && lsp->source.type == ISIS_SOURCE_EXTERNAL) {
|
||||
lsp->seq++;
|
||||
lsp->timestamp.tv_sec = now.tv_sec;
|
||||
lsp->timestamp.tv_nsec = now.tv_nsec;
|
||||
|
||||
lsp->lifetime = 0;
|
||||
isis_lsp_lifetime(lsp);
|
||||
|
||||
/* Build PDU */
|
||||
pdu = &lsp->pdu;
|
||||
if(level == ISIS_LEVEL_1) {
|
||||
isis_pdu_init(pdu, ISIS_PDU_L1_LSP);
|
||||
auth_type = config->level1_auth;
|
||||
lsp->auth_key = config->level1_key;
|
||||
} else {
|
||||
isis_pdu_init(pdu, ISIS_PDU_L2_LSP);
|
||||
auth_type = config->level2_auth;
|
||||
lsp->auth_key = config->level2_key;
|
||||
}
|
||||
|
||||
/* PDU header. */
|
||||
isis_pdu_add_u16(pdu, 0);
|
||||
isis_pdu_add_u16(pdu, 0);
|
||||
isis_pdu_add_u64(pdu, lsp->id);
|
||||
isis_pdu_add_u32(pdu, lsp->seq);
|
||||
isis_pdu_add_u16(pdu, 0);
|
||||
isis_pdu_add_u8(pdu, 0x03);
|
||||
|
||||
/* TLV section. */
|
||||
isis_pdu_add_tlv_auth(pdu, auth_type, lsp->auth_key);
|
||||
|
||||
/* Update length and authentication. */
|
||||
isis_pdu_update_len(pdu);
|
||||
isis_pdu_update_auth(pdu, lsp->auth_key);
|
||||
|
||||
/* 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);
|
||||
isis_lsp_purge(lsp);
|
||||
}
|
||||
next = hb_itor_next(itor);
|
||||
}
|
||||
@@ -784,9 +793,10 @@ isis_lsp_purge_external(isis_instance_s *instance, uint8_t level)
|
||||
*
|
||||
* @param instance ISIS instance
|
||||
* @param pdu received ISIS PDU
|
||||
* @param refresh automatically refresh LSP
|
||||
*/
|
||||
bool
|
||||
isis_lsp_update_external(isis_instance_s *instance, isis_pdu_s *pdu)
|
||||
isis_lsp_update_external(isis_instance_s *instance, isis_pdu_s *pdu, bool refresh)
|
||||
{
|
||||
uint8_t level;
|
||||
|
||||
@@ -854,7 +864,8 @@ isis_lsp_update_external(isis_instance_s *instance, isis_pdu_s *pdu)
|
||||
if(lsp->lifetime < ISIS_DEFAULT_LSP_LIFETIME_MIN) {
|
||||
/* Increase ISIS lifetime. */
|
||||
lsp->lifetime = ISIS_DEFAULT_LSP_LIFETIME_MIN;
|
||||
isis_lsp_refresh(lsp);
|
||||
isis_lsp_refresh(lsp);
|
||||
refresh = false;
|
||||
}
|
||||
refresh_interval = lsp->lifetime - 300;
|
||||
timer_add_periodic(&g_ctx->timer_root, &lsp->timer_refresh,
|
||||
@@ -864,6 +875,10 @@ isis_lsp_update_external(isis_instance_s *instance, isis_pdu_s *pdu)
|
||||
isis_lsp_lifetime(lsp);
|
||||
}
|
||||
|
||||
isis_lsp_flood(lsp);
|
||||
if(refresh) {
|
||||
isis_lsp_refresh(lsp);
|
||||
} else {
|
||||
isis_lsp_flood(lsp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -34,7 +34,7 @@ void
|
||||
isis_lsp_lifetime(isis_lsp_s *lsp);
|
||||
|
||||
void
|
||||
isis_lsp_sx_job(timer_s *timer);
|
||||
isis_lsp_tx_job(timer_s *timer);
|
||||
|
||||
isis_lsp_s *
|
||||
isis_lsp_new(uint64_t id, uint8_t level, isis_instance_s *instance);
|
||||
@@ -46,9 +46,12 @@ void
|
||||
isis_lsp_handler_rx(bbl_network_interface_s *interface, isis_pdu_s *pdu, uint8_t level);
|
||||
|
||||
void
|
||||
isis_lsp_purge_external(isis_instance_s *instance, uint8_t level);
|
||||
isis_lsp_purge(isis_lsp_s *lsp);
|
||||
|
||||
void
|
||||
isis_lsp_purge_all_external(isis_instance_s *instance, uint8_t level);
|
||||
|
||||
bool
|
||||
isis_lsp_update_external(isis_instance_s *instance, isis_pdu_s *pdu);
|
||||
isis_lsp_update_external(isis_instance_s *instance, isis_pdu_s *pdu, bool refresh);
|
||||
|
||||
#endif
|
||||
@@ -197,6 +197,30 @@ isis_system_id_to_str(uint8_t *system_id)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* isis_str_to_lsp_id
|
||||
*
|
||||
* @param str IS-IS lsp-id string
|
||||
* @param lsp_id IS-IS lsp-id (8 bytes)
|
||||
* @return true if successful
|
||||
*/
|
||||
bool
|
||||
isis_str_to_lsp_id(const char *str, uint64_t *lsp_id)
|
||||
{
|
||||
sscanf(str, "%hx.%hx.%hx.%hhx-%hhx",
|
||||
&((uint16_t*)lsp_id)[3],
|
||||
&((uint16_t*)lsp_id)[2],
|
||||
&((uint16_t*)lsp_id)[1],
|
||||
&((uint8_t*)lsp_id)[1],
|
||||
&((uint8_t*)lsp_id)[0]);
|
||||
|
||||
((uint16_t*)lsp_id)[3] = ((uint16_t*)lsp_id)[3];
|
||||
((uint16_t*)lsp_id)[2] = ((uint16_t*)lsp_id)[2];
|
||||
((uint16_t*)lsp_id)[1] = ((uint16_t*)lsp_id)[1];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* isis_lsp_id_to_str
|
||||
*
|
||||
|
||||
@@ -36,6 +36,9 @@ isis_str_to_system_id(const char *str, uint8_t *system_id);
|
||||
char *
|
||||
isis_system_id_to_str(uint8_t *system_id);
|
||||
|
||||
bool
|
||||
isis_str_to_lsp_id(const char *str, uint64_t *lsp_id);
|
||||
|
||||
char *
|
||||
isis_lsp_id_to_str(uint64_t *lsp_id);
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ extern uint8_t g_log_buf_cur;
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
} while(0)
|
||||
|
||||
#define LOG_NOARG(log_id_, fmt_) \
|
||||
do { \
|
||||
@@ -114,7 +114,7 @@ extern uint8_t g_log_buf_cur;
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
} while(0)
|
||||
|
||||
#else
|
||||
#define LOG(log_id_, fmt_, ...) \
|
||||
@@ -128,7 +128,7 @@ extern uint8_t g_log_buf_cur;
|
||||
fprintf(stdout, "%s "fmt_, log_format_timestamp(), ##__VA_ARGS__); \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
} while(0)
|
||||
|
||||
#define LOG_NOARG(log_id_, fmt_) \
|
||||
do { \
|
||||
@@ -141,7 +141,7 @@ extern uint8_t g_log_buf_cur;
|
||||
fprintf(stdout, "%s "fmt_, log_format_timestamp()); \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user