Mailing List Archive

Recent ripng breakage
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 ;)
Re: Recent ripng breakage [ In reply to ]
> 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

Same change broke other things as well. See [quagga-dev 492].

Is there any reason for not to revert this change in linklist.c?

--
Hasso Tepper
Re: Recent ripng breakage [ In reply to ]
> AFAIK need (is there really need?) to avoid duplicates was introduced
> by interface sorting patch by Cougar.

I think you actually mean [quagga-dev 227]

> for interface sorting? Why should we avoid duplicates in inetrface
> list at all?

I don't understand the question- you should only have one structure
for the interface. Suppose you start up zebra with the line
"interface ip.tun0", and set up the IP tunnel *after* zebra is
up and running, you should not be seeing two structures for ip.tun0
in the list.

> ((*list->cmp) (val, n->data) < 0)? Why return at all in case when
> comparable things are equal?

The structure is already there.. why would you create a new one?

--Sowmini
Re: Recent ripng breakage [ In reply to ]
sowmini.varadhan@sun.com wrote:
> > AFAIK need (is there really need?) to avoid duplicates was
> > introduced by interface sorting patch by Cougar.
>
> I think you actually mean [quagga-dev 227]
>
> > for interface sorting? Why should we avoid duplicates in
> > inetrface list at all?
>
> I don't understand the question- you should only have one structure
> for the interface. Suppose you start up zebra with the line
> "interface ip.tun0", and set up the IP tunnel *after* zebra is
> up and running, you should not be seeing two structures for ip.tun0
> in the list.

Ah, didn't think about it.

> > ((*list->cmp) (val, n->data) < 0)? Why return at all in case when
> > comparable things are equal?
>
> The structure is already there.. why would you create a new one?

You don't compare structures. What happens if you want to nodes in
list to be sorted by value what is same in many nodes?

--
Hasso Tepper
Re: Recent ripng breakage [ In reply to ]
Thanks for figuring this out!

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));
}

If a route is a prefix and a nexthop, I'd say that two routes with
differing prefixes and the same nexthop are different routes, and that
comparison function is just wrong. But I haven't understood the
context well enough to be sure.

--
Greg Troxel <gdt@ir.bbn.com>
Re: Recent ripng breakage [ In reply to ]
Greg Troxel wrote:
> Thanks for figuring this out!
>
> 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));
> }
>
> If a route is a prefix and a nexthop, I'd say that two routes with
> differing prefixes and the same nexthop are different routes, and
> that comparison function is just wrong. But I haven't understood
> the context well enough to be sure.

So are routes with same prefix and different nexthops. AFAICS this
compare function serves "sorted by what" purpose.

--
Hasso Tepper
Re: Recent ripng breakage [ In reply to ]
> > > ((*list->cmp) (val, n->data) < 0)? Why return at all in case when
> > > comparable things are equal?
> >
> > The structure is already there.. why would you create a new one?
>
> You don't compare structures. What happens if you want to nodes in
> list to be sorted by value what is same in many nodes?

I still don't parse the question.

My understanding is that list->cmp is a standard comparison function
that (like strcmp) returns greater than, equal to, or less than 0,
if arg1 is greater than, equal to, or less than arg2.

This should allow the caller to keep the list sorted by key, but
disallow duplicates (case when list->cmp returns 0).

--Sowmini
Re: Recent ripng breakage [ In reply to ]
OK, so there are two separate questions:

1) is this entry a dup (if not, skip). This requires a full compare.
The listnode_add_sort (which is undercommented, since it doesn't say
that it omits dups, and the name is list not set) function uses the
cmp function to decide if this is an equal match.

2) Where should it be put? (I suspect this doesn't really matter for
ripng packets, but I haven't read the spec enough to be sure.)

So, I think for rte_cmp, we should perhaps do

if prefix1 < prefix2 return -1
if prefix1 > prefix2 return 1
if nexthop1 < nexthop2 return -1
if nexthop1 > nexthop2 return 1
/* XXX anything else to check? interface*/

/* RTE strutures really are the same */
return 0;
Re: Recent ripng breakage [ In reply to ]
arg, now I think I see your point, which if I understand is that
listnode_add_sort is not suppose to omit duplicates, but just to sort.

Certainly the combination of the cmp function we have in
ripng_nexthop.c and that listnode_add_sort omits duplicates is a
problem. I suppose we really need to understand what the other
callers of listnode_add_sort expect and clean up the comments and fix
one of these things.

This is made more complex by the fact that either data->rinfo or
data->aggregate can be non-NULL, and so full sorting will have to
check one or the other, and the current comparison function uses
NEXTHOP_OUT which switches between rinfo and aggregate. But that
actually seems ok.

Sorry for the flurry of mail...
Re: Recent ripng breakage [ In reply to ]
Greg Troxel wrote:
> arg, now I think I see your point, which if I understand is that
> listnode_add_sort is not suppose to omit duplicates, but just to
> sort.

Yes, exactly.

> Certainly the combination of the cmp function we have in
> ripng_nexthop.c and that listnode_add_sort omits duplicates is a
> problem. I suppose we really need to understand what the other
> callers of listnode_add_sort expect and clean up the comments and
> fix one of these things.

We can't do that. What we should do is that we must not change
behavior of functions in core library. Quagga/zebra isn't just code
in the CVS. It's also isisd, mpls and for sure a lot of code we don't
even know about. Only god knows how many code this change broke ;).

