Use link-local addresses in recursive next hops for IPv6 BGP.
This commit is contained in:
parent
c477f48916
commit
1b180121a9
3 changed files with 21 additions and 12 deletions
|
@ -163,7 +163,9 @@ struct hostcache {
|
||||||
|
|
||||||
struct hostentry {
|
struct hostentry {
|
||||||
node ln;
|
node ln;
|
||||||
ip_addr addr; /* IP of host, part of key */
|
ip_addr addr; /* IP address of host, part of key */
|
||||||
|
ip_addr link; /* (link-local) IP address of host, used as gw
|
||||||
|
if host is directly attached */
|
||||||
struct rtable *tab; /* Dependent table, part of key*/
|
struct rtable *tab; /* Dependent table, part of key*/
|
||||||
struct hostentry *next; /* Next in hash chain */
|
struct hostentry *next; /* Next in hash chain */
|
||||||
unsigned hash_key; /* Hash key */
|
unsigned hash_key; /* Hash key */
|
||||||
|
@ -386,7 +388,7 @@ static inline void rta_free(rta *r) { if (r && !--r->uc) rta__free(r); }
|
||||||
void rta_dump(rta *);
|
void rta_dump(rta *);
|
||||||
void rta_dump_all(void);
|
void rta_dump_all(void);
|
||||||
void rta_show(struct cli *, rta *, ea_list *);
|
void rta_show(struct cli *, rta *, ea_list *);
|
||||||
void rta_set_recursive_next_hop(rtable *dep, rta *a, rtable *tab, ip_addr *gw);
|
void rta_set_recursive_next_hop(rtable *dep, rta *a, rtable *tab, ip_addr *gw, ip_addr *ll);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rta_set_recursive_next_hop() acquires hostentry from hostcache and
|
* rta_set_recursive_next_hop() acquires hostentry from hostcache and
|
||||||
|
|
|
@ -1358,11 +1358,12 @@ hc_resize(struct hostcache *hc, unsigned new_order)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hostentry *
|
static struct hostentry *
|
||||||
hc_new_hostentry(struct hostcache *hc, ip_addr a, rtable *dep, unsigned k)
|
hc_new_hostentry(struct hostcache *hc, ip_addr a, ip_addr ll, rtable *dep, unsigned k)
|
||||||
{
|
{
|
||||||
struct hostentry *he = sl_alloc(hc->slab);
|
struct hostentry *he = sl_alloc(hc->slab);
|
||||||
|
|
||||||
he->addr = a;
|
he->addr = a;
|
||||||
|
he->link = ll;
|
||||||
he->tab = dep;
|
he->tab = dep;
|
||||||
he->hash_key = k;
|
he->hash_key = k;
|
||||||
he->uc = 0;
|
he->uc = 0;
|
||||||
|
@ -1475,9 +1476,9 @@ rt_update_hostentry(rtable *tab, struct hostentry *he)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The host is directly reachable, us it as a gateway */
|
/* The host is directly reachable, use link as a gateway */
|
||||||
he->iface = a->iface;
|
he->iface = a->iface;
|
||||||
he->gw = he->addr;
|
he->gw = he->link;
|
||||||
he->dest = RTD_ROUTER;
|
he->dest = RTD_ROUTER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1531,7 +1532,7 @@ rt_update_hostcache(rtable *tab)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hostentry *
|
static struct hostentry *
|
||||||
rt_find_hostentry(rtable *tab, ip_addr a, rtable *dep)
|
rt_find_hostentry(rtable *tab, ip_addr a, ip_addr ll, rtable *dep)
|
||||||
{
|
{
|
||||||
struct hostentry *he;
|
struct hostentry *he;
|
||||||
|
|
||||||
|
@ -1544,15 +1545,15 @@ rt_find_hostentry(rtable *tab, ip_addr a, rtable *dep)
|
||||||
if (ipa_equal(he->addr, a) && (he->tab == dep))
|
if (ipa_equal(he->addr, a) && (he->tab == dep))
|
||||||
return he;
|
return he;
|
||||||
|
|
||||||
he = hc_new_hostentry(hc, a, dep, k);
|
he = hc_new_hostentry(hc, a, ll, dep, k);
|
||||||
rt_update_hostentry(tab, he);
|
rt_update_hostentry(tab, he);
|
||||||
return he;
|
return he;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rta_set_recursive_next_hop(rtable *dep, rta *a, rtable *tab, ip_addr *gw)
|
rta_set_recursive_next_hop(rtable *dep, rta *a, rtable *tab, ip_addr *gw, ip_addr *ll)
|
||||||
{
|
{
|
||||||
rta_apply_hostentry(a, rt_find_hostentry(tab, *gw, dep));
|
rta_apply_hostentry(a, rt_find_hostentry(tab, *gw, *ll, dep));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -805,11 +805,17 @@ static inline int
|
||||||
bgp_set_next_hop(struct bgp_proto *p, rta *a)
|
bgp_set_next_hop(struct bgp_proto *p, rta *a)
|
||||||
{
|
{
|
||||||
struct eattr *nh = ea_find(a->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
|
struct eattr *nh = ea_find(a->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
|
||||||
ip_addr nexthop = *(ip_addr *) nh->u.ptr->data;
|
ip_addr *nexthop = (ip_addr *) nh->u.ptr->data;
|
||||||
|
|
||||||
|
#ifdef IPV6
|
||||||
|
int second = (nh->u.ptr->length == NEXT_HOP_LENGTH);
|
||||||
|
#else
|
||||||
|
int second = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (p->cf->gw_mode == GW_DIRECT)
|
if (p->cf->gw_mode == GW_DIRECT)
|
||||||
{
|
{
|
||||||
neighbor *ng = neigh_find(&p->p, &nexthop, 0) ? : p->neigh;
|
neighbor *ng = neigh_find(&p->p, nexthop, 0) ? : p->neigh;
|
||||||
if (ng->scope == SCOPE_HOST)
|
if (ng->scope == SCOPE_HOST)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -819,7 +825,7 @@ bgp_set_next_hop(struct bgp_proto *p, rta *a)
|
||||||
a->hostentry = NULL;
|
a->hostentry = NULL;
|
||||||
}
|
}
|
||||||
else /* GW_RECURSIVE */
|
else /* GW_RECURSIVE */
|
||||||
rta_set_recursive_next_hop(p->p.table, a, p->igp_table, &nexthop);
|
rta_set_recursive_next_hop(p->p.table, a, p->igp_table, nexthop, nexthop + second);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue