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);
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;
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;
{
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;
{
list funclist;
+ funclist = ospf_opaque_wildcard_funclist;
+ list_delete (funclist);
+
funclist = ospf_opaque_type9_funclist;
list_delete (funclist);
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;
*/
struct opaque_info_per_type
{
+ u_char lsa_type;
u_char opaque_type;
enum { PROC_NORMAL, PROC_SUSPEND } status;
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
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;
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);
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;
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;
{
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);
;
}
+ 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);
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);
{
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);
{
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);
* 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;
* 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;
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)
{