I agree, that listnode_add_sort looks a little bit strange even
without last change. it doesn't sort actually if you are adding new
node and *list->cmp returns 0 - if it does, new node is added to the
end of list. But this is minor issue IMHO. Assuming that author of
original (maybe) thought that code should omit duplicates if it
really doesn't is certainly nonono.

--
Hasso Tepper
Elion Enterprises Ltd.
WAN administrator
Re: Recent ripng breakage [ In reply to ]
> Certainly the combination of the cmp function we have in
> ripng_nexthop.c and that listnode_add_sort omits duplicates is a
> problem. I suppose we really need to understand what the other
> callers of listnode_add_sort expect and clean up the comments and
> fix one of these things.

We can't do that. What we should do is that we must not change
behavior of functions in core library. Quagga/zebra isn't just code
in the CVS. It's also isisd, mpls and for sure a lot of code we don't
even know about. Only god knows how many code this change broke ;).

Well, changing behavior to make them meet their defined API is OK if
the behavior is wrong. But I agree that changing longstanding or
documented semantics is not ok.
What I really meant was to understand from the other callers whether
they expected dups to be omitted, to understand the historical "true
API" definition, since there isn't any documentation in the code.

Given that the 1.2 to 1.3 change modified the behavior from the
long-standing behavior, odds are very high that all authors of code
written before 2003-09-23 that calls listnode_add_sort do not expect
dups to be filtered.

So I think we are in agreement that the 1.2-1.3 delta should be backed
out, and then we can discuss with sowmini.varadhan@sun.com what the
issue was that gave rise to:

revision 1.3
date: 2003/09/23 23:47:14; author: paul; state: Exp; lines: +6 -2
2003-09-24 sowmini.varadhan@sun.com

* lib/linklist.c: (if_cmp_func) Fix handling of case where
list->cmp returns 0.

and solve it another way.

It may be that we want a linklist_add_sort_nodups() function that adds
the new node only if cmp(*) != 0.

I'd like to add comments to functions as we run into things that
specify their behavior a bit better. I've been looking at doxygen, so
I would wonder about using their structured markup, which is human
readable and extractable to form API docs.
Re: Recent ripng breakage [ In reply to ]
Greg Troxel wrote:
> Given that the 1.2 to 1.3 change modified the behavior from the
> long-standing behavior, odds are very high that all authors of code
> written before 2003-09-23 that calls listnode_add_sort do not
> expect dups to be filtered.

Yes. And that's why we shouldn't change it.

> So I think we are in agreement that the 1.2-1.3 delta should be
> backed out, and then we can discuss with sowmini.varadhan@sun.com
> what the issue was that gave rise to:
>
> revision 1.3
> date: 2003/09/23 23:47:14; author: paul; state: Exp; lines: +6
> -2 2003-09-24 sowmini.varadhan@sun.com
>
> * lib/linklist.c: (if_cmp_func) Fix handling of case where
> list->cmp returns 0.
>
> and solve it another way.
>
> It may be that we want a linklist_add_sort_nodups() function that
> adds the new node only if cmp(*) != 0.

That's might be idea, yes. Other way is to check before calling
listnode_add_sort() to avoid duplicates if needed. That's what
attached patch does. It reverts rev 1.3 linklist.c and adds check to
the lib/if.c. I can't test it at the moment, but it should work. Can
you test and commit it if it's ok?

I really should dig more into mathematics books ;).

--
Hasso Tepper
Elion Enterprises Ltd.
WAN administrator
Re: Recent ripng breakage [ In reply to ]
On Sat, 20 Dec 2003, Greg Troxel wrote:

> Well, changing behavior to make them meet their defined API is OK
> if the behavior is wrong. But I agree that changing longstanding
> or documented semantics is not ok.

