Minor BGP changes related to error wait time.
This commit is contained in:
parent
7238262671
commit
b99d378698
3 changed files with 58 additions and 57 deletions
|
@ -74,7 +74,6 @@ static int bgp_counter; /* Number of protocol instances using the listening so
|
||||||
static void bgp_close(struct bgp_proto *p, int apply_md5);
|
static void bgp_close(struct bgp_proto *p, int apply_md5);
|
||||||
static void bgp_connect(struct bgp_proto *p);
|
static void bgp_connect(struct bgp_proto *p);
|
||||||
static void bgp_active(struct bgp_proto *p);
|
static void bgp_active(struct bgp_proto *p);
|
||||||
static void bgp_stop(struct bgp_proto *p);
|
|
||||||
static sock *bgp_setup_listen_sk(void);
|
static sock *bgp_setup_listen_sk(void);
|
||||||
|
|
||||||
|
|
||||||
|
@ -221,9 +220,6 @@ bgp_close_conn(struct bgp_conn *conn)
|
||||||
/**
|
/**
|
||||||
* bgp_update_startup_delay - update a startup delay
|
* bgp_update_startup_delay - update a startup delay
|
||||||
* @p: BGP instance
|
* @p: BGP instance
|
||||||
* @conn: related BGP connection
|
|
||||||
* @code: BGP error code
|
|
||||||
* @subcode: BGP error subcode
|
|
||||||
*
|
*
|
||||||
* This function updates a startup delay that is used to postpone next BGP connect.
|
* This function updates a startup delay that is used to postpone next BGP connect.
|
||||||
* It also handles disable_after_error and might stop BGP instance when error
|
* It also handles disable_after_error and might stop BGP instance when error
|
||||||
|
@ -232,26 +228,11 @@ bgp_close_conn(struct bgp_conn *conn)
|
||||||
* It should be called when BGP protocol error happened.
|
* It should be called when BGP protocol error happened.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
bgp_update_startup_delay(struct bgp_proto *p, struct bgp_conn *conn, unsigned code, unsigned subcode)
|
bgp_update_startup_delay(struct bgp_proto *p)
|
||||||
{
|
{
|
||||||
struct bgp_config *cf = p->cf;
|
struct bgp_config *cf = p->cf;
|
||||||
|
|
||||||
/* Don't handle cease messages as errors */
|
DBG("BGP: Updating startup delay\n");
|
||||||
if (code == 6 && !subcode && p->last_error_class != BE_AUTO_DOWN)
|
|
||||||
{
|
|
||||||
p->startup_delay = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* During start, we only consider errors on outgoing connection, because
|
|
||||||
otherwise delay timer for outgoing connection is already running and
|
|
||||||
we could increase delay time two times (or more) per one attempt to
|
|
||||||
connect.
|
|
||||||
*/
|
|
||||||
if ((p->p.proto_state == PS_START) && (conn != &p->outgoing_conn))
|
|
||||||
return;
|
|
||||||
|
|
||||||
DBG("BGP: Updating startup delay %d %d\n", code, subcode);
|
|
||||||
|
|
||||||
if (p->last_proto_error && ((now - p->last_proto_error) >= cf->error_amnesia_time))
|
if (p->last_proto_error && ((now - p->last_proto_error) >= cf->error_amnesia_time))
|
||||||
p->startup_delay = 0;
|
p->startup_delay = 0;
|
||||||
|
@ -262,25 +243,17 @@ bgp_update_startup_delay(struct bgp_proto *p, struct bgp_conn *conn, unsigned co
|
||||||
{
|
{
|
||||||
p->startup_delay = 0;
|
p->startup_delay = 0;
|
||||||
p->p.disabled = 1;
|
p->p.disabled = 1;
|
||||||
if (p->p.proto_state == PS_START)
|
|
||||||
bgp_stop(p);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!p->startup_delay)
|
if (!p->startup_delay)
|
||||||
p->startup_delay = cf->error_delay_time_min;
|
p->startup_delay = cf->error_delay_time_min;
|
||||||
else
|
else
|
||||||
{
|
p->startup_delay = MIN(2 * p->startup_delay, cf->error_delay_time_max);
|
||||||
p->startup_delay *= 2;
|
|
||||||
if (p->startup_delay > cf->error_delay_time_max)
|
|
||||||
p->startup_delay = cf->error_delay_time_max;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bgp_graceful_close_conn(struct bgp_conn *conn)
|
bgp_graceful_close_conn(struct bgp_conn *conn, unsigned subcode)
|
||||||
{
|
{
|
||||||
switch (conn->state)
|
switch (conn->state)
|
||||||
{
|
{
|
||||||
|
@ -294,7 +267,7 @@ bgp_graceful_close_conn(struct bgp_conn *conn)
|
||||||
case BS_OPENSENT:
|
case BS_OPENSENT:
|
||||||
case BS_OPENCONFIRM:
|
case BS_OPENCONFIRM:
|
||||||
case BS_ESTABLISHED:
|
case BS_ESTABLISHED:
|
||||||
bgp_error(conn, 6, 0, NULL, 0);
|
bgp_error(conn, 6, subcode, NULL, 0);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
bug("bgp_graceful_close_conn: Unknown state %d", conn->state);
|
bug("bgp_graceful_close_conn: Unknown state %d", conn->state);
|
||||||
|
@ -307,7 +280,7 @@ bgp_down(struct bgp_proto *p)
|
||||||
if (p->start_state > BSS_PREPARE)
|
if (p->start_state > BSS_PREPARE)
|
||||||
bgp_close(p, 1);
|
bgp_close(p, 1);
|
||||||
|
|
||||||
DBG("BGP: DOWN\n");
|
BGP_TRACE(D_EVENTS, "Down");
|
||||||
proto_notify_state(&p->p, PS_DOWN);
|
proto_notify_state(&p->p, PS_DOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,12 +300,12 @@ bgp_decision(void *vp)
|
||||||
bgp_down(p);
|
bgp_down(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
bgp_stop(struct bgp_proto *p)
|
bgp_stop(struct bgp_proto *p, unsigned subcode)
|
||||||
{
|
{
|
||||||
proto_notify_state(&p->p, PS_STOP);
|
proto_notify_state(&p->p, PS_STOP);
|
||||||
bgp_graceful_close_conn(&p->outgoing_conn);
|
bgp_graceful_close_conn(&p->outgoing_conn, subcode);
|
||||||
bgp_graceful_close_conn(&p->incoming_conn);
|
bgp_graceful_close_conn(&p->incoming_conn, subcode);
|
||||||
ev_schedule(p->event);
|
ev_schedule(p->event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +332,7 @@ bgp_conn_leave_established_state(struct bgp_proto *p)
|
||||||
p->conn = NULL;
|
p->conn = NULL;
|
||||||
|
|
||||||
if (p->p.proto_state == PS_UP)
|
if (p->p.proto_state == PS_UP)
|
||||||
bgp_stop(p);
|
bgp_stop(p, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -501,7 +474,7 @@ bgp_setup_sk(struct bgp_proto *p, struct bgp_conn *conn, sock *s)
|
||||||
static void
|
static void
|
||||||
bgp_active(struct bgp_proto *p)
|
bgp_active(struct bgp_proto *p)
|
||||||
{
|
{
|
||||||
int delay = MIN(1, p->cf->start_delay_time);
|
int delay = MAX(1, p->cf->start_delay_time);
|
||||||
struct bgp_conn *conn = &p->outgoing_conn;
|
struct bgp_conn *conn = &p->outgoing_conn;
|
||||||
|
|
||||||
BGP_TRACE(D_EVENTS, "Connect delayed by %d seconds", delay);
|
BGP_TRACE(D_EVENTS, "Connect delayed by %d seconds", delay);
|
||||||
|
@ -517,7 +490,8 @@ bgp_apply_limits(struct bgp_proto *p)
|
||||||
{
|
{
|
||||||
log(L_WARN "%s: Route limit exceeded, shutting down", p->p.name);
|
log(L_WARN "%s: Route limit exceeded, shutting down", p->p.name);
|
||||||
bgp_store_error(p, NULL, BE_AUTO_DOWN, BEA_ROUTE_LIMIT_EXCEEDED);
|
bgp_store_error(p, NULL, BE_AUTO_DOWN, BEA_ROUTE_LIMIT_EXCEEDED);
|
||||||
bgp_stop(p);
|
bgp_update_startup_delay(p);
|
||||||
|
bgp_stop(p, 1); // Errcode 6, 1 - max number of prefixes reached
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,7 +658,7 @@ bgp_neigh_notify(neighbor *n)
|
||||||
{
|
{
|
||||||
BGP_TRACE(D_EVENTS, "Neighbor lost");
|
BGP_TRACE(D_EVENTS, "Neighbor lost");
|
||||||
bgp_store_error(p, NULL, BE_MISC, BEM_NEIGHBOR_LOST);
|
bgp_store_error(p, NULL, BE_MISC, BEM_NEIGHBOR_LOST);
|
||||||
bgp_stop(p);
|
bgp_stop(p, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -772,11 +746,23 @@ static int
|
||||||
bgp_shutdown(struct proto *P)
|
bgp_shutdown(struct proto *P)
|
||||||
{
|
{
|
||||||
struct bgp_proto *p = (struct bgp_proto *) P;
|
struct bgp_proto *p = (struct bgp_proto *) P;
|
||||||
|
unsigned subcode;
|
||||||
|
|
||||||
BGP_TRACE(D_EVENTS, "Shutdown requested");
|
BGP_TRACE(D_EVENTS, "Shutdown requested");
|
||||||
bgp_store_error(p, NULL, BE_MAN_DOWN, 0);
|
bgp_store_error(p, NULL, BE_MAN_DOWN, 0);
|
||||||
|
|
||||||
|
if (P->reconfiguring)
|
||||||
|
{
|
||||||
|
if (P->cf_new)
|
||||||
|
subcode = 6; // Errcode 6, 6 - other configuration change
|
||||||
|
else
|
||||||
|
subcode = 3; // Errcode 6, 3 - peer de-configured
|
||||||
|
}
|
||||||
|
else
|
||||||
|
subcode = 2; // Errcode 6, 2 - administrative shutdown
|
||||||
|
|
||||||
p->startup_delay = 0;
|
p->startup_delay = 0;
|
||||||
bgp_stop(p);
|
bgp_stop(p, subcode);
|
||||||
|
|
||||||
return p->p.proto_state;
|
return p->p.proto_state;
|
||||||
}
|
}
|
||||||
|
@ -815,12 +801,13 @@ bgp_init(struct proto_config *C)
|
||||||
void
|
void
|
||||||
bgp_error(struct bgp_conn *c, unsigned code, unsigned subcode, byte *data, int len)
|
bgp_error(struct bgp_conn *c, unsigned code, unsigned subcode, byte *data, int len)
|
||||||
{
|
{
|
||||||
|
struct bgp_proto *p = c->bgp;
|
||||||
|
|
||||||
if (c->state == BS_CLOSE)
|
if (c->state == BS_CLOSE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bgp_log_error(c->bgp, "Error", code, subcode, data, (len > 0) ? len : -len);
|
bgp_log_error(p, BE_BGP_TX, "Error", code, subcode, data, (len > 0) ? len : -len);
|
||||||
bgp_store_error(c->bgp, c, BE_BGP_TX, (code << 16) | subcode);
|
bgp_store_error(p, c, BE_BGP_TX, (code << 16) | subcode);
|
||||||
bgp_update_startup_delay(c->bgp, c, code, subcode);
|
|
||||||
bgp_conn_enter_close_state(c);
|
bgp_conn_enter_close_state(c);
|
||||||
|
|
||||||
c->notify_code = code;
|
c->notify_code = code;
|
||||||
|
@ -828,6 +815,12 @@ bgp_error(struct bgp_conn *c, unsigned code, unsigned subcode, byte *data, int l
|
||||||
c->notify_data = data;
|
c->notify_data = data;
|
||||||
c->notify_size = (len > 0) ? len : 0;
|
c->notify_size = (len > 0) ? len : 0;
|
||||||
bgp_schedule_packet(c, PKT_NOTIFICATION);
|
bgp_schedule_packet(c, PKT_NOTIFICATION);
|
||||||
|
|
||||||
|
if (code != 6)
|
||||||
|
{
|
||||||
|
bgp_update_startup_delay(p);
|
||||||
|
bgp_stop(p, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -129,12 +129,14 @@ void bgp_start_timer(struct timer *t, int value);
|
||||||
void bgp_check(struct bgp_config *c);
|
void bgp_check(struct bgp_config *c);
|
||||||
void bgp_error(struct bgp_conn *c, unsigned code, unsigned subcode, byte *data, int len);
|
void bgp_error(struct bgp_conn *c, unsigned code, unsigned subcode, byte *data, int len);
|
||||||
void bgp_close_conn(struct bgp_conn *c);
|
void bgp_close_conn(struct bgp_conn *c);
|
||||||
void bgp_update_startup_delay(struct bgp_proto *p, struct bgp_conn *conn, unsigned code, unsigned subcode);
|
void bgp_update_startup_delay(struct bgp_proto *p);
|
||||||
void bgp_conn_enter_established_state(struct bgp_conn *conn);
|
void bgp_conn_enter_established_state(struct bgp_conn *conn);
|
||||||
void bgp_conn_enter_close_state(struct bgp_conn *conn);
|
void bgp_conn_enter_close_state(struct bgp_conn *conn);
|
||||||
void bgp_conn_enter_idle_state(struct bgp_conn *conn);
|
void bgp_conn_enter_idle_state(struct bgp_conn *conn);
|
||||||
void bgp_store_error(struct bgp_proto *p, struct bgp_conn *c, u8 class, u32 code);
|
void bgp_store_error(struct bgp_proto *p, struct bgp_conn *c, u8 class, u32 code);
|
||||||
int bgp_apply_limits(struct bgp_proto *p);
|
int bgp_apply_limits(struct bgp_proto *p);
|
||||||
|
void bgp_stop(struct bgp_proto *p, unsigned subcode);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef LOCAL_DEBUG
|
#ifdef LOCAL_DEBUG
|
||||||
|
@ -184,7 +186,7 @@ void bgp_kick_tx(void *vconn);
|
||||||
void bgp_tx(struct birdsock *sk);
|
void bgp_tx(struct birdsock *sk);
|
||||||
int bgp_rx(struct birdsock *sk, int size);
|
int bgp_rx(struct birdsock *sk, int size);
|
||||||
const byte * bgp_error_dsc(byte *buff, unsigned code, unsigned subcode);
|
const byte * bgp_error_dsc(byte *buff, unsigned code, unsigned subcode);
|
||||||
void bgp_log_error(struct bgp_proto *p, char *msg, unsigned code, unsigned subcode, byte *data, unsigned len);
|
void bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsigned subcode, byte *data, unsigned len);
|
||||||
|
|
||||||
/* Packet types */
|
/* Packet types */
|
||||||
|
|
||||||
|
|
|
@ -619,14 +619,14 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, int len)
|
||||||
{
|
{
|
||||||
/* Should close the other connection */
|
/* Should close the other connection */
|
||||||
BGP_TRACE(D_EVENTS, "Connection collision, giving up the other connection");
|
BGP_TRACE(D_EVENTS, "Connection collision, giving up the other connection");
|
||||||
bgp_error(other, 6, 0, NULL, 0);
|
bgp_error(other, 6, 7, NULL, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Fall thru */
|
/* Fall thru */
|
||||||
case BS_ESTABLISHED:
|
case BS_ESTABLISHED:
|
||||||
/* Should close this connection */
|
/* Should close this connection */
|
||||||
BGP_TRACE(D_EVENTS, "Connection collision, giving up this connection");
|
BGP_TRACE(D_EVENTS, "Connection collision, giving up this connection");
|
||||||
bgp_error(conn, 6, 0, NULL, 0);
|
bgp_error(conn, 6, 7, NULL, 0);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
bug("bgp_rx_open: Unknown state");
|
bug("bgp_rx_open: Unknown state");
|
||||||
|
@ -957,14 +957,15 @@ bgp_error_dsc(byte *buff, unsigned code, unsigned subcode)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bgp_log_error(struct bgp_proto *p, char *msg, unsigned code, unsigned subcode, byte *data, unsigned len)
|
bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsigned subcode, byte *data, unsigned len)
|
||||||
{
|
{
|
||||||
const byte *name;
|
const byte *name;
|
||||||
byte namebuf[32];
|
byte namebuf[32];
|
||||||
byte *t, argbuf[36];
|
byte *t, argbuf[36];
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
if (code == 6 && !subcode) /* Don't report Cease messages */
|
/* Don't report Cease messages generated by myself */
|
||||||
|
if (code == 6 && class == BE_BGP_TX)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
name = bgp_error_dsc(namebuf, code, subcode);
|
name = bgp_error_dsc(namebuf, code, subcode);
|
||||||
|
@ -994,10 +995,10 @@ bgp_rx_notification(struct bgp_conn *conn, byte *pkt, int len)
|
||||||
|
|
||||||
unsigned code = pkt[19];
|
unsigned code = pkt[19];
|
||||||
unsigned subcode = pkt[20];
|
unsigned subcode = pkt[20];
|
||||||
int delay = 1;
|
int err = (code != 6);
|
||||||
|
|
||||||
bgp_log_error(conn->bgp, "Received error notification", code, subcode, pkt+21, len-21);
|
bgp_log_error(p, BE_BGP_RX, "Received", code, subcode, pkt+21, len-21);
|
||||||
bgp_store_error(conn->bgp, conn, BE_BGP_RX, (code << 16) | subcode);
|
bgp_store_error(p, conn, BE_BGP_RX, (code << 16) | subcode);
|
||||||
|
|
||||||
#ifndef IPV6
|
#ifndef IPV6
|
||||||
if ((code == 2) && ((subcode == 4) || (subcode == 7))
|
if ((code == 2) && ((subcode == 4) || (subcode == 7))
|
||||||
|
@ -1014,14 +1015,19 @@ bgp_rx_notification(struct bgp_conn *conn, byte *pkt, int len)
|
||||||
{
|
{
|
||||||
/* We try connect without capabilities */
|
/* We try connect without capabilities */
|
||||||
log(L_WARN "%s: Capability related error received, retry with capabilities disabled", p->p.name);
|
log(L_WARN "%s: Capability related error received, retry with capabilities disabled", p->p.name);
|
||||||
conn->bgp->start_state = BSS_CONNECT_NOCAP;
|
p->start_state = BSS_CONNECT_NOCAP;
|
||||||
delay = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (delay) bgp_update_startup_delay(conn->bgp, conn, code, subcode);
|
|
||||||
bgp_conn_enter_close_state(conn);
|
bgp_conn_enter_close_state(conn);
|
||||||
bgp_schedule_packet(conn, PKT_SCHEDULE_CLOSE);
|
bgp_schedule_packet(conn, PKT_SCHEDULE_CLOSE);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
bgp_update_startup_delay(p);
|
||||||
|
bgp_stop(p, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue