]> git.puffer.fish Git - matthieu/frr.git/commitdiff
ospf6d: Intra-prefix LSA update after frr restart
authorChirag Shah <chirag@cumulusnetworks.com>
Fri, 2 Mar 2018 22:20:26 +0000 (14:20 -0800)
committerChirag Shah <chirag@cumulusnetworks.com>
Thu, 8 Mar 2018 22:29:21 +0000 (14:29 -0800)
Initially INP LSA is originated, when connected
interface comes up. As neighbor is not up, LSA is
not transmitted but stored in DB.
As NSM transition to FULL, INP is scheduled but
ospf6_flood() would not originate the LSA as
current DB and new INP LSA same so it discards
the new LSA.
When Neighor becomes FULL, originate INP via
flushing current DB copy and generate new.
This is introduced as PR 1738 introduce,
premature aging of LSAs in nbr table as R1
going down. upon neigbor coming up, INP was
not updated to new age.

Ticket:CM-19926,CM-19945
Testing Done:

Topology R3 --- R1 -- R2, R1 have INP LSA.
After frr restart R2 and R3 re learnt R1's
INP LSA as new neighbor(s) come up.

Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
ospf6d/ospf6_area.h
ospf6d/ospf6_flood.c
ospf6d/ospf6_flood.h
ospf6d/ospf6_intra.c
ospf6d/ospf6_neighbor.c

index e162d21cd25f27fbb2b9145f80ed2cce1c4e686e..a44a432a0a96d5599fa101d015b274b0a3573f5f 100644 (file)
@@ -101,6 +101,7 @@ struct ospf6_area {
        struct timeval ts_spf; /* SPF calculation time stamp. */
 
        uint32_t full_nbrs; /* Fully adjacent neighbors. */
+       uint8_t intra_prefix_originate; /* Force intra_prefix lsa originate */
 };
 
 #define OSPF6_AREA_ENABLE     0x01
index dae10dce0d7e1cd5ba3c52daf74978395ccad393..6040c53dce191a9c03e5fd134afe640db738eaab 100644 (file)
@@ -156,6 +156,28 @@ void ospf6_lsa_purge(struct ospf6_lsa *lsa)
        ospf6_lsa_premature_aging(lsa);
 }
 
+/* Puring Multi Link-State IDs LSAs:
+ * Same Advertising Router with Multiple Link-State IDs
+ * LSAs, purging require to traverse all Link-State IDs
+ */
+void ospf6_lsa_purge_multi_ls_id(struct ospf6_area *oa, struct ospf6_lsa *lsa)
+{
+       int ls_id = 0;
+       struct ospf6_lsa *lsa_next;
+       uint16_t type;
+
+       type = lsa->header->type;
+
+       ospf6_lsa_purge(lsa);
+
+       lsa_next = ospf6_lsdb_lookup(type, htonl(++ls_id),
+                                    oa->ospf6->router_id, oa->lsdb);
+       while (lsa_next) {
+               ospf6_lsa_purge(lsa_next);
+               lsa_next = ospf6_lsdb_lookup(type, htonl(++ls_id),
+                                            oa->ospf6->router_id, oa->lsdb);
+       }
+}
 
 void ospf6_increment_retrans_count(struct ospf6_lsa *lsa)
 {
index f5d33e2843aa3269a24e56c0fd6f20aab0ccb15b..6931024fff43d0a74202a39a84113fe28dbd1cfc 100644 (file)
@@ -41,6 +41,9 @@ extern void ospf6_lsa_originate_interface(struct ospf6_lsa *lsa,
                                          struct ospf6_interface *oi);
 extern void ospf6_lsa_purge(struct ospf6_lsa *lsa);
 
+extern void ospf6_lsa_purge_multi_ls_id(struct ospf6_area *oa,
+                                       struct ospf6_lsa *lsa);
+
 /* access method to retrans_count */
 extern void ospf6_increment_retrans_count(struct ospf6_lsa *lsa);
 extern void ospf6_decrement_retrans_count(struct ospf6_lsa *lsa);
index 14f12d6b6a5faa6355d29ba1fddf1a84c8e68a6c..c9e2ff9eb5cc0e5242aceb9fc7ea1fb6bf924d8f 100644 (file)
@@ -1015,6 +1015,20 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
                return 0;
        }
 
+       /* Neighbor change to FULL, if INTRA-AREA-PREFIX LSA
+        * has not change, Flush old LSA and Re-Originate INP,
+        * as ospf6_flood() checks if LSA is same as DB,
+        * it won't be updated to neighbor's DB.
+        */
+       if (oa->intra_prefix_originate) {
+               if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
+                       zlog_debug("%s: Re-originate intra prefix LSA, Current full nbrs %u",
+                                  __PRETTY_FUNCTION__, oa->full_nbrs);
+               if (old)
+                       ospf6_lsa_purge_multi_ls_id(oa, old);
+               oa->intra_prefix_originate = 0;
+       }
+
        /* put prefixes to advertise */
        prefix_num = 0;
        op = (struct ospf6_prefix *)((caddr_t)intra_prefix_lsa
index 542a24bfc94b411316696dda2e894d54bfd52ad8..16bf2fd8e7bbb87ee6913f80566e2e954e4daccf 100644 (file)
@@ -188,6 +188,9 @@ static void ospf6_neighbor_state_change(u_char next_state,
                        OSPF6_NETWORK_LSA_SCHEDULE(on->ospf6_if);
                        OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(on->ospf6_if);
                }
+               if (next_state == OSPF6_NEIGHBOR_FULL)
+                       on->ospf6_if->area->intra_prefix_originate = 1;
+
                OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(on->ospf6_if->area);
 
                if (prev_state == OSPF6_NEIGHBOR_LOADING