From 09e4efdcb22ac13af3f6e3a38158871ed140e5e0 Mon Sep 17 00:00:00 2001 From: paul Date: Sat, 18 Jan 2003 00:12:02 +0000 Subject: Date: Fri, 20 Dec 2002 17:28:45 +0900 From: Masahiko Endo Reply-To: zebra@zebra.org To: zebra@zebra.org Cc: kunihiro@zebra.org, yokota@kddlabs.co.jp Subject: [zebra 16823] [PATCH] Bugfix and new feature in Opaque-LSA handling. ----- * ----- * ----- * ----- * ----- * ----- * ----- * ----- * ----- * ----- Changes 2002.12.20 1. Bug fixes 1.1 When an opaque LSA is being removed from (or added to) the LSDB, it does not mean a change in network topology. Therefore, SPF recalculation should not be triggered in that case. There was an assertion failure problem "assert (rn && rn->info)" inside the function "ospf_ase_incremental_update()", because the upper function "ospf_lsa_maxage_walker_remover()" called it when a type-11 opaque LSA is removed due to MaxAge. 1.2 Type-9 LSA is defined to have "link-local" flooding scope. In the Database exchange procedure with a new neighbor, a type-9 LSA was added in the database summary of a DD message, even if the link is different from the one that have bound to. 2. Feature enhancements 2.1 Though a "wildcard" concept to handle type-9/10/11 LSAs altogether has introduced about a year ago, it was only a symbol definition and actual handling mechanism was not implemented. Now it works. --- ospfd/ospf_lsa.c | 30 ++++++++++++++----- ospfd/ospf_nsm.c | 20 +++++++++++++ ospfd/ospf_opaque.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 128 insertions(+), 8 deletions(-) diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index c2fade2d..9a9942f3 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -2377,6 +2377,11 @@ ospf_lsa_install (struct ospf_interface *oi, struct ospf_lsa *lsa) break; #ifdef HAVE_OPAQUE_LSA case OSPF_OPAQUE_LINK_LSA: + if (IS_LSA_SELF (lsa)) + lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */ + else + ; /* Incoming "oi" for this LSA has set at LSUpd reception. */ + /* Fallthrough */ case OSPF_OPAQUE_AREA_LSA: case OSPF_OPAQUE_AS_LSA: new = ospf_opaque_lsa_install (lsa, rt_recalc); @@ -2611,21 +2616,32 @@ ospf_lsa_maxage_walker_remover (struct ospf_lsa *lsa, void *p_arg, int int_arg) switch (lsa->data->type) { - case OSPF_AS_EXTERNAL_LSA: #ifdef HAVE_OPAQUE_LSA case OSPF_OPAQUE_AS_LSA: + case OSPF_OPAQUE_LINK_LSA: + case OSPF_OPAQUE_AREA_LSA: + /* + * As a general rule, whenever network topology has changed + * (due to an LSA removal in this case), routing recalculation + * should be triggered. However, this is not true for opaque + * LSAs. Even if an opaque LSA instance is going to be removed + * from the routing domain, it does not mean a change in network + * topology, and thus, routing recalculation is not needed here. + */ + break; #endif /* HAVE_OPAQUE_LSA */ #ifdef HAVE_NSSA - case OSPF_AS_NSSA_LSA: + case OSPF_AS_NSSA_LSA: #endif - ospf_ase_incremental_update (lsa, ospf_top); - break; + case OSPF_AS_EXTERNAL_LSA: + ospf_ase_incremental_update (lsa, ospf_top); + break; default: - ospf_spf_calculate_schedule (); - break; + ospf_spf_calculate_schedule (); + break; } - ospf_lsa_maxage (lsa); + ospf_lsa_maxage (lsa); } return 0; diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c index cfb18a98..57303570 100644 --- a/ospfd/ospf_nsm.c +++ b/ospfd/ospf_nsm.c @@ -229,6 +229,26 @@ ospf_db_summary_add (struct ospf_lsa *lsa, void *v, int i) if (lsa == NULL) return 0; +#ifdef HAVE_OPAQUE_LSA + switch (lsa->data->type) + { + case OSPF_OPAQUE_LINK_LSA: + /* Exclude type-9 LSAs that does not have the same "oi" with "nbr". */ + if (lsa->oi != nbr->oi) + return 0; + break; + case OSPF_OPAQUE_AREA_LSA: + /* + * It is assured by the caller function "nsm_negotiation_done()" + * that every given LSA belongs to the same area with "nbr". + */ + break; + case OSPF_OPAQUE_AS_LSA: + default: + break; + } +#endif /* HAVE_OPAQUE_LSA */ + #ifdef HAVE_NSSA /* Stay away from any Local Translated Type-7 LSAs */ if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index 67c6608b..5d5b30c9 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -239,6 +239,7 @@ struct ospf_opaque_functab int (* del_lsa_hook)(struct ospf_lsa *lsa); }; +static list ospf_opaque_wildcard_funclist; /* Handle LSA-9/10/11 altogether. */ static list ospf_opaque_type9_funclist; static list ospf_opaque_type10_funclist; static list ospf_opaque_type11_funclist; @@ -255,6 +256,9 @@ ospf_opaque_funclist_init (void) { list funclist; + funclist = ospf_opaque_wildcard_funclist = list_new (); + funclist->del = ospf_opaque_del_functab; + funclist = ospf_opaque_type9_funclist = list_new (); funclist->del = ospf_opaque_del_functab; @@ -271,6 +275,9 @@ ospf_opaque_funclist_term (void) { list funclist; + funclist = ospf_opaque_wildcard_funclist; + list_delete (funclist); + funclist = ospf_opaque_type9_funclist; list_delete (funclist); @@ -289,6 +296,16 @@ ospf_get_opaque_funclist (u_char lsa_type) switch (lsa_type) { + case OPAQUE_TYPE_WILDCARD: + /* XXX + * This is an ugly trick to handle type-9/10/11 LSA altogether. + * Yes, "OPAQUE_TYPE_WILDCARD (value 0)" is not an LSA-type, nor + * an officially assigned opaque-type. + * Though it is possible that the value might be officially used + * in the future, we use it internally as a special label, for now. + */ + funclist = ospf_opaque_wildcard_funclist; + break; case OSPF_OPAQUE_LINK_LSA: funclist = ospf_opaque_type9_funclist; break; @@ -434,6 +451,7 @@ ospf_opaque_functab_lookup (struct ospf_lsa *lsa) */ struct opaque_info_per_type { + u_char lsa_type; u_char opaque_type; enum { PROC_NORMAL, PROC_SUSPEND } status; @@ -451,7 +469,7 @@ struct opaque_info_per_type struct thread *t_opaque_lsa_self; /* - * Backpointer to an "owner" which is opaque-type dependent. + * Backpointer to an "owner" which is LSA-type dependent. * type-9: struct ospf_interface * type-10: struct ospf_area * type-11: struct ospf @@ -523,11 +541,13 @@ register_opaque_info_per_type (struct ospf_opaque_functab *functab, listnode_add (top->opaque_lsa_self, oipt); break; default: + zlog_warn ("register_opaque_info_per_type: Unexpected LSA-type(%u)", new->data->type); free_opaque_info_per_type ((void *) oipt); oipt = NULL; goto out; /* This case may not exist. */ } + oipt->lsa_type = new->data->type; oipt->opaque_type = GET_OPAQUE_TYPE (ntohl (new->data->id.s_addr)); oipt->status = PROC_NORMAL; oipt->t_opaque_lsa_self = NULL; @@ -560,6 +580,32 @@ free_opaque_info_per_type (void *val) ospf_opaque_lsa_flush_schedule (lsa); } + /* Remove "oipt" from its owner's self-originated LSA list. */ + switch (oipt->lsa_type) + { + case OSPF_OPAQUE_LINK_LSA: + { + struct ospf_interface *oi = (struct ospf_interface *)(oipt->owner); + listnode_delete (oi->opaque_lsa_self, oipt); + break; + } + case OSPF_OPAQUE_AREA_LSA: + { + struct ospf_area *area = (struct ospf_area *)(oipt->owner); + listnode_delete (area->opaque_lsa_self, oipt); + break; + } + case OSPF_OPAQUE_AS_LSA: + { + struct ospf *top = (struct ospf *)(oipt->owner); + listnode_delete (top->opaque_lsa_self, oipt); + break; + } + default: + zlog_warn ("free_opaque_info_per_type: Unexpected LSA-type(%u)", oipt->lsa_type); + break; /* This case may not exist. */ + } + OSPF_TIMER_OFF (oipt->t_opaque_lsa_self); list_delete (oipt->id_list); XFREE (MTYPE_OPAQUE_INFO_PER_TYPE, oipt); @@ -923,6 +969,10 @@ ospf_opaque_new_if (struct interface *ifp) list funclist; int rc = -1; + funclist = ospf_opaque_wildcard_funclist; + if (opaque_lsa_new_if_callback (funclist, ifp) != 0) + goto out; + funclist = ospf_opaque_type9_funclist; if (opaque_lsa_new_if_callback (funclist, ifp) != 0) goto out; @@ -946,6 +996,10 @@ ospf_opaque_del_if (struct interface *ifp) list funclist; int rc = -1; + funclist = ospf_opaque_wildcard_funclist; + if (opaque_lsa_del_if_callback (funclist, ifp) != 0) + goto out; + funclist = ospf_opaque_type9_funclist; if (opaque_lsa_del_if_callback (funclist, ifp) != 0) goto out; @@ -968,6 +1022,9 @@ ospf_opaque_ism_change (struct ospf_interface *oi, int old_status) { list funclist; + funclist = ospf_opaque_wildcard_funclist; + opaque_lsa_ism_change_callback (funclist, oi, old_status); + funclist = ospf_opaque_type9_funclist; opaque_lsa_ism_change_callback (funclist, oi, old_status); @@ -1017,6 +1074,9 @@ ospf_opaque_nsm_change (struct ospf_neighbor *nbr, int old_state) ; } + funclist = ospf_opaque_wildcard_funclist; + opaque_lsa_nsm_change_callback (funclist, nbr, old_state); + funclist = ospf_opaque_type9_funclist; opaque_lsa_nsm_change_callback (funclist, nbr, old_state); @@ -1038,6 +1098,9 @@ ospf_opaque_config_write_router (struct vty *vty, struct ospf *ospf) if (CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE)) vty_out (vty, " capability opaque%s", VTY_NEWLINE); + funclist = ospf_opaque_wildcard_funclist; + opaque_lsa_config_write_router_callback (funclist, vty); + funclist = ospf_opaque_type9_funclist; opaque_lsa_config_write_router_callback (funclist, vty); @@ -1055,6 +1118,9 @@ ospf_opaque_config_write_if (struct vty *vty, struct interface *ifp) { list funclist; + funclist = ospf_opaque_wildcard_funclist; + opaque_lsa_config_write_if_callback (funclist, vty, ifp); + funclist = ospf_opaque_type9_funclist; opaque_lsa_config_write_if_callback (funclist, vty, ifp); @@ -1072,6 +1138,9 @@ ospf_opaque_config_write_debug (struct vty *vty) { list funclist; + funclist = ospf_opaque_wildcard_funclist; + opaque_lsa_config_write_debug_callback (funclist, vty); + funclist = ospf_opaque_type9_funclist; opaque_lsa_config_write_debug_callback (funclist, vty); @@ -1142,6 +1211,10 @@ ospf_opaque_lsa_install_hook (struct ospf_lsa *lsa) * Some Opaque-LSA user may want to monitor every LSA installation * into the LSDB, regardless with target LSA type. */ + funclist = ospf_opaque_wildcard_funclist; + if (new_lsa_callback (funclist, lsa) != 0) + goto out; + funclist = ospf_opaque_type9_funclist; if (new_lsa_callback (funclist, lsa) != 0) goto out; @@ -1169,6 +1242,10 @@ ospf_opaque_lsa_delete_hook (struct ospf_lsa *lsa) * Some Opaque-LSA user may want to monitor every LSA deletion * from the LSDB, regardless with target LSA type. */ + funclist = ospf_opaque_wildcard_funclist; + if (del_lsa_callback (funclist, lsa) != 0) + goto out; + funclist = ospf_opaque_type9_funclist; if (del_lsa_callback (funclist, lsa) != 0) goto out; @@ -1473,6 +1550,13 @@ ospf_opaque_lsa_install (struct ospf_lsa *lsa, int rt_recalc) switch (lsa->data->type) { case OSPF_OPAQUE_LINK_LSA: + if ((top = oi_to_top (lsa->oi)) == NULL) + { + /* Above conditions must have passed. */ + zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?"); + goto out; + } + break; case OSPF_OPAQUE_AREA_LSA: if (lsa->area == NULL || (top = lsa->area->top) == NULL) { -- cgit v1.2.1