]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospfd: flush self-originated lsa upon restart frr 1430/head
authorChirag Shah <chirag@cumulusnetworks.com>
Tue, 7 Nov 2017 02:17:19 +0000 (18:17 -0800)
committerChirag Shah <chirag@cumulusnetworks.com>
Wed, 8 Nov 2017 02:14:14 +0000 (18:14 -0800)
Router-ID change or ospf instance going down,
send LS-Upd with MAXAGE to self origintated LSAs to
all ospf neighbors.

Ticket:CM-1576
Testing Done:
Bring R1 - R2, Change Router-ID on R2, restart frr on R2
Validated R1 ospf LSDB for max aged 3600 LSA from R2.

Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
ospfd/ospf_flood.c
ospfd/ospf_lsa.c
ospfd/ospf_packet.c
ospfd/ospf_packet.h
ospfd/ospfd.c
ospfd/ospfd.h

index aac2f3ee92834b23c54630206394bdb3734faafa..facce9aafd1d3a54b9bb2896057d6539bf174b08 100644 (file)
@@ -361,9 +361,9 @@ static int ospf_flood_through_interface(struct ospf_interface *oi,
        if (IS_DEBUG_OSPF_EVENT)
                zlog_debug(
                        "ospf_flood_through_interface(): "
-                       "considering int %s, INBR(%s), LSA[%s]",
+                       "considering int %s, INBR(%s), LSA[%s] AGE %u",
                        IF_NAME(oi), inbr ? inet_ntoa(inbr->router_id) : "NULL",
-                       dump_lsa_key(lsa));
+                       dump_lsa_key(lsa), ntohs(lsa->data->ls_age));
 
        if (!ospf_if_is_enable(oi))
                return 0;
@@ -958,6 +958,9 @@ void ospf_lsa_flush_area(struct ospf_lsa *lsa, struct ospf_area *area)
           more time for the ACK to be received and avoid
           retransmissions */
        lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
+       if (IS_DEBUG_OSPF_EVENT)
+               zlog_debug("%s: MAXAGE set to LSA %s", __PRETTY_FUNCTION__,
+                          inet_ntoa(lsa->data->id));
        monotime(&lsa->tv_recv);
        lsa->tv_orig = lsa->tv_recv;
        ospf_flood_through_area(area, NULL, lsa);
index 4e6769405952f8723660785a80ad8395d914eb46..fc866df965b74a5f5cc7656dc5cd7374c871f43d 100644 (file)
@@ -3302,6 +3302,8 @@ void ospf_flush_self_originated_lsas_now(struct ospf *ospf)
        struct route_node *rn;
        int need_to_flush_ase = 0;
 
+       ospf->inst_shutdown = 1;
+
        for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
                if ((lsa = area->router_lsa_self) != NULL) {
                        if (IS_DEBUG_OSPF_EVENT)
index 633c3deeafd92166e847d57b879c0ea18c1928e0..33792bbff3f4b185916f11a44821dd7377db4677 100644 (file)
@@ -518,7 +518,8 @@ int ospf_ls_upd_timer(struct thread *thread)
                }
 
                if (listcount(update) > 0)
-                       ospf_ls_upd_send(nbr, update, OSPF_SEND_PACKET_DIRECT);
+                       ospf_ls_upd_send(nbr, update,
+                                        OSPF_SEND_PACKET_DIRECT, 0);
                list_delete_and_null(&update);
        }
 
@@ -1609,10 +1610,10 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh,
                if (length + ntohs(find->data->length) > ospf_packet_max(oi)) {
                        if (oi->type == OSPF_IFTYPE_NBMA)
                                ospf_ls_upd_send(nbr, ls_upd,
-                                                OSPF_SEND_PACKET_DIRECT);
+                                                OSPF_SEND_PACKET_DIRECT, 0);
                        else
                                ospf_ls_upd_send(nbr, ls_upd,
-                                                OSPF_SEND_PACKET_INDIRECT);
+                                                OSPF_SEND_PACKET_INDIRECT, 0);
 
                        /* Only remove list contents.  Keep ls_upd. */
                        list_delete_all_node(ls_upd);
@@ -1630,10 +1631,11 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh,
        /* Send rest of Link State Update. */
        if (listcount(ls_upd) > 0) {
                if (oi->type == OSPF_IFTYPE_NBMA)
-                       ospf_ls_upd_send(nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
+                       ospf_ls_upd_send(nbr, ls_upd,
+                                        OSPF_SEND_PACKET_DIRECT, 0);
                else
                        ospf_ls_upd_send(nbr, ls_upd,
-                                        OSPF_SEND_PACKET_INDIRECT);
+                                        OSPF_SEND_PACKET_INDIRECT, 0);
 
                list_delete_and_null(&ls_upd);
        } else
@@ -3792,7 +3794,13 @@ void ospf_ls_upd_send_lsa(struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
        update = list_new();
 
        listnode_add(update, lsa);
-       ospf_ls_upd_send(nbr, update, flag);
+
+       /*ospf instance is going down, send self originated
+        * MAXAGE LSA update to neighbors to remove from LSDB */
+       if (nbr->oi->ospf->inst_shutdown && IS_LSA_MAXAGE(lsa))
+               ospf_ls_upd_send(nbr, update, flag, 1);
+       else
+               ospf_ls_upd_send(nbr, update, flag, 0);
 
        list_delete_and_null(&update);
 }
