]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: re-add write trigger logic
authorQuentin Young <qlyoung@cumulusnetworks.com>
Mon, 6 Nov 2017 19:15:36 +0000 (14:15 -0500)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Thu, 30 Nov 2017 21:18:06 +0000 (16:18 -0500)
Apparently I didn't fully understand how subgroup packets make their way
out to individual peers. Turns out (on the base branch) we just busy
poll while waiting for packets to make their way onto subgroup queues.
While this needs to be fixed in the future, for now readding this logic
fixes performance issues with convergence.

bgpd/bgp_packet.c

index 31918236ef42b6145c04a7948549a2a44549c6d7..b28612922fbb0f447e30ff8f8b53872b5e1a2ecd 100644 (file)
@@ -305,6 +305,59 @@ int bgp_nlri_parse(struct peer *peer, struct attr *attr,
        return -1;
 }
 
+/* The next action for the peer from a write perspective */
+static void bgp_write_proceed_actions(struct peer *peer)
+{
+       afi_t afi;
+       safi_t safi;
+       struct peer_af *paf;
+       struct bpacket *next_pkt;
+       struct update_subgroup *subgrp;
+
+       for (afi = AFI_IP; afi < AFI_MAX; afi++)
+               for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
+                       paf = peer_af_find(peer, afi, safi);
+                       if (!paf)
+                               continue;
+                       subgrp = paf->subgroup;
+                       if (!subgrp)
+                               continue;
+
+                       next_pkt = paf->next_pkt_to_send;
+                       if (next_pkt && next_pkt->buffer) {
+                               BGP_TIMER_ON(peer->t_generate_updgrp_packets,
+                                            bgp_generate_updgrp_packets, 0);
+                               return;
+                       }
+
+                       /* No packets readily available for AFI/SAFI, are there
+                        * subgroup packets
+                        * that need to be generated? */
+                       if (bpacket_queue_is_full(SUBGRP_INST(subgrp),
+                                                 SUBGRP_PKTQ(subgrp))
+                           || subgroup_packets_to_build(subgrp)) {
+                               BGP_TIMER_ON(peer->t_generate_updgrp_packets,
+                                            bgp_generate_updgrp_packets, 0);
+                               return;
+                       }
+
+                       /* No packets to send, see if EOR is pending */
+                       if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
+                               if (!subgrp->t_coalesce
+                                   && peer->afc_nego[afi][safi]
+                                   && peer->synctime
+                                   && !CHECK_FLAG(peer->af_sflags[afi][safi],
+                                                  PEER_STATUS_EOR_SEND)
+                                   && safi != SAFI_MPLS_VPN) {
+                                       BGP_TIMER_ON(
+                                               peer->t_generate_updgrp_packets,
+                                               bgp_generate_updgrp_packets, 0);
+                                       return;
+                               }
+                       }
+               }
+}
+
 /**
  * Enqueue onto the peer's output buffer any packets which are pending for the
  * update group it is a member of.
@@ -407,6 +460,8 @@ int bgp_generate_updgrp_packets(struct thread *thread)
                        }
        } while (s);
 
+       bgp_write_proceed_actions(peer);
+
        return 0;
 }