diff options
-rw-r--r-- | usr.sbin/bgpd/bgpd.conf.5 | 19 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 4 | ||||
-rw-r--r-- | usr.sbin/bgpd/parse.y | 10 | ||||
-rw-r--r-- | usr.sbin/bgpd/printconf.c | 8 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.c | 5 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.h | 7 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_peer.c | 4 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_update.c | 34 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.c | 14 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.h | 3 |
10 files changed, 88 insertions, 20 deletions
diff --git a/usr.sbin/bgpd/bgpd.conf.5 b/usr.sbin/bgpd/bgpd.conf.5 index be7057365c4..ce606f25492 100644 --- a/usr.sbin/bgpd/bgpd.conf.5 +++ b/usr.sbin/bgpd/bgpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bgpd.conf.5,v 1.197 2019/10/31 09:09:04 benno Exp $ +.\" $OpenBSD: bgpd.conf.5,v 1.198 2020/01/24 05:44:05 claudio Exp $ .\" .\" Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org> .\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: October 31 2019 $ +.Dd $Mdocdate: January 24 2020 $ .Dt BGPD.CONF 5 .Os .Sh NAME @@ -1057,6 +1057,21 @@ is specified, the session will be restarted after .Ar number minutes. .Pp +.Pp +.It Xo +.Ic max-prefix Ar number Ic out +.Op Ic restart Ar number +.Xc +Terminate the session when the maximum +.Ar number +of prefixes sent is exceeded +(no such limit is imposed by default). +If +.Ic restart +is specified, the session will be restarted after +.Ar number +minutes. +.Pp .It Ic multihop Ar hops Neighbors not in the same AS as the local .Xr bgpd 8 diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index eedf36a5e3f..12313bf4c16 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.398 2020/01/21 11:10:24 claudio Exp $ */ +/* $OpenBSD: bgpd.h,v 1.399 2020/01/24 05:44:05 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -379,10 +379,12 @@ struct peer_config { u_int32_t remote_as; u_int32_t local_as; u_int32_t max_prefix; + u_int32_t max_out_prefix; enum export_type export_type; enum enforce_as enforce_as; enum enforce_as enforce_local_as; u_int16_t max_prefix_restart; + u_int16_t max_out_prefix_restart; u_int16_t holdtime; u_int16_t min_holdtime; u_int16_t local_short_as; diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y index b91def2cfcd..d7f5da990c9 100644 --- a/usr.sbin/bgpd/parse.y +++ b/usr.sbin/bgpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.402 2019/09/27 10:26:32 claudio Exp $ */ +/* $OpenBSD: parse.y,v 1.403 2020/01/24 05:44:05 claudio Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -1391,6 +1391,14 @@ peeropts : REMOTEAS as4number { curpeer->conf.max_prefix = $2; curpeer->conf.max_prefix_restart = $3; } + | MAXPREFIX NUMBER OUT restart { + if ($2 < 0 || $2 > UINT_MAX) { + yyerror("bad maximum number of prefixes"); + YYERROR; + } + curpeer->conf.max_out_prefix = $2; + curpeer->conf.max_out_prefix_restart = $4; + } | TCP MD5SIG PASSWORD string { if (curpeer->conf.auth.method) { yyerror("auth method cannot be redefined"); diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c index 429706a4bbb..caa03e1b407 100644 --- a/usr.sbin/bgpd/printconf.c +++ b/usr.sbin/bgpd/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.140 2019/08/07 10:26:41 claudio Exp $ */ +/* $OpenBSD: printconf.c,v 1.141 2020/01/24 05:44:05 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -616,6 +616,12 @@ print_peer(struct peer_config *p, struct bgpd_config *conf, const char *c) printf(" restart %u", p->max_prefix_restart); printf("\n"); } + if (p->max_out_prefix) { + printf("%s\tmax-prefix %u out", c, p->max_out_prefix); + if (p->max_out_prefix_restart) + printf(" restart %u", p->max_out_prefix_restart); + printf("\n"); + } if (p->holdtime) printf("%s\tholdtime %u\n", c, p->holdtime); if (p->min_holdtime) diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index e2e0ac27114..f819f4c1947 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.499 2020/01/10 13:22:26 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.500 2020/01/24 05:44:05 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -59,8 +59,6 @@ int rde_attr_add(struct filterstate *, u_char *, u_int16_t); u_int8_t rde_attr_missing(struct rde_aspath *, int, u_int16_t); int rde_get_mp_nexthop(u_char *, u_int16_t, u_int8_t, struct filterstate *); -void rde_update_err(struct rde_peer *, u_int8_t , u_int8_t, - void *, u_int16_t); void rde_as4byte_fixup(struct rde_peer *, struct rde_aspath *); void rde_reflector(struct rde_peer *, struct rde_aspath *); @@ -535,6 +533,7 @@ badnetdel: peer = peer_get(p.conf.id); if (peer != NULL) { p.stats.prefix_cnt = peer->prefix_cnt; + p.stats.prefix_out_cnt = peer->prefix_out_cnt; p.stats.prefix_rcvd_update = peer->prefix_rcvd_update; p.stats.prefix_rcvd_withdraw = diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h index 776c37a03f2..6cba62d44d7 100644 --- a/usr.sbin/bgpd/rde.h +++ b/usr.sbin/bgpd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.232 2020/01/09 15:50:34 claudio Exp $ */ +/* $OpenBSD: rde.h,v 1.233 2020/01/24 05:44:05 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and @@ -97,7 +97,8 @@ struct rde_peer { u_int64_t prefix_sent_update; u_int64_t prefix_sent_withdraw; u_int64_t prefix_sent_eor; - u_int32_t prefix_cnt; /* # of prefixes */ + u_int32_t prefix_cnt; + u_int32_t prefix_out_cnt; u_int32_t remote_bgpid; /* host byte order! */ u_int32_t up_nlricnt; u_int32_t up_wcnt; @@ -359,6 +360,8 @@ int mrt_dump_v2_hdr(struct mrt *, struct bgpd_config *, void mrt_dump_upcall(struct rib_entry *, void *); /* rde.c */ +void rde_update_err(struct rde_peer *, u_int8_t , u_int8_t, + void *, u_int16_t); void rde_update_log(const char *, u_int16_t, const struct rde_peer *, const struct bgpd_addr *, const struct bgpd_addr *, u_int8_t); diff --git a/usr.sbin/bgpd/rde_peer.c b/usr.sbin/bgpd/rde_peer.c index feac4ecdc27..ce0662e51cb 100644 --- a/usr.sbin/bgpd/rde_peer.c +++ b/usr.sbin/bgpd/rde_peer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_peer.c,v 1.3 2020/01/21 06:22:17 claudio Exp $ */ +/* $OpenBSD: rde_peer.c,v 1.4 2020/01/24 05:44:05 claudio Exp $ */ /* * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org> @@ -420,6 +420,7 @@ peer_up(struct rde_peer *peer, struct session_up *sup) fatal("%s: prefix_dump_new", __func__); peer_flush(peer, AID_UNSPEC, 0); peer->prefix_cnt = 0; + peer->prefix_out_cnt = 0; peer->state = PEER_DOWN; } peer->remote_bgpid = ntohl(sup->remote_bgpid); @@ -461,6 +462,7 @@ peer_down(struct rde_peer *peer, void *bula) /* flush Adj-RIB-In */ peer_flush(peer, AID_UNSPEC, 0); peer->prefix_cnt = 0; + peer->prefix_out_cnt = 0; peer_imsg_flush(peer); diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c index d290c5436a6..6e8c1ce4b9f 100644 --- a/usr.sbin/bgpd/rde_update.c +++ b/usr.sbin/bgpd/rde_update.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_update.c,v 1.122 2019/08/13 12:16:20 claudio Exp $ */ +/* $OpenBSD: rde_update.c,v 1.123 2020/01/24 05:44:05 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org> @@ -144,8 +144,10 @@ withdraw: /* withdraw prefix */ pt_getaddr(old->pt, &addr); if (prefix_adjout_withdraw(peer, &addr, - old->pt->prefixlen) == 1) + old->pt->prefixlen) == 1) { + peer->prefix_out_cnt--; peer->up_wcnt++; + } } else { switch (up_test_update(peer, new)) { case 1: @@ -169,10 +171,22 @@ withdraw: /* only send update if path changed */ if (prefix_adjout_update(peer, &state, &addr, - new->pt->prefixlen, prefix_vstate(new)) == 1) + new->pt->prefixlen, prefix_vstate(new)) == 1) { + peer->prefix_out_cnt++; peer->up_nlricnt++; + } rde_filterstate_clean(&state); + + /* max prefix checker outbound */ + if (peer->conf.max_out_prefix && + peer->prefix_out_cnt > peer->conf.max_out_prefix) { + log_peer_warnx(&peer->conf, + "outbound prefix limit reached (>%u/%u)", + peer->prefix_out_cnt, peer->conf.max_out_prefix); + rde_update_err(peer, ERR_CEASE, + ERR_CEASE_MAX_SENT_PREFIX, NULL, 0); + } } } @@ -214,11 +228,23 @@ up_generate_default(struct filter_head *rules, struct rde_peer *peer, return; } - if (prefix_adjout_update(peer, &state, &addr, 0, ROA_NOTFOUND) == 1) + if (prefix_adjout_update(peer, &state, &addr, 0, ROA_NOTFOUND) == 1) { + peer->prefix_out_cnt++; peer->up_nlricnt++; + } /* no longer needed */ rde_filterstate_clean(&state); + + /* max prefix checker outbound */ + if (peer->conf.max_out_prefix && + peer->prefix_out_cnt > peer->conf.max_out_prefix) { + log_peer_warnx(&peer->conf, + "outbound prefix limit reached (>%u/%u)", + peer->prefix_out_cnt, peer->conf.max_out_prefix); + rde_update_err(peer, ERR_CEASE, + ERR_CEASE_MAX_SENT_PREFIX, NULL, 0); + } } /* only for IPv4 */ diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c index c1498fbc2f0..56a252196e5 100644 --- a/usr.sbin/bgpd/session.c +++ b/usr.sbin/bgpd/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.397 2020/01/21 11:12:06 claudio Exp $ */ +/* $OpenBSD: session.c,v 1.398 2020/01/24 05:44:05 claudio Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org> @@ -2511,6 +2511,7 @@ session_dispatch_imsg(struct imsgbuf *ibuf, int idx, u_int *listener_cnt) struct kif *kif; u_char *data; int n, fd, depend_ok, restricted; + u_int16_t t; u_int8_t aid, errcode, subcode; while (ibuf) { @@ -2795,10 +2796,15 @@ session_dispatch_imsg(struct imsgbuf *ibuf, int idx, u_int *listener_cnt) case ERR_CEASE: switch (subcode) { case ERR_CEASE_MAX_PREFIX: + case ERR_CEASE_MAX_SENT_PREFIX: + t = p->conf.max_out_prefix_restart; + if (subcode == ERR_CEASE_MAX_PREFIX) + t = p->conf.max_prefix_restart; + bgp_fsm(p, EVNT_STOP); - if (p->conf.max_prefix_restart) - timer_set(p, Timer_IdleHold, 60 * - p->conf.max_prefix_restart); + if (t) + timer_set(p, Timer_IdleHold, + 60 * t); break; default: bgp_fsm(p, EVNT_CON_FATAL); diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h index 298286f5cbe..4448a2af79c 100644 --- a/usr.sbin/bgpd/session.h +++ b/usr.sbin/bgpd/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.143 2020/01/21 11:12:06 claudio Exp $ */ +/* $OpenBSD: session.h,v 1.144 2020/01/24 05:44:05 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -169,6 +169,7 @@ struct peer_stats { time_t last_read; time_t last_write; u_int32_t prefix_cnt; + u_int32_t prefix_out_cnt; u_int8_t last_sent_errcode; u_int8_t last_sent_suberr; u_int8_t last_rcvd_errcode; |