@@ -3875,7 +3883,8 @@ static struct ospf_packet *ospf_ls_upd_packet_new(struct list *update,
 }
 
 static void ospf_ls_upd_queue_send(struct ospf_interface *oi,
-                                  struct list *update, struct in_addr addr)
+                                  struct list *update, struct in_addr addr,
+                                  int send_lsupd_now)
 {
        struct ospf_packet *op;
        u_int16_t length = OSPF_HEADER_SIZE;
@@ -3908,9 +3917,20 @@ static void ospf_ls_upd_queue_send(struct ospf_interface *oi,
 
        /* Add packet to the interface output queue. */
        ospf_packet_add(oi, op);
-
-       /* Hook thread to write packet. */
-       OSPF_ISM_WRITE_ON(oi->ospf);
+       /* Call ospf_write() right away to send ospf packets to neighbors */
+       if (send_lsupd_now) {
+               struct thread os_packet_thd;
+
+               os_packet_thd.arg = (void *)oi->ospf;
+               if (oi->on_write_q == 0) {
+                       listnode_add(oi->ospf->oi_write_q, oi);
+                       oi->on_write_q = 1;
+               }
+               ospf_write(&os_packet_thd);
+       } else {
+               /* Hook thread to write packet. */
+               OSPF_ISM_WRITE_ON(oi->ospf);
+       }
 }
 
 static int ospf_ls_upd_send_queue_event(struct thread *thread)
@@ -3934,7 +3954,7 @@ static int ospf_ls_upd_send_queue_event(struct thread *thread)
 
                update = (struct list *)rn->info;
 
-               ospf_ls_upd_queue_send(oi, update, rn->p.u.prefix4);
+               ospf_ls_upd_queue_send(oi, update, rn->p.u.prefix4, 0);
 
                /* list might not be empty. */
                if (listcount(update) == 0) {
@@ -3961,7 +3981,8 @@ static int ospf_ls_upd_send_queue_event(struct thread *thread)
        return 0;
 }
 
-void ospf_ls_upd_send(struct ospf_neighbor *nbr, struct list *update, int flag)
+void ospf_ls_upd_send(struct ospf_neighbor *nbr, struct list *update, int flag,
+                     int send_lsupd_now)
 {
        struct ospf_interface *oi;
        struct ospf_lsa *lsa;
@@ -4006,8 +4027,24 @@ void ospf_ls_upd_send(struct ospf_neighbor *nbr, struct list *update, int flag)
        for (ALL_LIST_ELEMENTS_RO(update, node, lsa))
                listnode_add(rn->info,
                             ospf_lsa_lock(lsa)); /* oi->ls_upd_queue */
+       if (send_lsupd_now) {
+               struct list *send_update_list;
+               struct route_node *rn, *rnext;
 
-       thread_add_event(master, ospf_ls_upd_send_queue_event, oi, 0,
+               for (rn = route_top(oi->ls_upd_queue); rn; rn = rnext) {
+                       rnext = route_next(rn);
+
+                       if (rn->info == NULL)
+                               continue;
+
+                       send_update_list = (struct list *)rn->info;
+
+                       ospf_ls_upd_queue_send(oi, send_update_list,
+                                              rn->p.u.prefix4, 1);
+
+               }
+       } else
+               thread_add_event(master, ospf_ls_upd_send_queue_event, oi, 0,
                         &oi->t_ls_upd_event);
 }
 
index a3617c7bdacd616519532f81ba5f57631ba371fa..78b2b81e5060d0ff5e6b790f0d215f9bc03b206f 100644 (file)
@@ -152,7 +152,7 @@ extern void ospf_db_desc_resend(struct ospf_neighbor *);
 extern void ospf_ls_req_send(struct ospf_neighbor *);
 extern void ospf_ls_upd_send_lsa(struct ospf_neighbor *, struct ospf_lsa *,
                                 int);
-extern void ospf_ls_upd_send(struct ospf_neighbor *, struct list *, int);
+extern void ospf_ls_upd_send(struct ospf_neighbor *, struct list *, int, int);
 extern void ospf_ls_ack_send(struct ospf_neighbor *, struct ospf_lsa *);
 extern void ospf_ls_ack_send_delayed(struct ospf_interface *);
 extern void ospf_ls_retransmit(struct ospf_interface *, struct ospf_lsa *);
index b0646495a581cd87ed269b5cd01dcf0347369889..a37867fe236091fb1d202c791e4527aea0234be6 100644 (file)
@@ -596,8 +596,7 @@ static void ospf_finish_final(struct ospf *ospf)
 
        ospf_opaque_type11_lsa_term(ospf);
 
-       /* be nice if this worked, but it doesn't */
-       /*ospf_flush_self_originated_lsas_now (ospf);*/
+       ospf_flush_self_originated_lsas_now(ospf);
 
        /* Unregister redistribution */
        for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
index df318cf2c0aa0e276b5ae2aad1655b257fa48304..6cccccc64901c1418aa4feace23c51c71ebe3dd4 100644 (file)
@@ -310,6 +310,10 @@ struct ospf {
 
        struct route_table *distance_table;
 
+       /* Used during ospf instance going down send LSDB
+        * update to neighbors immediatly */
+       uint8_t inst_shutdown;
+
        QOBJ_FIELDS
 };
 DECLARE_QOBJ_TYPE(ospf)