lsa_refresh() was able to resurect dead LSA resulting in zombie anouncements.
authorclaudio <claudio@openbsd.org>
Mon, 19 Jul 2010 09:11:08 +0000 (09:11 +0000)
committerclaudio <claudio@openbsd.org>
Mon, 19 Jul 2010 09:11:08 +0000 (09:11 +0000)
Make sure that if the LSA is managed by this router that we force timed-out
LSA to stay timed out which causes them to be pruned in the secound round.
This problem can show up when not exactly the same LSA is pruned because
the checksum is used as tiebreaker resulting in indeterministic selection
of which LSA is considered newer.
OK bluhm@, sthen@

usr.sbin/ospfd/rde_lsdb.c

index df30c01..650235b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde_lsdb.c,v 1.43 2009/11/12 22:29:15 claudio Exp $ */
+/*     $OpenBSD: rde_lsdb.c,v 1.44 2010/07/19 09:11:08 claudio Exp $ */
 
 /*
  * Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org>
@@ -626,7 +626,11 @@ lsa_refresh(struct vertex *v)
        u_int16_t        len;
 
        /* refresh LSA by increasing sequence number by one */
-       v->lsa->hdr.age = htons(DEFAULT_AGE);
+       if (v->self && ntohs(v->lsa->hdr.age) >= MAX_AGE)
+               /* self originated network that is currently beeing removed */
+               v->lsa->hdr.age = htons(MAX_AGE);
+       else
+               v->lsa->hdr.age = htons(DEFAULT_AGE);
        seqnum = ntohl(v->lsa->hdr.seq_num);
        if (seqnum++ == MAX_SEQ_NUM)
                /* XXX fix me */
@@ -776,7 +780,7 @@ lsa_equal(struct lsa *a, struct lsa *b)
                return (0);
        if (a->hdr.opts != b->hdr.opts)
                return (0);
-       /* LSA with age MAX_AGE are never equal */
+       /* LSAs with age MAX_AGE are never equal */
        if (a->hdr.age == htons(MAX_AGE) || b->hdr.age == htons(MAX_AGE))
                return (0);
        if (memcmp(&a->data, &b->data, ntohs(a->hdr.len) -