The semantics were clearly broken though, or rather, there were no
semantics in place /at all/ to deal with the comparator returning
equal/0. Sowmini's change established the behaviour in the first
place.

> What I really meant was to understand from the other callers
> whether they expected dups to be omitted, to understand the
> historical "true API" definition, since there isn't any
> documentation in the code.

Indeed.

> Given that the 1.2 to 1.3 change modified the behavior from the
> long-standing behavior, odds are very high that all authors of code
> written before 2003-09-23 that calls listnode_add_sort do not
> expect dups to be filtered.

Who knows, it was clearly borken previously, consider if we add a
element "foo" to a list, if the list contains:

foo

the new foo would /not/ be added. if it contained:

foo
food

it would /not/ be added. If it contained:

foo
bar

it /would/. So it was just borked previously. Sowmini's change at
least makes it /consistently/ not add the element.

> So I think we are in agreement that the 1.2-1.3 delta should be
> backed out, and then we can discuss with sowmini.varadhan@sun.com
> what the issue was that gave rise to:
>
> revision 1.3
> date: 2003/09/23 23:47:14; author: paul; state: Exp; lines: +6 -2
> 2003-09-24 sowmini.varadhan@sun.com
>
> * lib/linklist.c: (if_cmp_func) Fix handling of case where
> list->cmp returns 0.
>
> and solve it another way.

I'd rather it not be backed out. I'd rather we fix the users and/or
consider whether we need to add something to lists to allow them to
add duplicate entries. Indeed, clean up the damn thing.

> I'd like to add comments to functions as we run into things that
> specify their behavior a bit better. I've been looking at doxygen,
> so I would wonder about using their structured markup, which is
> human readable and extractable to form API docs.

Yes, would be good.

regards,
--
Paul Jakma paul@clubi.ie paul@jakma.org Key ID: 64A2FF6A
warning: do not ever send email to spam@dishone.st
Fortune:
A right is not what someone gives you; it's what no one can take from you.
-- Ramsey Clark
Re: Recent ripng breakage [ In reply to ]
On Sat, 20 Dec 2003, Paul Jakma wrote:

> consider whether we need to add something to lists to allow them to
> add duplicate entries. Indeed, clean up the damn thing.

Eg, another problem with it is that it (..._add_sort) returns void,
user has no idea whether it was inserted or not. Is that good?

regards,
--
Paul Jakma paul@clubi.ie paul@jakma.org Key ID: 64A2FF6A
warning: do not ever send email to spam@dishone.st
Fortune:
I don't mind what Congress does, as long as they don't do it in the
streets and frighten the horses.
-- Victor Hugo
Re: Recent ripng breakage [ In reply to ]
Paul Jakma wrote:
> On Sat, 20 Dec 2003, Greg Troxel wrote:
> > Well, changing behavior to make them meet their defined API is OK
> > if the behavior is wrong. But I agree that changing longstanding
> > or documented semantics is not ok.
>
> The semantics were clearly broken though, or rather, there were no
> semantics in place /at all/ to deal with the comparator returning
> equal/0. Sowmini's change established the behaviour in the first
> place.

Wrong. Semantics existed - node was added to the end of list in case
compare returned 0. I agree that it is strange/broken/whatever, but
it didn't drop node. And that's what I wouldn't change.

> > So I think we are in agreement that the 1.2-1.3 delta should be
> > backed out, and then we can discuss with sowmini.varadhan@sun.com
> > what the issue was that gave rise to:
> >
> > revision 1.3
> > date: 2003/09/23 23:47:14; author: paul; state: Exp; lines: +6
> > -2 2003-09-24 sowmini.varadhan@sun.com
> >
> > * lib/linklist.c: (if_cmp_func) Fix handling of case where
> > list->cmp returns 0.
> >
> > and solve it another way.
>
> I'd rather it not be backed out. I'd rather we fix the users and/or
> consider whether we need to add something to lists to allow them to
> add duplicate entries. Indeed, clean up the damn thing.

I think that givinig to the listnode_add_sort function behavior what
perfectly makes sense and doesn't brake any code is very trivial. See
attached patch against CVS. With this patch function does what his
name says - it adds (name isn't listnode_add_or_drop_sort ;) node to
the list sorted. It just fixes one little thing which was
strange/broken - if cmp returned 0, node was added to the end of
list.

And as I already said previously - if there is need to drop nodes if
cmp returns 0, check must be done before calling listnode_add_sort()
or implement listnode_add_sort_nodups() function for example.

--
Hasso Tepper
Elion Enterprises Ltd.
WAN administrator
Re: Recent ripng breakage [ In reply to ]
On Sun, 21 Dec 2003, Hasso Tepper wrote:

> Wrong. Semantics existed - node was added to the end of list in
> case compare returned 0.

urg.. i somehow only looked at the loop itself. Yes, it defaults to
adding.

> I agree that it is strange/broken/whatever, but it didn't drop
> node.

It did get dropped before, how is it guaranteed to be added? Oh
wait.. yes, it does :) (apologies.)

