mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
BGP runs TX as a deferred routine
This should help flushing the tx buffers as soon as possible.
This commit is contained in:
parent
6eea722d3f
commit
45fb9742f0
@ -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;
|
||||
|
||||
if (bc->c.debug & D_EVENTS)
|
||||
log(L_TRACE "%s.%s: TX resending %u routes",
|
||||
bc->c.proto->name, bc->c.name, seen);
|
||||
|
||||
}
|
||||
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 (seen)
|
||||
bgp_schedule_packet(p->conn, bc, PKT_UPDATE);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user