mirror of
https://github.com/rtbrick/bngblaster.git
synced 2024-05-06 15:54:57 +00:00
OSPF minor update
This commit is contained in:
@@ -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_ {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user