summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd/parse.y
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2004-08-17 16:06:40 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2004-08-17 16:06:40 +0000
commit9e4dbd85e4c2ac29a9c1481e61eccb60cacea781 (patch)
tree4b7860ee5b27291a13c25a9a41dca35fcc290823 /usr.sbin/bgpd/parse.y
parent4a3db94e9fd4fdc7f702554b46b4aac260f62c1a (diff)
Merge set constructs in neighbor statements. This fixes a common problem:
previous sets were cleared by the last one. OK henning@
Diffstat (limited to 'usr.sbin/bgpd/parse.y')
-rw-r--r--usr.sbin/bgpd/parse.y59
1 files changed, 34 insertions, 25 deletions
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index 7c98357000f..f34717bd509 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.133 2004/08/13 14:03:20 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.134 2004/08/17 16:06:39 claudio Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -92,6 +92,7 @@ int expand_rule(struct filter_rule *, struct filter_peers_l *,
struct filter_match_l *, struct filter_set *);
int str2key(char *, char *, size_t);
int neighbor_consistent(struct peer *);
+int merge_filterset(struct filter_set *, struct filter_set *);
TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
struct sym {
@@ -704,12 +705,12 @@ peeropts : REMOTEAS asnumber {
curpeer->conf.capabilities = $3;
}
| SET filter_set_opt {
- memcpy(&curpeer->conf.attrset, &$2,
- sizeof(curpeer->conf.attrset));
+ if (merge_filterset(&curpeer->conf.attrset, &$2) == -1)
+ YYERROR;
}
| SET optnl "{" optnl filter_set_l optnl "}" {
- memcpy(&curpeer->conf.attrset, &$5,
- sizeof(curpeer->conf.attrset));
+ if (merge_filterset(&curpeer->conf.attrset, &$5) == -1)
+ YYERROR;
}
| mrtdump
| REFLECTOR {
@@ -1058,27 +1059,8 @@ filter_set : /* empty */ {
filter_set_l : filter_set_l comma filter_set_opt {
$$ = $1;
- if ($$.flags & $3.flags) {
- yyerror("redefining set shitz is not fluffy");
+ if (merge_filterset(&$$, &$3) == 1)
YYERROR;
- }
- $$.flags |= $3.flags;
- if ($3.flags & SET_LOCALPREF)
- $$.localpref = $3.localpref;
- if ($3.flags & SET_MED)
- $$.med = $3.med;
- if ($3.flags & SET_NEXTHOP)
- memcpy(&$$.nexthop, &$3.nexthop,
- sizeof($$.nexthop));
- if ($3.flags & SET_PREPEND)
- $$.prepend = $3.prepend;
- if ($3.flags & SET_PFTABLE)
- strlcpy($$.pftable, $3.pftable,
- sizeof($$.pftable));
- if ($3.flags & SET_COMMUNITY) {
- $$.community.as = $3.community.as;
- $$.community.type = $3.community.type;
- }
}
| filter_set_opt
;
@@ -1955,3 +1937,30 @@ neighbor_consistent(struct peer *p)
return (0);
}
+
+int
+merge_filterset(struct filter_set *a, struct filter_set *b)
+{
+ if (a->flags & b->flags) {
+ yyerror("redefining set parameters is not fluffy");
+ return (-1);
+ }
+ a->flags |= b->flags;
+ if (b->flags & SET_LOCALPREF)
+ a->localpref = b->localpref;
+ if (b->flags & SET_MED)
+ a->med = b->med;
+ if (b->flags & SET_NEXTHOP)
+ memcpy(&a->nexthop, &b->nexthop,
+ sizeof(a->nexthop));
+ if (b->flags & SET_PREPEND)
+ a->prepend = b->prepend;
+ if (b->flags & SET_PFTABLE)
+ strlcpy(a->pftable, b->pftable,
+ sizeof(a->pftable));
+ if (b->flags & SET_COMMUNITY) {
+ a->community.as = b->community.as;
+ a->community.type = b->community.type;
+ }
+ return (0);
+}