conn->keepalive_timer = NULL;
rfree(conn->hold_timer);
conn->hold_timer = NULL;
-
+ rfree(conn->send_hold_timer);
+ conn->send_hold_timer = NULL;
rfree(conn->tx_ev);
conn->tx_ev = NULL;
- rfree(conn->sk);
+
+ sk_close(conn->sk);
conn->sk = NULL;
mb_free(conn->local_open_msg);
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, " Send hold timer: %t/%u",
+ tm_remains(p->conn->send_hold_timer), p->conn->send_hold_time);
+ }
#if 0
struct bgp_stats *s = &p->stats;
int notify_code, notify_subcode, notify_size;
byte *notify_data;
- uint hold_time, keepalive_time; /* Times calculated from my and neighbor's requirements */
+ uint hold_time, keepalive_time, send_hold_time; /* Times calculated from my and neighbor's requirements */
};
+struct bgp_listen_request {
+ node n; /* Node in bgp_socket / pending list */
+ struct bgp_socket *sock; /* Assigned socket */
+ ip_addr addr;
+ struct iface *iface;
+ struct iface *vrf;
+ uint port;
+ uint flags;
+};
+
struct bgp_proto {
struct proto p;
const struct bgp_config *cf; /* Shortcut to BGP configuration */
GRACEFUL, RESTART, AWARE, CHECK, LINK, PORT, EXTENDED, MESSAGES, SETKEY,
STRICT, BIND, CONFEDERATION, MEMBER, MULTICAST, FLOW4, FLOW6, LONG,
LIVED, STALE, IMPORT, IBGP, EBGP, MANDATORY, INTERNAL, EXTERNAL, SETS,
- DYNAMIC, RANGE, NAME, DIGITS, BGP_AIGP, AIGP, ORIGINATE, COST, ENFORCE,
+ DYNAMIC, RANGE, NAME, DIGITS, AIGP, ORIGINATE, COST, ENFORCE,
FIRST, FREE, VALIDATE, BASE, ROLE, ROLES, PEER, PROVIDER, CUSTOMER,
- RS_SERVER, RS_CLIENT, REQUIRE, BGP_OTC, GLOBAL)
+ RS_SERVER, RS_CLIENT, REQUIRE, BGP_OTC, GLOBAL, SEND)
%type <i> bgp_nh
%type <i32> bgp_afi
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(conn->hold_timer, conn->hold_time);
- bgp_start_timer(conn->send_hold_timer, conn->send_hold_time);
+ 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);
}
put_u16(buf+16, len);
buf[18] = type;
- return sk_send(sk, len);
+ int success = sk_send(sk, len);
+ if (success && ((conn->state == BS_ESTABLISHED) || (conn->state == BS_OPENCONFIRM)))
- bgp_start_timer(conn->send_hold_timer, conn->send_hold_time);
++ bgp_start_timer(conn->bgp, conn->send_hold_timer, conn->send_hold_time);
+
+ return success;
}
/**
{
struct bgp_conn *conn = sk->data;
- bgp_start_timer(conn->send_hold_timer, conn->send_hold_time);
+ ASSERT_DIE(birdloop_inside(conn->bgp->p.loop));
++
+ /* Pending message was passed to kernel */
+ if ((conn->state == BS_ESTABLISHED) || (conn->state == BS_OPENCONFIRM))
++ bgp_start_timer(conn->bgp, conn->send_hold_timer, conn->send_hold_time);
+
DBG("BGP: TX hook\n");
uint max = 1024;
while (--max && (bgp_fire_tx(conn) > 0))