Implements import route limits.
This commit is contained in:
parent
925fe2d3de
commit
72b28a041d
4 changed files with 42 additions and 8 deletions
|
@ -212,7 +212,7 @@ bgp_update_startup_delay(struct bgp_proto *p, struct bgp_conn *conn, unsigned co
|
||||||
struct bgp_config *cf = p->cf;
|
struct bgp_config *cf = p->cf;
|
||||||
|
|
||||||
/* Don't handle cease messages as errors */
|
/* Don't handle cease messages as errors */
|
||||||
if (code == 6 && !subcode)
|
if (code == 6 && !subcode && p->last_error_class != BE_AUTO_DOWN)
|
||||||
{
|
{
|
||||||
p->startup_delay = 0;
|
p->startup_delay = 0;
|
||||||
return;
|
return;
|
||||||
|
@ -483,6 +483,21 @@ bgp_active(struct bgp_proto *p, int delay)
|
||||||
bgp_start_timer(conn->connect_retry_timer, delay);
|
bgp_start_timer(conn->connect_retry_timer, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
bgp_apply_limits(struct bgp_proto *p)
|
||||||
|
{
|
||||||
|
if (p->cf->route_limit && (p->p.stats.imp_routes > p->cf->route_limit))
|
||||||
|
{
|
||||||
|
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_stop(p);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bgp_connect - initiate an outgoing connection
|
* bgp_connect - initiate an outgoing connection
|
||||||
* @p: BGP instance
|
* @p: BGP instance
|
||||||
|
@ -848,8 +863,9 @@ bgp_check(struct bgp_config *c)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *bgp_state_names[] = { "Idle", "Connect", "Active", "OpenSent", "OpenConfirm", "Established", "Close" };
|
static char *bgp_state_names[] = { "Idle", "Connect", "Active", "OpenSent", "OpenConfirm", "Established", "Close" };
|
||||||
static char *bgp_err_classes[] = { "", "Error: ", "Socket: ", "Received: ", "BGP Error: ", "Automatic shutdown", ""};
|
static char *bgp_err_classes[] = { "", "Error: ", "Socket: ", "Received: ", "BGP Error: ", "Automatic shutdown: ", ""};
|
||||||
static char *bgp_misc_errors[] = { "", "Neighbor lost", "Invalid next hop", "Kernel MD5 auth failed" };
|
static char *bgp_misc_errors[] = { "", "Neighbor lost", "Invalid next hop", "Kernel MD5 auth failed" };
|
||||||
|
static char *bgp_auto_errors[] = { "", "Route limit exceeded"};
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -873,6 +889,9 @@ bgp_get_status(struct proto *P, byte *buf)
|
||||||
case BE_BGP_TX:
|
case BE_BGP_TX:
|
||||||
err2 = bgp_error_dsc(errbuf, p->last_error_code >> 16, p->last_error_code & 0xFF);
|
err2 = bgp_error_dsc(errbuf, p->last_error_code >> 16, p->last_error_code & 0xFF);
|
||||||
break;
|
break;
|
||||||
|
case BE_AUTO_DOWN:
|
||||||
|
err2 = bgp_auto_errors[p->last_error_code];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (P->proto_state == PS_DOWN)
|
if (P->proto_state == PS_DOWN)
|
||||||
|
|
|
@ -31,6 +31,7 @@ struct bgp_config {
|
||||||
int rr_client; /* Whether neighbor is RR client of me */
|
int rr_client; /* Whether neighbor is RR client of me */
|
||||||
int rs_client; /* Whether neighbor is RS client of me */
|
int rs_client; /* Whether neighbor is RS client of me */
|
||||||
int advertise_ipv4; /* Whether we should add IPv4 capability advertisement to OPEN message */
|
int advertise_ipv4; /* Whether we should add IPv4 capability advertisement to OPEN message */
|
||||||
|
u32 route_limit; /* Number of routes that may be imported, 0 means disable limit */
|
||||||
unsigned connect_retry_time;
|
unsigned connect_retry_time;
|
||||||
unsigned hold_time, initial_hold_time;
|
unsigned hold_time, initial_hold_time;
|
||||||
unsigned keepalive_time;
|
unsigned keepalive_time;
|
||||||
|
@ -132,6 +133,7 @@ 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);
|
||||||
|
|
||||||
|
|
||||||
#ifdef LOCAL_DEBUG
|
#ifdef LOCAL_DEBUG
|
||||||
|
@ -256,8 +258,11 @@ void bgp_log_error(struct bgp_proto *p, char *msg, unsigned code, unsigned subco
|
||||||
|
|
||||||
#define BEM_NEIGHBOR_LOST 1
|
#define BEM_NEIGHBOR_LOST 1
|
||||||
#define BEM_INVALID_NEXT_HOP 2
|
#define BEM_INVALID_NEXT_HOP 2
|
||||||
#define BEM_INVALID_MD5 3 /* MD5 authentication kernel request failed (possibly not supported */
|
#define BEM_INVALID_MD5 3 /* MD5 authentication kernel request failed (possibly not supported) */
|
||||||
|
|
||||||
|
/* Automatic shutdown error codes */
|
||||||
|
|
||||||
|
#define BEA_ROUTE_LIMIT_EXCEEDED 1
|
||||||
|
|
||||||
/* Well-known communities */
|
/* Well-known communities */
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE,
|
||||||
BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN, BGP_NEXT_HOP,
|
BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN, BGP_NEXT_HOP,
|
||||||
BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS,
|
BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS,
|
||||||
PASSWORD, RR, RS, CLIENT, CLUSTER, ID, AS4, ADVERTISE, IPV4,
|
PASSWORD, RR, RS, CLIENT, CLUSTER, ID, AS4, ADVERTISE, IPV4,
|
||||||
CAPABILITIES)
|
CAPABILITIES, LIMIT)
|
||||||
|
|
||||||
CF_GRAMMAR
|
CF_GRAMMAR
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ bgp_proto:
|
||||||
| bgp_proto CAPABILITIES bool ';' { BGP_CFG->capabilities = $3; }
|
| bgp_proto CAPABILITIES bool ';' { BGP_CFG->capabilities = $3; }
|
||||||
| bgp_proto ADVERTISE IPV4 bool ';' { BGP_CFG->advertise_ipv4 = $4; }
|
| bgp_proto ADVERTISE IPV4 bool ';' { BGP_CFG->advertise_ipv4 = $4; }
|
||||||
| bgp_proto PASSWORD TEXT ';' { BGP_CFG->password = $3; }
|
| bgp_proto PASSWORD TEXT ';' { BGP_CFG->password = $3; }
|
||||||
|
| bgp_proto ROUTE LIMIT expr ';' { BGP_CFG->route_limit = $4; }
|
||||||
;
|
;
|
||||||
|
|
||||||
CF_ADDTO(dynamic_attr, BGP_PATH
|
CF_ADDTO(dynamic_attr, BGP_PATH
|
||||||
|
|
|
@ -725,13 +725,19 @@ bgp_do_rx_update(struct bgp_conn *conn,
|
||||||
e->net = n;
|
e->net = n;
|
||||||
e->pflags = 0;
|
e->pflags = 0;
|
||||||
rte_update(p->p.table, n, &p->p, &p->p, e);
|
rte_update(p->p.table, n, &p->p, &p->p, e);
|
||||||
|
if (bgp_apply_limits(p) < 0)
|
||||||
|
goto bad2;
|
||||||
}
|
}
|
||||||
|
rta_free(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
|
bgp_error(conn, 3, err, NULL, 0);
|
||||||
|
bad2:
|
||||||
if (a)
|
if (a)
|
||||||
rta_free(a);
|
rta_free(a);
|
||||||
if (err)
|
|
||||||
bgp_error(conn, 3, err, NULL, 0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -825,6 +831,8 @@ bgp_do_rx_update(struct bgp_conn *conn,
|
||||||
e->net = n;
|
e->net = n;
|
||||||
e->pflags = 0;
|
e->pflags = 0;
|
||||||
rte_update(p->p.table, n, &p->p, &p->p, e);
|
rte_update(p->p.table, n, &p->p, &p->p, e);
|
||||||
|
if (bgp_apply_limits(p) < 0)
|
||||||
|
goto bad2;
|
||||||
}
|
}
|
||||||
rta_free(a);
|
rta_free(a);
|
||||||
}
|
}
|
||||||
|
@ -834,6 +842,7 @@ bgp_do_rx_update(struct bgp_conn *conn,
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
bgp_error(conn, 3, 9, start, len0);
|
bgp_error(conn, 3, 9, start, len0);
|
||||||
|
bad2:
|
||||||
if (a)
|
if (a)
|
||||||
rta_free(a);
|
rta_free(a);
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in a new issue