summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2024-05-29 10:41:13 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2024-05-29 10:41:13 +0000
commit29acfa92095727af5e4fbdc6d0e47462ed87eeaf (patch)
tree7178a1b0092fc0c756adca6fd1cb1f36f5be3858 /usr.sbin
parent15a86675bb317da7791b817cf2a1bda59889c8ed (diff)
Handle IPvX only interfaces with IPvY sessions more gracefully.
In up_get_nexthop() check that the local_vX_addr is actually valid before using it. In the UPDATE generation functions check that the nexthop is valid before adding it and fail hard if it does not exist. You can't announce an IPv4 prefix/gateway over an IPv6 only link. OK henning@ sthen@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bgpd/rde_update.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c
index 2c2cf4c4a15..2c81bbe216c 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.166 2024/01/23 16:13:35 claudio Exp $ */
+/* $OpenBSD: rde_update.c,v 1.167 2024/05/29 10:41:12 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -454,16 +454,18 @@ up_generate_default(struct rde_peer *peer, uint8_t aid)
static struct bgpd_addr *
up_get_nexthop(struct rde_peer *peer, struct filterstate *state, uint8_t aid)
{
- struct bgpd_addr *peer_local;
+ struct bgpd_addr *peer_local = NULL;
switch (aid) {
case AID_INET:
case AID_VPN_IPv4:
- peer_local = &peer->local_v4_addr;
+ if (peer->local_v4_addr.aid == AID_INET)
+ peer_local = &peer->local_v4_addr;
break;
case AID_INET6:
case AID_VPN_IPv6:
- peer_local = &peer->local_v6_addr;
+ if (peer->local_v4_addr.aid == AID_INET6)
+ peer_local = &peer->local_v6_addr;
break;
case AID_FLOWSPECv4:
case AID_FLOWSPECv6:
@@ -613,6 +615,8 @@ up_generate_attr(struct ibuf *buf, struct rde_peer *peer,
case ATTR_NEXTHOP:
switch (aid) {
case AID_INET:
+ if (nh == NULL)
+ return -1;
if (attr_writebuf(buf, ATTR_WELL_KNOWN,
ATTR_NEXTHOP, &nh->exit_nexthop.v4,
sizeof(nh->exit_nexthop.v4)) == -1)
@@ -889,6 +893,8 @@ up_generate_mp_reach(struct ibuf *buf, struct rde_peer *peer,
switch (aid) {
case AID_INET6:
+ if (nh == NULL)
+ return -1;
/* NH LEN */
if (ibuf_add_n8(buf, sizeof(struct in6_addr)) == -1)
return -1;
@@ -898,6 +904,8 @@ up_generate_mp_reach(struct ibuf *buf, struct rde_peer *peer,
return -1;
break;
case AID_VPN_IPv4:
+ if (nh == NULL)
+ return -1;
/* NH LEN */
if (ibuf_add_n8(buf,
sizeof(uint64_t) + sizeof(struct in_addr)) == -1)
@@ -911,6 +919,8 @@ up_generate_mp_reach(struct ibuf *buf, struct rde_peer *peer,
return -1;
break;
case AID_VPN_IPv6:
+ if (nh == NULL)
+ return -1;
/* NH LEN */
if (ibuf_add_n8(buf,
sizeof(uint64_t) + sizeof(struct in6_addr)) == -1)
@@ -1091,10 +1101,10 @@ up_dump_update(struct ibuf *buf, struct rde_peer *peer, uint8_t aid)
fail:
/* Not enough space. Drop prefix, it will never fit. */
pt_getaddr(p->pt, &addr);
- log_peer_warnx(&peer->conf, "path attributes to large, "
+ log_peer_warnx(&peer->conf, "dump of path attributes failed, "
"prefix %s/%d dropped", log_addr(&addr), p->pt->prefixlen);
- up_prefix_free(&peer->updates[AID_INET], p, peer, 0);
+ up_prefix_free(&peer->updates[aid], p, peer, 0);
/* XXX should probably send a withdraw for this prefix */
return -1;
}