diff options
Diffstat (limited to 'ospf6d/ospf6_flood.c')
| -rw-r--r-- | ospf6d/ospf6_flood.c | 115 |
1 files changed, 114 insertions, 1 deletions
diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index 738c2218fa..f13ed3e3bb 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -41,6 +41,7 @@ #include "ospf6_flood.h" #include "ospf6_nssa.h" +#include "ospf6_gr.h" unsigned char conf_debug_ospf6_flooding; @@ -89,6 +90,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 +117,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 +150,48 @@ 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) +{ + uint32_t id = lsa->header->id; + struct ospf6_area *oa; + struct listnode *lnode; + + ospf6_lsa_purge(lsa); + + ospf6_remove_id_from_external_id_table(ospf6, id); + + /* Delete the corresponding NSSA LSA */ + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, lnode, oa)) { + lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_TYPE_7), id, + ospf6->router_id, oa->lsdb); + if (lsa) { + if (IS_OSPF6_DEBUG_NSSA) + zlog_debug("withdraw type 7 lsa, LS ID: %u", + htonl(id)); + + ospf6_lsa_purge(lsa); + } + } +} + void ospf6_lsa_purge(struct ospf6_lsa *lsa) { struct ospf6_lsa *self; @@ -271,6 +324,22 @@ void ospf6_install_lsa(struct ospf6_lsa *lsa) /* actually install */ lsa->installed = now; + + /* Topo change handling */ + if (CHECK_LSA_TOPO_CHG_ELIGIBLE(ntohs(lsa->header->type))) { + + /* check if it is new lsa ? or existing lsa got modified ?*/ + if (!old || OSPF6_LSA_IS_CHANGED(old, lsa)) { + struct ospf6 *ospf6; + + ospf6 = ospf6_get_by_lsdb(lsa); + + assert(ospf6); + + ospf6_helper_handle_topo_chg(ospf6, lsa); + } + } + ospf6_lsdb_add(lsa, lsa->lsdb); if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7) { @@ -964,6 +1033,50 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from, != from->ospf6_if->area->ospf6->router_id) ospf6_flood(from, new); + /* Received Grace-LSA */ + if (IS_GRACE_LSA(new)) { + struct ospf6 *ospf6; + + ospf6 = ospf6_get_by_lsdb(new); + + assert(ospf6); + + if (OSPF6_LSA_IS_MAXAGE(new)) { + + if (IS_DEBUG_OSPF6_GR) + zlog_debug( + "%s, Received a maxage GraceLSA from router %pI4", + __func__, + &new->header->adv_router); + if (old) { + ospf6_process_maxage_grace_lsa( + ospf6, new, from); + } else { + if (IS_DEBUG_OSPF6_GR) + zlog_debug( + "%s, GraceLSA doesn't exist in lsdb, so discarding GraceLSA", + __func__); + return; + } + } else { + + if (IS_DEBUG_OSPF6_GR) + zlog_debug( + "%s, Received a GraceLSA from router %pI4", + __func__, + &new->header->adv_router); + + if (ospf6_process_grace_lsa(ospf6, new, from) + == OSPF6_GR_NOT_HELPER) { + if (IS_DEBUG_OSPF6_GR) + zlog_debug( + "%s, Not moving to HELPER role, So dicarding GraceLSA", + __func__); + return; + } + } + } + /* (d), installing lsdb, which may cause routing table calculation (replacing database copy) */ ospf6_install_lsa(new); |
