diff options
author | David Lamparter <equinox@diac24.net> | 2009-03-13 09:40:24 +0100 |
---|---|---|
committer | David Lamparter <equinox@diac24.net> | 2010-02-03 05:23:29 +0100 |
commit | 63cf3e60162a47952d1578d574d7d9186df936c0 (patch) | |
tree | 606436c3be90b14b14fc04f86f12c7ccc96b3761 /bgpd | |
parent | 553dc585041231151be4eeeb7184a61fc62817ef (diff) | |
download | quagga-63cf3e60162a47952d1578d574d7d9186df936c0.tar.bz2 quagga-63cf3e60162a47952d1578d574d7d9186df936c0.tar.xz |
bgpd: Fix nexthops for IPv4 routes on IPv6 peerings.
This patch fixes the nexthop used when transporting IPv4 routes
over an IPv6 BGP peering. Previously, the bgp router id was used;
with this patch, the lowest IP from the interface is used.
Diffstat (limited to 'bgpd')
-rw-r--r-- | bgpd/bgp_zebra.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index f3baeee0..d4f95745 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -432,6 +432,28 @@ if_lookup_by_ipv4_exact (struct in_addr *addr) return NULL; } +static int +if_get_ipv4 (struct interface *ifp, struct in_addr *addr) +{ + struct listnode *cnode; + struct connected *connected; + struct prefix *cp; + int hit = 0; + + for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected)) + { + cp = connected->address; + + if (cp->family == AF_INET) + if (!hit || ntohl(cp->u.prefix4.s_addr) < ntohl(addr->s_addr)) + { + memcpy (addr, &cp->u.prefix4, IPV4_MAX_BYTELEN); + hit = 1; + } + } + return hit; +} + #ifdef HAVE_IPV6 struct interface * if_lookup_by_ipv6 (struct in6_addr *addr) @@ -586,7 +608,8 @@ bgp_nexthop_set (union sockunion *local, union sockunion *remote, struct interface *direct = NULL; /* IPv4 nexthop. I don't care about it. */ - if (peer->local_id.s_addr) + ret = if_get_ipv4 (ifp, &nexthop->v4); + if (!ret && peer->local_id.s_addr) nexthop->v4 = peer->local_id; /* Global address*/ |