diff options
Diffstat (limited to 'ospf6d/ospf6_flood.c')
| -rw-r--r-- | ospf6d/ospf6_flood.c | 66 |
1 files changed, 58 insertions, 8 deletions
diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index 05b43189e9..3d52597161 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -89,6 +89,16 @@ void ospf6_lsa_originate(struct ospf6_lsa *lsa) struct ospf6_lsa *old; struct ospf6_lsdb *lsdb_self; + if (lsa->header->adv_router == INADDR_ANY) { + if (IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa->header->type)) + zlog_debug( + "Refusing to originate LSA (zero router ID): %s", + lsa->name); + + ospf6_lsa_delete(lsa); + return; + } + /* find previous LSA */ old = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id, lsa->header->adv_router, lsa->lsdb); @@ -106,7 +116,7 @@ void ospf6_lsa_originate(struct ospf6_lsa *lsa) lsdb_self = ospf6_get_scoped_lsdb_self(lsa); ospf6_lsdb_add(ospf6_lsa_copy(lsa), lsdb_self); - lsa->refresh = NULL; + THREAD_OFF(lsa->refresh); thread_add_timer(master, ospf6_lsa_refresh, lsa, OSPF_LS_REFRESH_TIME, &lsa->refresh); @@ -139,6 +149,31 @@ void ospf6_lsa_originate_interface(struct ospf6_lsa *lsa, ospf6_lsa_originate(lsa); } +void ospf6_remove_id_from_external_id_table(struct ospf6 *ospf6, + uint32_t id) +{ + struct prefix prefix_id; + struct route_node *node; + + /* remove binding in external_id_table */ + prefix_id.family = AF_INET; + prefix_id.prefixlen = 32; + prefix_id.u.prefix4.s_addr = id; + node = route_node_lookup(ospf6->external_id_table, &prefix_id); + assert(node); + node->info = NULL; + route_unlock_node(node); /* to free the lookup lock */ + route_unlock_node(node); /* to free the original lock */ + +} + +void ospf6_external_lsa_purge(struct ospf6 *ospf6, struct ospf6_lsa *lsa) +{ + ospf6_lsa_purge(lsa); + + ospf6_remove_id_from_external_id_table(ospf6, lsa->header->id); +} + void ospf6_lsa_purge(struct ospf6_lsa *lsa) { struct ospf6_lsa *self; @@ -299,7 +334,7 @@ void ospf6_flood_interface(struct ospf6_neighbor *from, struct ospf6_lsa *lsa, { struct listnode *node, *nnode; struct ospf6_neighbor *on; - struct ospf6_lsa *req; + struct ospf6_lsa *req, *old; int retrans_added = 0; int is_debug = 0; @@ -408,12 +443,27 @@ void ospf6_flood_interface(struct ospf6_neighbor *from, struct ospf6_lsa *lsa, if (is_debug) zlog_debug("Add retrans-list of neighbor %s ", on->name); - ospf6_increment_retrans_count(lsa); - ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); - thread_add_timer(master, ospf6_lsupdate_send_neighbor, - on, on->ospf6_if->rxmt_interval, - &on->thread_send_lsupdate); - retrans_added++; + + /* Do not increment the retrans count if the lsa is + * already present in the retrans list. + */ + old = ospf6_lsdb_lookup( + lsa->header->type, lsa->header->id, + lsa->header->adv_router, on->retrans_list); + if (!old) { + if (is_debug) + zlog_debug( + "Increment %s from retrans_list of %s", + lsa->name, on->name); + ospf6_increment_retrans_count(lsa); + ospf6_lsdb_add(ospf6_lsa_copy(lsa), + on->retrans_list); + thread_add_timer( + master, ospf6_lsupdate_send_neighbor, + on, on->ospf6_if->rxmt_interval, + &on->thread_send_lsupdate); + retrans_added++; + } } } |