> I think that givinig to the listnode_add_sort function behavior
> what perfectly makes sense and doesn't brake any code is very
> trivial. See attached patch against CVS. With this patch function
> does what his name says - it adds (name isn't
> listnode_add_or_drop_sort ;) node to the list sorted. It just fixes
> one little thing which was strange/broken - if cmp returned 0, node
> was added to the end of list.

Ok, fair enough.

> And as I already said previously - if there is need to drop nodes
> if cmp returns 0, check must be done before calling
> listnode_add_sort() or implement listnode_add_sort_nodups()
> function for example.

Yes, agreed. Apply.

regards,
--
Paul Jakma paul@clubi.ie paul@jakma.org Key ID: 64A2FF6A
warning: do not ever send email to spam@dishone.st
Fortune:
Today is a good day for information-gathering. Read someone else's mail file.
Re: Recent ripng breakage [ In reply to ]
Paul Jakma wrote:
> Yes, agreed. Apply.

Done.

--
Hasso Tepper
Elion Enterprises Ltd.
WAN administrator
Re: Recent ripng breakage [ In reply to ]
I updated after your commit and can verify that ripngd works in my
setup (2 ethernets and a ppp link, and both ethernet prefixes are
advertised over the ppp link). OSPF (v4) works as well (on
NetBSD/i386 1.6.2_RC2).

Thanks for all your help on this.

--
Greg Troxel <gdt@ir.bbn.com>
Re: Recent ripng breakage [ In reply to ]
It is a very good news.

One of the purpose of the 6WIND's patch, that uses the
link_list_add_sort feature, is to support the Next Hop routing
optimization of the RFC2080.

Before sending, the routes, that need to be sent, are sorted according
to their NH. This sorting is used to build many sub-sets of RTEs, then a
NH RTE is added between each sub-set.

Regards,
Vincent

2.1.1 Next Hop

RIPng provides the ability to specify the immediate next hop IPv6
address to which packets to a destination specified by a route table
entry (RTE) should be forwarded in much the same way as RIP-2 [2].
In RIP-2, each route table entry has a next hop field. Including a
next hop field for each RTE in RIPng would nearly double the size of
the RTE. Therefore, in RIPng, the next hop is specified by a special
RTE and applies to all of the address RTEs following the next hop RTE
until the end of the message or until another next hop RTE is
encountered.

A next hop RTE is identified by a value of 0xFF in the metric field
of an RTE. The prefix field specifies the IPv6 address of the next
hop. The route tag and prefix length in the next hop RTE must be set
to zero on sending and ignored on receiption.

The next hop Route Table Entry (RTE) has the following format:

0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
~ IPv6 next hop address (16) ~
| |
+---------------------------------------------------------------+
| must be zero (2) |must be zero(1)| 0xFF |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Specifying a value of 0:0:0:0:0:0:0:0 in the prefix field of a next
hop RTE indicates that the next hop address should be the originator
of the RIPng advertisement. An address specified as a next hop must
be a link-local address.

The purpose of the next hop RTE is to eliminate packets being routed
through extra hops in the system. It is particularly useful when
RIPng is not being run on all of the routers on a network. Note that
next hop RTE is "advisory". That is, if the provided information is
ignored, a possibly sub-optimal, but absolutely valid, route may be
taken. If the received next hop address is not a link-local address,
it should be treated as 0:0:0:0:0:0:0:0.



Greg Troxel wrote:

>I updated after your commit and can verify that ripngd works in my
>setup (2 ethernets and a ppp link, and both ethernet prefixes are
>advertised over the ppp link). OSPF (v4) works as well (on
>NetBSD/i386 1.6.2_RC2).
>
>Thanks for all your help on this.
>
>
>
Re: Recent ripng breakage [ In reply to ]
> revision 1.3
> date: 2003/09/23 23:47:14; author: paul; state: Exp; lines: +6 -2
> 2003-09-24 sowmini.varadhan@sun.com
>
> * lib/linklist.c: (if_cmp_func) Fix handling of case where
> list->cmp returns 0.
>
> and solve it another way.
>
> It may be that we want a linklist_add_sort_nodups() function that adds
> the new node only if cmp(*) != 0.

