summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2010-02-11 13:18:05 +0000
committerclaudio <claudio@openbsd.org>2010-02-11 13:18:05 +0000
commit003f2e7133912f442e015db89fb6dba4ac4bf753 (patch)
tree5e17fbbad568b1e8cd5a6ba5bb619ef554dce854
parentForce a space between address and nexthop. IPv6 is overflowing all size (diff)
downloadwireguard-openbsd-003f2e7133912f442e015db89fb6dba4ac4bf753.tar.xz
wireguard-openbsd-003f2e7133912f442e015db89fb6dba4ac4bf753.zip
While looking through this code I figured out that set nexthop self and
no-modify are not supported for MP protocols like IPv6. Add support for those and while testing find another bug in the same region. Inverse the check for the return value of memcmp() -- we're interested in equality. Until now IPv6 was running with an implicit set nexthop self on all iBGP sessions. Oups. set nexthop stuff is OK when tested henning@ and sthen@
-rw-r--r--usr.sbin/bgpd/rde_update.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c
index c3e63268c08..8ebf4d6d1d5 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.77 2010/01/13 06:02:37 claudio Exp $ */
+/* $OpenBSD: rde_update.c,v 1.78 2010/02/11 13:18:05 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -606,11 +606,23 @@ up_generate_mp_reach(struct rde_peer *peer, struct update_attr *upa,
upa->mpattr[20] = 0; /* Reserved must be 0 */
/* nexthop dance see also up_get_nexthop() */
- if (peer->conf.ebgp == 0) {
+ if (a->flags & F_NEXTHOP_NOMODIFY) {
+ /* no modify flag set */
+ if (a->nexthop == NULL)
+ memcpy(&upa->mpattr[4], &peer->local_v6_addr.v6,
+ sizeof(struct in6_addr));
+ else
+ memcpy(&upa->mpattr[4],
+ &a->nexthop->exit_nexthop.v6,
+ sizeof(struct in6_addr));
+ } else if (a->flags & F_NEXTHOP_SELF)
+ memcpy(&upa->mpattr[4], &peer->local_v6_addr.v6,
+ sizeof(struct in6_addr));
+ else if (!peer->conf.ebgp) {
/* ibgp */
if (a->nexthop == NULL ||
(a->nexthop->exit_nexthop.aid == AID_INET6 &&
- memcmp(&a->nexthop->exit_nexthop.v6,
+ !memcmp(&a->nexthop->exit_nexthop.v6,
&peer->remote_addr.v6, sizeof(struct in6_addr))))
memcpy(&upa->mpattr[4], &peer->local_v6_addr.v6,
sizeof(struct in6_addr));
@@ -653,11 +665,25 @@ up_generate_mp_reach(struct rde_peer *peer, struct update_attr *upa,
upa->mpattr[3] = sizeof(u_int64_t) + sizeof(struct in_addr);
/* nexthop dance see also up_get_nexthop() */
- if (peer->conf.ebgp == 0) {
+ if (a->flags & F_NEXTHOP_NOMODIFY) {
+ /* no modify flag set */
+ if (a->nexthop == NULL)
+ memcpy(&upa->mpattr[12],
+ &peer->local_v4_addr.v4,
+ sizeof(struct in_addr));
+ else
+ /* nexthops are stored as IPv4 addrs */
+ memcpy(&upa->mpattr[12],
+ &a->nexthop->exit_nexthop.v4,
+ sizeof(struct in_addr));
+ } else if (a->flags & F_NEXTHOP_SELF)
+ memcpy(&upa->mpattr[12], &peer->local_v4_addr.v4,
+ sizeof(struct in_addr));
+ else if (!peer->conf.ebgp) {
/* ibgp */
if (a->nexthop == NULL ||
(a->nexthop->exit_nexthop.aid == AID_INET &&
- memcmp(&a->nexthop->exit_nexthop.v4,
+ !memcmp(&a->nexthop->exit_nexthop.v4,
&peer->remote_addr.v4, sizeof(struct in_addr))))
memcpy(&upa->mpattr[12],
&peer->local_v4_addr.v4,