Nest: Keep multipath next hops sorted
This commit is contained in:
parent
a1839f3c61
commit
84cac51a51
5 changed files with 39 additions and 8 deletions
|
@ -506,6 +506,8 @@ int mpnh__same(struct mpnh *x, struct mpnh *y); /* Compare multipath nexthops */
|
||||||
static inline int mpnh_same(struct mpnh *x, struct mpnh *y)
|
static inline int mpnh_same(struct mpnh *x, struct mpnh *y)
|
||||||
{ return (x == y) || mpnh__same(x, y); }
|
{ return (x == y) || mpnh__same(x, y); }
|
||||||
struct mpnh *mpnh_merge(struct mpnh *x, struct mpnh *y, int rx, int ry, int max, linpool *lp);
|
struct mpnh *mpnh_merge(struct mpnh *x, struct mpnh *y, int rx, int ry, int max, linpool *lp);
|
||||||
|
void mpnh_insert(struct mpnh **n, struct mpnh *y);
|
||||||
|
int mpnh_is_sorted(struct mpnh *x);
|
||||||
|
|
||||||
void rta_init(void);
|
void rta_init(void);
|
||||||
rta *rta_lookup(rta *); /* Get rta equivalent to this one, uc++ */
|
rta *rta_lookup(rta *); /* Get rta equivalent to this one, uc++ */
|
||||||
|
|
|
@ -302,6 +302,34 @@ mpnh_merge(struct mpnh *x, struct mpnh *y, int rx, int ry, int max, linpool *lp)
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mpnh_insert(struct mpnh **n, struct mpnh *x)
|
||||||
|
{
|
||||||
|
for (; *n; n = &((*n)->next))
|
||||||
|
{
|
||||||
|
int cmp = mpnh_compare_node(*n, x);
|
||||||
|
|
||||||
|
if (cmp < 0)
|
||||||
|
continue;
|
||||||
|
else if (cmp > 0)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
x->next = *n;
|
||||||
|
*n = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
mpnh_is_sorted(struct mpnh *x)
|
||||||
|
{
|
||||||
|
for (; x && x->next; x = x->next)
|
||||||
|
if (mpnh_compare_node(x, x->next) >= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static struct mpnh *
|
static struct mpnh *
|
||||||
mpnh_copy(struct mpnh *o)
|
mpnh_copy(struct mpnh *o)
|
||||||
|
|
|
@ -804,6 +804,13 @@ rte_validate(rte *e)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((e->attrs->dest == RTD_MULTIPATH) && !mpnh_is_sorted(e->attrs->nexthops))
|
||||||
|
{
|
||||||
|
log(L_WARN "Ignoring unsorted multipath route %I/%d received via %s",
|
||||||
|
n->n.prefix, n->n.pxlen, e->sender->proto->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,6 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
|
||||||
{
|
{
|
||||||
/* ECMP route */
|
/* ECMP route */
|
||||||
struct mpnh *nhs = NULL;
|
struct mpnh *nhs = NULL;
|
||||||
struct mpnh **nhp = &nhs;
|
|
||||||
int num = 0;
|
int num = 0;
|
||||||
|
|
||||||
for (rt = en->routes; rt && (num < p->ecmp); rt = rt->next)
|
for (rt = en->routes; rt && (num < p->ecmp); rt = rt->next)
|
||||||
|
@ -185,9 +184,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
|
||||||
nh->gw = rt->next_hop;
|
nh->gw = rt->next_hop;
|
||||||
nh->iface = rt->from->nbr->iface;
|
nh->iface = rt->from->nbr->iface;
|
||||||
nh->weight = rt->from->ifa->cf->ecmp_weight;
|
nh->weight = rt->from->ifa->cf->ecmp_weight;
|
||||||
nh->next = NULL;
|
mpnh_insert(&nhs, nh);
|
||||||
*nhp = nh;
|
|
||||||
nhp = &(nh->next);
|
|
||||||
num++;
|
num++;
|
||||||
|
|
||||||
if (rt->tag != rt_tag)
|
if (rt->tag != rt_tag)
|
||||||
|
|
|
@ -81,7 +81,6 @@ static_install(struct proto *p, struct static_route *r, struct iface *ifa)
|
||||||
{
|
{
|
||||||
struct static_route *r2;
|
struct static_route *r2;
|
||||||
struct mpnh *nhs = NULL;
|
struct mpnh *nhs = NULL;
|
||||||
struct mpnh **nhp = &nhs;
|
|
||||||
|
|
||||||
for (r2 = r->mp_next; r2; r2 = r2->mp_next)
|
for (r2 = r->mp_next; r2; r2 = r2->mp_next)
|
||||||
if (r2->installed)
|
if (r2->installed)
|
||||||
|
@ -90,9 +89,7 @@ static_install(struct proto *p, struct static_route *r, struct iface *ifa)
|
||||||
nh->gw = r2->via;
|
nh->gw = r2->via;
|
||||||
nh->iface = r2->neigh->iface;
|
nh->iface = r2->neigh->iface;
|
||||||
nh->weight = r2->masklen; /* really */
|
nh->weight = r2->masklen; /* really */
|
||||||
nh->next = NULL;
|
mpnh_insert(&nhs, nh);
|
||||||
*nhp = nh;
|
|
||||||
nhp = &(nh->next);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There is at least one nexthop */
|
/* There is at least one nexthop */
|
||||||
|
|
Loading…
Reference in a new issue