mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
Nest: Fix bug in recursive routes with MPLS-labeled nexthops
When a recursive route with MPLS-labeled nexthop was exported to kernel and read back, the nexthop_same() failed due to different labels_orig field and kernel protocol reinstalled it unnecessarily. For comparing hext hops, route cache has to distinguish ones with different labels_orig, but KRT has to ignore that, so we need two nexthop compare functions. Thanks to Marcel Menzel for the bugreport.
This commit is contained in:
parent
472be46f7a
commit
f40e2bc270
@ -694,6 +694,9 @@ static inline size_t nexthop_size(const struct nexthop *nh)
|
|||||||
int nexthop__same(struct nexthop *x, struct nexthop *y); /* Compare multipath nexthops */
|
int nexthop__same(struct nexthop *x, struct nexthop *y); /* Compare multipath nexthops */
|
||||||
static inline int nexthop_same(struct nexthop *x, struct nexthop *y)
|
static inline int nexthop_same(struct nexthop *x, struct nexthop *y)
|
||||||
{ return (x == y) || nexthop__same(x, y); }
|
{ return (x == y) || nexthop__same(x, y); }
|
||||||
|
int nexthop_equal_(struct nexthop *x, struct nexthop *y); /* Compare multipath nexthops, ignore labels_orig */
|
||||||
|
static inline int nexthop_equal(struct nexthop *x, struct nexthop *y)
|
||||||
|
{ return (x == y) || nexthop_equal_(x, y); }
|
||||||
struct nexthop *nexthop_merge(struct nexthop *x, struct nexthop *y, int rx, int ry, int max, linpool *lp);
|
struct nexthop *nexthop_merge(struct nexthop *x, struct nexthop *y, int rx, int ry, int max, linpool *lp);
|
||||||
struct nexthop *nexthop_sort(struct nexthop *x);
|
struct nexthop *nexthop_sort(struct nexthop *x);
|
||||||
static inline void nexthop_link(struct rta *a, const struct nexthop *from)
|
static inline void nexthop_link(struct rta *a, const struct nexthop *from)
|
||||||
|
@ -185,21 +185,41 @@ nexthop_hash(struct nexthop *x)
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
nexthop_equal_1(struct nexthop *x, struct nexthop *y)
|
||||||
|
{
|
||||||
|
if (!ipa_equal(x->gw, y->gw) || (x->iface != y->iface) ||
|
||||||
|
(x->flags != y->flags) || (x->weight != y->weight) ||
|
||||||
|
(x->labels != y->labels))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < x->labels; i++)
|
||||||
|
if (x->label[i] != y->label[i])
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
nexthop_equal_(struct nexthop *x, struct nexthop *y)
|
||||||
|
{
|
||||||
|
/* Like nexthop_same(), but ignores difference between local labels and labels from hostentry */
|
||||||
|
|
||||||
|
for (; x && y; x = x->next, y = y->next)
|
||||||
|
if (!nexthop_equal_1(x, y))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return x == y;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nexthop__same(struct nexthop *x, struct nexthop *y)
|
nexthop__same(struct nexthop *x, struct nexthop *y)
|
||||||
{
|
{
|
||||||
for (; x && y; x = x->next, y = y->next)
|
for (; x && y; x = x->next, y = y->next)
|
||||||
{
|
if (!nexthop_equal_1(x, y) ||
|
||||||
if (!ipa_equal(x->gw, y->gw) || (x->iface != y->iface) ||
|
(x->labels_orig != y->labels_orig))
|
||||||
(x->flags != y->flags) || (x->weight != y->weight) ||
|
|
||||||
(x->labels_orig != y->labels_orig) || (x->labels != y->labels))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (int i = 0; i < x->labels; i++)
|
|
||||||
if (x->label[i] != y->label[i])
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x == y;
|
return x == y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -619,7 +619,7 @@ krt_same_dest(rte *k, rte *e)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (ka->dest == RTD_UNICAST)
|
if (ka->dest == RTD_UNICAST)
|
||||||
return nexthop_same(&(ka->nh), &(ea->nh));
|
return nexthop_equal(&(ka->nh), &(ea->nh));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user