]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BGP runs TX as a deferred routine
authorMaria Matejka <mq@ucw.cz>
Thu, 27 Jun 2024 07:34:23 +0000 (09:34 +0200)
committerMaria Matejka <mq@ucw.cz>
Fri, 28 Jun 2024 20:03:45 +0000 (22:03 +0200)
This should help flushing the tx buffers as soon as possible.

proto/bgp/attrs.c
proto/bgp/bgp.c
proto/bgp/bgp.h
proto/bgp/packets.c

index 7cc3e514259f3e361d940c22f74bd0ffabb8bc1e..6da6e1a869221eef8952f125294b0947bf2ed02d 100644 (file)
@@ -1841,32 +1841,34 @@ bgp_done_prefix(struct bgp_ptx_private *c, struct bgp_prefix *px, struct bgp_buc
 void
 bgp_tx_resend(struct bgp_proto *p, struct bgp_channel *bc)
 {
-  BGP_PTX_LOCK(bc->tx, c);
-
-  ASSERT_DIE(bc->tx_keep);
   uint seen = 0;
-
-  HASH_WALK(c->prefix_hash, next, px)
   {
-    if (!px->cur)
+    BGP_PTX_LOCK(bc->tx, c);
+
+    ASSERT_DIE(bc->tx_keep);
+
+    HASH_WALK(c->prefix_hash, next, px)
     {
-      ASSERT_DIE(px->last);
-      struct bgp_bucket *last = px->last;
+      if (!px->cur)
+      {
+       ASSERT_DIE(px->last);
+       struct bgp_bucket *last = px->last;
 
-      /* Remove the last reference, we wanna resend the route */
-      px->last->px_uc--;
-      px->last = NULL;
+       /* Remove the last reference, we wanna resend the route */
+       px->last->px_uc--;
+       px->last = NULL;
 
-      /* And send it once again */
-      seen += bgp_update_prefix(c, px, last);
+       /* And send it once again */
+       seen += bgp_update_prefix(c, px, last);
+      }
     }
-  }
-  HASH_WALK_END;
+    HASH_WALK_END;
 
-  if (bc->c.debug & D_EVENTS)
-    log(L_TRACE "%s.%s: TX resending %u routes",
-       bc->c.proto->name, bc->c.name, seen);
+    if (bc->c.debug & D_EVENTS)
+      log(L_TRACE "%s.%s: TX resending %u routes",
+         bc->c.proto->name, bc->c.name, seen);
 
+  }
   if (seen)
     bgp_schedule_packet(p->conn, bc, PKT_UPDATE);
 }
index b0ec980d36859b0594c5b2a1efa8a1f50edd3593..163fdf6a6113a0125c7aef989a7bfb470b2a0fc7 100644 (file)
@@ -475,8 +475,6 @@ bgp_close_conn(struct bgp_conn *conn)
   conn->hold_timer = NULL;
   rfree(conn->send_hold_timer);
   conn->send_hold_timer = NULL;
-  rfree(conn->tx_ev);
-  conn->tx_ev = NULL;
 
   sk_close(conn->sk);
   conn->sk = NULL;
@@ -1168,10 +1166,6 @@ bgp_keepalive_timeout(timer *t)
 
   DBG("BGP: Keepalive timer\n");
   bgp_schedule_packet(conn, NULL, PKT_KEEPALIVE);
-
-  /* Kick TX a bit faster */
-  if (ev_active(conn->tx_ev))
-    ev_run(conn->tx_ev);
 }
 
 void
@@ -1211,8 +1205,6 @@ bgp_setup_conn(struct bgp_proto *p, struct bgp_conn *conn)
   conn->hold_timer     = tm_new_init(p->p.pool, bgp_hold_timeout,       conn, 0, 0);
   conn->keepalive_timer        = tm_new_init(p->p.pool, bgp_keepalive_timeout, conn, 0, 0);
   conn->send_hold_timer = tm_new_init(p->p.pool, bgp_send_hold_timeout, conn, 0, 0);
-
-  conn->tx_ev = ev_new_init(p->p.pool, bgp_kick_tx, conn);
 }
 
 static void
@@ -2796,9 +2788,8 @@ bgp_show_proto_info(struct proto *P)
            tm_remains(p->conn->hold_timer), p->conn->hold_time);
     cli_msg(-1006, "    Keepalive timer:  %t/%u",
            tm_remains(p->conn->keepalive_timer), p->conn->keepalive_time);
-    cli_msg(-1006, "    TX pending:       %d bytes%s",
-           p->conn->sk->tpos - p->conn->sk->ttx,
-           ev_active(p->conn->tx_ev) ? " (refill scheduled)" : "");
+    cli_msg(-1006, "    TX pending:       %d bytes",
+           p->conn->sk->tpos - p->conn->sk->ttx);
     cli_msg(-1006, "    Send hold timer:  %t/%u",
            tm_remains(p->conn->send_hold_timer), p->conn->send_hold_time);
 }
