Skip to content

Commit

Permalink
ISIS Broadcast Support (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
GIC-de committed Jun 17, 2024
1 parent 19478bd commit 2550721
Show file tree
Hide file tree
Showing 33 changed files with 948 additions and 161 deletions.
19 changes: 16 additions & 3 deletions code/bngblaster/src/bbl_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -665,9 +665,10 @@ json_parse_network_interface(json_t *network_interface, bbl_network_config_s *ne
const char *schema[] = {
"interface", "address", "gateway",
"address-ipv6", "gateway-ipv6", "ipv6-router-advertisement",
"gateway-mac", "vlan", "mtu",
"gateway-resolve-wait", "isis-instance-id", "isis-level",
"isis-p2p", "isis-l1-metric", "isis-l2-metric",
"gateway-mac", "vlan", "mtu", "gateway-resolve-wait",
"isis-instance-id", "isis-level", "isis-p2p",
"isis-l1-metric", "isis-l2-metric",
"isis-l1-priority", "isis-l2-priority",
"ospfv2-instance-id", "ospfv2-metric", "ospfv2-type",
"ospfv3-instance-id", "ospfv3-metric", "ospfv3-type",
"ldp-instance-id"
Expand Down Expand Up @@ -774,6 +775,18 @@ json_parse_network_interface(json_t *network_interface, bbl_network_config_s *ne
} else {
network_config->isis_l2_metric = 10;
}
JSON_OBJ_GET_NUMBER(network_interface, value, "network", "isis-l1-priority", 0, 127);
if(value) {
network_config->isis_l1_priority = json_number_value(value);
} else {
network_config->isis_l1_priority = 10;
}
JSON_OBJ_GET_NUMBER(network_interface, value, "network", "isis-l2-priority", 0, 127);
if(value) {
network_config->isis_l2_priority = json_number_value(value);
} else {
network_config->isis_l2_priority = 10;
}
}

/* OSPF interface configuration */
Expand Down
2 changes: 2 additions & 0 deletions code/bngblaster/src/bbl_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ typedef struct bbl_network_config_
bool isis_p2p;
uint32_t isis_l1_metric;
uint32_t isis_l2_metric;
uint8_t isis_l1_priority;
uint8_t isis_l2_priority;

uint16_t ospfv2_instance_id;
uint32_t ospfv2_metric;
Expand Down
3 changes: 2 additions & 1 deletion code/bngblaster/src/bbl_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const char *schema_all_args[] = {
"group", "group-iter", "group-count", "source1", "source2", "source3",
"local-ipv4-address", "peer-ipv4-address",
"instance", "level", "pdu", "lsa",
"tunnel-id", "sessions",
"tunnel-id", "sessions", "priority",
"result-code", "error-code", "error-message",
"disconnect-code", "disconnect-protocol",
"disconnect-direction", "disconnect-message",
Expand Down Expand Up @@ -254,6 +254,7 @@ struct action actions[] = {
{"isis-lsp-purge", isis_ctrl_lsp_purge, schema_all_args, false},
{"isis-lsp-flap", isis_ctrl_lsp_flap, schema_all_args, false},
{"isis-teardown", isis_ctrl_teardown, schema_all_args, false},
{"isis-update-priority", isis_ctrl_update_priority, schema_all_args, false},
{"ospf-interfaces", ospf_ctrl_interfaces, schema_all_args, true},
{"ospf-neighbors", ospf_ctrl_neighbors, schema_all_args, true},
{"ospf-database", ospf_ctrl_database, schema_all_args, true},
Expand Down
2 changes: 2 additions & 0 deletions code/bngblaster/src/bbl_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ static const ipv6_prefix mock_ipv6_ia_pd = {
#define BBL_IF_SEND_LDP_HELLO_IPV6 0x00000020
#define BBL_IF_SEND_OSPFV2_HELLO 0x00000040
#define BBL_IF_SEND_OSPFV3_HELLO 0x00000080
#define BBL_IF_SEND_ISIS_L1_HELLO 0x00000100
#define BBL_IF_SEND_ISIS_L2_HELLO 0x00000200

#define BBL_AVG_SAMPLES 5
#define BBL_MAX_STREAM_OVERHEAD 128
Expand Down
1 change: 0 additions & 1 deletion code/bngblaster/src/bbl_network.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ typedef struct bbl_network_interface_
struct timer_ *timer_arp;
struct timer_ *timer_nd;
struct timer_ *timer_ra;
struct timer_ *timer_isis_hello;

uint8_t *mc_packets;
uint16_t mc_packet_len;
Expand Down
6 changes: 6 additions & 0 deletions code/bngblaster/src/bbl_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1486,6 +1486,12 @@ 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, &eth);
} else if(interface->send_requests & BBL_IF_SEND_ISIS_L1_HELLO) {
interface->send_requests &= ~BBL_IF_SEND_ISIS_L1_HELLO;
result = isis_hello_encode(interface, buf, len, &eth, ISIS_LEVEL_1);
} else if(interface->send_requests & BBL_IF_SEND_ISIS_L2_HELLO) {
interface->send_requests &= ~BBL_IF_SEND_ISIS_L2_HELLO;
result = isis_hello_encode(interface, buf, len, &eth, ISIS_LEVEL_2);
} else if(interface->send_requests & BBL_IF_SEND_LDP_HELLO_IPV6) {
interface->send_requests &= ~BBL_IF_SEND_LDP_HELLO_IPV6;
result = ldp_hello_ipv6_encode(interface, buf, len, &eth);
Expand Down
8 changes: 7 additions & 1 deletion code/bngblaster/src/isis/isis.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ isis_handler_rx(bbl_network_interface_s *interface, bbl_ethernet_header_s *eth)
isis_pdu_type_string(pdu.pdu_type), interface->name);

switch(pdu.pdu_type) {
case ISIS_PDU_L1_HELLO:
isis_hello_handler_rx(interface, eth, &pdu, ISIS_LEVEL_1);
break;
case ISIS_PDU_L2_HELLO:
isis_hello_handler_rx(interface, eth, &pdu, ISIS_LEVEL_2);
break;
case ISIS_PDU_P2P_HELLO:
isis_p2p_hello_handler_rx(interface, &pdu);
break;
Expand Down Expand Up @@ -160,7 +166,7 @@ isis_teardown_job(timer_s *timer) {
for(int i=0; i<ISIS_LEVELS; i++) {
adjacency = instance->level[i].adjacency;
while(adjacency) {
isis_adjacency_down(adjacency);
isis_adjacency_down(adjacency, "teardown");
adjacency = adjacency->next;
}
}
Expand Down
2 changes: 2 additions & 0 deletions code/bngblaster/src/isis/isis.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include "isis_utils.h"
#include "isis_pdu.h"
#include "isis_adjacency.h"
#include "isis_peer.h"
#include "isis_hello.h"
#include "isis_p2p_hello.h"
#include "isis_csnp.h"
#include "isis_psnp.h"
Expand Down
39 changes: 24 additions & 15 deletions code/bngblaster/src/isis/isis_adjacency.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ isis_adjacency_init(bbl_network_interface_s *interface,
adjacency_p2p->level = interface_config->isis_level;
adjacency_p2p->state = ISIS_P2P_ADJACENCY_STATE_DOWN;
interface->send_requests |= BBL_IF_SEND_ISIS_P2P_HELLO;
} else {
instance->next_pseudo_node_id++;
}

/* Init adjacency levels. */
Expand All @@ -58,10 +60,10 @@ isis_adjacency_init(bbl_network_interface_s *interface,
adjacency->instance = instance;
if(interface_config->isis_p2p) {
if(!adjacency_p2p) return false;
adjacency->p2p = true;
adjacency->peer = adjacency_p2p->peer;
} else {
adjacency->peer = calloc(1, sizeof(isis_peer_s));
if(!adjacency->peer) return false;
adjacency->pseudo_node_id = instance->next_pseudo_node_id;
}
if(instance->level[i].adjacency) {
adjacency->next = instance->level[i].adjacency;
Expand All @@ -70,12 +72,17 @@ isis_adjacency_init(bbl_network_interface_s *interface,

adjacency->flood_tree = hb_tree_new((dict_compare_func)isis_lsp_id_compare);
adjacency->psnp_tree = hb_tree_new((dict_compare_func)isis_lsp_id_compare);
adjacency->levels = interface_config->isis_level;
adjacency->level = level;
adjacency->window_size = config->lsp_tx_window_size;
if(level == ISIS_LEVEL_1) {
adjacency->priority = interface_config->isis_l1_priority;
adjacency->metric = interface_config->isis_l1_metric;
interface->send_requests |= BBL_IF_SEND_ISIS_L1_HELLO;
} else {
adjacency->priority = interface_config->isis_l2_priority;
adjacency->metric = interface_config->isis_l2_metric;
interface->send_requests |= BBL_IF_SEND_ISIS_L2_HELLO;
}
}
return true;
Expand All @@ -102,18 +109,23 @@ 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_tx_job);

timer_add_periodic(&g_ctx->timer_root, &adjacency->timer_retry,
"ISIS RETRY", config->lsp_retry_interval, 0, adjacency, &isis_lsp_retry_job);

timer_add_periodic(&g_ctx->timer_root, &adjacency->timer_csnp,
"ISIS CSNP", config->csnp_interval, 0, adjacency, &isis_csnp_job);

timer_add(&g_ctx->timer_root, &adjacency->timer_csnp_next,
"ISIS CSNP", 0, 10 * MSEC, adjacency, &isis_csnp_job);

if(adjacency->p2p) {
timer_add_periodic(&g_ctx->timer_root, &adjacency->timer_tx,
"ISIS TX", 0, config->lsp_tx_interval * MSEC, adjacency, &isis_lsp_tx_p2p_job);

timer_add_periodic(&g_ctx->timer_root, &adjacency->timer_retry,
"ISIS RETRY", config->lsp_retry_interval, 0, adjacency, &isis_lsp_retry_job);
} else {
timer_add_periodic(&g_ctx->timer_root, &adjacency->timer_tx,
"ISIS TX", 0, config->lsp_tx_interval * MSEC, adjacency, &isis_lsp_tx_job);
}

g_ctx->routing_sessions++;
}

Expand All @@ -123,25 +135,22 @@ isis_adjacency_up(isis_adjacency_s *adjacency)
* @param adjacency IS-IS adjacency
*/
void
isis_adjacency_down(isis_adjacency_s *adjacency)
isis_adjacency_down(isis_adjacency_s *adjacency, const char *reason)
{

if(adjacency->state == ISIS_ADJACENCY_STATE_DOWN) {
return;
}
adjacency->state = ISIS_ADJACENCY_STATE_DOWN;

LOG(ISIS, "ISIS %s adjacency DOWN to %s on interface %s \n",
LOG(ISIS, "ISIS %s adjacency DOWN to %s on interface %s (%s)\n",
isis_level_string(adjacency->level),
isis_system_id_to_str(adjacency->peer->system_id),
adjacency->interface->name);

adjacency->state = ISIS_ADJACENCY_STATE_DOWN;
adjacency->interface->name, reason);

timer_del(adjacency->timer_tx);
timer_del(adjacency->timer_retry);
timer_del(adjacency->timer_csnp);
timer_del(adjacency->timer_csnp_next);
timer_del(adjacency->timer_hold);

if(g_ctx->routing_sessions) g_ctx->routing_sessions--;
}
2 changes: 1 addition & 1 deletion code/bngblaster/src/isis/isis_adjacency.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ void
isis_adjacency_up(isis_adjacency_s *adjacency);

void
isis_adjacency_down(isis_adjacency_s *adjacency);
isis_adjacency_down(isis_adjacency_s *adjacency, const char *reason);

#endif
3 changes: 3 additions & 0 deletions code/bngblaster/src/isis/isis_csnp.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ isis_csnp_job(timer_s *timer)
struct timespec ago;
clock_gettime(CLOCK_MONOTONIC, &now);

/* Return if we are not the DIS */
if(adjacency->dis) return;

/* Build PDU */
if(level == ISIS_LEVEL_1) {
isis_pdu_init(&pdu, ISIS_PDU_L1_CSNP);
Expand Down
76 changes: 65 additions & 11 deletions code/bngblaster/src/isis/isis_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,14 @@
static json_t *
isis_ctrl_adjacency(isis_adjacency_s *adjacency)
{
isis_peer_s *peer;
json_t *root = NULL;
json_t *peer = NULL;
json_t *peers = NULL;
json_t *stats = NULL;
if(!adjacency) {
return NULL;
}

stats = json_object();
if(adjacency->level == ISIS_LEVEL_1) {
json_object_set(stats, "l1-hello-rx", json_integer(adjacency->stats.hello_rx));
Expand All @@ -68,23 +69,38 @@ isis_ctrl_adjacency(isis_adjacency_s *adjacency)
json_object_set(stats, "l2-lsp-tx", json_integer(adjacency->stats.lsp_tx));
}

peer = json_pack("{ss si}",
"system-id", isis_system_id_to_str(adjacency->peer->system_id),
"hold-timer", adjacency->peer->hold_time);
peers = json_array();

peer = adjacency->peer;
while(peer) {
json_array_append(peers, json_pack("{ss ss si si ss}",
"system-id", isis_system_id_to_str(peer->system_id),
"mac", format_mac_address(peer->mac),
"priority", peer->priority,
"hold-timer", peer->hold_time,
"state", isis_peer_state_string(peer->state)));
peer = peer->next;
}

root = json_pack("{ss ss ss si ss so so}",
"interface", adjacency->interface->name,
"type", "LAN",
"type", "Broadcast",
"level", isis_level_string(adjacency->level),
"instance-id", adjacency->instance->config->id,
"adjacency-state", isis_adjacency_state_string(adjacency->state),
"peer", peer,
"peers", peers,
"stats", stats);

if(!root) {
if(peer) json_decref(peer);
if(peers) json_decref(peers);
if(stats) json_decref(stats);
} else {
if(adjacency->dis) {
json_object_set(root, "dis", json_string(isis_system_id_to_str(adjacency->dis->system_id)));
} else {
json_object_set(root, "dis", json_string(adjacency->instance->config->system_id_str));
}
}

return root;
}

Expand Down Expand Up @@ -124,9 +140,10 @@ isis_ctrl_adjacency_p2p(bbl_network_interface_s *network_interface)
json_object_set(stats, "l2-lsp-tx", json_integer(adjacency->stats.lsp_tx));
}

peer = json_pack("{ss si}",
peer = json_pack("{ss si ss}",
"system-id", isis_system_id_to_str(p2p_adjacency->peer->system_id),
"hold-timer", p2p_adjacency->peer->hold_time);
"hold-timer", p2p_adjacency->peer->hold_time,
"state", isis_peer_state_string(p2p_adjacency->peer->state));

root = json_pack("{ss ss, ss si ss so so}",
"interface", p2p_adjacency->interface->name,
Expand Down Expand Up @@ -460,4 +477,41 @@ isis_ctrl_teardown(int fd, uint32_t session_id __attribute__((unused)), json_t *
{
isis_teardown();
return bbl_ctrl_status(fd, "ok", 200, NULL);
}

int
isis_ctrl_update_priority(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments)
{
int level = 0;
int priority = 0;
char *ifname;
bbl_network_interface_s *interface = NULL;
isis_adjacency_s *adjacency;

/* Unpack further arguments */
if(json_unpack(arguments, "{s:s}", "interface", &ifname) != 0) {
return bbl_ctrl_status(fd, "error", 400, "missing argument interface");
}
interface = bbl_network_interface_get(ifname);
if(!interface) {
return bbl_ctrl_status(fd, "error", 404, "interface not found");
}

if(json_unpack(arguments, "{s:i}", "priority", &priority) != 0) { \
return bbl_ctrl_status(fd, "error", 400, "missing argument priority");
}
if(priority < 0 || priority > 127) {
return bbl_ctrl_status(fd, "error", 400, "invalid priority (0-127)");
}

ISIS_CTRL_ARG_LEVEL(arguments, fd, level);
adjacency = interface->isis_adjacency[level-1];
if(!adjacency) {
return bbl_ctrl_status(fd, "error", 404, "adjacency not found");
}

adjacency->priority = priority;
isis_peer_dis_elect(adjacency);
isis_lsp_self_update(adjacency->instance, adjacency->level);
return bbl_ctrl_status(fd, "ok", 200, NULL);
}
3 changes: 3 additions & 0 deletions code/bngblaster/src/isis/isis_ctrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,7 @@ isis_ctrl_lsp_flap(int fd, uint32_t session_id __attribute__((unused)), json_t *
int
isis_ctrl_teardown(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments __attribute__((unused)));

int
isis_ctrl_update_priority(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments);

#endif
Loading

0 comments on commit 2550721

Please sign in to comment.