]> git.proxmox.com Git - mirror_frr.git/commitdiff
ospfd: When a neighbor goes down clear the oi->obuf if we can
authorDonald Sharp <sharpd@nvidia.com>
Thu, 11 Aug 2022 01:49:37 +0000 (21:49 -0400)
committerDonald Sharp <sharpd@nvidia.com>
Thu, 11 Aug 2022 17:30:32 +0000 (13:30 -0400)
When a neighbor goes down on an interface and that interface
has no more neighbors in a viable state where packets should
be being sent, then let's clear up the oi->obuf associated
with the interface the neighbor is on.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
ospfd/ospf_nsm.c

index 333389596b1b97f120ec24c5738914e5243ac11f..1373e5e1bb3ee5fefa004ab84b51403a0071fc6f 100644 (file)
@@ -382,6 +382,10 @@ static void nsm_clear_adj(struct ospf_neighbor *nbr)
 
 static int nsm_kill_nbr(struct ospf_neighbor *nbr)
 {
+       struct ospf_interface *oi = nbr->oi;
+       struct ospf_neighbor *on;
+       struct route_node *rn;
+
        /* killing nbr_self is invalid */
        if (nbr == nbr->oi->nbr_self) {
                assert(nbr != nbr->oi->nbr_self);
@@ -407,6 +411,42 @@ static int nsm_kill_nbr(struct ospf_neighbor *nbr)
                                ospf_get_name(nbr->oi->ospf));
        }
 
+       /*
+        * Do we have any neighbors that are also operating
+        * on this interface?
+        */
+       for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
+               on = rn->info;
+
+               if (!on)
+                       continue;
+
+               if (on == nbr || on == oi->nbr_self)
+                       continue;
+
+               /*
+                * on is in some state where we might be
+                * sending packets on this interface
+                */
+               if (on->state > NSM_Down) {
+                       route_unlock_node(rn);
+                       return 0;
+               }
+       }
+       /*
+        * If we get here we know that this interface
+        * has no neighbors in a state where we could
+        * be sending packets.  Let's flush anything
+        * we got.
+        */
+       ospf_fifo_flush(oi->obuf);
+       if (oi->on_write_q) {
+               listnode_delete(oi->ospf->oi_write_q, oi);
+               if (list_isempty(oi->ospf->oi_write_q))
+                       THREAD_OFF(oi->ospf->t_write);
+               oi->on_write_q = 0;
+       }
+
        return 0;
 }