summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2020-04-23 16:13:11 +0000
committerclaudio <claudio@openbsd.org>2020-04-23 16:13:11 +0000
commit589de3c25c20495f83da58532a7fe7ae3e9fcb69 (patch)
tree2059ad4b1de8cd9109525cc861cf2028f948459d /usr.sbin/bgpd
parentCorrectly parse "0/0" as the default route when specifying (diff)
downloadwireguard-openbsd-589de3c25c20495f83da58532a7fe7ae3e9fcb69.tar.xz
wireguard-openbsd-589de3c25c20495f83da58532a7fe7ae3e9fcb69.zip
Store local-address by address family. This allows to configure both
an IPv4 and IPv6 local-address on a group and the neighbors bind to the right local-address. Also implement 'no local-address' to reset a previously set local address back to zero. This should help with IBGP and multihop session config and hopefully reduce repetition in bgpd configs. OK sthen@ benno@
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/bgpd.h5
-rw-r--r--usr.sbin/bgpd/parse.y43
-rw-r--r--usr.sbin/bgpd/pfkey.c33
-rw-r--r--usr.sbin/bgpd/printconf.c10
-rw-r--r--usr.sbin/bgpd/session.c15
-rw-r--r--usr.sbin/bgpd/util.c4
6 files changed, 81 insertions, 29 deletions
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index cdcc0bddc71..3876b9e125c 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.401 2020/02/14 13:54:31 claudio Exp $ */
+/* $OpenBSD: bgpd.h,v 1.402 2020/04/23 16:13:11 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -365,7 +365,8 @@ struct capabilities {
struct peer_config {
struct bgpd_addr remote_addr;
- struct bgpd_addr local_addr;
+ struct bgpd_addr local_addr_v4;
+ struct bgpd_addr local_addr_v6;
struct peer_auth auth;
struct capabilities capabilities;
char group[PEER_DESCR_LEN];
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index b5b9db12f3c..9f5df25ba15 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.405 2020/03/16 14:47:30 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.406 2020/04/23 16:13:11 claudio Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -1260,8 +1260,27 @@ peeropts : REMOTEAS as4number {
free($2);
}
| LOCALADDR address {
- memcpy(&curpeer->conf.local_addr, &$2,
- sizeof(curpeer->conf.local_addr));
+ if ($2.aid == AID_INET)
+ memcpy(&curpeer->conf.local_addr_v4, &$2,
+ sizeof(curpeer->conf.local_addr_v4));
+ else if ($2.aid == AID_INET6)
+ memcpy(&curpeer->conf.local_addr_v6, &$2,
+ sizeof(curpeer->conf.local_addr_v6));
+ else {
+ yyerror("Unsupported address family %s for "
+ "local-addr", aid2str($2.aid));
+ YYERROR;
+ }
+ }
+ | yesno LOCALADDR {
+ if ($1) {
+ yyerror("bad local-address definition");
+ YYERROR;
+ }
+ memset(&curpeer->conf.local_addr_v4, 0,
+ sizeof(curpeer->conf.local_addr_v4));
+ memset(&curpeer->conf.local_addr_v6, 0,
+ sizeof(curpeer->conf.local_addr_v6));
}
| MULTIHOP NUMBER {
if ($2 < 2 || $2 > 255) {
@@ -4176,11 +4195,17 @@ str2key(char *s, char *dest, size_t max_len)
int
neighbor_consistent(struct peer *p)
{
- /* local-address and peer's address: same address family */
- if (p->conf.local_addr.aid &&
- p->conf.local_addr.aid != p->conf.remote_addr.aid) {
- yyerror("local-address and neighbor address "
- "must be of the same address family");
+ struct bgpd_addr *local_addr;
+
+ switch (p->conf.remote_addr.aid) {
+ case AID_INET:
+ local_addr = &p->conf.local_addr_v4;
+ break;
+ case AID_INET6:
+ local_addr = &p->conf.local_addr_v6;
+ break;
+ default:
+ yyerror("Bad address family for remote-addr");
return (-1);
}
@@ -4189,7 +4214,7 @@ neighbor_consistent(struct peer *p)
p->conf.auth.method == AUTH_IPSEC_IKE_AH ||
p->conf.auth.method == AUTH_IPSEC_MANUAL_ESP ||
p->conf.auth.method == AUTH_IPSEC_MANUAL_AH) &&
- !p->conf.local_addr.aid) {
+ local_addr->aid == AID_UNSPEC) {
yyerror("neighbors with any form of IPsec configured "
"need local-address to be specified");
return (-1);
diff --git a/usr.sbin/bgpd/pfkey.c b/usr.sbin/bgpd/pfkey.c
index 64baf454de7..78e53bc5572 100644
--- a/usr.sbin/bgpd/pfkey.c
+++ b/usr.sbin/bgpd/pfkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkey.c,v 1.60 2019/10/01 11:05:30 claudio Exp $ */
+/* $OpenBSD: pfkey.c,v 1.61 2020/04/23 16:13:11 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -55,6 +55,18 @@ int pfkey_send(int, uint8_t, uint8_t, uint8_t,
pfkey_send(fd, satype, cmd, dir, from, to, \
0, 0, 0, NULL, 0, 0, NULL, sport, dport)
+static struct bgpd_addr *
+pfkey_localaddr(struct peer *p)
+{
+ switch (p->conf.remote_addr.aid) {
+ case AID_INET:
+ return &p->conf.local_addr_v4;
+ case AID_INET6:
+ return &p->conf.local_addr_v6;
+ }
+ fatalx("Unknown AID in pfkey_localaddr");
+}
+
int
pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir,
struct bgpd_addr *src, struct bgpd_addr *dst, u_int32_t spi,
@@ -530,12 +542,12 @@ pfkey_md5sig_establish(struct peer *p)
u_int32_t spi_out = 0;
u_int32_t spi_in = 0;
- if (pfkey_sa_add(&p->conf.local_addr, &p->conf.remote_addr,
+ if (pfkey_sa_add(pfkey_localaddr(p), &p->conf.remote_addr,
p->conf.auth.md5key_len, p->conf.auth.md5key,
&spi_out) == -1)
goto fail;
- if (pfkey_sa_add(&p->conf.remote_addr, &p->conf.local_addr,
+ if (pfkey_sa_add(&p->conf.remote_addr, pfkey_localaddr(p),
p->conf.auth.md5key_len, p->conf.auth.md5key,
&spi_in) == -1)
goto fail;
@@ -582,6 +594,7 @@ static int
pfkey_ipsec_establish(struct peer *p)
{
uint8_t satype = SADB_SATYPE_ESP;
+ struct bgpd_addr *local_addr = pfkey_localaddr(p);
/* cleanup first, unlike in the TCP MD5 case */
if (p->auth.established) {
@@ -601,7 +614,7 @@ pfkey_ipsec_establish(struct peer *p)
satype = p->auth.method == AUTH_IPSEC_MANUAL_ESP ?
SADB_SATYPE_ESP : SADB_SATYPE_AH;
if (pfkey_send(pfkey_fd, satype, SADB_ADD, 0,
- &p->conf.local_addr, &p->conf.remote_addr,
+ local_addr, &p->conf.remote_addr,
p->conf.auth.spi_out,
p->conf.auth.auth_alg_out,
p->conf.auth.auth_keylen_out,
@@ -614,7 +627,7 @@ pfkey_ipsec_establish(struct peer *p)
if (pfkey_reply(pfkey_fd, NULL) == -1)
goto fail_key;
if (pfkey_send(pfkey_fd, satype, SADB_ADD, 0,
- &p->conf.remote_addr, &p->conf.local_addr,
+ &p->conf.remote_addr, local_addr,
p->conf.auth.spi_in,
p->conf.auth.auth_alg_in,
p->conf.auth.auth_keylen_in,
@@ -632,25 +645,25 @@ pfkey_ipsec_establish(struct peer *p)
}
if (pfkey_flow(pfkey_fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_OUT,
- &p->conf.local_addr, &p->conf.remote_addr, 0, BGP_PORT) == -1)
+ local_addr, &p->conf.remote_addr, 0, BGP_PORT) == -1)
goto fail_flow;
if (pfkey_reply(pfkey_fd, NULL) == -1)
goto fail_flow;
if (pfkey_flow(pfkey_fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_OUT,
- &p->conf.local_addr, &p->conf.remote_addr, BGP_PORT, 0) == -1)
+ local_addr, &p->conf.remote_addr, BGP_PORT, 0) == -1)
goto fail_flow;
if (pfkey_reply(pfkey_fd, NULL) == -1)
goto fail_flow;
if (pfkey_flow(pfkey_fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_IN,
- &p->conf.remote_addr, &p->conf.local_addr, 0, BGP_PORT) == -1)
+ &p->conf.remote_addr, local_addr, 0, BGP_PORT) == -1)
goto fail_flow;
if (pfkey_reply(pfkey_fd, NULL) == -1)
goto fail_flow;
if (pfkey_flow(pfkey_fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_IN,
- &p->conf.remote_addr, &p->conf.local_addr, BGP_PORT, 0) == -1)
+ &p->conf.remote_addr, local_addr, BGP_PORT, 0) == -1)
goto fail_flow;
if (pfkey_reply(pfkey_fd, NULL) == -1)
goto fail_flow;
@@ -768,7 +781,7 @@ pfkey_establish(struct peer *p)
* remote_addr cannot change, so no copy, SPI are
* handled by the method specific functions.
*/
- memcpy(&p->auth.local_addr, &p->conf.local_addr,
+ memcpy(&p->auth.local_addr, pfkey_localaddr(p),
sizeof(p->auth.local_addr));
p->auth.method = p->conf.auth.method;
diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c
index caa03e1b407..951ccb16bed 100644
--- a/usr.sbin/bgpd/printconf.c
+++ b/usr.sbin/bgpd/printconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: printconf.c,v 1.141 2020/01/24 05:44:05 claudio Exp $ */
+/* $OpenBSD: printconf.c,v 1.142 2020/04/23 16:13:11 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -608,8 +608,12 @@ print_peer(struct peer_config *p, struct bgpd_config *conf, const char *c)
printf("%s\tmultihop %u\n", c, p->distance);
if (p->passive)
printf("%s\tpassive\n", c);
- if (p->local_addr.aid)
- printf("%s\tlocal-address %s\n", c, log_addr(&p->local_addr));
+ if (p->local_addr_v4.aid)
+ printf("%s\tlocal-address %s\n", c,
+ log_addr(&p->local_addr_v4));
+ if (p->local_addr_v6.aid)
+ printf("%s\tlocal-address %s\n", c,
+ log_addr(&p->local_addr_v6));
if (p->max_prefix) {
printf("%s\tmax-prefix %u", c, p->max_prefix);
if (p->max_prefix_restart)
diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c
index 6902a5ff0ee..c92a5132c1f 100644
--- a/usr.sbin/bgpd/session.c
+++ b/usr.sbin/bgpd/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.399 2020/02/12 10:33:56 claudio Exp $ */
+/* $OpenBSD: session.c,v 1.400 2020/04/23 16:13:11 claudio Exp $ */
/*
* Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
@@ -1039,6 +1039,7 @@ int
session_connect(struct peer *peer)
{
struct sockaddr *sa;
+ struct bgpd_addr *bind_addr = NULL;
socklen_t sa_len;
/*
@@ -1066,8 +1067,16 @@ session_connect(struct peer *peer)
tcp_md5_set(peer->fd, peer);
peer->wbuf.fd = peer->fd;
- /* if update source is set we need to bind() */
- if ((sa = addr2sa(&peer->conf.local_addr, 0, &sa_len)) != NULL) {
+ /* if local-address is set we need to bind() */
+ switch (peer->conf.remote_addr.aid) {
+ case AID_INET:
+ bind_addr = &peer->conf.local_addr_v4;
+ break;
+ case AID_INET6:
+ bind_addr = &peer->conf.local_addr_v6;
+ break;
+ }
+ if (bind_addr && (sa = addr2sa(bind_addr, 0, &sa_len)) != NULL) {
if (bind(peer->fd, sa, sa_len) == -1) {
log_peer_warn(&peer->conf, "session_connect bind");
bgp_fsm(peer, EVNT_CON_OPENFAIL);
diff --git a/usr.sbin/bgpd/util.c b/usr.sbin/bgpd/util.c
index 778083958d9..39480fe82ee 100644
--- a/usr.sbin/bgpd/util.c
+++ b/usr.sbin/bgpd/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.52 2020/02/12 10:33:56 claudio Exp $ */
+/* $OpenBSD: util.c,v 1.53 2020/04/23 16:13:11 claudio Exp $ */
/*
* Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
@@ -844,7 +844,7 @@ addr2sa(struct bgpd_addr *addr, u_int16_t port, socklen_t *len)
struct sockaddr_in *sa_in = (struct sockaddr_in *)&ss;
struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)&ss;
- if (addr->aid == AID_UNSPEC)
+ if (addr == NULL || addr->aid == AID_UNSPEC)
return (NULL);
bzero(&ss, sizeof(ss));