summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2012-11-13 09:47:21 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2012-11-13 09:47:21 +0000
commitbb8c0be811b76c6ab88d9ab6f84dfd86fefb3dbb (patch)
treea8f0d48b7ce316fd0743d13e0b77734b4a78b42d
parent006fb6cf8bdb3bff5e028c1acaa88a19108a3c62 (diff)
Allow filtering based on the NEXTHOP attribute. This allows to build rules
like: allow from any nexthop neighbor (to allow only prefixes that use the routers IP address as nexthop). Lots of testing, input and OK florian@
-rw-r--r--usr.sbin/bgpd/bgpd.conf.517
-rw-r--r--usr.sbin/bgpd/bgpd.h10
-rw-r--r--usr.sbin/bgpd/parse.y22
-rw-r--r--usr.sbin/bgpd/printconf.c9
-rw-r--r--usr.sbin/bgpd/rde_filter.c37
5 files changed, 86 insertions, 9 deletions
diff --git a/usr.sbin/bgpd/bgpd.conf.5 b/usr.sbin/bgpd/bgpd.conf.5
index bc689c36ab7..10fcf658a39 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.121 2012/08/24 17:04:06 jmc Exp $
+.\" $OpenBSD: bgpd.conf.5,v 1.122 2012/11/13 09:47:20 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: August 24 2012 $
+.Dd $Mdocdate: November 13 2012 $
.Dt BGPD.CONF 5
.Os
.Sh NAME
@@ -1175,6 +1175,19 @@ is repeated more than
.Ar len
times.
.Pp
+.It Ic nexthop Ar address
+This rule applies only to
+.Em UPDATES
+where the nexthop is equal to
+.Ar address.
+The
+.Ar address
+can be set to
+.Em neighbor
+in which case the nexthop is compared against the address of the neighbor.
+Nexthop filtering is not supported on locally announced networks and one must
+take into consideration previous rules overwriting nexthops.
+.Pp
.It Xo
.Ic prefix
.Ar address Ns Li / Ns Ar len
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index 370b62ab320..a412a641531 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.273 2012/09/18 10:10:00 claudio Exp $ */
+/* $OpenBSD: bgpd.h,v 1.274 2012/11/13 09:47:20 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -749,6 +749,13 @@ struct filter_prefix {
u_int8_t len;
};
+struct filter_nexthop {
+ struct bgpd_addr addr;
+ u_int8_t flags;
+#define FILTER_NEXTHOP_ADDR 1
+#define FILTER_NEXTHOP_NEIGHBOR 2
+};
+
struct filter_prefixlen {
enum comp_ops op;
u_int8_t aid;
@@ -759,6 +766,7 @@ struct filter_prefixlen {
struct filter_match {
struct filter_prefix prefix;
struct filter_prefixlen prefixlen;
+ struct filter_nexthop nexthop;
struct filter_as as;
struct filter_aslen aslen;
struct filter_community community;
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index 1099ef26833..460f016201a 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.264 2012/09/23 09:39:17 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.265 2012/11/13 09:47:20 claudio Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -1700,6 +1700,26 @@ filter_elm : filter_prefix_h {
}
fmopts.aid = AID_INET6;
}
+ | NEXTHOP address {
+ if (fmopts.m.nexthop.flags) {
+ yyerror("nexthop already specified");
+ YYERROR;
+ }
+ if (fmopts.aid && fmopts.aid != $2.aid) {
+ yyerror("nexthop address family doesn't match "
+ "rule address family");
+ YYERROR;
+ }
+ fmopts.m.nexthop.addr = $2;
+ fmopts.m.nexthop.flags = FILTER_NEXTHOP_ADDR;
+ }
+ | NEXTHOP NEIGHBOR {
+ if (fmopts.m.nexthop.flags) {
+ yyerror("nexthop already specified");
+ YYERROR;
+ }
+ fmopts.m.nexthop.flags = FILTER_NEXTHOP_NEIGHBOR;
+ }
;
prefixlenop : unaryop NUMBER {
diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c
index 803f83d9d34..ca1071872b9 100644
--- a/usr.sbin/bgpd/printconf.c
+++ b/usr.sbin/bgpd/printconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: printconf.c,v 1.88 2012/09/23 09:39:18 claudio Exp $ */
+/* $OpenBSD: printconf.c,v 1.89 2012/11/13 09:47:20 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -561,6 +561,13 @@ print_rule(struct peer *peer_l, struct filter_rule *r)
}
}
+ if (r->match.nexthop.flags) {
+ if (r->match.nexthop.flags == FILTER_NEXTHOP_NEIGHBOR)
+ printf("nexthop neighbor ");
+ else
+ printf("nexthop %s ", log_addr(&r->match.nexthop.addr));
+ }
+
if (r->match.as.type) {
if (r->match.as.type == AS_ALL)
printf("AS %s ", log_as(r->match.as.as));
diff --git a/usr.sbin/bgpd/rde_filter.c b/usr.sbin/bgpd/rde_filter.c
index d2f630155c4..f38284de83f 100644
--- a/usr.sbin/bgpd/rde_filter.c
+++ b/usr.sbin/bgpd/rde_filter.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_filter.c,v 1.67 2011/09/20 21:19:06 claudio Exp $ */
+/* $OpenBSD: rde_filter.c,v 1.68 2012/11/13 09:47:20 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -26,7 +26,7 @@
#include "rde.h"
int rde_filter_match(struct filter_rule *, struct rde_aspath *,
- struct bgpd_addr *, u_int8_t, struct rde_peer *);
+ struct bgpd_addr *, u_int8_t, struct rde_peer *, struct rde_peer *);
int filterset_equal(struct filter_set_head *, struct filter_set_head *);
enum filter_actions
@@ -58,7 +58,7 @@ rde_filter(u_int16_t ribid, struct rde_aspath **new, struct filter_head *rules,
if (f->peer.peerid != 0 &&
f->peer.peerid != peer->conf.id)
continue;
- if (rde_filter_match(f, asp, prefix, prefixlen, peer)) {
+ if (rde_filter_match(f, asp, prefix, prefixlen, peer, from)) {
if (asp != NULL && new != NULL) {
/* asp may get modified so create a copy */
if (*new == NULL) {
@@ -267,7 +267,8 @@ rde_apply_set(struct rde_aspath *asp, struct filter_set_head *sh,
int
rde_filter_match(struct filter_rule *f, struct rde_aspath *asp,
- struct bgpd_addr *prefix, u_int8_t plen, struct rde_peer *peer)
+ struct bgpd_addr *prefix, u_int8_t plen, struct rde_peer *peer,
+ struct rde_peer *from)
{
u_int32_t pas;
int cas, type;
@@ -384,6 +385,34 @@ rde_filter_match(struct filter_rule *f, struct rde_aspath *asp,
}
/* NOTREACHED */
}
+ if (f->match.nexthop.flags != 0) {
+ struct bgpd_addr *nexthop, *cmpaddr;
+ if (asp->nexthop == NULL)
+ /* no nexthop, skip */
+ return (0);
+ nexthop = &asp->nexthop->exit_nexthop;
+ if (f->match.nexthop.flags == FILTER_NEXTHOP_ADDR)
+ cmpaddr = &f->match.nexthop.addr;
+ else
+ cmpaddr = &from->remote_addr;
+ if (cmpaddr->aid != nexthop->aid)
+ /* don't use IPv4 rules for IPv6 and vice versa */
+ return (0);
+
+ switch (cmpaddr->aid) {
+ case AID_INET:
+ if (cmpaddr->v4.s_addr != nexthop->v4.s_addr)
+ return (0);
+ break;
+ case AID_INET6:
+ if (memcmp(&cmpaddr->v6, &nexthop->v6,
+ sizeof(struct in6_addr)))
+ return (0);
+ break;
+ default:
+ fatalx("King Bula lost in address space");
+ }
+ }
/* matched somewhen or is anymatch rule */
return (1);