funny ECMP
Ingo Flaschberger
if at xip.at
Wed Aug 25 22:52:48 UTC 2010
Hi,
currently I stick at this (last?) problem:
assume routingtable: net gw
postion type
1 route 10.13.13.0/24 10.11.11.1
2 route 10.13.13.0/24 10.11.11.2
3 interface route 10.13.13.90/24
delete route 2
delete route 1
-> ping 10.13.13.95 via interface -> crash
because route 2 is not deleted from radix_mask-list,
route 2 appears again, but is deleted - kernel panic
Problem is generated here:
sys/net/radix.c in rn_addroute
/* Promote general routes from below */
if (x->rn_bit < 0) {
printf("rn_addroute: x->rn_bit < 0\n");
for (mp = &t->rn_mklist; x; x = x->rn_dupedkey) {
printf("rn_addroute: for (mp = &t->rn_mklist; x; x = x->rn_dupedkey)\n");
/* XXX what todo with multipath-routes?? */
here for every multipath-route
of this netmask a new radix-mask
is added when the route for an interface
is added.
I'm not shure if the generated mask are linked together?
(Should they be linked?)
if (x->rn_mask && (x->rn_bit >= b_leaf) && x->rn_mklist == 0) {
printf("rn_addroute: new mask - next = 0\n");
*mp = m = rn_new_radix_mask(x, 0);
if (m) {
mp = &m->rm_mklist;
printf("rn_addroute: if (m)\n");
}
}
}
Final crash occurs in route.c after getting a rt_entry back from here:
sys/net/radix.c in rn_match
/* start searching up the tree */
do {
register struct radix_mask *m;
t = t->rn_parent;
printf("rn_match: parent %lu\n", (u_int64_t) t);
m = t->rn_mklist;
/*
* If non-contiguous masks ever become important
* we can restore the masking and open coding of
* the search and satisfaction test and put the
* calculation of "off" back before the "do".
*/
while (m) {
if (m->rm_flags & RNF_NORMAL) {
if (rn_bit <= m->rm_bit) {
printf("rn_match: found leaf: %lu\n", (u_int64_t) m->rm_leaf);
The already deleted route 2 is then
found again!
return (m->rm_leaf);
}
} else {
off = min(t->rn_offset, matched_off);
x = rn_search_m(v, t, m->rm_mask);
while (x && x->rn_mask != m->rm_mask)
x = x->rn_dupedkey;
if (x && rn_satisfies_leaf(v, x, off)) {
printf("rn_match: rn_satisfies_leaf: %lu\n", (u_int64_t) x);
return x;
}
}
m = m->rm_mklist;
}
} while (t != top);
The problem happen only for more than 2 same route sin the system.
sys/net/radix_mpath.c in rt_mpath_deldup
the radix_masklist should be deleted, changed?
rt_mpath_deldup is only called for the 2nd and more routes in the table,
the first route is deleted with standard radix delete.
I have really no idea how radix_mask (should) work - help really needed.
Kind regards,
Ingo Flaschberger
More information about the freebsd-net
mailing list