summaryrefslogtreecommitdiffstats
path: root/bgpd
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2009-03-13 09:40:24 +0100
committerDavid Lamparter <equinox@diac24.net>2010-02-03 05:23:29 +0100
commit63cf3e60162a47952d1578d574d7d9186df936c0 (patch)
tree606436c3be90b14b14fc04f86f12c7ccc96b3761 /bgpd
parent553dc585041231151be4eeeb7184a61fc62817ef (diff)
downloadquagga-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.c25
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*/