From ee7408c2be2cd514ba6eefc5589e57a6056198dc Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Fri, 7 May 2010 15:54:27 +0200 Subject: [PATCH] Fixes a bug in LSA flooding. LSAs are sometimes prematurely removed from LS retransmission lists. --- proto/ospf/lsack.c | 3 --- proto/ospf/lsupd.c | 42 ++++++++++++++++++------------------------ 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/proto/ospf/lsack.c b/proto/ospf/lsack.c index c05f0196..53422e53 100644 --- a/proto/ospf/lsack.c +++ b/proto/ospf/lsack.c @@ -183,9 +183,6 @@ ospf_lsack_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa, DBG("Deleting LS Id: %R RT: %R Type: %u from LS Retl for neighbor %R\n", lsa.id, lsa.rt, lsa.type, n->rid); s_rem_node(SNODE en); - if (en->lsa_body != NULL) - mb_free(en->lsa_body); - en->lsa_body = NULL; ospf_hash_delete(n->lsrth, en); } } diff --git a/proto/ospf/lsupd.c b/proto/ospf/lsupd.c index 7d5d89da..62e7eac1 100644 --- a/proto/ospf/lsupd.c +++ b/proto/ospf/lsupd.c @@ -241,9 +241,6 @@ ospf_lsupd_flood(struct proto_ospf *po, if ((en = ospf_hash_find_header(nn->lsrth, domain, hh)) != NULL) { s_rem_node(SNODE en); - if (en->lsa_body != NULL) - mb_free(en->lsa_body); - en->lsa_body = NULL; ospf_hash_delete(nn->lsrth, en); } } @@ -585,6 +582,23 @@ ospf_lsupd_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa, continue; } + /* Remove old from all ret lists */ + /* pg 144 (5c) */ + /* Must be done before (5b), otherwise it also removes the new entries from (5b) */ + if (lsadb) + WALK_LIST(ift, po->iface_list) + WALK_LIST(ntmp, ift->neigh_list) + { + struct top_hash_entry *en; + if (ntmp->state > NEIGHBOR_EXSTART) + if ((en = ospf_hash_find_header(ntmp->lsrth, domain, &lsadb->lsa)) != NULL) + { + s_rem_node(SNODE en); + ospf_hash_delete(ntmp->lsrth, en); + } + } + + /* pg 144 (5b) */ if (ospf_lsupd_flood(po, n, lsa, &lsatmp, domain, 1) == 0) { DBG("Wasn't flooded back\n"); /* ps 144(5e), pg 153 */ @@ -597,24 +611,6 @@ ospf_lsupd_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa, ospf_lsack_enqueue(n, lsa, ACKL_DELAY); } - /* Remove old from all ret lists */ - /* pg 144 (5c) */ - if (lsadb) - WALK_LIST(ift, po->iface_list) - WALK_LIST(ntmp, ift->neigh_list) - { - struct top_hash_entry *en; - if (ntmp->state > NEIGHBOR_EXSTART) - if ((en = ospf_hash_find_header(ntmp->lsrth, domain, &lsadb->lsa)) != NULL) - { - s_rem_node(SNODE en); - if (en->lsa_body != NULL) - mb_free(en->lsa_body); - en->lsa_body = NULL; - ospf_hash_delete(ntmp->lsrth, en); - } - } - if ((lsatmp.age == LSA_MAXAGE) && (lsatmp.sn == LSA_MAXSEQNO) && lsadb && can_flush_lsa(po)) { @@ -661,10 +657,8 @@ ospf_lsupd_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa, { /* pg145 (7a) */ s_rem_node(SNODE en); - if (en->lsa_body != NULL) - mb_free(en->lsa_body); - en->lsa_body = NULL; ospf_hash_delete(n->lsrth, en); + if (ifa->state == OSPF_IS_BACKUP) { if (n->rid == ifa->drid)