index a4fcc65bdec14925ed53da5c3c0fe8e3ca34d147..7b7908f6d2f113e02c070b80357d8af736e338fa 100644 (file)
@@ -309,7 +309,6 @@ struct bgp_conn {
   timer *hold_timer;
   timer *keepalive_timer;
   timer *send_hold_timer;
-  event *tx_ev;
   u32 packets_to_send;                 /* Bitmap of packet types to be sent */
   u32 channels_to_send;                        /* Bitmap of channels with packets to be sent */
   u8 last_channel;                     /* Channel used last time for TX */
@@ -708,7 +707,6 @@ int bgp_check_capabilities(struct bgp_conn *conn);
 const struct bgp_af_desc *bgp_get_af_desc(u32 afi);
 const struct bgp_af_caps *bgp_find_af_caps(struct bgp_caps *caps, u32 afi);
 void bgp_schedule_packet(struct bgp_conn *conn, struct bgp_channel *c, int type);
-void bgp_kick_tx(void *vconn);
 void bgp_tx(struct birdsock *sk);
 int bgp_rx(struct birdsock *sk, uint size);
 void bgp_do_uncork(callback *);
index 530b2d744ac684a73f5f9ca9142f8036c53ef8bc..10ee4bc0395cc4a39e80c3fcfae57a0b284f62ab 100644 (file)
@@ -1052,9 +1052,12 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, uint len)
       conn->hold_time, conn->keepalive_time, p->remote_as, p->remote_id, conn->as4_session);
 
   bgp_schedule_packet(conn, NULL, PKT_KEEPALIVE);
-  bgp_start_timer(p, conn->hold_timer, conn->hold_time);
-  bgp_start_timer(p, conn->send_hold_timer, conn->send_hold_time);
-  bgp_conn_enter_openconfirm_state(conn);
+  if (conn->sk)
+  {
+    bgp_start_timer(p, conn->hold_timer, conn->hold_time);
+    bgp_start_timer(p, conn->send_hold_timer, conn->send_hold_time);
+    bgp_conn_enter_openconfirm_state(conn);
+  }
 }
 
 
@@ -3142,6 +3145,12 @@ bgp_fire_tx(struct bgp_conn *conn)
   return 0;
 }
 
+static void bgp_tx_deferred(struct deferred_call *dc);
+struct bgp_tx_deferred_call {
+  struct deferred_call dc;
+  struct bgp_conn *conn;
+};
+
 /**
  * bgp_schedule_packet - schedule a packet for transmission
  * @conn: connection
@@ -3161,6 +3170,8 @@ bgp_schedule_packet(struct bgp_conn *conn, struct bgp_channel *c, int type)
   else
     BGP_TRACE(D_PACKETS, "Scheduling packet type %d", type);
 
+  bool was_active = conn->channels_to_send || conn->packets_to_send;
+
   if (c)
   {
     if (! conn->channels_to_send)
@@ -3175,18 +3186,28 @@ bgp_schedule_packet(struct bgp_conn *conn, struct bgp_channel *c, int type)
   else
     conn->packets_to_send |= 1 << type;
 
-  if ((conn->sk->tpos == conn->sk->tbuf) && !ev_active(conn->tx_ev))
-    proto_send_event(&p->p, conn->tx_ev);
+  if (was_active || (conn->sk->tpos != conn->sk->tbuf))
+    return;
+  else if ((type == PKT_KEEPALIVE) || (this_birdloop != p->p.loop))
+    while (bgp_fire_tx(conn) > 0)
+      ;
+  else
+  {
+    struct bgp_tx_deferred_call btdc = {
+      .dc.hook = bgp_tx_deferred,
+      .conn = conn,
+    };
+    defer_call(&btdc.dc, sizeof btdc);
+  }
 }
-void
-bgp_kick_tx(void *vconn)
-{
-  struct bgp_conn *conn = vconn;
 
+static void
+bgp_tx_deferred(struct deferred_call *dc)
+{
+  struct bgp_conn *conn = SKIP_BACK(struct bgp_tx_deferred_call, dc, dc)->conn;
   DBG("BGP: kicking TX\n");
   while (bgp_fire_tx(conn) > 0)
-    MAYBE_DEFER_TASK(proto_event_list(&conn->bgp->p), conn->tx_ev,
-       "BGP TX for %s", conn->bgp->p.name);
+    ;
 }
 
 void
@@ -3202,8 +3223,7 @@ bgp_tx(sock *sk)
 
   DBG("BGP: TX hook\n");
   while (bgp_fire_tx(conn) > 0)
-    MAYBE_DEFER_TASK(proto_event_list(&conn->bgp->p), conn->tx_ev,
-       "BGP TX for %s", conn->bgp->p.name);
+    ;
 }