-.\" $OpenBSD: bgpd.conf.5,v 1.174 2018/09/07 10:59:16 claudio Exp $
+.\" $OpenBSD: bgpd.conf.5,v 1.175 2018/09/08 15:25:27 benno Exp $
.\"
.\" Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
.\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: September 7 2018 $
+.Dd $Mdocdate: September 8 2018 $
.Dt BGPD.CONF 5
.Os
.Sh NAME
.Pq Ic inet Ns | Ns Ic inet6
.Ic priority Ar number Op Ic set ...\&
.Xc
-.\" NOT IMPLEMENTED. DO WE WANT THIS?
-.\" .It Xo
-.\" .Ic network prefix-set
-.\" .Ar name
-.\" .Op Ic set ...\&
-.\" .Xc
Announce the specified network as belonging to our AS.
If set to
.Ic connected ,
.Ic prefix Ar address Ns Li / Ns Ar len Ic prexiflen Ic >= Ar len
.Ed
.Pp
-.It Ic prefix-set Ar name
+.It Ic prefix-set Ar name Op Ic or-longer
This rule applies only to
.Em UPDATES
that match the given prefix-set
.Ar name .
+With
+.Ic or-longer ,
+the
+.Em UPDATES
+will match any prefix in the prefix-set where
+.Bd -literal -offset indent
+.Ic address Ns Li / Ns Ar len Ic prexiflen Ic >= Ar len
.Pp
.It Ic quick
If an
-/* $OpenBSD: bgpd.h,v 1.336 2018/09/07 11:50:32 benno Exp $ */
+/* $OpenBSD: bgpd.h,v 1.337 2018/09/08 15:25:27 benno Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
NETWORK_CONNECTED,
NETWORK_RTLABEL,
NETWORK_MRTCLONE,
- NETWORK_PRIORITY
+ NETWORK_PRIORITY,
};
struct network_config {
#define PREFIXSET_FLAG_FILTER 0x01
#define PREFIXSET_FLAG_DIRTY 0x02 /* prefix-set changed at reload */
+#define PREFIXSET_FLAG_OPS 0x04 /* indiv. prefixes have prefixlenops */
+#define PREFIXSET_FLAG_LONGER 0x08 /* filter all prefixes with or-longer */
struct filter_prefixset {
int flags;
-/* $OpenBSD: parse.y,v 1.340 2018/09/08 12:29:19 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.341 2018/09/08 15:25:27 benno Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
}
fmopts.m.nexthop.flags = FILTER_NEXTHOP_NEIGHBOR;
}
- | PREFIXSET STRING {
+ | PREFIXSET STRING prefixlenop {
+ struct prefixset *ps;
if (fmopts.prefix_l != NULL) {
yyerror("\"prefix\" already specified, cannot "
"be used with \"prefix-set\" in the same "
free($2);
YYERROR;
}
- if ((find_prefixset($2, conf->prefixsets)) == NULL) {
+ if ((ps = find_prefixset($2, conf->prefixsets))
+ == NULL) {
yyerror("prefix-set not defined");
free($2);
YYERROR;
free($2);
YYERROR;
}
+ if (!($3.op == OP_NONE ||
+ ($3.op == OP_RANGE &&
+ $3.len_min == -1 && $3.len_max == -1))) {
+ yyerror("prefix-sets can only use option "
+ "or-longer");
+ free($2);
+ YYERROR;
+ }
+ if ($3.op == OP_RANGE && ps->sflags & PREFIXSET_FLAG_OPS) {
+ yyerror("prefix-set %s contains prefixlen "
+ "operators and cannot be used in with a "
+ "or-longer filter", ps->name);
+ free($2);
+ YYERROR;
+ }
+ if ($3.op == OP_RANGE && $3.len_min == -1 &&
+ $3.len_min == -1)
+ fmopts.m.prefixset.flags |=
+ PREFIXSET_FLAG_LONGER;
fmopts.m.prefixset.flags |= PREFIXSET_FLAG_FILTER;
fmopts.m.prefixset.ps = NULL;
free($2);
-/* $OpenBSD: printconf.c,v 1.113 2018/09/08 09:33:54 claudio Exp $ */
+/* $OpenBSD: printconf.c,v 1.114 2018/09/08 15:25:27 benno Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
if (r->match.prefixset.flags & PREFIXSET_FLAG_FILTER)
printf("prefix-set \"%s\" ", r->match.prefixset.name);
+ if (r->match.prefixset.flags & PREFIXSET_FLAG_LONGER)
+ printf("or-longer ");
if (r->match.nexthop.flags) {
if (r->match.nexthop.flags == FILTER_NEXTHOP_NEIGHBOR)
-/* $OpenBSD: rde.h,v 1.188 2018/09/07 10:49:22 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.189 2018/09/08 15:25:27 benno Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
u_int8_t);
/* rde_trie.c */
-int trie_add(struct trie_head *, struct bgpd_addr *, u_int8_t,
- u_int8_t, u_int8_t);
+int trie_add(struct trie_head *, struct bgpd_addr *, u_int8_t, u_int8_t,
+ u_int8_t);
void trie_free(struct trie_head *);
-int trie_match(struct trie_head *, struct bgpd_addr *, u_int8_t);
+int trie_match(struct trie_head *, struct bgpd_addr *, u_int8_t, int);
void trie_dump(struct trie_head *);
int trie_equal(struct trie_head *, struct trie_head *);
-/* $OpenBSD: rde_filter.c,v 1.104 2018/09/07 16:45:23 benno Exp $ */
+/* $OpenBSD: rde_filter.c,v 1.105 2018/09/08 15:25:27 benno Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
}
/*
- * XXX must be second to last because we unconditionally return here.
* prefixset and prefix filter rules are mutual exclusive
*/
if (f->match.prefixset.flags != 0) {
pt_getaddr(p->re->prefix, prefix);
plen = p->re->prefix->prefixlen;
-
if (f->match.prefixset.ps == NULL ||
- !trie_match(&f->match.prefixset.ps->th, prefix, plen))
+ !trie_match(&f->match.prefixset.ps->th, prefix, plen,
+ (f->match.prefixset.flags & PREFIXSET_FLAG_LONGER)))
return (0);
} else if (f->match.prefix.addr.aid != 0)
return (rde_prefix_match(&f->match.prefix, p));
-/* $OpenBSD: rde_trie.c,v 1.3 2018/09/07 20:26:30 claudio Exp $ */
+/* $OpenBSD: rde_trie.c,v 1.4 2018/09/08 15:25:27 benno Exp $ */
/*
* Copyright (c) 2018 Claudio Jeker <claudio@openbsd.org>
}
static int
-trie_match_v4(struct trie_head *th, struct in_addr *prefix, u_int8_t plen)
+trie_match_v4(struct trie_head *th, struct in_addr *prefix, u_int8_t plen,
+ int orlonger)
{
struct tentry_v4 *n;
if (n->addr.s_addr != mp.s_addr)
break; /* off path, no match possible */
+ /* the match covers all larger prefixlens */
+ if (n->node && orlonger)
+ return 1;
+
/* plen is from 1 - 32 but the bitmask starts with 0 */
if (n->node && inet4isset(&n->plenmask, plen - 1))
return 1; /* prefixlen allowed, match */
}
static int
-trie_match_v6(struct trie_head *th, struct in6_addr *prefix, u_int8_t plen)
+trie_match_v6(struct trie_head *th, struct in6_addr *prefix, u_int8_t plen,
+ int orlonger)
{
struct tentry_v6 *n;
if (memcmp(&n->addr, &mp, sizeof(mp)) != 0)
break; /* off path, no match possible */
+ /* the match covers all larger prefixlens */
+ if (n->node && orlonger)
+ return 1;
+
/* plen is from 1 - 128 but the bitmask starts with 0 */
if (n->node && inet6isset(&n->plenmask, plen - 1))
return 1; /* prefixlen allowed, match */
/* find first matching element in the trie for prefix "prefix/plen" */
int
-trie_match(struct trie_head *th, struct bgpd_addr *prefix, u_int8_t plen)
+trie_match(struct trie_head *th, struct bgpd_addr *prefix, u_int8_t plen,
+ int orlonger)
{
switch (prefix->aid) {
case AID_INET:
- return trie_match_v4(th, &prefix->v4, plen);
+ return trie_match_v4(th, &prefix->v4, plen, orlonger);
case AID_INET6:
- return trie_match_v6(th, &prefix->v6, plen);
+ return trie_match_v6(th, &prefix->v6, plen, orlonger);
default:
/* anything else is no match */
return 0;