mirror of
https://github.com/rtbrick/bngblaster.git
synced 2024-05-06 15:54:57 +00:00
start work on OSPF serializer
This commit is contained in:
committed by
Christian Giese
parent
4917f751dd
commit
09afad7320
+16
-10
@@ -12,6 +12,7 @@
|
||||
#include "lspgen.h"
|
||||
#include "lspgen_lsdb.h"
|
||||
#include "lspgen_isis.h"
|
||||
#include "lspgen_ospf.h"
|
||||
|
||||
/*
|
||||
* Globals
|
||||
@@ -555,8 +556,8 @@ lspgen_gen_ospf2_attr(struct lsdb_ctx_ *ctx)
|
||||
/* Host name */
|
||||
if (node->node_name) {
|
||||
lsdb_reset_attr_template(&attr_template);
|
||||
attr_template.key.ordinal = 1;
|
||||
attr_template.key.attr_type = ISIS_TLV_HOSTNAME;
|
||||
attr_template.key.ordinal = OSPF_LSA_OPAQUE_AREA;
|
||||
attr_template.key.attr_type = OSPF_TLV_HOSTNAME;
|
||||
strncpy(attr_template.key.hostname, node->node_name, sizeof(attr_template.key.hostname)-1);
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
}
|
||||
@@ -572,8 +573,8 @@ lspgen_gen_ospf2_attr(struct lsdb_ctx_ *ctx)
|
||||
attr_template.key.prefix.adv_sid = true;
|
||||
}
|
||||
attr_template.key.prefix.node_flag = true;
|
||||
attr_template.key.ordinal = 1;
|
||||
attr_template.key.attr_type = ISIS_TLV_EXTD_IPV4_REACH;
|
||||
attr_template.key.ordinal = OSPF_LSA_ROUTER;
|
||||
attr_template.key.attr_type = OSPF_ROUTER_LSA_LINK_STUB;
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
|
||||
/* external prefixes */
|
||||
@@ -584,11 +585,13 @@ lspgen_gen_ospf2_attr(struct lsdb_ctx_ *ctx)
|
||||
lspgen_store_addr(ext_addr4, (uint8_t*)&attr_template.key.prefix.ipv4_prefix.address, 4);
|
||||
attr_template.key.prefix.ipv4_prefix.len = ctx->ipv4_ext_prefix.len;
|
||||
attr_template.key.prefix.metric = 100;
|
||||
attr_template.key.attr_type = ISIS_TLV_EXTD_IPV4_REACH;
|
||||
attr_template.key.ordinal = OSPF_LSA_EXTERNAL;
|
||||
attr_template.key.attr_type = OSPF_EXTERNAL_PREFIX;
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
ext_addr4 += ext_incr4;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!ctx->no_sr) {
|
||||
/* SR capability */
|
||||
lsdb_reset_attr_template(&attr_template);
|
||||
@@ -604,6 +607,7 @@ lspgen_gen_ospf2_attr(struct lsdb_ctx_ *ctx)
|
||||
attr_template.key.ordinal = 1;
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Walk all of our neighbors.
|
||||
@@ -612,9 +616,10 @@ lspgen_gen_ospf2_attr(struct lsdb_ctx_ *ctx)
|
||||
|
||||
/* Generate an IS reach for each link */
|
||||
lsdb_reset_attr_template(&attr_template);
|
||||
attr_template.key.attr_type = ISIS_TLV_EXTD_IS_REACH;
|
||||
memcpy(attr_template.key.link.remote_node_id, link->key.remote_node_id, 7);
|
||||
attr_template.key.link.metric = link->link_metric;
|
||||
attr_template.key.ordinal = OSPF_LSA_ROUTER;
|
||||
attr_template.key.attr_type = 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);
|
||||
|
||||
/* Generate an IPv4 prefix for each link */
|
||||
@@ -624,8 +629,9 @@ lspgen_gen_ospf2_attr(struct lsdb_ctx_ *ctx)
|
||||
addr += link->link_index * inc;
|
||||
lspgen_store_addr(addr, (uint8_t*)&attr_template.key.prefix.ipv4_prefix.address, sizeof(ipv4addr_t));
|
||||
attr_template.key.prefix.ipv4_prefix.len = ctx->ipv4_link_prefix.len;
|
||||
attr_template.key.prefix.metric = link->link_metric;
|
||||
attr_template.key.attr_type = ISIS_TLV_EXTD_IPV4_REACH;
|
||||
attr_template.key.prefix.metric = link->link_metric; /* TODO clip metric */
|
||||
attr_template.key.ordinal = OSPF_LSA_ROUTER;
|
||||
attr_template.key.attr_type = OSPF_ROUTER_LSA_LINK_STUB;
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ void lspgen_write_config(lsdb_ctx_t *);
|
||||
extern struct keyval_ isis_level_names[];
|
||||
|
||||
/* lspgen_packet.c */
|
||||
void lspgen_serialize_attr(lsdb_attr_t *, io_buffer_t *);
|
||||
void lspgen_serialize_attr(lsdb_ctx_t *, lsdb_attr_t *, io_buffer_t *);
|
||||
void lspgen_gen_packet(lsdb_ctx_t *);
|
||||
|
||||
/* lspgen_seq_cache.c */
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "lspgen.h"
|
||||
#include "lspgen_lsdb.h"
|
||||
#include "lspgen_isis.h"
|
||||
#include "lspgen_ospf.h"
|
||||
|
||||
/*
|
||||
* Convert the node_id string to binary data.
|
||||
@@ -690,7 +691,7 @@ lsdb_get_link(struct lsdb_ctx_ *ctx, struct lsdb_link_ *link_template)
|
||||
/*
|
||||
* Link State Attributes / name mappings
|
||||
*/
|
||||
struct keyval_ attr_names[] = {
|
||||
struct keyval_ isis_attr_names[] = {
|
||||
{ ISIS_TLV_AREA, "Area" },
|
||||
{ ISIS_TLV_PROTOCOLS, "Protocol" },
|
||||
{ ISIS_TLV_EXTD_IS_REACH, "Link" },
|
||||
@@ -704,12 +705,12 @@ struct keyval_ attr_names[] = {
|
||||
};
|
||||
|
||||
char *
|
||||
lsdb_format_attr(struct lsdb_attr_ *attr)
|
||||
lsdb_format_isis_attr(struct lsdb_attr_ *attr)
|
||||
{
|
||||
static char buf[128];
|
||||
int len;
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%s (%u)", val2key(attr_names, attr->key.attr_type), attr->key.attr_type);
|
||||
len = snprintf(buf, sizeof(buf), "%s (%u)", val2key(isis_attr_names, attr->key.attr_type), attr->key.attr_type);
|
||||
|
||||
switch(attr->key.attr_type) {
|
||||
case ISIS_TLV_PROTOCOLS:
|
||||
@@ -747,6 +748,43 @@ lsdb_format_attr(struct lsdb_attr_ *attr)
|
||||
return buf;
|
||||
}
|
||||
|
||||
struct keyval_ ospf_attr_names[] = {
|
||||
{ OSPF_TLV_HOSTNAME, "Hostname" },
|
||||
{ 0, NULL}
|
||||
};
|
||||
|
||||
char *
|
||||
lsdb_format_ospf2_attr(struct lsdb_attr_ *attr)
|
||||
{
|
||||
static char buf[128];
|
||||
int len;
|
||||
|
||||
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;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *
|
||||
lsdb_format_attr(lsdb_ctx_t *ctx, struct lsdb_attr_ *attr)
|
||||
{
|
||||
switch (ctx->protocol_id) {
|
||||
case PROTO_ISIS:
|
||||
return lsdb_format_isis_attr(attr);
|
||||
case PROTO_OSPF2:
|
||||
return lsdb_format_ospf2_attr(attr);
|
||||
default:
|
||||
LOG_NOARG(ERROR, "Unknown protocol\n");
|
||||
}
|
||||
return "Unknown protocol";
|
||||
}
|
||||
|
||||
/*
|
||||
* Use this function to clear attributes.
|
||||
* The default ordinal is set to the worst.
|
||||
@@ -760,9 +798,10 @@ lsdb_reset_attr_template(lsdb_attr_t *attr_template)
|
||||
}
|
||||
|
||||
bool
|
||||
lsdb_is_ipv4_attr(lsdb_attr_t *attr)
|
||||
lsdb_is_ipv4_attr(lsdb_ctx_t *ctx, lsdb_attr_t *attr)
|
||||
{
|
||||
switch (attr->key.attr_type) {
|
||||
if (ctx->protocol_id == PROTO_ISIS) {
|
||||
switch (attr->key.attr_type) {
|
||||
case ISIS_TLV_IPV4_ADDR:
|
||||
case ISIS_TLV_EXTD_IPV4_REACH:
|
||||
return true;
|
||||
@@ -773,14 +812,20 @@ lsdb_is_ipv4_attr(lsdb_attr_t *attr)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (ctx->protocol_id == PROTO_OSPF2) {
|
||||
/* OSPFv2 only has IPV4 related attributes added */
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
lsdb_is_ipv6_attr(lsdb_attr_t *attr)
|
||||
lsdb_is_ipv6_attr(lsdb_ctx_t *ctx, lsdb_attr_t *attr)
|
||||
{
|
||||
switch (attr->key.attr_type) {
|
||||
if (ctx->protocol_id == PROTO_ISIS) {
|
||||
switch (attr->key.attr_type) {
|
||||
case ISIS_TLV_IPV6_ADDR:
|
||||
case ISIS_TLV_EXTD_IPV6_REACH:
|
||||
return true;
|
||||
@@ -791,6 +836,10 @@ lsdb_is_ipv6_attr(lsdb_attr_t *attr)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (ctx->protocol_id == PROTO_OSPF3) {
|
||||
/* OSPFv3 only has IPV6 related attributes added */
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -803,6 +852,7 @@ lsdb_attr_t *
|
||||
lsdb_add_node_attr(lsdb_node_t *node, lsdb_attr_t *attr_template)
|
||||
{
|
||||
dict_insert_result result;
|
||||
lsdb_ctx_t *ctx;
|
||||
struct lsdb_attr_ *attr;
|
||||
void **p;
|
||||
uint8_t data[255]; /* One max-sized TLV */
|
||||
@@ -812,17 +862,19 @@ lsdb_add_node_attr(lsdb_node_t *node, lsdb_attr_t *attr_template)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx = node->ctx;
|
||||
|
||||
/*
|
||||
* Refuse addition of v4 attributes if v4 is turned off.
|
||||
*/
|
||||
if (node->ctx->no_ipv4 && lsdb_is_ipv4_attr(attr_template)) {
|
||||
if (ctx->no_ipv4 && lsdb_is_ipv4_attr(ctx, attr_template)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Refuse addition of v6 attributes if v6 is turned off.
|
||||
*/
|
||||
if (node->ctx->no_ipv6 && lsdb_is_ipv6_attr(attr_template)) {
|
||||
if (ctx->no_ipv6 && lsdb_is_ipv6_attr(ctx, attr_template)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -863,7 +915,7 @@ lsdb_add_node_attr(lsdb_node_t *node, lsdb_attr_t *attr_template)
|
||||
buf.data = data;
|
||||
buf.idx = 0;
|
||||
buf.size = sizeof(data);
|
||||
lspgen_serialize_attr(attr, &buf);
|
||||
lspgen_serialize_attr(ctx, attr, &buf);
|
||||
attr->size = buf.idx;
|
||||
|
||||
/*
|
||||
@@ -872,7 +924,7 @@ lsdb_add_node_attr(lsdb_node_t *node, lsdb_attr_t *attr_template)
|
||||
node->attr_count++;
|
||||
|
||||
LOG(LSDB, " Add attr %s to node %s (%s), size %u\n",
|
||||
lsdb_format_attr(attr),
|
||||
lsdb_format_attr(ctx, attr),
|
||||
lsdb_format_node(node),
|
||||
lsdb_format_node_id(node->key.node_id),
|
||||
attr->size);
|
||||
|
||||
+194
-21
@@ -10,6 +10,7 @@
|
||||
#include "lspgen.h"
|
||||
#include "lspgen_lsdb.h"
|
||||
#include "lspgen_isis.h"
|
||||
#include "lspgen_ospf.h"
|
||||
#include "hmac_md5.h"
|
||||
|
||||
/*
|
||||
@@ -205,7 +206,7 @@ calculate_cksum(uint8_t *buf, uint16_t len)
|
||||
* Helper for calculating when to start a new packet.
|
||||
*/
|
||||
uint32_t
|
||||
lspgen_calculate_auth_len(lsdb_ctx_t *ctx)
|
||||
lspgen_calculate_isis_auth_len(lsdb_ctx_t *ctx)
|
||||
{
|
||||
uint8_t auth_len;
|
||||
|
||||
@@ -429,14 +430,10 @@ lspgen_serialize_prefix_subtlv(lsdb_attr_t *attr, io_buffer_t *buf,
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialize a attribute into a buffer.
|
||||
*
|
||||
* This is used in two places.
|
||||
* 1) When an attribute gets added for size measurement.
|
||||
* 2) When the actual link-state packets gets built.
|
||||
* Serialize an IS-IS attribute into a buffer.
|
||||
*/
|
||||
void
|
||||
lspgen_serialize_attr(lsdb_attr_t *attr, io_buffer_t *buf)
|
||||
lspgen_serialize_isis_attr(lsdb_attr_t *attr, io_buffer_t *buf)
|
||||
{
|
||||
uint32_t metric, mask;
|
||||
uint8_t attr_len, flags;
|
||||
@@ -597,6 +594,48 @@ lspgen_serialize_attr(lsdb_attr_t *attr, io_buffer_t *buf)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialize an OSPFv2 attribute into a buffer.
|
||||
*/
|
||||
void
|
||||
lspgen_serialize_ospf2_attr(lsdb_attr_t *attr, io_buffer_t *buf)
|
||||
{
|
||||
uint16_t attr_len;
|
||||
|
||||
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;
|
||||
|
||||
default:
|
||||
LOG(ERROR, "No packet serializer for attr %d\n", attr->key.attr_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialize a attribute into a buffer.
|
||||
*
|
||||
* This is used in two places.
|
||||
* 1) When an attribute gets added for size measurement.
|
||||
* 2) When the actual link-state packets gets built.
|
||||
*/
|
||||
void
|
||||
lspgen_serialize_attr(lsdb_ctx_t *ctx, lsdb_attr_t *attr, io_buffer_t *buf)
|
||||
{
|
||||
switch (ctx->protocol_id) {
|
||||
case PROTO_ISIS:
|
||||
lspgen_serialize_isis_attr(attr, buf);
|
||||
break;
|
||||
case PROTO_OSPF2:
|
||||
lspgen_serialize_ospf2_attr(attr, buf);
|
||||
break;
|
||||
default:
|
||||
LOG_NOARG(ERROR, "Unknown protocol\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update length field of last TLV written to the buffer.
|
||||
*/
|
||||
@@ -722,10 +761,10 @@ lspgen_refresh_interval (lsdb_ctx_t *ctx)
|
||||
}
|
||||
|
||||
/*
|
||||
* Walk the graph of the LSDB and serialize packets.
|
||||
* Walk the graph of the LSDB and serialize IS-IS packets.
|
||||
*/
|
||||
void
|
||||
lspgen_gen_packet_node(lsdb_node_t *node)
|
||||
lspgen_gen_isis_packet_node(lsdb_node_t *node)
|
||||
{
|
||||
lsdb_ctx_t *ctx;
|
||||
struct lsdb_packet_ *packet;
|
||||
@@ -785,7 +824,7 @@ lspgen_gen_packet_node(lsdb_node_t *node)
|
||||
/*
|
||||
* Space left in this packet ?
|
||||
*/
|
||||
min_len = lspgen_calculate_auth_len(ctx);
|
||||
min_len = lspgen_calculate_isis_auth_len(ctx);
|
||||
min_len += attr->size + TLV_OVERHEAD;
|
||||
if (packet && packet->buf.idx > (1465-min_len)) {
|
||||
|
||||
@@ -826,7 +865,7 @@ lspgen_gen_packet_node(lsdb_node_t *node)
|
||||
push_be_uint(&packet->buf, 1, 0); /* Length */
|
||||
}
|
||||
|
||||
lspgen_serialize_attr(attr, &packet->buf);
|
||||
lspgen_serialize_attr(ctx, attr, &packet->buf);
|
||||
lspgen_update_tlv_length(&packet->buf, tlv_start_idx);
|
||||
|
||||
last_attr = attr->key.attr_type;
|
||||
@@ -837,6 +876,140 @@ lspgen_gen_packet_node(lsdb_node_t *node)
|
||||
dict_itor_free(itor);
|
||||
}
|
||||
|
||||
/*
|
||||
* Walk the graph of the LSDB and serialize OSPFv2 packets.
|
||||
*/
|
||||
void
|
||||
lspgen_gen_ospf2_packet_node(lsdb_node_t *node)
|
||||
{
|
||||
lsdb_ctx_t *ctx;
|
||||
struct lsdb_packet_ *packet;
|
||||
struct lsdb_attr_ *attr;
|
||||
dict_itor *itor;
|
||||
uint32_t id, last_attr, tlv_start_idx, min_len;
|
||||
|
||||
ctx = node->ctx;
|
||||
|
||||
packet = NULL;
|
||||
id = 0;
|
||||
last_attr = 0;
|
||||
tlv_start_idx = 0;
|
||||
|
||||
/*
|
||||
* Flush old serialized packets.
|
||||
*/
|
||||
dict_clear(node->packet_dict, lsdb_free_packet);
|
||||
|
||||
if (!node->attr_dict) {
|
||||
/*
|
||||
* No attributes. This is a purge.
|
||||
*/
|
||||
packet = lspgen_add_packet(ctx, node, id);
|
||||
lspgen_finalize_packet(ctx, node, packet);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Walk the node attributes.
|
||||
*/
|
||||
itor = dict_itor_new(node->attr_dict);
|
||||
if (!itor) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Node DB empty ?
|
||||
*/
|
||||
if (!dict_itor_first(itor)) {
|
||||
dict_itor_free(itor);
|
||||
LOG(ERROR, "No Attributes for node %s\n", lsdb_format_node(node));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start refresh timer.
|
||||
*/
|
||||
if (ctx->ctrl_socket_path) {
|
||||
timer_add_periodic(&ctx->timer_root, &node->refresh_timer, "refresh",
|
||||
lspgen_refresh_interval(ctx), 0, node, &lspgen_refresh_cb);
|
||||
}
|
||||
|
||||
do {
|
||||
attr = *dict_itor_datum(itor);
|
||||
|
||||
/*
|
||||
* Space left in this packet ?
|
||||
*/
|
||||
min_len = lspgen_calculate_isis_auth_len(ctx);
|
||||
min_len += attr->size + TLV_OVERHEAD;
|
||||
if (packet && packet->buf.idx > (1465-min_len)) {
|
||||
|
||||
/*
|
||||
* No space left. Finalize this packet.
|
||||
*/
|
||||
lspgen_finalize_packet(ctx, node, packet);
|
||||
packet = NULL;
|
||||
|
||||
id++;
|
||||
if (id > 255) {
|
||||
dict_itor_free(itor);
|
||||
LOG(ERROR, "Exhausted fragments for node %s\n", lsdb_format_node(node));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Need a fresh packet ?
|
||||
*/
|
||||
if (!packet) {
|
||||
packet = lspgen_add_packet(ctx, node, id);
|
||||
tlv_start_idx = packet->buf.idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode node attributes.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Start a fresh TLV ?
|
||||
*/
|
||||
if ((last_attr != attr->key.attr_type) ||
|
||||
(lspgen_calculate_tlv_space(&packet->buf, tlv_start_idx) < attr->size) ||
|
||||
attr->key.start_tlv) {
|
||||
tlv_start_idx = packet->buf.idx;
|
||||
push_be_uint(&packet->buf, 1, attr->key.attr_type); /* Type */
|
||||
push_be_uint(&packet->buf, 1, 0); /* Length */
|
||||
}
|
||||
|
||||
lspgen_serialize_attr(ctx, attr, &packet->buf);
|
||||
lspgen_update_tlv_length(&packet->buf, tlv_start_idx);
|
||||
|
||||
last_attr = attr->key.attr_type;
|
||||
|
||||
} while (dict_itor_next(itor));
|
||||
|
||||
lspgen_finalize_packet(ctx, node, packet);
|
||||
dict_itor_free(itor);
|
||||
}
|
||||
|
||||
void
|
||||
lspgen_gen_packet_node(lsdb_node_t *node)
|
||||
{
|
||||
lsdb_ctx_t *ctx;
|
||||
|
||||
ctx = node->ctx;
|
||||
switch (ctx->protocol_id) {
|
||||
case PROTO_ISIS:
|
||||
lspgen_gen_isis_packet_node(node);
|
||||
break;
|
||||
case PROTO_OSPF2:
|
||||
lspgen_gen_ospf2_packet_node(node);
|
||||
break;
|
||||
default:
|
||||
LOG_NOARG(ERROR, "Unknown protocol\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Walk the graph of the LSDB and serialize packets.
|
||||
*/
|
||||
@@ -866,17 +1039,17 @@ lspgen_gen_packet(lsdb_ctx_t *ctx)
|
||||
do {
|
||||
node = *dict_itor_datum(itor);
|
||||
|
||||
/*
|
||||
* Init per-packet tree for this node.
|
||||
*/
|
||||
if (!node->packet_dict) {
|
||||
node->packet_dict = hb_dict_new((dict_compare_func)lsdb_compare_packet);
|
||||
}
|
||||
/*
|
||||
* Init per-packet tree for this node.
|
||||
*/
|
||||
if (!node->packet_dict) {
|
||||
node->packet_dict = hb_dict_new((dict_compare_func)lsdb_compare_packet);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate the link-state packets for this node.
|
||||
*/
|
||||
lspgen_gen_packet_node(node);
|
||||
/*
|
||||
* Generate the link-state packets for this node.
|
||||
*/
|
||||
lspgen_gen_packet_node(node);
|
||||
|
||||
} while (dict_itor_next(itor));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user