summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd/parse.y
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2007-04-23 13:04:25 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2007-04-23 13:04:25 +0000
commit08c3c9310d4b3dbbe393bd4048439d572c15a835 (patch)
tree595e0a61227029b9198526b626ac9bce5ac2390e /usr.sbin/bgpd/parse.y
parentd1c0f4acb7b6be8baa3fd007c8fde95a78ab1dab (diff)
Make bgpd 4-byte AS compatible. All internal representations of AS numbers
are now 4-byte instead of the old 2-byte numbers. The only exception are communities because they can not be switched. The RDE will inflate and deflate the ASPATH and AGGREGATOR attributes on demand and create the NEW_ASPATH and NEW_AGGREGATOR field whenever needed. Both old and new stile sessions are supported and can be mixed. Currently new stile sessions with the 4-byte AS number capability turned on are only enabled if one of the AS numbers involved is a 4-byte one. This is based on an initial diff by Geoff Huston gih (at) apnic (dot) net Cleanup, testing and bug-fixes by myself (via AS 3.10). Currently mrt table dumps are producing incompatible output this will be fixed afterwards -- this diff is already big enough. "get it in if you think it is ready" henning@
Diffstat (limited to 'usr.sbin/bgpd/parse.y')
-rw-r--r--usr.sbin/bgpd/parse.y68
1 files changed, 59 insertions, 9 deletions
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index 64c5852fe94..45bddeef586 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.203 2007/04/17 17:17:45 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.204 2007/04/23 13:04:24 claudio Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -172,8 +172,8 @@ typedef struct {
%token IPV4 IPV6
%token QUALIFY VIA
%token <v.string> STRING
-%type <v.number> number asnumber optnumber yesno inout espah
-%type <v.number> family restart
+%type <v.number> number asnumber as4number optnumber yesno inout
+%type <v.number> espah family restart
%type <v.string> string
%type <v.addr> address
%type <v.prefix> prefix addrspec
@@ -224,7 +224,44 @@ asnumber : number {
}
}
-string : string STRING {
+as4number : STRING {
+ const char *errstr;
+ char *dot;
+ u_int32_t uvalh = 0, uval;
+
+ if ((dot = strchr($1,'.')) != NULL) {
+ *dot++ = '\0';
+ uvalh = strtonum($1, 0, USHRT_MAX, &errstr);
+ if (errstr) {
+ yyerror("number %s is %s", $1, errstr);
+ free($1);
+ YYERROR;
+ }
+ uval = strtonum(dot, 0, USHRT_MAX, &errstr);
+ if (errstr) {
+ yyerror("number %s is %s", dot, errstr);
+ free($1);
+ YYERROR;
+ }
+ free($1);
+ } else {
+ uval = strtonum($1, 0, USHRT_MAX - 1, &errstr);
+ if (errstr) {
+ yyerror("number %s is %s", $1, errstr);
+ free($1);
+ YYERROR;
+ }
+ free($1);
+ }
+ if (uvalh == 0 && uval == AS_TRANS) {
+ yyerror("AS %u is reserved and may not be used",
+ AS_TRANS);
+ YYERROR;
+ }
+ $$ = uval | (uvalh << 16);
+ }
+
+string : string STRING {
if (asprintf(&$$, "%s %s", $1, $2) == -1)
fatal("string: asprintf");
free($1);
@@ -233,7 +270,7 @@ string : string STRING {
| STRING
;
-yesno : STRING {
+yesno : STRING {
if (!strcmp($1, "yes"))
$$ = 1;
else if (!strcmp($1, "no"))
@@ -256,7 +293,7 @@ varset : STRING '=' string {
}
;
-include : INCLUDE STRING {
+include : INCLUDE STRING {
struct file *nfile;
if ((nfile = include_file($2)) == NULL) {
@@ -271,8 +308,16 @@ include : INCLUDE STRING {
}
;
-conf_main : AS asnumber {
+conf_main : AS as4number {
conf->as = $2;
+ if ($2 > USHRT_MAX)
+ conf->short_as = AS_TRANS;
+ else
+ conf->short_as = $2;
+ }
+ | AS as4number asnumber {
+ conf->as = $2;
+ conf->short_as = $3;
}
| ROUTERID address {
if ($2.af != AF_INET) {
@@ -654,7 +699,7 @@ peeroptsl : peeropts nl
| error nl
;
-peeropts : REMOTEAS asnumber {
+peeropts : REMOTEAS as4number {
curpeer->conf.remote_as = $2;
}
| DESCR string {
@@ -1214,7 +1259,7 @@ filter_as_l : filter_as
}
;
-filter_as : asnumber {
+filter_as : as4number {
if (($$ = calloc(1, sizeof(struct filter_as_l))) ==
NULL)
fatal(NULL);
@@ -2250,6 +2295,7 @@ alloc_peer(void)
p->conf.capabilities.mp_v6 = SAFI_NONE;
p->conf.capabilities.refresh = 1;
p->conf.capabilities.restart = 0;
+ p->conf.capabilities.as4byte = 0;
p->conf.softreconfig_in = 1;
p->conf.softreconfig_out = 1;
@@ -2511,6 +2557,10 @@ neighbor_consistent(struct peer *p)
return (-1);
}
+ /* for testing: enable 4-byte AS number capability if necessary */
+ if (conf->as > USHRT_MAX || p->conf.remote_as > USHRT_MAX)
+ p->conf.capabilities.as4byte = 1;
+
/* set default values if they where undefined */
p->conf.ebgp = (p->conf.remote_as != conf->as);
if (p->conf.announce_type == ANNOUNCE_UNDEF)