Better selection of link-local NLRI addresses, at least for our own
address. Need to do it better for the other neighbors -- the current solution works only if they use the standard 64+64 global addresses and the interface identifier in lower 64 bits is the same as for the link-scope addresses.
This commit is contained in:
parent
7b7a7b43a6
commit
11d4474c17
3 changed files with 26 additions and 5 deletions
|
@ -434,6 +434,19 @@ bgp_start_neighbor(struct bgp_proto *p)
|
||||||
{
|
{
|
||||||
p->local_addr = p->neigh->iface->addr->ip;
|
p->local_addr = p->neigh->iface->addr->ip;
|
||||||
DBG("BGP: local=%I remote=%I\n", p->local_addr, p->next_hop);
|
DBG("BGP: local=%I remote=%I\n", p->local_addr, p->next_hop);
|
||||||
|
#ifdef IPV6
|
||||||
|
{
|
||||||
|
struct ifa *a;
|
||||||
|
p->local_link = ipa_or(ipa_build(0xfe80,0,0,0), ipa_and(p->local_addr, ipa_build(0,0,~0,~0)));
|
||||||
|
WALK_LIST(a, p->neigh->iface->addrs)
|
||||||
|
if (a->scope == SCOPE_LINK)
|
||||||
|
{
|
||||||
|
p->local_link = a->ip;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DBG("BGP: Selected link-level address %I\n", p->local_link);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
bgp_initiate(p);
|
bgp_initiate(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ struct bgp_proto {
|
||||||
#ifdef IPV6
|
#ifdef IPV6
|
||||||
byte *mp_reach_start, *mp_unreach_start; /* Multiprotocol BGP attribute notes */
|
byte *mp_reach_start, *mp_unreach_start; /* Multiprotocol BGP attribute notes */
|
||||||
unsigned mp_reach_len, mp_unreach_len;
|
unsigned mp_reach_len, mp_unreach_len;
|
||||||
|
ip_addr local_link; /* Link-level version of local_addr */
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -193,20 +193,27 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
|
||||||
nh = ea_find(buck->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
|
nh = ea_find(buck->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
|
||||||
ASSERT(nh);
|
ASSERT(nh);
|
||||||
ip = *(ip_addr *) nh->u.ptr->data;
|
ip = *(ip_addr *) nh->u.ptr->data;
|
||||||
|
is_ll = 0;
|
||||||
if (ipa_equal(ip, p->local_addr))
|
if (ipa_equal(ip, p->local_addr))
|
||||||
|
{
|
||||||
is_ll = 1;
|
is_ll = 1;
|
||||||
|
ip_ll = p->local_link;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
n = neigh_find(&p->p, &ip, 0);
|
n = neigh_find(&p->p, &ip, 0);
|
||||||
if (n && n->iface == p->neigh->iface)
|
if (n && n->iface == p->neigh->iface)
|
||||||
|
{
|
||||||
|
/* FIXME: We are assuming the global scope addresses use the lower 64 bits
|
||||||
|
* as an interface identifier which hasn't necessarily to be true.
|
||||||
|
*/
|
||||||
is_ll = 1;
|
is_ll = 1;
|
||||||
else
|
ip_ll = ipa_or(ipa_build(0xfe800000,0,0,0), ipa_and(ip, ipa_build(0,0,~0,~0)));
|
||||||
is_ll = 0;
|
}
|
||||||
}
|
}
|
||||||
if (is_ll)
|
if (is_ll)
|
||||||
{
|
{
|
||||||
*tmp++ = 32;
|
*tmp++ = 32;
|
||||||
ip_ll = ipa_or(ipa_build(0xfe80,0,0,0), ipa_and(ip, ipa_build(0,0,~0,~0)));
|
|
||||||
ipa_hton(ip);
|
ipa_hton(ip);
|
||||||
memcpy(tmp, &ip, 16);
|
memcpy(tmp, &ip, 16);
|
||||||
ipa_hton(ip_ll);
|
ipa_hton(ip_ll);
|
||||||
|
|
Loading…
Reference in a new issue