OSPF minor update

This commit is contained in:
Christian Giese
2023-07-13 07:00:56 +00:00
parent 522c1dd2e5
commit 0e6f052d99
3 changed files with 164 additions and 7 deletions
+21 -2
View File
@@ -18,6 +18,11 @@
#define OSPF_LSA_TYPES 12
#define OSPF_LSA_LINK_P2P 1
#define OSPF_LSA_LINK_TRANSIT 2
#define OSPF_LSA_LINK_STUB 3
#define OSPF_LSA_LINK_VIRTUAL 4
#define OSPF_VERSION_2 2
#define OSPF_VERSION_3 3
@@ -30,6 +35,7 @@
#define OSPFV3_DBD_LEN_MIN 28
#define OSPF_TX_BUF_LEN 1500
#define OSPF_MAX_SELF_LSA_LEN 1024
#define OSPF_OPTION_E_BIT 0x02
#define OSPF_OPTION_LLS_BIT 0x10
@@ -44,6 +50,9 @@
#define OSPF_LSA_SEQ_INIT 0x80000001
#define OSPF_LSA_SEQ_MAX 0x7fffffff
#define OSPF_LSA_BORDER_ROUTER 0x01
#define OSPF_LSA_EXTERNAL_ROUTER 0x02
#define OSPF_OFFSET_VERSION 0
#define OSPF_OFFSET_TYPE 1
#define OSPF_OFFSET_PACKET_LEN 2
@@ -264,10 +273,9 @@ typedef struct ospf_neighbor_ {
bool master;
bool oob_resync;
uint32_t dd;
uint32_t dr;
uint32_t bdr;
uint32_t dd;
uint8_t state;
ospf_lsa_key_s dbd_lsa_start; /* DBD LSA cursor */
@@ -300,6 +308,8 @@ typedef struct ospf_interface_ {
uint16_t max_len; /* max OSPF payload len without fragmentation */
uint16_t max_fragment_len; /* max OSPF payload len with fragmentation */
uint16_t metric;
uint32_t dr;
uint32_t bdr;
struct {
@@ -370,6 +380,14 @@ typedef struct ospf_lsa_header_ {
uint16_t length; /* Length */
} __attribute__ ((__packed__)) ospf_lsa_header_s;
typedef struct ospf_lsa_link_s {
uint32_t link_id; /* Link ID */
uint32_t link_data; /* Link Data */
uint8_t type; /* Type */
uint8_t tos; /* Tos */
uint16_t metric; /* Metric */
} __attribute__ ((__packed__)) ospf_lsa_link_s;
typedef struct ospf_lsa_ {
ospf_instance_s *instance;
@@ -395,6 +413,7 @@ typedef struct ospf_lsa_ {
uint8_t *lsa;
uint16_t lsa_len;
uint16_t lsa_buf_len;
} ospf_lsa_s;
typedef struct ospf_flood_entry_ {
+138
View File
@@ -124,6 +124,144 @@ NEXT:
}
}
ospf_lsa_s *
ospf_lsa_new(ospf_lsa_key_s *key, ospf_instance_s *ospf_instance)
{
ospf_lsa_s *lsa = calloc(1, sizeof(ospf_lsa_s));
lsa->instance = ospf_instance;
memcpy(&lsa->key, key, sizeof(ospf_lsa_key_s));
return lsa;
}
static bool
ospf_lsa_add_interface(ospf_lsa_s *lsa, ospf_interface_s *ospf_interface)
{
ospf_neighbor_s *neighbor = ospf_interface->neighbors;
ospf_lsa_link_s *link = (ospf_lsa_link_s*)(lsa->lsa+lsa->lsa_len);
if(ospf_interface->type == OSPF_INTERFACE_P2P) {
if(!(neighbor && neighbor->state == OSPF_NBSTATE_FULL)) {
return false;
}
link->link_id = neighbor->router_id;
link->link_data = ospf_interface->interface->ip.address;
link->type = OSPF_LSA_LINK_P2P;
} else if(ospf_interface->type == OSPF_INTERFACE_BROADCAST) {
while(neighbor) {
if(neighbor->state == OSPF_NBSTATE_FULL &&
(ospf_interface->state == OSPF_IFSTATE_DR ||
ospf_interface->dr == neighbor->router_id)) {
break;
}
neighbor = neighbor->next;
}
if(neighbor) {
link->link_id = ospf_interface->dr;
link->link_data = ospf_interface->interface->ip.address;
link->type = OSPF_LSA_LINK_TRANSIT;
} else {
link->link_id = ospf_interface->interface->ip.address & ipv4_len_to_mask(ospf_interface->interface->ip.len);
link->link_data = ipv4_len_to_mask(ospf_interface->interface->ip.len);
link->type = OSPF_LSA_LINK_STUB;
}
} else {
return false;
}
link->tos = 0;
link->metric = htobe16(ospf_interface->metric);
lsa->lsa_len += sizeof(ospf_lsa_link_s);
return true;
}
/**
* This function adds/updates
* the self originated Type 1 Router.
*
* @param ospf_instance OSPF instance
* @return true (success) / false (error)
*/
bool
ospf_lsa_self_update(ospf_instance_s *ospf_instance)
{
ospf_interface_s *ospf_interface = ospf_instance->interfaces;
void **search = NULL;
dict_insert_result result;
uint8_t options = 0;
uint16_t *links;
ospf_lsa_s *lsa;
ospf_lsa_header_s *hdr;
ospf_lsa_link_s *link;
ospf_lsa_key_s key = {
.type = OSPF_LSA_TYPE_1,
.id = ospf_instance->config->router_id,
.router = ospf_instance->config->router_id
};
search = hb_tree_search(ospf_instance->lsdb, &key);
if(search) {
/* Update existing LSA. */
lsa = *search;
} else {
/* Create new LSA. */
lsa = ospf_lsa_new(&key, ospf_instance);
result = hb_tree_insert(ospf_instance->lsdb, &key);
if(result.inserted) {
*result.datum_ptr = lsa;
} else {
LOG_NOARG(OSPF, "Failed to add LSA to LSDB\n");
return NULL;
}
}
if(lsa->lsa_buf_len < OSPF_MAX_SELF_LSA_LEN) {
if(lsa->lsa) free(lsa->lsa);
lsa->lsa = malloc(OSPF_MAX_SELF_LSA_LEN);
lsa->lsa_len = 0;
lsa->lsa_buf_len = OSPF_MAX_SELF_LSA_LEN;
}
clock_gettime(CLOCK_MONOTONIC, &lsa->timestamp);
if(ospf_instance->teardown) {
lsa->age = OSPF_LSA_MAX_AGE;
}
hdr = (ospf_lsa_header_s*)lsa->lsa;
hdr->age = htobe16(lsa->age);
hdr->options = options;
hdr->type = OSPF_LSA_TYPE_1;
hdr->id = ospf_instance->config->router_id;
hdr->router = ospf_instance->config->router_id;
hdr->seq = htobe32(lsa->seq);
hdr->checksum = 0;
hdr->length = 0;
lsa->lsa_len = OSPF_LSA_HDR_LEN;
*(lsa->lsa+lsa->lsa_len++) = OSPF_LSA_BORDER_ROUTER|OSPF_LSA_EXTERNAL_ROUTER;
*(lsa->lsa+lsa->lsa_len++) = 0;
links = (uint16_t*)(lsa->lsa+lsa->lsa_len);
/* Add loopback */
link = (ospf_lsa_link_s*)(lsa->lsa+lsa->lsa_len);
lsa->lsa_len += sizeof(ospf_lsa_link_s);
link->link_id = ospf_instance->config->router_id;
link->link_data = 0xffffffff;
link->type = OSPF_LSA_LINK_STUB;
link->tos = 0;
link->metric = 0;
links++;
while(ospf_interface && lsa->lsa_len+sizeof(ospf_lsa_link_s)<=lsa->lsa_buf_len) {
if(ospf_lsa_add_interface(lsa, ospf_interface)) {
links++;
}
ospf_interface = ospf_interface->next;
}
return true;
}
#if 0
/**
* ospf_lsa_process_entries
+5 -5
View File
@@ -359,7 +359,7 @@ ospf_neighbor_dbd_rx(ospf_interface_s *ospf_interface,
bbl_network_interface_s *interface = ospf_interface->interface;
ospf_instance_s *ospf_instance = ospf_interface->instance;
ospf_lsa_header_s *lsa_hdr;
ospf_lsa_header_s *hdr;
ospf_lsa_s *lsa;
void **search = NULL;
@@ -483,17 +483,17 @@ ospf_neighbor_dbd_rx(ospf_interface_s *ospf_interface,
}
while(OSPF_PDU_CURSOR_LEN(pdu) >= OSPF_LSA_HDR_LEN) {
lsa_hdr = (ospf_lsa_header_s*)OSPF_PDU_CURSOR(pdu);
hdr = (ospf_lsa_header_s*)OSPF_PDU_CURSOR(pdu);
OSPF_PDU_CURSOR_INC(pdu, OSPF_LSA_HDR_LEN);
search = hb_tree_search(ospf_instance->lsdb, &lsa_hdr->type);
search = hb_tree_search(ospf_instance->lsdb, &hdr->type);
if(search) {
lsa = *search;
if(be32toh(lsa_hdr->seq) <= lsa->seq) {
if(be32toh(hdr->seq) <= lsa->seq) {
continue;
}
}
hb_tree_insert(ospf_neighbor->request_tree, &lsa_hdr->type);
hb_tree_insert(ospf_neighbor->request_tree, &hdr->type);
}
if(!(ospf_neighbor->dbd_more || flags & OSPF_DBD_FLAG_M)) {