summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd/parse.y
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2004-05-17 12:39:33 +0000
committerDamien Miller <djm@cvs.openbsd.org>2004-05-17 12:39:33 +0000
commita74d240e1f035cf15ade49b9233080a0dd32ad05 (patch)
treefed5bf61ab95bfca13f112c19059765153821251 /usr.sbin/bgpd/parse.y
parent4126f8f2d4e3ed383225cb8d06c0724ff7698c95 (diff)
extend filter language to allow basic setting of COMMUNITIES attribute.
ok claudio@
Diffstat (limited to 'usr.sbin/bgpd/parse.y')
-rw-r--r--usr.sbin/bgpd/parse.y102
1 files changed, 79 insertions, 23 deletions
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index 91647e5b16f..92f73b5ff0a 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.110 2004/05/08 20:58:00 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.111 2004/05/17 12:39:32 djm Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -84,6 +84,7 @@ int symset(const char *, const char *, int);
char *symget(const char *);
int atoul(char *, u_long *);
int getcommunity(char *);
+int parsecommunity(char *, int *, int *);
typedef struct {
union {
@@ -791,32 +792,13 @@ filter_match : /* empty */ { bzero(&$$, sizeof($$)); }
$$.as.type = $1;
}
| COMMUNITY STRING {
- char *p;
- int i;
-
bzero(&$$, sizeof($$));
- if ((p = strchr($2, ':')) == NULL) {
- free($2);
- yyerror("Bad community syntax");
- YYERROR;
- }
- *p++ = 0;
- if ((i = getcommunity($2)) == COMMUNITY_ERROR) {
- free($2);
- YYERROR;
- }
- if (i == 0 || i == USHRT_MAX) {
- free($2);
- yyerror("Bad community AS number");
- YYERROR;
- }
- $$.community.as = i;
- if ((i = getcommunity(p)) == COMMUNITY_ERROR) {
+ if (parsecommunity($2, &$$.community.as,
+ &$$.community.type) == -1) {
free($2);
YYERROR;
}
free($2);
- $$.community.type = i;
}
;
@@ -876,6 +858,10 @@ filter_set_l : filter_set_l comma filter_set_opt {
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
;
@@ -917,6 +903,34 @@ filter_set_opt : LOCALPREF number {
YYERROR;
}
}
+ | COMMUNITY STRING {
+ $$.flags = SET_COMMUNITY;
+ if (parsecommunity($2, &$$.community.as,
+ &$$.community.type) == -1) {
+ free($2);
+ YYERROR;
+ }
+ free($2);
+ if ($$.community.as <= 0 || $$.community.as > 0xffff) {
+ yyerror("Invalid comminity");
+ YYERROR;
+ }
+ /* Don't allow setting of unknown well-known types */
+ if ($$.community.as == COMMUNITY_WELLKNOWN) {
+ switch ($$.community.type) {
+ case COMMUNITY_NO_EXPORT:
+ case COMMUNITY_NO_ADVERTISE:
+ case COMMUNITY_NO_EXPSUBCONFED:
+ /* valid */
+ break;
+ default:
+ /* unknown */
+ yyerror("Invalid well-known community");
+ YYERROR;
+ break;
+ }
+ }
+ }
;
comma : ","
@@ -1418,6 +1432,48 @@ getcommunity(char *s)
return (ulval);
}
+int
+parsecommunity(char *s, int *as, int *type)
+{
+ char *p;
+ int i;
+
+ /* Well-known communities */
+ if (strcasecmp(s, "NO_EXPORT") == 0) {
+ *as = COMMUNITY_WELLKNOWN;
+ *type = COMMUNITY_NO_EXPORT;
+ return (0);
+ } else if (strcasecmp(s, "NO_ADVERTISE") == 0) {
+ *as = COMMUNITY_WELLKNOWN;
+ *type = COMMUNITY_NO_ADVERTISE;
+ return (0);
+ } else if (strcasecmp(s, "NO_EXPORT_SUBCONFED") == 0) {
+ *as = COMMUNITY_WELLKNOWN;
+ *type = COMMUNITY_NO_EXPSUBCONFED;
+ return (0);
+ }
+
+ if ((p = strchr(s, ':')) == NULL) {
+ yyerror("Bad community syntax");
+ return (-1);
+ }
+ *p++ = 0;
+
+ if ((i = getcommunity(s)) == COMMUNITY_ERROR)
+ return (-1);
+ if (i == 0 || i == USHRT_MAX) {
+ yyerror("Bad community AS number");
+ return (-1);
+ }
+ *as = i;
+
+ if ((i = getcommunity(p)) == COMMUNITY_ERROR)
+ return (-1);
+ *type = i;
+
+ return (0);
+}
+
struct peer *
alloc_peer(void)
{
@@ -1621,4 +1677,4 @@ neighbor_consistent(struct peer *p)
}
return (0);
-} \ No newline at end of file
+}