On 2016 Sep 26 (Mon) at 20:09:13 +0200 (+0200), Peter Hessler wrote: :We already have a local AS saved per peer. Let's use it. This is very :useful when one needs to change their local AS. : :" :neighbor 192.0.2.1 { : remote-as 65530 : local-as 131000 :} :" : :OK? :
Updated! Now it works far better, it supports "local-as 131000 65000", works better with prepend-self. You MUST use filters to protect yourself from receiving your own routes over the local-as peer. There be dragons and grues. OK? Index: bgpd.conf.5 =================================================================== RCS file: /cvs/openbsd/src/usr.sbin/bgpd/bgpd.conf.5,v retrieving revision 1.152 diff -u -p -u -p -r1.152 bgpd.conf.5 --- bgpd.conf.5 13 Jan 2017 18:59:12 -0000 1.152 +++ bgpd.conf.5 27 May 2017 09:04:28 -0000 @@ -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. +If the first AS number is a 4-byte AS it is possible to specify a secondary +2-byte AS number which is used for neighbors which do not support 4-byte AS +numbers. +The default for the secondary AS is 23456. +.Pp +This option is dangerous, and requires you to add filters to prevent +receiving your global ASN from this peer. +Intended to be used temporarily, for migrations to another AS. +.Pp .It Ic log no Disable neighbor specific logging. .Pp Index: parse.y =================================================================== RCS file: /cvs/openbsd/src/usr.sbin/bgpd/parse.y,v retrieving revision 1.300 diff -u -p -u -p -r1.300 parse.y --- parse.y 26 May 2017 14:08:51 -0000 1.300 +++ parse.y 27 May 2017 08:55:02 -0000 @@ -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}, Index: printconf.c =================================================================== RCS file: /cvs/openbsd/src/usr.sbin/bgpd/printconf.c,v retrieving revision 1.100 diff -u -p -u -p -r1.100 printconf.c --- printconf.c 24 Jan 2017 04:22:42 -0000 1.100 +++ printconf.c 26 May 2017 18:01:32 -0000 @@ -414,6 +414,8 @@ print_peer(struct peer_config *p, struct 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\n", c, log_as(p->local_as)); if (p->down) printf("%s\tdown\n", c); if (p->distance > 1) Index: rde.c =================================================================== RCS file: /cvs/openbsd/src/usr.sbin/bgpd/rde.c,v retrieving revision 1.361 diff -u -p -u -p -r1.361 rde.c --- rde.c 25 Jan 2017 03:21:55 -0000 1.361 +++ rde.c 27 May 2017 08:26:56 -0000 @@ -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 */ Index: rde_filter.c =================================================================== RCS file: /cvs/openbsd/src/usr.sbin/bgpd/rde_filter.c,v retrieving revision 1.80 diff -u -p -u -p -r1.80 rde_filter.c --- rde_filter.c 24 Jan 2017 04:22:42 -0000 1.80 +++ rde_filter.c 27 May 2017 08:44:37 -0000 @@ -106,7 +106,7 @@ rde_apply_set(struct rde_aspath *asp, st } 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); Index: rde_update.c =================================================================== RCS file: /cvs/openbsd/src/usr.sbin/bgpd/rde_update.c,v retrieving revision 1.84 diff -u -p -u -p -r1.84 rde_update.c --- rde_update.c 24 Jan 2017 04:22:42 -0000 1.84 +++ rde_update.c 27 May 2017 08:43:51 -0000 @@ -746,9 +746,9 @@ up_generate_attr(struct rde_peer *peer, /* 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,10 +881,10 @@ up_generate_attr(struct rde_peer *peer, if (neednewpath) { if (!peer->conf.ebgp || peer->conf.flags & PEERFLAG_TRANS_AS) - pdata = aspath_prepend(a->aspath, rde_local_as(), 0, + pdata = aspath_prepend(a->aspath, peer->conf.local_as, 0, &plen); else - pdata = aspath_prepend(a->aspath, rde_local_as(), 1, + pdata = aspath_prepend(a->aspath, peer->conf.local_as, 1, &plen); flags = ATTR_OPTIONAL|ATTR_TRANSITIVE; if (!(a->flags & F_PREFIX_ANNOUNCED)) Index: session.c =================================================================== RCS file: /cvs/openbsd/src/usr.sbin/bgpd/session.c,v retrieving revision 1.359 diff -u -p -u -p -r1.359 session.c --- session.c 13 Feb 2017 14:48:44 -0000 1.359 +++ session.c 27 May 2017 07:51:34 -0000 @@ -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 @@ -2128,7 +2128,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; @@ -3110,7 +3110,7 @@ session_template_clone(struct peer *p, s 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; -- Politicians are the same all over. They promise to build a bridge even where there is no river. -- Nikita Khrushchev