diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2010-02-11 13:18:06 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2010-02-11 13:18:06 +0000 |
commit | e3c06d9197bf7d3013c72dc37f16089b0d9dfa1e (patch) | |
tree | e8b98a1edd2fa09c1b4e635147cbd3d3863f1e04 /usr.sbin | |
parent | a0e2045d6293f6bd3054c20f10faff5aaec4403d (diff) |
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@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bgpd/rde_update.c | 36 |
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, |