Greg Troxel reported [quagga-users 1068] that ripng sends packets with
only one route. I can confirm that. And I found cause of it as well.
Cause is cvs diff -r 1.2 -r 1.3 lib/linklist.c
What happens is that no prefixes is added to the list of routes to
send because:
+ if ((*list->cmp) (val, n->data) == 0)
+ return;
In ripngd/ripng_nexthop.c function ripng_rte_add uses
listnode_add_sort to add prefixes to the list. But it fails to add
most of prefixes because it compares nexthop's which are 0:: in most
of cases.
_ripng_rte_cmp(struct ripng_rte_data *A, struct ripng_rte_data *B) {
return addr6_cmp(&NEXTHOP_OUT(A), &NEXTHOP_OUT(B));
}
I don't have time at the moment to dig it further (my mathematics
books are waiting ;). But I have feeling that we try to use
listnode_add_sort in conflicting situations. In one case we might
compare things that are equal and add nodes to the list even if they
are. In other case we should avoid duplicates.
AFAIK need (is there really need?) to avoid duplicates was introduced
by interface sorting patch by Cougar.
So, correct solution would be to revert last change in
listnode_add_sort and introduce new function listnode_add_sort_nodup
for interface sorting? Why should we avoid duplicates in inetrface
list at all? Solaris have several interfaces with same name? IE. why
not just if ((*list->cmp) (val, n->data) <= 0) instead of if
((*list->cmp) (val, n->data) < 0)? Why return at all in case when
comparable things are equal?
Hope, it helps.
--
Hasso Tepper
PS. I should stop reading mail probably to avoid temptation to hack on
something ;)
only one route. I can confirm that. And I found cause of it as well.
Cause is cvs diff -r 1.2 -r 1.3 lib/linklist.c
What happens is that no prefixes is added to the list of routes to
send because:
+ if ((*list->cmp) (val, n->data) == 0)
+ return;
In ripngd/ripng_nexthop.c function ripng_rte_add uses
listnode_add_sort to add prefixes to the list. But it fails to add
most of prefixes because it compares nexthop's which are 0:: in most
of cases.
_ripng_rte_cmp(struct ripng_rte_data *A, struct ripng_rte_data *B) {
return addr6_cmp(&NEXTHOP_OUT(A), &NEXTHOP_OUT(B));
}
I don't have time at the moment to dig it further (my mathematics
books are waiting ;). But I have feeling that we try to use
listnode_add_sort in conflicting situations. In one case we might
compare things that are equal and add nodes to the list even if they
are. In other case we should avoid duplicates.
AFAIK need (is there really need?) to avoid duplicates was introduced
by interface sorting patch by Cougar.
So, correct solution would be to revert last change in
listnode_add_sort and introduce new function listnode_add_sort_nodup
for interface sorting? Why should we avoid duplicates in inetrface
list at all? Solaris have several interfaces with same name? IE. why
not just if ((*list->cmp) (val, n->data) <= 0) instead of if
((*list->cmp) (val, n->data) < 0)? Why return at all in case when
comparable things are equal?
Hope, it helps.
--
Hasso Tepper
PS. I should stop reading mail probably to avoid temptation to hack on
something ;)