summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd/rde_update.c
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2020-01-24 05:44:06 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2020-01-24 05:44:06 +0000
commit18714bc720466665754233878ce5dc928c5e264c (patch)
tree1748273ea31fe1a803acc9dbc4715f1207c3edc1 /usr.sbin/bgpd/rde_update.c
parente77c61be3d8b544fc0434e23b24bcef0665b0e8a (diff)
Implement 'max-prefix NUM out' to limit the number of announced prefixes.
This is an easy safety switch to not leak full tables to upstreams and peers. If the limit is hit a Cease notification is sent and the session is closed. This implements most of https://tools.ietf.org/html/draft-sa-idr-maxprefix-00 OK job@
Diffstat (limited to 'usr.sbin/bgpd/rde_update.c')
-rw-r--r--usr.sbin/bgpd/rde_update.c34
1 files changed, 30 insertions, 4 deletions
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 */