diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index b0ec980d..163fdf6a 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -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); } diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index a4fcc65b..7b7908f6 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -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 *); diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 530b2d74..4f4f0c4f 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -3142,6 +3142,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 +3167,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 +3183,27 @@ 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) + bgp_fire_tx(conn); + 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 +3219,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); + ; }