diff options
author | claudio <claudio@openbsd.org> | 2020-04-23 16:13:11 +0000 |
---|---|---|
committer | claudio <claudio@openbsd.org> | 2020-04-23 16:13:11 +0000 |
commit | 589de3c25c20495f83da58532a7fe7ae3e9fcb69 (patch) | |
tree | 2059ad4b1de8cd9109525cc861cf2028f948459d /usr.sbin/bgpd | |
parent | Correctly parse "0/0" as the default route when specifying (diff) | |
download | wireguard-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.h | 5 | ||||
-rw-r--r-- | usr.sbin/bgpd/parse.y | 43 | ||||
-rw-r--r-- | usr.sbin/bgpd/pfkey.c | 33 | ||||
-rw-r--r-- | usr.sbin/bgpd/printconf.c | 10 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.c | 15 | ||||
-rw-r--r-- | usr.sbin/bgpd/util.c | 4 |
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)); |