summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
authorPeter Hessler <phessler@cvs.openbsd.org>2017-05-27 10:33:16 +0000
committerPeter Hessler <phessler@cvs.openbsd.org>2017-05-27 10:33:16 +0000
commitefb6405e7545eb5d56da61172ae8d83dd2d83f68 (patch)
tree3d9fa3146d0848f975da194f96a7713ab1e117b4 /usr.sbin/bgpd
parentd8cd89b85096bd42ba8e0bac6ab519621550a679 (diff)
Allow OpenBGPD to selectively choose which local ASN to use per-peer.
This is intended to be used for ASN migrations, not for permanent use. You MUST use filters to protect yourself from receiving your own routes. There be dragons and grues. OK claudio@ benno@
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/bgpd.conf.513
-rw-r--r--usr.sbin/bgpd/parse.y16
-rw-r--r--usr.sbin/bgpd/printconf.c8
-rw-r--r--usr.sbin/bgpd/rde.c5
-rw-r--r--usr.sbin/bgpd/rde_filter.c4
-rw-r--r--usr.sbin/bgpd/rde_update.c16
-rw-r--r--usr.sbin/bgpd/session.c10
7 files changed, 52 insertions, 20 deletions
diff --git a/usr.sbin/bgpd/bgpd.conf.5 b/usr.sbin/bgpd/bgpd.conf.5
index 95dfa8b6072..953ae15c6d1 100644
--- a/usr.sbin/bgpd/bgpd.conf.5
+++ b/usr.sbin/bgpd/bgpd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: bgpd.conf.5,v 1.153 2017/05/27 10:24:44 phessler Exp $
+.\" $OpenBSD: bgpd.conf.5,v 1.154 2017/05/27 10:33:15 phessler Exp $
.\"
.\" Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
.\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -874,6 +874,17 @@ is given,
.Xr bgpd 8
binds to this address first.
.Pp
+.It Ic local-as Ar as-number Op Ar as-number
+Set the AS number sent to the remote system.
+Used as described above under
+.Sx GLOBAL CONFIGURATION
+option
+.Ic AS .
+.Pp
+Since there is no AS path loop check, this option is dangerous, and
+requires you to add filters to prevent receiving your ASNs.
+Intended to be used temporarily, for migrations to another AS.
+.Pp
.It Ic log no
Disable neighbor specific logging.
.Pp
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index cb5a0a966db..0ccc8be5a27 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.302 2017/05/27 10:24:44 phessler Exp $ */
+/* $OpenBSD: parse.y,v 1.303 2017/05/27 10:33:15 phessler Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -188,7 +188,7 @@ typedef struct {
%token RDOMAIN RD EXPORTTRGT IMPORTTRGT
%token RDE RIB EVALUATE IGNORE COMPARE
%token GROUP NEIGHBOR NETWORK
-%token REMOTEAS DESCR LOCALADDR MULTIHOP PASSIVE MAXPREFIX RESTART
+%token LOCALAS REMOTEAS DESCR LOCALADDR MULTIHOP PASSIVE MAXPREFIX RESTART
%token ANNOUNCE CAPABILITIES REFRESH AS4BYTE CONNECTRETRY
%token DEMOTE ENFORCE NEIGHBORAS REFLECTOR DEPEND DOWN SOFTRECONFIG
%token DUMP IN OUT SOCKET RESTRICTED
@@ -1038,6 +1038,17 @@ peeroptsl : peeropts nl
peeropts : REMOTEAS as4number {
curpeer->conf.remote_as = $2;
}
+ | LOCALAS as4number {
+ curpeer->conf.local_as = $2;
+ if ($2 > USHRT_MAX)
+ curpeer->conf.local_short_as = AS_TRANS;
+ else
+ curpeer->conf.local_short_as = $2;
+ }
+ | LOCALAS as4number asnumber {
+ curpeer->conf.local_as = $2;
+ curpeer->conf.local_short_as = $3;
+ }
| DESCR string {
if (strlcpy(curpeer->conf.descr, $2,
sizeof(curpeer->conf.descr)) >=
@@ -2369,6 +2380,7 @@ lookup(char *s)
{ "large-community", LARGECOMMUNITY},
{ "listen", LISTEN},
{ "local-address", LOCALADDR},
+ { "local-as", LOCALAS},
{ "localpref", LOCALPREF},
{ "log", LOG},
{ "match", MATCH},
diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c
index d9bea4e4196..30cb76545db 100644
--- a/usr.sbin/bgpd/printconf.c
+++ b/usr.sbin/bgpd/printconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: printconf.c,v 1.101 2017/05/27 10:24:44 phessler Exp $ */
+/* $OpenBSD: printconf.c,v 1.102 2017/05/27 10:33:15 phessler Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -424,6 +424,12 @@ print_peer(struct peer_config *p, struct bgpd_config *conf, const char *c)
printf("%s\trib \"%s\"\n", c, p->rib);
if (p->remote_as)
printf("%s\tremote-as %s\n", c, log_as(p->remote_as));
+ if (p->local_as != conf->as) {
+ printf("%s\tlocal-as %s", c, log_as(p->local_as));
+ if (p->local_as > USHRT_MAX && p->local_short_as != AS_TRANS)
+ printf(" %u", p->local_short_as);
+ printf("\n");
+ }
if (p->down)
printf("%s\tdown\n", c);
if (p->distance > 1)
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index 37d98d7b7d9..6eb27eef66a 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.361 2017/01/25 03:21:55 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.362 2017/05/27 10:33:15 phessler Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -1103,7 +1103,8 @@ rde_update_dispatch(struct imsg *imsg)
p += 2 + attrpath_len;
/* aspath needs to be loop free nota bene this is not a hard error */
- if (peer->conf.ebgp && !aspath_loopfree(asp->aspath, conf->as))
+ if (peer->conf.ebgp &&
+ !aspath_loopfree(asp->aspath, peer->conf.local_as))
asp->flags |= F_ATTR_LOOP;
/* parse nlri prefix */
diff --git a/usr.sbin/bgpd/rde_filter.c b/usr.sbin/bgpd/rde_filter.c
index 7bbc9e3a443..9809fd35111 100644
--- a/usr.sbin/bgpd/rde_filter.c
+++ b/usr.sbin/bgpd/rde_filter.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_filter.c,v 1.81 2017/05/27 10:24:44 phessler Exp $ */
+/* $OpenBSD: rde_filter.c,v 1.82 2017/05/27 10:33:15 phessler Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -106,7 +106,7 @@ rde_apply_set(struct rde_aspath *asp, struct filter_set_head *sh,
}
break;
case ACTION_SET_PREPEND_SELF:
- prep_as = rde_local_as();
+ prep_as = peer->conf.local_as;
prepend = set->action.prepend;
np = aspath_prepend(asp->aspath, prep_as, prepend, &nl);
aspath_put(asp->aspath);
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c
index af01d7cf6b8..24b4335be5c 100644
--- a/usr.sbin/bgpd/rde_update.c
+++ b/usr.sbin/bgpd/rde_update.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_update.c,v 1.84 2017/01/24 04:22:42 benno Exp $ */
+/* $OpenBSD: rde_update.c,v 1.85 2017/05/27 10:33:15 phessler Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -746,9 +746,11 @@ up_generate_attr(struct rde_peer *peer, struct update_attr *upa,
/* aspath */
if (!peer->conf.ebgp ||
peer->conf.flags & PEERFLAG_TRANS_AS)
- pdata = aspath_prepend(a->aspath, rde_local_as(), 0, &plen);
+ pdata = aspath_prepend(a->aspath, peer->conf.local_as, 0,
+ &plen);
else
- pdata = aspath_prepend(a->aspath, rde_local_as(), 1, &plen);
+ pdata = aspath_prepend(a->aspath, peer->conf.local_as, 1,
+ &plen);
if (!rde_as4byte(peer))
pdata = aspath_deflate(pdata, &plen, &neednewpath);
@@ -881,11 +883,11 @@ up_generate_attr(struct rde_peer *peer, struct update_attr *upa,
if (neednewpath) {
if (!peer->conf.ebgp ||
peer->conf.flags & PEERFLAG_TRANS_AS)
- pdata = aspath_prepend(a->aspath, rde_local_as(), 0,
- &plen);
+ pdata = aspath_prepend(a->aspath, peer->conf.local_as,
+ 0, &plen);
else
- pdata = aspath_prepend(a->aspath, rde_local_as(), 1,
- &plen);
+ pdata = aspath_prepend(a->aspath, peer->conf.local_as,
+ 1, &plen);
flags = ATTR_OPTIONAL|ATTR_TRANSITIVE;
if (!(a->flags & F_PREFIX_ANNOUNCED))
flags |= ATTR_PARTIAL;
diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c
index c1d98b78947..32405955b3e 100644
--- a/usr.sbin/bgpd/session.c
+++ b/usr.sbin/bgpd/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.360 2017/05/26 20:55:30 phessler Exp $ */
+/* $OpenBSD: session.c,v 1.361 2017/05/27 10:33:15 phessler Exp $ */
/*
* Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
@@ -1467,7 +1467,7 @@ session_open(struct peer *p)
if (p->capa.ann.as4byte) { /* 4 bytes data */
u_int32_t nas;
- nas = htonl(conf->as);
+ nas = htonl(p->conf.local_as);
errs += session_capa_add(opb, CAPA_AS4BYTE, sizeof(nas));
errs += ibuf_add(opb, &nas, sizeof(nas));
}
@@ -1484,7 +1484,7 @@ session_open(struct peer *p)
}
msg.version = 4;
- msg.myas = htons(conf->short_as);
+ msg.myas = htons(p->conf.local_short_as);
if (p->conf.holdtime)
msg.holdtime = htons(p->conf.holdtime);
else
@@ -2136,7 +2136,7 @@ parse_open(struct peer *peer)
/* if remote-as is zero and it's a cloned neighbor, accept any */
if (peer->template && !peer->conf.remote_as && as != AS_TRANS) {
peer->conf.remote_as = as;
- peer->conf.ebgp = (peer->conf.remote_as != conf->as);
+ peer->conf.ebgp = (peer->conf.remote_as != peer->conf.local_as);
if (!peer->conf.ebgp)
/* force enforce_as off for iBGP sessions */
peer->conf.enforce_as = ENFORCE_AS_OFF;
@@ -3126,7 +3126,7 @@ session_template_clone(struct peer *p, struct sockaddr *ip, u_int32_t id,
if (as) {
p->conf.remote_as = as;
- p->conf.ebgp = (p->conf.remote_as != conf->as);
+ p->conf.ebgp = (p->conf.remote_as != p->conf.local_as);
if (!p->conf.ebgp)
/* force enforce_as off for iBGP sessions */
p->conf.enforce_as = ENFORCE_AS_OFF;