]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospfd: For an ABR, ensure the right LSID is MaxAge'd
authorPradosh Mohapatra <pmohapat@cumulusnetworks.com>
Mon, 28 Apr 2014 10:58:06 +0000 (10:58 +0000)
committerDavid Lamparter <equinox@opensourcerouting.org>
Wed, 14 May 2014 14:46:41 +0000 (16:46 +0200)
PROBLEM:

Accurate garbage collection of maxage LSAs. The global OSPF structure has
a maxage_lsa tree - the key to the tree is <ls-id, adv-router> tuple. Suppose
the ABR has multiple areas and has originated some intra-area LSAs. The
key for all those LSAs is the same. The code then ends up in a state where
all but the first LSA do not get cleaned up from the areas' LSDB. A subsequent
event would readvertise those LSAs.

PATCH:

Since the LSA is going to stick around till it actually gets cleaned up by
the maxage_walker, make the LSA pointer as the key. Each distinct LSA that
gets maxage'd then gets added to the tree and will get cleaned up correctly.

Signed-off-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
[CF: Use CHAR_BIT; use uintptr_t; use sizeof(field) instead of sizeof(type)]
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
[DL: this must remain a temporary fix! needs to be redone after 0.99.23]
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
lib/prefix.h
ospfd/ospf_lsa.c

index 9ef70ff50c8e0e2b5a294c478f98fe2c8827dc20..45889e0862521a9cc6027d15ddebbc1da37ad4c7 100644 (file)
@@ -52,6 +52,7 @@ struct prefix
       struct in_addr adv_router;
     } lp;
     u_char val[8];
+    uintptr_t ptr;
   } u __attribute__ ((aligned (8)));
 };
 
@@ -89,6 +90,14 @@ struct prefix_rd
   u_char val[8] __attribute__ ((aligned (8)));
 };
 
+/* Prefix for a generic pointer */
+struct prefix_ptr
+{
+  u_char family;
+  u_char prefixlen;
+  uintptr_t prefix __attribute__ ((aligned (8)));
+};
+
 /* helper to get type safety/avoid casts on calls
  * (w/o this, functions accepting all prefix types need casts on the caller
  * side, which strips type safety since the cast will accept any pointer
index 369655163af5af2a08a892d8b0d7cc61c50eb528..0a66b1d4c73130139e2146667144f9410b9a257b 100644 (file)
@@ -2903,9 +2903,11 @@ void
 ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
 {
   struct route_node *rn;
-  struct prefix_ls lsa_prefix;
+  struct prefix_ptr lsa_prefix;
 
-  ls_prefix_set (&lsa_prefix, lsa);
+  lsa_prefix.family = 0;
+  lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
+  lsa_prefix.prefix = (uintptr_t) lsa;
 
   if ((rn = route_node_lookup(ospf->maxage_lsa,
                              (struct prefix *)&lsa_prefix)))
@@ -2929,7 +2931,7 @@ ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
 void
 ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
 {
-  struct prefix_ls lsa_prefix;
+  struct prefix_ptr lsa_prefix;
   struct route_node *rn;
 
   /* When we saw a MaxAge LSA flooded to us, we put it on the list
@@ -2942,12 +2944,18 @@ ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
       return;
     }
 
-  ls_prefix_set (&lsa_prefix, lsa);
+  lsa_prefix.family = 0;
+  lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
+  lsa_prefix.prefix = (uintptr_t) lsa;
+
   if ((rn = route_node_get (ospf->maxage_lsa,
                            (struct prefix *)&lsa_prefix)) != NULL)
     {
       if (rn->info != NULL)
        {
+         if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
+           zlog_debug ("LSA[%s]: found LSA (%p) in table for LSA %p %d",
+                       dump_lsa_key (lsa), rn->info, lsa, lsa_prefix.prefixlen);
          route_unlock_node (rn);
        }
       else