summaryrefslogtreecommitdiffstats
path: root/ospfd/ospf_opaque.c
diff options
context:
space:
mode:
authorChristian Hopps <chopps@labn.net>2022-01-08 22:57:10 +0100
committerChristian Hopps <chopps@labn.net>2022-06-02 22:37:16 +0200
commit5349121b4c6ea2126be87bcbe6400a8f10ea99fc (patch)
tree4863a63656b2f3d7ff45f0b6eac69dfe5d030163 /ospfd/ospf_opaque.c
parentospfd: cli: add "show ip ospf reachable-routers" CLI (diff)
downloadfrr-5349121b4c6ea2126be87bcbe6400a8f10ea99fc.tar.xz
frr-5349121b4c6ea2126be87bcbe6400a8f10ea99fc.zip
ospfd: api: fix recovery of LSA after restart of api client
Prior to this fix, restarting the client just failed b/c the code tried to "refresh" the existing LSA being added, except that code checked for meta-data to exist, which was deleted when the client disconnected previously (or had never connected and the LSA state was picked up from the network). Signed-off-by: Christian Hopps <chopps@labn.net>
Diffstat (limited to 'ospfd/ospf_opaque.c')
-rw-r--r--ospfd/ospf_opaque.c96
1 files changed, 49 insertions, 47 deletions
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index 947454c0d..7e95cb591 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -74,9 +74,8 @@ int ospf_apiserver_enable;
static void ospf_opaque_register_vty(void);
static void ospf_opaque_funclist_init(void);
static void ospf_opaque_funclist_term(void);
-static void free_opaque_info_per_type(void *val);
+static void free_opaque_info_per_type_del(void *val);
static void free_opaque_info_per_id(void *val);
-static void free_opaque_info_owner(void *val);
static int ospf_opaque_lsa_install_hook(struct ospf_lsa *lsa);
static int ospf_opaque_lsa_delete_hook(struct ospf_lsa *lsa);
@@ -141,7 +140,7 @@ int ospf_opaque_type9_lsa_init(struct ospf_interface *oi)
list_delete(&oi->opaque_lsa_self);
oi->opaque_lsa_self = list_new();
- oi->opaque_lsa_self->del = free_opaque_info_per_type;
+ oi->opaque_lsa_self->del = free_opaque_info_per_type_del;
oi->t_opaque_lsa_self = NULL;
return 0;
}
@@ -161,7 +160,7 @@ int ospf_opaque_type10_lsa_init(struct ospf_area *area)
list_delete(&area->opaque_lsa_self);
area->opaque_lsa_self = list_new();
- area->opaque_lsa_self->del = free_opaque_info_per_type;
+ area->opaque_lsa_self->del = free_opaque_info_per_type_del;
area->t_opaque_lsa_self = NULL;
#ifdef MONITOR_LSDB_CHANGE
@@ -189,7 +188,7 @@ int ospf_opaque_type11_lsa_init(struct ospf *top)
list_delete(&top->opaque_lsa_self);
top->opaque_lsa_self = list_new();
- top->opaque_lsa_self->del = free_opaque_info_per_type;
+ top->opaque_lsa_self->del = free_opaque_info_per_type_del;
top->t_opaque_lsa_self = NULL;
#ifdef MONITOR_LSDB_CHANGE
@@ -263,6 +262,9 @@ static const char *ospf_opaque_type_name(uint8_t opaque_type)
struct opaque_info_per_type; /* Forward declaration. */
+static void free_opaque_info_per_type(struct opaque_info_per_type *oipt,
+ bool cleanup_owner);
+
struct ospf_opaque_functab {
uint8_t opaque_type;
struct opaque_info_per_type *oipt;
@@ -433,12 +435,9 @@ void ospf_delete_opaque_functab(uint8_t lsa_type, uint8_t opaque_type)
if (functab->opaque_type == opaque_type) {
/* Cleanup internal control information, if it
* still remains. */
- if (functab->oipt != NULL) {
- free_opaque_info_owner(functab->oipt);
- free_opaque_info_per_type(
- functab->oipt);
- }
-
+ if (functab->oipt != NULL)
+ free_opaque_info_per_type(functab->oipt,
+ true);
/* Dequeue listnode entry from the list. */
listnode_delete(funclist, functab);
@@ -558,8 +557,7 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab,
case OSPF_OPAQUE_AS_LSA:
top = ospf_lookup_by_vrf_id(new->vrf_id);
if (new->area != NULL && (top = new->area->ospf) == NULL) {
- free_opaque_info_owner(oipt);
- free_opaque_info_per_type(oipt);
+ free_opaque_info_per_type(oipt, true);
oipt = NULL;
goto out; /* This case may not exist. */
}
@@ -571,8 +569,7 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab,
EC_OSPF_LSA_UNEXPECTED,
"register_opaque_info_per_type: Unexpected LSA-type(%u)",
new->data->type);
- free_opaque_info_owner(oipt);
- free_opaque_info_per_type(oipt);
+ free_opaque_info_per_type(oipt, true);
oipt = NULL;
goto out; /* This case may not exist. */
}
@@ -589,42 +586,13 @@ out:
return oipt;
}
-/* Remove "oipt" from its owner's self-originated LSA list. */
-static void free_opaque_info_owner(void *val)
-{
- struct opaque_info_per_type *oipt = (struct opaque_info_per_type *)val;
-
- 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:
- flog_warn(EC_OSPF_LSA_UNEXPECTED,
- "free_opaque_info_owner: Unexpected LSA-type(%u)",
- oipt->lsa_type);
- break; /* This case may not exist. */
- }
-}
-
-static void free_opaque_info_per_type(void *val)
+static void free_opaque_info_per_type(struct opaque_info_per_type *oipt,
+ bool cleanup_owner)
{
- struct opaque_info_per_type *oipt = (struct opaque_info_per_type *)val;
struct opaque_info_per_id *oipi;
struct ospf_lsa *lsa;
struct listnode *node, *nnode;
+ struct list *l;
/* Control information per opaque-id may still exist. */
for (ALL_LIST_ELEMENTS(oipt->id_list, node, nnode, oipi)) {
@@ -637,10 +605,37 @@ static void free_opaque_info_per_type(void *val)
OSPF_TIMER_OFF(oipt->t_opaque_lsa_self);
list_delete(&oipt->id_list);
+ if (cleanup_owner) {
+ /* Remove from its owner's self-originated LSA list. */
+ switch (oipt->lsa_type) {
+ case OSPF_OPAQUE_LINK_LSA:
+ l = ((struct ospf_interface *)oipt->owner)
+ ->opaque_lsa_self;
+ break;
+ case OSPF_OPAQUE_AREA_LSA:
+ l = ((struct ospf_area *)oipt->owner)->opaque_lsa_self;
+ break;
+ case OSPF_OPAQUE_AS_LSA:
+ l = ((struct ospf *)oipt->owner)->opaque_lsa_self;
+ break;
+ default:
+ flog_warn(
+ EC_OSPF_LSA_UNEXPECTED,
+ "free_opaque_info_owner: Unexpected LSA-type(%u)",
+ oipt->lsa_type);
+ return;
+ }
+ listnode_delete(l, oipt);
+ }
XFREE(MTYPE_OPAQUE_INFO_PER_TYPE, oipt);
return;
}
+static void free_opaque_info_per_type_del(void *val)
+{
+ free_opaque_info_per_type((struct opaque_info_per_type *)val, false);
+}
+
static struct opaque_info_per_type *
lookup_opaque_info_by_type(struct ospf_lsa *lsa)
{
@@ -758,6 +753,13 @@ out:
return oipi;
}
+int ospf_opaque_is_owned(struct ospf_lsa *lsa)
+{
+ struct opaque_info_per_type *oipt = lookup_opaque_info_by_type(lsa);
+
+ return (oipt != NULL && lookup_opaque_info_by_id(oipt, lsa) != NULL);
+}
+
/*------------------------------------------------------------------------*
* Following are (vty) configuration functions for Opaque-LSAs handling.
*------------------------------------------------------------------------*/