mirror of
https://github.com/rtbrick/bngblaster.git
synced 2024-05-06 15:54:57 +00:00
add support for the first few OSPF messages
This commit is contained in:
committed by
Christian Giese
parent
de843be48b
commit
b8e1b9c955
+14
-15
@@ -557,9 +557,9 @@ lspgen_gen_ospf2_attr(struct lsdb_ctx_ *ctx)
|
||||
if (node->node_name) {
|
||||
lsdb_reset_attr_template(&attr_template);
|
||||
attr_template.key.ordinal = 1;
|
||||
attr_template.key.msg[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.msg[1] = OSPF_LSA_OPAQUE_AREA;
|
||||
attr_template.key.msg[2] = OSPF_TLV_HOSTNAME;
|
||||
attr_template.key.attr_cp[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.attr_cp[1] = OSPF_LSA_OPAQUE_AREA_RI;
|
||||
attr_template.key.attr_cp[2] = OSPF_TLV_HOSTNAME;
|
||||
strncpy(attr_template.key.hostname, node->node_name, sizeof(attr_template.key.hostname)-1);
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
}
|
||||
@@ -576,9 +576,9 @@ lspgen_gen_ospf2_attr(struct lsdb_ctx_ *ctx)
|
||||
}
|
||||
attr_template.key.prefix.node_flag = true;
|
||||
|
||||
attr_template.key.msg[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.msg[1] = OSPF_LSA_ROUTER;
|
||||
attr_template.key.msg[2] = OSPF_ROUTER_LSA_LINK_STUB;
|
||||
attr_template.key.attr_cp[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.attr_cp[1] = OSPF_LSA_ROUTER;
|
||||
attr_template.key.attr_cp[2] = OSPF_ROUTER_LSA_LINK_STUB;
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
|
||||
/* external prefixes */
|
||||
@@ -590,9 +590,8 @@ lspgen_gen_ospf2_attr(struct lsdb_ctx_ *ctx)
|
||||
attr_template.key.prefix.ipv4_prefix.len = ctx->ipv4_ext_prefix.len;
|
||||
attr_template.key.prefix.metric = 100;
|
||||
|
||||
attr_template.key.msg[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.msg[1] = OSPF_LSA_EXTERNAL;
|
||||
attr_template.key.msg[2] = OSPF_EXTERNAL_PREFIX;;
|
||||
attr_template.key.attr_cp[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.attr_cp[1] = OSPF_LSA_EXTERNAL;
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
ext_addr4 += ext_incr4;
|
||||
}
|
||||
@@ -625,9 +624,9 @@ lspgen_gen_ospf2_attr(struct lsdb_ctx_ *ctx)
|
||||
* TODO Type-2 LSA handling.
|
||||
*/
|
||||
lsdb_reset_attr_template(&attr_template);
|
||||
attr_template.key.msg[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.msg[1] = OSPF_LSA_ROUTER;
|
||||
attr_template.key.msg[2] = OSPF_ROUTER_LSA_LINK_PTP;
|
||||
attr_template.key.attr_cp[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.attr_cp[1] = OSPF_LSA_ROUTER;
|
||||
attr_template.key.attr_cp[2] = OSPF_ROUTER_LSA_LINK_PTP;
|
||||
memcpy(attr_template.key.link.remote_node_id, link->key.remote_node_id, 4);
|
||||
attr_template.key.link.metric = link->link_metric; /* TODO clip metric */
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
@@ -641,9 +640,9 @@ lspgen_gen_ospf2_attr(struct lsdb_ctx_ *ctx)
|
||||
attr_template.key.prefix.ipv4_prefix.len = ctx->ipv4_link_prefix.len;
|
||||
attr_template.key.prefix.metric = link->link_metric; /* TODO clip metric */
|
||||
|
||||
attr_template.key.msg[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.msg[1] = OSPF_LSA_ROUTER;
|
||||
attr_template.key.msg[2] = OSPF_ROUTER_LSA_LINK_STUB;
|
||||
attr_template.key.attr_cp[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.attr_cp[1] = OSPF_LSA_ROUTER;
|
||||
attr_template.key.attr_cp[2] = OSPF_ROUTER_LSA_LINK_STUB;
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ extern struct keyval_ isis_level_names[];
|
||||
/* lspgen_packet.c */
|
||||
void lspgen_serialize_attr(lsdb_ctx_t *, lsdb_attr_t *, lsdb_packet_t *);
|
||||
void lspgen_gen_packet(lsdb_ctx_t *);
|
||||
void lspgen_reset_packet_buffer(struct lsdb_packet_ *);
|
||||
|
||||
/* lspgen_seq_cache.c */
|
||||
void lspgen_read_seq_cache(lsdb_ctx_t *);
|
||||
|
||||
@@ -748,8 +748,22 @@ lsdb_format_isis_attr(struct lsdb_attr_ *attr)
|
||||
return buf;
|
||||
}
|
||||
|
||||
struct keyval_ ospf_attr_names[] = {
|
||||
{ OSPF_TLV_HOSTNAME, "Hostname" },
|
||||
struct keyval_ ospf_attr_l0_names[] = {
|
||||
{ OSPF_MSG_LSUPDATE, "LS-Update" },
|
||||
{ 0, NULL}
|
||||
};
|
||||
|
||||
struct keyval_ ospf_attr_l1_names[] = {
|
||||
{ OSPF_LSA_ROUTER, "Router-LSA" },
|
||||
{ OSPF_LSA_EXTERNAL, "External-LSA" },
|
||||
{ OSPF_LSA_OPAQUE_AREA_RI, "Opaque-LSA-RI" },
|
||||
{ 0, NULL}
|
||||
};
|
||||
|
||||
struct keyval_ ospf_attr_l2_names[] = {
|
||||
{ OSPF_ROUTER_LSA_LINK_PTP, "ptp-link" },
|
||||
{ OSPF_ROUTER_LSA_LINK_STUB, "ptp-stub" },
|
||||
{ OSPF_TLV_HOSTNAME, "Hostname" },
|
||||
{ 0, NULL}
|
||||
};
|
||||
|
||||
@@ -758,16 +772,42 @@ lsdb_format_ospf2_attr(struct lsdb_attr_ *attr)
|
||||
{
|
||||
static char buf[128];
|
||||
int len;
|
||||
uint attr_cp;
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%s (%u)", val2key(ospf_attr_names, attr->key.attr_type), attr->key.attr_type);
|
||||
|
||||
switch(attr->key.attr_type) {
|
||||
case OSPF_TLV_HOSTNAME:
|
||||
len += snprintf(buf+len, sizeof(buf)-len, " '%s'", attr->key.hostname);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
attr_cp = attr->key.attr_cp[0];
|
||||
len = snprintf(buf, sizeof(buf), "%s", val2key(ospf_attr_l0_names, attr_cp));
|
||||
attr_cp = attr->key.attr_cp[1];
|
||||
if (attr_cp) {
|
||||
len += snprintf(buf+len, sizeof(buf)-len, " %s", val2key(ospf_attr_l1_names, attr_cp));
|
||||
}
|
||||
attr_cp = attr->key.attr_cp[2];
|
||||
if (attr_cp) {
|
||||
len += snprintf(buf+len, sizeof(buf)-len, " %s", val2key(ospf_attr_l2_names, attr_cp));
|
||||
}
|
||||
|
||||
switch(attr->key.attr_cp[1]) {
|
||||
case OSPF_LSA_EXTERNAL:
|
||||
len += snprintf(buf+len, sizeof(buf)-len, " %s, metric %u",
|
||||
format_ipv4_prefix(&attr->key.prefix.ipv4_prefix),
|
||||
attr->key.prefix.metric);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(attr->key.attr_cp[2]) {
|
||||
case OSPF_ROUTER_LSA_LINK_STUB:
|
||||
len += snprintf(buf+len, sizeof(buf)-len, " %s, metric %u",
|
||||
format_ipv4_prefix(&attr->key.prefix.ipv4_prefix),
|
||||
attr->key.prefix.metric);
|
||||
break;
|
||||
case OSPF_TLV_HOSTNAME:
|
||||
len += snprintf(buf+len, sizeof(buf)-len, ": %s", attr->key.hostname);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -856,6 +896,7 @@ lsdb_add_node_attr(lsdb_node_t *node, lsdb_attr_t *attr_template)
|
||||
struct lsdb_attr_ *attr;
|
||||
void **p;
|
||||
lsdb_packet_t packet;
|
||||
int idx;
|
||||
|
||||
if (!node) {
|
||||
return NULL;
|
||||
@@ -911,20 +952,25 @@ lsdb_add_node_attr(lsdb_node_t *node, lsdb_attr_t *attr_template)
|
||||
/*
|
||||
* Calculate the size, by serializing the data into a dummy packet buffer.
|
||||
*/
|
||||
packet.buf.data = packet.data;
|
||||
//buf.data = data;
|
||||
packet.buf.idx = 0;
|
||||
//buf.idx = 0;
|
||||
packet.buf.size = sizeof(packet.data);
|
||||
//buf.size = sizeof(data);
|
||||
lspgen_reset_packet_buffer(&packet);
|
||||
lspgen_serialize_attr(ctx, attr, &packet);
|
||||
attr->size = packet.buf.idx;
|
||||
//attr->size = buf.idx;
|
||||
|
||||
/*
|
||||
* Find lowest level size.
|
||||
*/
|
||||
for (idx = MAX_MSG_LEVEL-1; idx; idx--) {
|
||||
if (packet.bufX[idx].idx) {
|
||||
attr->size += packet.bufX[idx].idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Book keeping.
|
||||
*/
|
||||
node->attr_count++;
|
||||
attr->parent = node;
|
||||
|
||||
LOG(LSDB, " Add attr %s to node %s (%s), size %u\n",
|
||||
lsdb_format_attr(ctx, attr),
|
||||
|
||||
@@ -262,6 +262,8 @@ typedef struct msg_stack_ {
|
||||
struct io_buffer_ buf[1]; /* variable length */
|
||||
} msg_stack_t;
|
||||
|
||||
#define MAX_MSG_LEVEL 4
|
||||
|
||||
/*
|
||||
* An Attribute hanging off a node or link
|
||||
*/
|
||||
@@ -272,7 +274,7 @@ typedef struct lsdb_attr_ {
|
||||
*/
|
||||
struct {
|
||||
uint8_t ordinal; /* Used for ordering message generation */
|
||||
uint8_t msg[4]; /* code points for multiple levels */
|
||||
uint8_t attr_cp[MAX_MSG_LEVEL]; /* code points for multiple levels */
|
||||
uint8_t attr_type; /* Type */
|
||||
bool start_tlv; /* Always start a fresh TLV */
|
||||
union {
|
||||
@@ -289,6 +291,7 @@ typedef struct lsdb_attr_ {
|
||||
} key;
|
||||
|
||||
uint32_t size; /* on-the wire space required in bytes */
|
||||
struct lsdb_node_ *parent;
|
||||
} lsdb_attr_t;
|
||||
|
||||
/*
|
||||
@@ -309,10 +312,11 @@ typedef struct lsdb_packet_ {
|
||||
} key;
|
||||
|
||||
struct io_buffer_ buf;
|
||||
struct io_buffer_ bufX[MAX_MSG_LEVEL];
|
||||
uint8_t data[1500]; /* fixed buffer */
|
||||
uint8_t redzone[8]; /* Overwrite detection */
|
||||
|
||||
uint8_t prev_attr_cp[4]; /* cached code points for previous attr */
|
||||
uint8_t prev_attr_cp[MAX_MSG_LEVEL]; /* cached code points for previous attr */
|
||||
|
||||
} lsdb_packet_t;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#define OSPF_LSA_EXTERNAL 5
|
||||
|
||||
#define OSPF_LSA_OPAQUE_LINK 9
|
||||
#define OSPF_LSA_OPAQUE_AREA 10
|
||||
#define OSPF_LSA_OPAQUE_AREA_RI 104
|
||||
#define OSPF_LSA_OPAQUE_DOMAIN 11
|
||||
|
||||
#define OSPF_TLV_HOSTNAME 7
|
||||
@@ -26,7 +26,4 @@ enum {
|
||||
/* Router LSA */
|
||||
OSPF_ROUTER_LSA_LINK_PTP,
|
||||
OSPF_ROUTER_LSA_LINK_STUB,
|
||||
|
||||
/* External LSA */
|
||||
OSPF_EXTERNAL_PREFIX,
|
||||
};
|
||||
|
||||
+253
-12
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
void lspgen_gen_packet_node(lsdb_node_t *);
|
||||
|
||||
#define PAD4(X) ((X+3)&(~3)) /* 32-Bit padding */
|
||||
|
||||
void
|
||||
lspgen_gen_isis_packet_header(lsdb_ctx_t *ctx, lsdb_node_t *node, lsdb_packet_t *packet)
|
||||
{
|
||||
@@ -114,7 +116,7 @@ lspgen_gen_packet_header(lsdb_ctx_t *ctx, lsdb_node_t *node, lsdb_packet_t *pack
|
||||
lspgen_gen_isis_packet_header(ctx, node, packet);
|
||||
break;
|
||||
case PROTO_OSPF2:
|
||||
lspgen_gen_ospf2_packet_header(ctx, node, packet);
|
||||
//lspgen_gen_ospf2_packet_header(ctx, node, packet);
|
||||
break;
|
||||
default:
|
||||
LOG_NOARG(ERROR, "Unknown protocol\n");
|
||||
@@ -597,26 +599,243 @@ lspgen_serialize_isis_attr(lsdb_attr_t *attr, lsdb_packet_t *packet)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Inititialize a next level buffer to the remnants of the passed in buffer.
|
||||
* This gives us nice hierarchical buffers with vboundary protection.
|
||||
*/
|
||||
void
|
||||
lspgen_propagate_buffer_down (lsdb_packet_t *packet, uint level)
|
||||
{
|
||||
struct io_buffer_ *cur, *next;
|
||||
|
||||
/* boundary protection */
|
||||
if (level >= MAX_MSG_LEVEL - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
cur = &packet->bufX[level];
|
||||
next = &packet->bufX[level+1];
|
||||
|
||||
next->data = cur->data + cur->idx;
|
||||
next->size = cur->size - cur->idx;
|
||||
next->idx = 0;
|
||||
next->start_idx = 0;
|
||||
}
|
||||
|
||||
void
|
||||
lspgen_propagate_buffer_up (lsdb_packet_t *packet, uint level)
|
||||
{
|
||||
struct io_buffer_ *cur, *prev;
|
||||
|
||||
/* boundary protection */
|
||||
if (level == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
cur = &packet->bufX[level];
|
||||
prev = &packet->bufX[level-1];
|
||||
|
||||
prev->idx += cur->idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialize an OSPFv2 attribute into a packet buffer.
|
||||
*/
|
||||
void
|
||||
lspgen_serialize_ospf2_attr(lsdb_attr_t *attr, lsdb_packet_t *packet)
|
||||
{
|
||||
io_buffer_t *buf;
|
||||
uint16_t attr_len;
|
||||
lsdb_node_t *node;
|
||||
io_buffer_t *buf0, *buf1, *buf2;
|
||||
uint16_t attr_len, checksum;
|
||||
uint32_t router_id, mask;
|
||||
|
||||
buf = &packet->buf;
|
||||
node = packet->parent;
|
||||
|
||||
switch (attr->key.attr_type) {
|
||||
case OSPF_TLV_HOSTNAME:
|
||||
attr_len = strnlen(attr->key.hostname, sizeof(attr->key.hostname));
|
||||
push_data(buf, (uint8_t *)attr->key.hostname, attr_len);
|
||||
break;
|
||||
buf0 = &packet->bufX[0];
|
||||
buf1 = &packet->bufX[1];
|
||||
buf2 = &packet->bufX[2];
|
||||
|
||||
/*
|
||||
* New Level 0 message ?
|
||||
*/
|
||||
if (packet->prev_attr_cp[0] != attr->key.attr_cp[0]) {
|
||||
|
||||
/* close Level 0 */
|
||||
switch (packet->prev_attr_cp[0]) {
|
||||
case OSPF_MSG_LSUPDATE:
|
||||
write_be_uint(buf0->data+2, 2, buf0->idx); /* Packet length */
|
||||
write_be_uint(buf0->data+12, 2, calculate_cksum(buf0->data, buf0->idx)); /* Checksum */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* open Level 0 */
|
||||
switch(attr->key.attr_cp[0]) {
|
||||
case OSPF_MSG_LSUPDATE:
|
||||
|
||||
push_be_uint(buf0, 1, 2); /* Version */
|
||||
push_be_uint(buf0, 1, OSPF_MSG_LSUPDATE); /* Msg */
|
||||
push_be_uint(buf0, 2, 0); /* Packet length - will be overwritten later */
|
||||
|
||||
router_id = read_be_uint(node->key.node_id, 4);
|
||||
push_be_uint(buf0, 4, router_id); /* Router ID */
|
||||
push_be_uint(buf0, 4, node->ctx->topology_id.area); /* Area ID */
|
||||
|
||||
push_be_uint(buf0, 2, 0); /* Checksum - will be overwritten later */
|
||||
|
||||
push_be_uint(buf0, 2, 0); /* Authentication Type */
|
||||
push_be_uint(buf0, 8, 0); /* Authentication */
|
||||
|
||||
push_be_uint(buf0, 4, 0); /* # LSAs - will be overwritten later */
|
||||
|
||||
lspgen_propagate_buffer_down(packet, 0);
|
||||
break;
|
||||
default:
|
||||
LOG(ERROR, "No Level 0 open packet serializer for attr %d\n", attr->key.attr_cp[0]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* New Level 1 message ?
|
||||
*/
|
||||
if (packet->prev_attr_cp[1] != attr->key.attr_cp[1]) {
|
||||
|
||||
/* close Level 1 */
|
||||
switch (packet->prev_attr_cp[1]) {
|
||||
case OSPF_LSA_ROUTER:
|
||||
case OSPF_LSA_EXTERNAL:
|
||||
case OSPF_LSA_OPAQUE_AREA_RI:
|
||||
inc_be_uint(buf0->data+24, 4); /* Update #LSAs */
|
||||
|
||||
write_be_uint(buf1->data+16, 2, 0); /* reset checksum field */
|
||||
checksum = calculate_fletcher_cksum(buf1->data, 16, buf1->idx);
|
||||
write_be_uint(packet->data+16, 2, checksum); /* LSA Checksum */
|
||||
|
||||
lspgen_propagate_buffer_up(packet, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* open Level 1 */
|
||||
switch(attr->key.attr_cp[1]) {
|
||||
case OSPF_LSA_ROUTER:
|
||||
push_be_uint(buf1, 2, 1); /* LS-age */
|
||||
push_be_uint(buf1, 1, 0); /* Options */
|
||||
push_be_uint(buf1, 1, OSPF_LSA_ROUTER); /* LS-Type */
|
||||
router_id = read_be_uint(node->key.node_id, 4);
|
||||
push_be_uint(buf1, 4, router_id); /* Link State ID */
|
||||
push_be_uint(buf1, 4, router_id); /* Advertising Router */
|
||||
push_be_uint(&packet->buf, 4, node->sequence); /* Sequence */
|
||||
push_be_uint(buf1, 2, 0); /* Checksum - will be overwritten later */
|
||||
push_be_uint(buf1, 2, 0); /* Length - will be overwritten later */
|
||||
|
||||
push_be_uint(buf1, 1, 0x02); /* Flags, E */
|
||||
push_be_uint(buf1, 1, 0);
|
||||
push_be_uint(buf1, 2, 0); /* # links - will be overwritten later */
|
||||
|
||||
lspgen_propagate_buffer_down(packet, 1);
|
||||
break;
|
||||
|
||||
case OSPF_LSA_EXTERNAL:
|
||||
push_be_uint(buf1, 2, 1); /* LS-age */
|
||||
push_be_uint(buf1, 1, 0); /* Options */
|
||||
push_be_uint(buf1, 1, 5); /* LS-Type */
|
||||
push_data(buf1, (uint8_t*)&attr->key.prefix.ipv4_prefix.address, 4); /* Link State ID */
|
||||
router_id = read_be_uint(node->key.node_id, 4);
|
||||
push_be_uint(buf1, 4, router_id); /* Advertising Router */
|
||||
push_be_uint(&packet->buf, 4, node->sequence); /* Sequence */
|
||||
push_be_uint(buf1, 2, 0); /* Checksum - will be overwritten later */
|
||||
push_be_uint(buf1, 2, 0); /* Length - will be overwritten later */
|
||||
|
||||
mask = 0xffffffff;
|
||||
/* convert prefix length to mask */
|
||||
mask &= ~((1 << ((32 - attr->key.prefix.ipv4_prefix.len)))-1);
|
||||
push_be_uint(buf1, 4, mask); /* Network Mask */
|
||||
|
||||
push_be_uint(buf1, 1, 0x80); /* E2 */
|
||||
push_be_uint(buf1, 1, 0); /* Options */
|
||||
push_be_uint(buf1, 3, attr->key.prefix.metric); /* Metric */
|
||||
push_be_uint(buf1, 4, 0); /* Forwarding Address */
|
||||
push_be_uint(buf1, 4, 0); /* External Route Tag */
|
||||
|
||||
lspgen_propagate_buffer_down(packet, 1);
|
||||
break;
|
||||
|
||||
case OSPF_LSA_OPAQUE_AREA_RI:
|
||||
push_be_uint(buf1, 2, 1); /* LS-age */
|
||||
push_be_uint(buf1, 1, 0); /* Options */
|
||||
push_be_uint(buf1, 1, 10); /* LS-Type */
|
||||
push_be_uint(buf1, 1, 4); /* Opaque Type: Router-Information */
|
||||
push_be_uint(buf1, 3, 0); /* Opaque subtype */
|
||||
router_id = read_be_uint(node->key.node_id, 4);
|
||||
push_be_uint(buf1, 4, router_id); /* Advertising Router */
|
||||
push_be_uint(&packet->buf, 4, node->sequence); /* Sequence */
|
||||
push_be_uint(buf1, 2, 0); /* Checksum - will be overwritten later */
|
||||
push_be_uint(buf1, 2, 0); /* Length - will be overwritten later */
|
||||
|
||||
lspgen_propagate_buffer_down(packet, 1);
|
||||
break;
|
||||
default:
|
||||
LOG(ERROR, "No Level 1 open packet serializer for attr %d\n", attr->key.attr_cp[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* New Level 2 message ?
|
||||
*/
|
||||
if (packet->prev_attr_cp[2] != attr->key.attr_cp[2]) {
|
||||
|
||||
/* close Level 2 */
|
||||
switch (packet->prev_attr_cp[2]) {
|
||||
case OSPF_ROUTER_LSA_LINK_PTP:
|
||||
case OSPF_ROUTER_LSA_LINK_STUB:
|
||||
inc_be_uint(buf1->data+22, 1); /* Update #links */
|
||||
|
||||
lspgen_propagate_buffer_up(packet, 2);
|
||||
break;
|
||||
}
|
||||
|
||||
/* open Level 2 */
|
||||
switch(attr->key.attr_cp[2]) {
|
||||
case OSPF_ROUTER_LSA_LINK_PTP:
|
||||
push_be_uint(buf2, 4, 0); /* Link ID */
|
||||
push_be_uint(buf2, 4, 0); /* Link Data */
|
||||
push_be_uint(buf2, 1, 1); /* Type ptp */
|
||||
push_be_uint(buf2, 1, 0); /* #TOS */
|
||||
push_be_uint(buf2, 2, 100); /* metric */
|
||||
|
||||
lspgen_propagate_buffer_down(packet, 2);
|
||||
break;
|
||||
|
||||
case OSPF_ROUTER_LSA_LINK_STUB:
|
||||
push_be_uint(buf2, 4, 1); /* Link ID */
|
||||
push_be_uint(buf2, 4, 0xffffffff); /* Link Data */
|
||||
push_be_uint(buf2, 1, 3); /* Type stub */
|
||||
push_be_uint(buf2, 1, 0); /* #TOS */
|
||||
push_be_uint(buf2, 2, 100); /* metric */
|
||||
|
||||
lspgen_propagate_buffer_down(packet, 2);
|
||||
break;
|
||||
|
||||
case OSPF_TLV_HOSTNAME:
|
||||
attr_len = strnlen(attr->key.hostname, sizeof(attr->key.hostname));
|
||||
if (attr_len) {
|
||||
push_be_uint(buf2, 2, 7); /* Type */
|
||||
push_be_uint(buf2, 2, attr_len); /* Length */
|
||||
push_data(buf2, (uint8_t *)attr->key.hostname, attr_len);
|
||||
push_be_uint(buf2, PAD4(attr_len), 0); /* Padding zeros */
|
||||
}
|
||||
|
||||
lspgen_propagate_buffer_down(packet, 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(ERROR, "No Level 2 open packet serializer for attr %d\n", attr->key.attr_cp[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
LOG(ERROR, "No packet serializer for attr %d\n", attr->key.attr_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -666,6 +885,23 @@ lspgen_calculate_tlv_space(io_buffer_t *buf, uint32_t tlv_start_idx)
|
||||
return 255 - tlv_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset all packet buffers.
|
||||
*/
|
||||
void
|
||||
lspgen_reset_packet_buffer (struct lsdb_packet_ *packet)
|
||||
{
|
||||
uint idx;
|
||||
|
||||
packet->buf.data = packet->data;
|
||||
packet->buf.start_idx = 0;
|
||||
packet->buf.idx = 0;
|
||||
packet->buf.size = sizeof(packet->data);
|
||||
for (idx = 0; idx < MAX_MSG_LEVEL; idx++) {
|
||||
memcpy(&packet->bufX[idx], &packet->buf, sizeof(struct io_buffer_));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup / Create a fresh packet based on the id.
|
||||
*/
|
||||
@@ -711,6 +947,11 @@ lspgen_add_packet(lsdb_ctx_t *ctx, lsdb_node_t *node, uint32_t id)
|
||||
*/
|
||||
packet->parent = node;
|
||||
|
||||
/*
|
||||
* Reset buffers.
|
||||
*/
|
||||
lspgen_reset_packet_buffer(packet);
|
||||
|
||||
/*
|
||||
* Write header for link-state packet.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user