sowmini.varadhan@sun.com had the problem that she added the line
"interface ip.tun0" in zebra.conf started up zebra, and later plumbed
("created") the ip.tun0 interface. zebra ended up with 2 structures,
one with index -1, and another with the correct ifindex

To me, the name "listnode_add_sort" says, "add this node to the
list if it doesn't exist, and keep the list sorted by key (where key
is defined by the cmp function)"

IMO, adding dups is just memory leakage, and sounds like poor design.
ymmv.

--Sowmini
Re: Recent ripng breakage [ In reply to ]
>
> IMO, adding dups is just memory leakage, and sounds like poor design.
> ymmv.
>
> --Sowmini

I'd like to add, having a list that "allows dups" leads to a whole
bunch of questions. What are the semantics associated with "listnode_delete"?
It seems to delete just the first instance. What are the semantics
of "listnode_find" (is the caller expected to march down the list and
diddle all of the node entries that match the key?)? Sounds pretty
shady to me.

--Sowmini
Re: Recent ripng breakage [ In reply to ]
sowmini.varadhan@Sun.COM wrote:
> > IMO, adding dups is just memory leakage, and sounds like poor
> > design. ymmv.
> >
> > --Sowmini
>
> I'd like to add, having a list that "allows dups" leads to a whole
> bunch of questions. What are the semantics associated with
> "listnode_delete"? It seems to delete just the first instance. What
> are the semantics of "listnode_find" (is the caller expected to
> march down the list and diddle all of the node entries that match
> the key?)? Sounds pretty shady to me.

There are already cases where listnode_add_sort are used and avoiding
dups are handeled _outside_. Look at ospf_area_get function in
ospfd/ospfd.c for example. At first there is check if area with this
name exist.

About listnode_delete and listnode_find ... You don't have to use
list->cmp for these functions. You don't have to use them at all. In
ripng case listnode_add_sort is used to build list of routes which
will be included in ripng announce packet. When building packet this
list is just "walked through" and if it's finished, list is
destroyed. That's all.

You just have to know semantics of this function.

And I repeat - we shouldn't change semantics of core functions unless
there is VERY strong need for that.

--
Hasso Tepper
Elion Enterprises Ltd.
WAN administrator
Re: Recent ripng breakage [ In reply to ]
> There are already cases where listnode_add_sort are used and avoiding
> dups are handeled _outside_. Look at ospf_area_get function in
> ospfd/ospfd.c for example. At first there is check if area with this
> name exist.

Yes, but is everybody doing this? I'm not sure zebra is.

--Sowmini
Re: Recent ripng breakage [ In reply to ]
Hasso Tepper wrote:

> for (n = list->head; n; n = n->next)
> {
> - if ((*list->cmp) (val, n->data) == 0)
> - return;
> - if ((*list->cmp) (val, n->data) < 0)
> + if ((*list->cmp) (val, n->data) <= 0)
> {


Just one question: why would you change the comparison operator from '<'
to '<='? Before your change, a duplicate element would have been added
right after those which already exist in the list, by that maintaining
some sort of chronological sense within the list elements. After your
change, it would precede any prior equal elements. Any particular reason
for that? (personally, I think the former is more natural with zebra
linked lists, which add elements to their tails)

Gilad
Re: Recent ripng breakage [ In reply to ]
sowmini.varadhan@sun.com had the problem that she added the line
"interface ip.tun0" in zebra.conf started up zebra, and later plumbed
("created") the ip.tun0 interface. zebra ended up with 2 structures,
one with index -1, and another with the correct ifindex

Sure, this is a bug. But it's incorrect to jump to the conclusion
that an underlying library routine is incorrect.


To me, the name "listnode_add_sort" says, "add this node to the
list if it doesn't exist, and keep the list sorted by key (where key
is defined by the cmp function)"

To me, it says "add this node (even if dup), and put it in sorted
order, where nodes for which cmp returns 0 are considered sorted in
either order".

If the function were meant to not allow duplicates, it would have been
called a set, not a list; lists in general allow duplicates.

IMO, adding dups is just memory leakage, and sounds like poor design.
ymmv.

It depends on what the items are, why they are there, and what the
definition of duplicate is. The incorrect design (I'll try to stay
away from value-judgement-laden words) in this case was the use of a
routine in way that was not intended, and then modiying the routine,
changing the semantics in incompatible ways, resulting in the failure
of other code, leading to a period when quagga _did not work_ and
causing a number of people to spend quite a few hours fixing it.

The underlying problem that gave rise to this is that the function was
not adequately commented; these issues should have been clear from
reading the source, but weren't.

--
Greg Troxel <gdt@ir.bbn.com>

1 2  View All