diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2004-05-17 12:39:33 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2004-05-17 12:39:33 +0000 |
commit | a74d240e1f035cf15ade49b9233080a0dd32ad05 (patch) | |
tree | fed5bf61ab95bfca13f112c19059765153821251 /usr.sbin/bgpd/parse.y | |
parent | 4126f8f2d4e3ed383225cb8d06c0724ff7698c95 (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.y | 102 |
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 +} |