summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2004-07-28 14:15:29 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2004-07-28 14:15:29 +0000
commitc39db0e7f98d09e58327f229f705c6aa6265b81f (patch)
tree424b98641c3f0420dd6676d0d01a32442bf679ed /usr.sbin
parentaa334bff81d9c3c9813e2699ef1e1f1792f313f8 (diff)
add list expansion for AS in filter rules
actually, it's list expansion on steroids, this works: deny from any { source-AS { 3320 852 } AS { 4589 174 } }
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bgpd/parse.y111
1 files changed, 90 insertions, 21 deletions
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index 918a0afa699..5acee6a79ee 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.122 2004/07/28 12:46:36 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.123 2004/07/28 14:15:28 henning Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -72,9 +72,15 @@ struct filter_prefix_l {
struct filter_prefix p;
};
+struct filter_as_l {
+ struct filter_as_l *next;
+ struct as_filter a;
+};
+
struct filter_match_l {
struct filter_match m;
struct filter_prefix_l *prefix_l;
+ struct filter_as_l *as_l;
} fmopts;
struct peer *alloc_peer(void);
@@ -111,6 +117,7 @@ typedef struct {
struct filter_peers_l *filter_peers;
struct filter_match_l filter_match;
struct filter_prefix_l *filter_prefix;
+ struct filter_as_l *filter_as;
struct filter_prefixlen prefixlen;
struct filter_set filter_set;
struct {
@@ -150,10 +157,12 @@ typedef struct {
%type <v.u8> action quick direction
%type <v.filter_peers> filter_peer filter_peer_l filter_peer_h
%type <v.filter_match> filter_match filter_elm filter_match_h
+%type <v.filter_as> filter_as filter_as_l filter_as_h
+%type <v.filter_as> filter_as_t filter_as_t_l
%type <v.prefixlen> prefixlenop
%type <v.filter_set> filter_set filter_set_l filter_set_opt
%type <v.filter_prefix> filter_prefix filter_prefix_l filter_prefix_h
-%type <v.u8> unaryop binaryop filter_as
+%type <v.u8> unaryop binaryop filter_as_type
%type <v.encspec> encspec;
%%
@@ -868,6 +877,51 @@ filter_prefix : prefix {
}
;
+filter_as_h : filter_as_t
+ | '{' filter_as_t_l '}' { $$ = $2; }
+ ;
+
+filter_as_t_l : filter_as_t
+ | filter_as_t_l comma filter_as_t {
+ struct filter_as_l *a;
+
+ /* merge, both can be lists */
+ for (a = $1; a != NULL && a->next != NULL; a = a->next)
+ ; /* nothing */
+ if (a != NULL)
+ a->next = $3;
+ $$ = $1;
+ }
+ ;
+
+filter_as_t : filter_as_type filter_as {
+ $$ = $2;
+ $$->a.type = $1;
+ }
+ | filter_as_type '{' filter_as_l '}' {
+ struct filter_as_l *a;
+
+ $$ = $3;
+ for (a = $$; a != NULL; a = a->next)
+ a->a.type = $1;
+ }
+ ;
+
+filter_as_l : filter_as { $$ = $1; }
+ | filter_as_l comma filter_as {
+ $3->next = $1;
+ $$ = $3;
+ }
+ ;
+
+filter_as : asnumber {
+ if (($$ = calloc(1, sizeof(struct filter_as_l))) ==
+ NULL)
+ fatal(NULL);
+ $$->a.as = $1;
+ }
+ ;
+
filter_match_h : /* empty */ { bzero(&$$, sizeof($$)); }
| { bzero(&fmopts, sizeof(fmopts)); }
filter_match {
@@ -887,9 +941,8 @@ filter_elm : filter_prefix_h {
sizeof(fmopts.m.prefixlen));
fmopts.m.prefixlen.af = AF_INET;
}
- | filter_as asnumber {
- fmopts.m.as.as = $2;
- fmopts.m.as.type = $1;
+ | filter_as_h {
+ fmopts.as_l = $1;
}
| COMMUNITY STRING {
if (parsecommunity($2, &fmopts.m.community.as,
@@ -926,7 +979,7 @@ prefixlenop : unaryop number {
}
;
-filter_as : AS { $$ = AS_ALL; }
+filter_as_type : AS { $$ = AS_ALL; }
| SOURCEAS { $$ = AS_SOURCE; }
| TRANSITAS { $$ = AS_TRANSIT; }
;
@@ -1710,30 +1763,42 @@ expand_rule(struct filter_rule *rule, struct filter_peers_l *peer,
struct filter_rule *r;
struct filter_peers_l *p, *pnext;
struct filter_prefix_l *prefix, *prefix_next;
+ struct filter_as_l *a, *anext;
p = peer;
do {
prefix = match->prefix_l;
do {
- if ((r = calloc(1, sizeof(struct filter_rule))) ==
- NULL) {
- log_warn("expand_rule");
- return (-1);
- }
+ a = match->as_l;
+ do {
+ if ((r = calloc(1,
+ sizeof(struct filter_rule))) == NULL) {
+ log_warn("expand_rule");
+ return (-1);
+ }
- memcpy(r, rule, sizeof(struct filter_rule));
- memcpy(&r->match, match, sizeof(struct filter_match));
- memcpy(&r->set, set, sizeof(struct filter_set));
+ memcpy(r, rule, sizeof(struct filter_rule));
+ memcpy(&r->match, match,
+ sizeof(struct filter_match));
+ memcpy(&r->set, set, sizeof(struct filter_set));
- if (p != NULL)
- memcpy(&r->peer, &p->p,
- sizeof(struct filter_peers));
+ if (p != NULL)
+ memcpy(&r->peer, &p->p,
+ sizeof(struct filter_peers));
- if (prefix != NULL)
- memcpy(&r->match.prefix, &prefix->p,
- sizeof(r->match.prefix));
+ if (prefix != NULL)
+ memcpy(&r->match.prefix, &prefix->p,
+ sizeof(r->match.prefix));
- TAILQ_INSERT_TAIL(filter_l, r, entry);
+ if (a != NULL)
+ memcpy(&r->match.as, &a->a,
+ sizeof(struct as_filter));
+
+ TAILQ_INSERT_TAIL(filter_l, r, entry);
+
+ if (a != NULL)
+ a = a->next;
+ } while (a != NULL);
if (prefix != NULL)
prefix = prefix->next;
@@ -1753,6 +1818,10 @@ expand_rule(struct filter_rule *rule, struct filter_peers_l *peer,
free(prefix);
}
+ for (a = match->as_l; a != NULL; a = anext) {
+ anext = a->next;
+ free(a);
+ }
return (0);
}