mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 15:16:20 +00:00
bgpd: fix update-source for IPv6 (BZ#548)
if update-source was given as interface name, bgpd was unconditionally trying to bind to an IPv4 address from that interface. change function to find the best-matching (number of address bits) same-family address on the interface.
This commit is contained in:
parent
188506f4c6
commit
5d3c53b999
@ -258,21 +258,37 @@ bgp_bind_address (int sock, struct in_addr *addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct in_addr *
|
||||
bgp_update_address (struct interface *ifp)
|
||||
static int
|
||||
bgp_update_address (struct interface *ifp, const union sockunion *dst,
|
||||
union sockunion *addr)
|
||||
{
|
||||
struct prefix_ipv4 *p;
|
||||
struct prefix *p, *sel, *d;
|
||||
struct connected *connected;
|
||||
struct listnode *node;
|
||||
int common;
|
||||
|
||||
d = sockunion2hostprefix (dst);
|
||||
sel = NULL;
|
||||
common = -1;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
|
||||
{
|
||||
p = (struct prefix_ipv4 *) connected->address;
|
||||
|
||||
if (p->family == AF_INET)
|
||||
return &p->prefix;
|
||||
p = connected->address;
|
||||
if (p->family != d->family)
|
||||
continue;
|
||||
if (prefix_common_bits (p, d) > common)
|
||||
{
|
||||
sel = p;
|
||||
common = prefix_common_bits (sel, d);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
prefix_free (d);
|
||||
if (!sel)
|
||||
return 1;
|
||||
|
||||
prefix2sockunion (sel, addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Update source selection. */
|
||||
@ -280,7 +296,7 @@ static void
|
||||
bgp_update_source (struct peer *peer)
|
||||
{
|
||||
struct interface *ifp;
|
||||
struct in_addr *addr;
|
||||
union sockunion addr;
|
||||
|
||||
/* Source is specified with interface name. */
|
||||
if (peer->update_if)
|
||||
@ -289,11 +305,10 @@ bgp_update_source (struct peer *peer)
|
||||
if (! ifp)
|
||||
return;
|
||||
|
||||
addr = bgp_update_address (ifp);
|
||||
if (! addr)
|
||||
if (bgp_update_address (ifp, &peer->su, &addr))
|
||||
return;
|
||||
|
||||
bgp_bind_address (peer->fd, addr);
|
||||
sockunion_bind (peer->fd, &addr, 0, &addr);
|
||||
}
|
||||
|
||||
/* Source is specified with IP address. */
|
||||
|
Loading…
Reference in New Issue
Block a user