Commit 86c84d76 authored by Ondřej Filip's avatar Ondřej Filip

Huge OSPF database redesign. Since now, all LSAs of all areas

are in single database. This avoids duplication of external LSAs and
fixes bug in external LSA distribution.
parent 777acf91
......@@ -49,5 +49,4 @@ OSPF
- automatic generation of external route tags (RFC1403)
- RFC1587 NSSA areas
- RFC2370 opaque LSA's
- AS external LSAs are in topology database of every OSPF Area
- Limit export rate of external LSAs (like Gated does)
......@@ -104,7 +104,6 @@ ospf_vlink_item:
ospf_vlink_start: VIRTUAL LINK idval
{
log("Vlink start");
if (this_area->areaid == 0) cf_error("Virtual link cannot be in backbone");
this_ipatt = cfg_allocz(sizeof(struct ospf_iface_patt));
add_tail(&this_area->vlink_list, NODE this_ipatt);
......@@ -200,7 +199,6 @@ ipa_ne: IPA ELIGIBLE ';'
ospf_iface_start:
{
log("Iface start");
this_ipatt = cfg_allocz(sizeof(struct ospf_iface_patt));
add_tail(&this_area->patt_list, NODE this_ipatt);
OSPF_PATT->cost = COST_D;
......
......@@ -25,11 +25,11 @@ ospf_dbdes_send(struct ospf_neighbor *n)
struct ospf_packet *op;
struct ospf_iface *ifa = n->ifa;
struct ospf_area *oa = ifa->oa;
u16 length;
struct proto *p = (struct proto *) (ifa->proto);
u16 i, j;
struct proto_ospf *po = oa->po;
struct proto *p = &po->proto;
u16 length, i, j;
if ((oa->rt == NULL) || (EMPTY_LIST(oa->lsal)))
if ((oa->rt == NULL) || (EMPTY_LIST(po->lsal)))
originate_rt_lsa(oa);
switch (n->state)
......@@ -40,7 +40,7 @@ ospf_dbdes_send(struct ospf_neighbor *n)
op = (struct ospf_packet *) pkt;
ospf_pkt_fill_hdr(ifa, pkt, DBDES_P);
pkt->iface_mtu = htons(ifa->iface->mtu);
pkt->options = ifa->oa->opt.byte;
pkt->options = oa->opt.byte;
pkt->imms = n->myimms;
pkt->ddseq = htonl(n->dds);
length = sizeof(struct ospf_dbdes_packet);
......@@ -64,7 +64,7 @@ ospf_dbdes_send(struct ospf_neighbor *n)
ospf_pkt_fill_hdr(ifa, pkt, DBDES_P);
pkt->iface_mtu = htons(ifa->iface->mtu);
pkt->options = ifa->oa->opt.byte;
pkt->options = oa->opt.byte;
pkt->ddseq = htonl(n->dds);
j = i = (ospf_pkt_maxsize(ifa) - sizeof(struct ospf_dbdes_packet)) / sizeof(struct ospf_lsa_header); /* Number of possible lsaheaders to send */
......@@ -77,10 +77,17 @@ ospf_dbdes_send(struct ospf_neighbor *n)
DBG("Number of LSA: %d\n", j);
for (; i > 0; i--)
{
struct top_hash_entry *en;
en = (struct top_hash_entry *) sn;
struct top_hash_entry *en= (struct top_hash_entry *) sn;
int send = 1;
if ((n->ifa->type != OSPF_IT_VLINK) || (en->lsa.type != LSA_T_EXT))
/* Don't send ext LSA into stub areas */
if (oa->stub && (en->lsa.type == LSA_T_EXT)) send = 0;
/* Don't send ext LSAs through VLINK */
if ((ifa->type == OSPF_IT_VLINK) && (en->lsa.type == LSA_T_EXT)) send = 0;;
/* Don't send LSA of other areas */
if ((en->lsa.type != LSA_T_EXT) && (en->oa != oa)) send = 0;
if (send)
{
htonlsah(&(en->lsa), lsa);
DBG("Working on: %d\n", i);
......@@ -91,7 +98,7 @@ ospf_dbdes_send(struct ospf_neighbor *n)
}
else i++; /* No lsa added */
if (sn == STAIL(n->ifa->oa->lsal))
if (sn == STAIL(po->lsal))
{
i--;
break;
......@@ -100,7 +107,7 @@ ospf_dbdes_send(struct ospf_neighbor *n)
sn = sn->next;
}
if (sn == STAIL(n->ifa->oa->lsal))
if (sn == STAIL(po->lsal))
{
DBG("Number of LSA NOT sent: %d\n", i);
DBG("M bit unset.\n");
......@@ -163,7 +170,8 @@ ospf_dbdes_reqladd(struct ospf_dbdes_packet *ps, struct ospf_neighbor *n)
{
struct ospf_lsa_header *plsa, lsa;
struct top_hash_entry *he, *sn;
struct top_graph *gr = n->ifa->oa->gr;
struct ospf_area *oa = n->ifa->oa;
struct top_graph *gr = oa->po->gr;
struct ospf_packet *op;
int i, j;
......@@ -177,13 +185,13 @@ ospf_dbdes_reqladd(struct ospf_dbdes_packet *ps, struct ospf_neighbor *n)
for (i = 0; i < j; i++)
{
ntohlsah(plsa + i, &lsa);
if (((he = ospf_hash_find(gr, lsa.id, lsa.rt, lsa.type)) == NULL) ||
if (((he = ospf_hash_find(gr, oa->areaid, lsa.id, lsa.rt, lsa.type)) == NULL) ||
(lsa_comp(&lsa, &(he->lsa)) == 1))
{
/* Is this condition necessary? */
if (ospf_hash_find(n->lsrqh, lsa.id, lsa.rt, lsa.type) == NULL)
if (ospf_hash_find(n->lsrqh, oa->areaid, lsa.id, lsa.rt, lsa.type) == NULL)
{
sn = ospf_hash_get(n->lsrqh, lsa.id, lsa.rt, lsa.type);
sn = ospf_hash_get(n->lsrqh, oa, lsa.id, lsa.rt, lsa.type);
ntohlsah(plsa + i, &(sn->lsa));
s_add_tail(&(n->lsrql), SNODE sn);
}
......@@ -195,7 +203,7 @@ void
ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
struct ospf_iface *ifa, struct ospf_neighbor *n)
{
struct proto *p = (struct proto *) ifa->proto;
struct proto *p = &ifa->oa->po->proto;
u32 myrid = p->cf->global->router_id;
unsigned int size = ntohs(ps->ospf_packet.length);
......
......@@ -16,7 +16,7 @@ ospf_hello_receive(struct ospf_hello_packet *ps,
ip_addr olddr, oldbdr;
ip_addr mask;
char *beg = "Bad OSPF hello packet from ", *rec = " received: ";
struct proto *p = (struct proto *) ifa->proto;
struct proto *p = (struct proto *) ifa->oa->po;
unsigned int size = ntohs(ps->ospf_packet.length), i, twoway, oldpriority, eligible = 0, peers;
OSPF_TRACE(D_PACKETS, "Received hello from %I via %s%s", faddr,
......@@ -172,6 +172,7 @@ ospf_hello_send(timer * timer, int poll, struct ospf_neighbor *dirn)
u32 *pp;
int i, send;
struct nbma_node *nb;
if (timer == NULL)
ifa = dirn->ifa;
else
......@@ -183,7 +184,7 @@ ospf_hello_send(timer * timer, int poll, struct ospf_neighbor *dirn)
if (ifa->stub)
return; /* Don't send any packet on stub iface */
p = (struct proto *) (ifa->proto);
p = (struct proto *) (ifa->oa->po);
DBG("%s: Hello/Poll timer fired on interface %s.\n",
p->name, ifa->iface->name);
/* Now we should send a hello packet */
......
......@@ -35,7 +35,7 @@ static void
wait_timer_hook(timer * timer)
{
struct ospf_iface *ifa = (struct ospf_iface *) timer->data;
struct proto *p = (struct proto *) (ifa->proto);
struct proto *p = &ifa->oa->po->proto;
OSPF_TRACE(D_EVENTS, "Wait timer fired on interface %s.", ifa->iface->name);
ospf_iface_sm(ifa, ISM_WAITF);
......@@ -45,9 +45,7 @@ static sock *
ospf_open_ip_socket(struct ospf_iface *ifa)
{
sock *ipsk;
struct proto *p;
p = (struct proto *) (ifa->proto);
struct proto *p = &ifa->oa->po->proto;
ipsk = sk_new(p->pool);
ipsk->type = SK_IP;
......@@ -86,7 +84,7 @@ ospf_open_ip_socket(struct ospf_iface *ifa)
void
ospf_iface_chstate(struct ospf_iface *ifa, u8 state)
{
struct proto_ospf *po = ifa->proto;
struct proto_ospf *po = ifa->oa->po;
struct proto *p = &po->proto;
u8 oldstate = ifa->state;
......@@ -149,8 +147,8 @@ ospf_iface_chstate(struct ospf_iface *ifa, u8 state)
{
ospf_lsupd_flush_nlsa(ifa->nlsa, ifa->oa);
}
if (can_flush_lsa(ifa->oa))
flush_lsa(ifa->nlsa, ifa->oa);
if (can_flush_lsa(po))
flush_lsa(ifa->nlsa, po);
ifa->nlsa = NULL;
}
}
......@@ -162,8 +160,8 @@ static void
ospf_iface_down(struct ospf_iface *ifa)
{
struct ospf_neighbor *n, *nx;
struct proto *p = &ifa->proto->proto;
struct proto_ospf *po = ifa->proto;
struct proto_ospf *po = ifa->oa->po;
struct proto *p = &po->proto;
struct ospf_iface *iff;
/* First of all kill all the related vlinks */
......@@ -287,9 +285,7 @@ static sock *
ospf_open_mc_socket(struct ospf_iface *ifa)
{
sock *mcsk;
struct proto *p;
p = (struct proto *) (ifa->proto);
struct proto *p = &ifa->oa->po->proto;
mcsk = sk_new(p->pool);
mcsk->type = SK_IP_MC;
......@@ -342,9 +338,9 @@ static void
ospf_iface_add(struct object_lock *lock)
{
struct ospf_iface *ifa = lock->data;
struct proto_ospf *po = ifa->proto;
struct iface *iface = lock->iface;
struct proto_ospf *po = ifa->oa->po;
struct proto *p = &po->proto;
struct iface *iface = lock->iface;
ifa->lock = lock;
......@@ -387,7 +383,6 @@ ospf_iface_new(struct proto_ospf *po, struct iface *iface,
struct ospf_area *oa;
ifa = mb_allocz(p->pool, sizeof(struct ospf_iface));
ifa->proto = po;
ifa->iface = iface;
ifa->cost = ip->cost;
......
......@@ -37,7 +37,7 @@ ospf_lsack_send(struct ospf_neighbor *n, int queue)
struct ospf_lsa_header *h;
struct lsah_n *no;
struct ospf_iface *ifa = n->ifa;
struct proto *p = &n->ifa->proto->proto;
struct proto *p = &n->ifa->oa->po->proto;
if (EMPTY_LIST(n->ackl[queue]))
return;
......@@ -122,7 +122,7 @@ ospf_lsack_receive(struct ospf_lsack_packet *ps,
struct ospf_lsa_header lsa, *plsa;
u16 nolsa;
struct top_hash_entry *en;
struct proto *p = (struct proto *) ifa->proto;
struct proto *p = &ifa->oa->po->proto;
unsigned int size = ntohs(ps->ospf_packet.length), i;
OSPF_TRACE(D_PACKETS, "Received LS ack from %I", n->ip);
......@@ -146,7 +146,7 @@ ospf_lsack_receive(struct ospf_lsack_packet *ps,
for (i = 0; i < nolsa; i++)
{
ntohlsah(plsa + i, &lsa);
if ((en = ospf_hash_find_header(n->lsrth, &lsa)) == NULL)
if ((en = ospf_hash_find_header(n->lsrth, n->ifa->oa->areaid, &lsa)) == NULL)
continue; /* pg 155 */
if (lsa_comp(&lsa, &en->lsa) != CMP_SAME) /* pg 156 */
......
......@@ -9,9 +9,10 @@
#include "ospf.h"
void
flush_lsa(struct top_hash_entry *en, struct ospf_area *oa)
flush_lsa(struct top_hash_entry *en, struct proto_ospf *po)
{
struct proto *p = &oa->po->proto;
struct proto *p = &po->proto;
OSPF_TRACE(D_EVENTS,
"Going to remove node Type: %u, Id: %I, Rt: %I, Age: %u, SN: 0x%x",
en->lsa.type, en->lsa.id, en->lsa.rt, en->lsa.age, en->lsa.sn);
......@@ -19,14 +20,14 @@ flush_lsa(struct top_hash_entry *en, struct ospf_area *oa)
if (en->lsa_body != NULL)
mb_free(en->lsa_body);
en->lsa_body = NULL;
ospf_hash_delete(oa->gr, en);
ospf_hash_delete(po->gr, en);
}
/**
* ospf_age
* @oa: ospf area
* @po: ospf protocol
*
* This function is periodicaly invoked from area_disp(). It computes the new
* This function is periodicaly invoked from ospf_disp(). It computes the new
* age of all LSAs and old (@age is higher than %LSA_MAXAGE) LSAs are flushed
* whenever possible. If an LSA originated by the router itself is older
* than %LSREFRESHTIME a new instance is originated.
......@@ -38,19 +39,17 @@ flush_lsa(struct top_hash_entry *en, struct ospf_area *oa)
* table calculation results.
*/
void
ospf_age(struct ospf_area *oa)
ospf_age(struct proto_ospf *po)
{
struct proto *p = &oa->po->proto;
struct proto_ospf *po = (struct proto_ospf *) p;
struct proto *p = &po->proto;
struct top_hash_entry *en, *nxt;
int flush = can_flush_lsa(oa);
int cleanup = (oa->rt && (oa->rt->dist != LSINFINITY));
int flush = can_flush_lsa(po);
if (cleanup) OSPF_TRACE(D_EVENTS, "Running ospf_age cleanup");
if (po->cleanup) OSPF_TRACE(D_EVENTS, "Running ospf_age cleanup");
WALK_SLIST_DELSAFE(en, nxt, oa->lsal)
WALK_SLIST_DELSAFE(en, nxt, po->lsal)
{
if (cleanup)
if (po->cleanup)
{
en->color = OUTSPF;
en->dist = LSINFINITY;
......@@ -63,7 +62,7 @@ ospf_age(struct ospf_area *oa)
if (en->lsa.age == LSA_MAXAGE)
{
if (flush)
flush_lsa(en, oa);
flush_lsa(en, po);
continue;
}
if ((en->lsa.rt == p->cf->global->router_id) &&(en->lsa.age >=
......@@ -76,20 +75,21 @@ ospf_age(struct ospf_area *oa)
en->inst_t = now;
en->ini_age = 0;
lsasum_calculate(&en->lsa, en->lsa_body);
ospf_lsupd_flood(NULL, NULL, &en->lsa, NULL, oa, 1);
ospf_lsupd_flood(NULL, NULL, &en->lsa, NULL, en->oa, 1);
continue;
}
if ((en->lsa.age = (en->ini_age + (now - en->inst_t))) >= LSA_MAXAGE)
{
if (flush)
{
flush_lsa(en, oa);
flush_lsa(en, po);
schedule_rtcalc(po);
}
else
en->lsa.age = LSA_MAXAGE;
}
}
po->cleanup = 0;
}
void
......@@ -446,9 +446,9 @@ lsa_install_new(struct ospf_lsa_header *lsa, void *body, struct ospf_area *oa)
struct top_hash_entry *en;
struct proto_ospf *po = oa->po;
if ((en = ospf_hash_find_header(oa->gr, lsa)) == NULL)
if ((en = ospf_hash_find_header(po->gr, oa->areaid, lsa)) == NULL)
{
en = ospf_hash_get_header(oa->gr, lsa);
en = ospf_hash_get_header(po->gr, oa, lsa);
change = 1;
}
else
......@@ -474,7 +474,7 @@ lsa_install_new(struct ospf_lsa_header *lsa, void *body, struct ospf_area *oa)
DBG("Inst lsa: Id: %I, Rt: %I, Type: %u, Age: %u, Sum: %u, Sn: 0x%x\n",
lsa->id, lsa->rt, lsa->type, lsa->age, lsa->checksum, lsa->sn);
s_add_tail(&oa->lsal, SNODE en);
s_add_tail(&po->lsal, SNODE en);
en->inst_t = now;
if (en->lsa_body != NULL)
mb_free(en->lsa_body);
......
......@@ -22,7 +22,7 @@ u16 lsasum_check(struct ospf_lsa_header *h, void *body);
int lsa_comp(struct ospf_lsa_header *l1, struct ospf_lsa_header *l2);
struct top_hash_entry *lsa_install_new(struct ospf_lsa_header *lsa,
void *body, struct ospf_area *oa);
void ospf_age(struct ospf_area *oa);
void flush_lsa(struct top_hash_entry *en, struct ospf_area *oa);
void ospf_age(struct proto_ospf *po);
void flush_lsa(struct top_hash_entry *en, struct proto_ospf *po);
#endif /* _BIRD_OSPF_LSALIB_H_ */
......@@ -18,7 +18,7 @@ ospf_lsreq_send(struct ospf_neighbor *n)
struct ospf_lsreq_header *lsh;
u16 length;
int i, j;
struct proto *p = &n->ifa->proto->proto;
struct proto *p = &n->ifa->oa->po->proto;
pk = (struct ospf_lsreq_packet *) n->ifa->ip_sk->tbuf;
op = (struct ospf_packet *) n->ifa->ip_sk->tbuf;
......@@ -73,7 +73,9 @@ ospf_lsreq_receive(struct ospf_lsreq_packet *ps,
slab *upslab;
unsigned int size = ntohs(ps->ospf_packet.length);
int i, lsano;
struct proto *p = (struct proto *) ifa->proto;
struct ospf_area *oa = ifa->oa;
struct proto_ospf *po = oa->po;
struct proto *p = &po->proto;
if (n->state < NEIGHBOR_EXCHANGE)
return;
......@@ -96,7 +98,7 @@ ospf_lsreq_receive(struct ospf_lsreq_packet *ps,
llsh->lsh.rt = ntohl(lsh->rt);
llsh->lsh.type = lsh->type;
add_tail(&uplist, NODE llsh);
if (ospf_hash_find(n->ifa->oa->gr, llsh->lsh.id, llsh->lsh.rt,
if (ospf_hash_find(po->gr, oa->areaid, llsh->lsh.id, llsh->lsh.rt,
llsh->lsh.type) == NULL)
{
log(L_WARN
......
......@@ -13,7 +13,6 @@
* @n: neighbor than sent this lsa (or NULL if generated)
* @hn: LSA header followed by lsa body in network endianity (may be NULL)
* @hh: LSA header in host endianity (must be filled)
* @po: actual instance of OSPF protocol
* @iff: interface which received this LSA (or NULL if LSA is generated)
* @oa: ospf_area which is the LSA generated for
* @rtl: add this LSA into retransmission list
......@@ -48,16 +47,8 @@ ospf_lsupd_flood(struct ospf_neighbor *n, struct ospf_lsa_header *hn,
}
else
{
if (oa->areaid == BACKBONE)
{
if ((ifa->type != OSPF_IT_VLINK) && (ifa->oa != oa))
continue;
}
else
{
if (ifa->oa != oa)
continue;
}
if (ifa->oa != oa)
continue;
}
ret = 0;
WALK_LIST(NODE nn, ifa->neigh_list)
......@@ -66,7 +57,7 @@ ospf_lsupd_flood(struct ospf_neighbor *n, struct ospf_lsa_header *hn,
continue;
if (nn->state < NEIGHBOR_FULL)
{
if ((en = ospf_hash_find_header(nn->lsrqh, hh)) != NULL)
if ((en = ospf_hash_find_header(nn->lsrqh, nn->ifa->oa->areaid, hh)) != NULL)
{
switch (lsa_comp(hh, &en->lsa))
{
......@@ -105,9 +96,9 @@ ospf_lsupd_flood(struct ospf_neighbor *n, struct ospf_lsa_header *hn,
if (rtl)
{
if ((en = ospf_hash_find_header(nn->lsrth, hh)) == NULL)
if ((en = ospf_hash_find_header(nn->lsrth, nn->ifa->oa->areaid, hh)) == NULL)
{
en = ospf_hash_get_header(nn->lsrth, hh);
en = ospf_hash_get_header(nn->lsrth, nn->ifa->oa, hh);
}
else
{
......@@ -120,7 +111,7 @@ ospf_lsupd_flood(struct ospf_neighbor *n, struct ospf_lsa_header *hn,
}
else
{
if ((en = ospf_hash_find_header(nn->lsrth, hh)) != NULL)
if ((en = ospf_hash_find_header(nn->lsrth, nn->ifa->oa->areaid, hh)) != NULL)
{
s_rem_node(SNODE en);
if (en->lsa_body != NULL)
......@@ -177,7 +168,7 @@ ospf_lsupd_flood(struct ospf_neighbor *n, struct ospf_lsa_header *hn,
htonlsah(hh, lh);
help = (u8 *) (lh + 1);
en = ospf_hash_find_header(oa->gr, hh);
en = ospf_hash_find_header(po->gr, oa->areaid, hh);
htonlsab(en->lsa_body, help, hh->type, hh->length
- sizeof(struct ospf_lsa_header));
}
......@@ -229,7 +220,9 @@ ospf_lsupd_send_list(struct ospf_neighbor *n, list * l)
struct top_hash_entry *en;
struct ospf_lsupd_packet *pk;
struct ospf_packet *op;
struct proto *p = &n->ifa->oa->po->proto;
struct ospf_area *oa = n->ifa->oa;
struct proto_ospf *po = oa->po;
struct proto *p = &po->proto;
void *pktpos;
if (EMPTY_LIST(*l))
......@@ -247,7 +240,7 @@ ospf_lsupd_send_list(struct ospf_neighbor *n, list * l)
WALK_LIST(llsh, *l)
{
if ((en = ospf_hash_find(n->ifa->oa->gr, llsh->lsh.id, llsh->lsh.rt,
if ((en = ospf_hash_find(po->gr, oa->areaid, llsh->lsh.id, llsh->lsh.rt,
llsh->lsh.type)) == NULL)
continue; /* Probably flushed LSA */
/* FIXME This is a bug! I cannot flush LSA that is in lsrt */
......@@ -294,8 +287,8 @@ ospf_lsupd_receive(struct ospf_lsupd_packet *ps,
struct ospf_neighbor *ntmp;
struct ospf_lsa_header *lsa;
struct ospf_area *oa;
struct proto_ospf *po = ifa->proto;
struct proto *p = (struct proto *) po;
struct proto_ospf *po = ifa->oa->po;
struct proto *p = &po->proto;
unsigned int i, sendreq = 1, size = ntohs(ps->ospf_packet.length);
if (n->state < NEIGHBOR_EXCHANGE)
......@@ -372,7 +365,7 @@ ospf_lsupd_receive(struct ospf_lsupd_packet *ps,
lsatmp.type, lsatmp.id, lsatmp.rt, lsatmp.sn, lsatmp.age,
lsatmp.checksum);
lsadb = ospf_hash_find_header(oa->gr, &lsatmp);
lsadb = ospf_hash_find_header(po->gr, oa->areaid, &lsatmp);
#ifdef LOCAL_DEBUG
if (lsadb)
......@@ -382,7 +375,7 @@ ospf_lsupd_receive(struct ospf_lsupd_packet *ps,
#endif
/* pg 143 (4) */
if ((lsatmp.age == LSA_MAXAGE) && (lsadb == NULL) && can_flush_lsa(oa))
if ((lsatmp.age == LSA_MAXAGE) && (lsadb == NULL) && can_flush_lsa(po))
{
ospf_lsack_enqueue(n, lsa, ACKL_DIRECT);
continue;
......@@ -433,7 +426,7 @@ ospf_lsupd_receive(struct ospf_lsupd_packet *ps,
lsasum_check(lsa, (lsa + 1)); /* It also calculates chsum! */
lsatmp.checksum = ntohs(lsa->checksum);
ospf_lsupd_flood(NULL, lsa, &lsatmp, NULL, oa, 0);
if (en = ospf_hash_find_header(oa->gr, &lsatmp))
if (en = ospf_hash_find_header(po->gr, oa->areaid, &lsatmp))
{
ospf_lsupd_flood(NULL, NULL, &en->lsa, NULL, oa, 1);
}
......@@ -468,7 +461,7 @@ ospf_lsupd_receive(struct ospf_lsupd_packet *ps,
{
struct top_hash_entry *en;
if (ntmp->state > NEIGHBOR_EXSTART)
if ((en = ospf_hash_find_header(ntmp->lsrth, &lsadb->lsa)) != NULL)
if ((en = ospf_hash_find_header(ntmp->lsrth, ntmp->ifa->oa->areaid, &lsadb->lsa)) != NULL)
{
s_rem_node(SNODE en);
if (en->lsa_body != NULL)
......@@ -479,9 +472,9 @@ ospf_lsupd_receive(struct ospf_lsupd_packet *ps,
}
if ((lsatmp.age == LSA_MAXAGE) && (lsatmp.sn == LSA_MAXSEQNO)
&& lsadb && can_flush_lsa(oa))
&& lsadb && can_flush_lsa(po))
{
flush_lsa(lsadb, oa);
flush_lsa(lsadb, po);
schedule_rtcalc(po);
continue;
} /* FIXME lsack? */
......@@ -504,7 +497,7 @@ ospf_lsupd_receive(struct ospf_lsupd_packet *ps,
{
struct top_hash_entry *en;
DBG("PG145(7) Got the same LSA\n");
if ((en = ospf_hash_find_header(n->lsrth, &lsadb->lsa)) != NULL)
if ((en = ospf_hash_find_header(n->lsrth, n->ifa->oa->areaid, &lsadb->lsa)) != NULL)
{
/* pg145 (7a) */
s_rem_node(SNODE en);
......
......@@ -33,7 +33,7 @@ void ackd_timer_hook(timer * t);
struct ospf_neighbor *
ospf_neighbor_new(struct ospf_iface *ifa)
{
struct proto *p = (struct proto *) (ifa->proto);
struct proto *p = (struct proto *) (ifa->oa->po);
struct pool *pool = rp_new(p->pool, "OSPF Neighbor");
struct ospf_neighbor *n = mb_allocz(pool, sizeof(struct ospf_neighbor));
......@@ -231,7 +231,7 @@ can_do_adj(struct ospf_neighbor *n)
int i;
ifa = n->ifa;
p = (struct proto *) (ifa->proto);
p = (struct proto *) (ifa->oa->po);
i = 0;
switch (ifa->type)
......@@ -289,8 +289,8 @@ can_do_adj(struct ospf_neighbor *n)
void
ospf_neigh_sm(struct ospf_neighbor *n, int event)
{
struct proto_ospf *po = n->ifa->proto;
struct proto *p = (struct proto *) po;
struct proto_ospf *po = n->ifa->oa->po;
struct proto *p = &po->proto;
DBG("Neighbor state machine for neighbor %I, event \"%s\".", n->ip,
ospf_inm[event]);
......@@ -322,7 +322,7 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event)
if (n->state == NEIGHBOR_EXSTART)
{
neigh_chstate(n, NEIGHBOR_EXCHANGE);
s_init(&(n->dbsi), &(n->ifa->oa->lsal));
s_init(&(n->dbsi), &po->lsal);
while (!EMPTY_LIST(n->ackl[ACKL_DELAY]))
{
struct lsah_n *no;
......@@ -396,7 +396,7 @@ bdr_election(struct ospf_iface *ifa)
u32 myid;
ip_addr ndrip, nbdrip;
int doadj;
struct proto *p = &ifa->proto->proto;
struct proto *p = &ifa->oa->po->proto;
DBG("(B)DR election.\n");
......@@ -541,13 +541,10 @@ ospf_find_area(struct proto_ospf *po, u32 aid)
void
neighbor_timer_hook(timer * timer)
{
struct ospf_neighbor *n;
struct ospf_iface *ifa;
struct proto *p;
struct ospf_neighbor *n = (struct ospf_neighbor *) timer->data;
struct ospf_iface *ifa = n->ifa;
struct proto *p = &ifa->oa->po->proto;
n = (struct ospf_neighbor *) timer->data;
ifa = n->ifa;
p = (struct proto *) (ifa->proto);
OSPF_TRACE(D_EVENTS,
"Inactivity timer fired on interface %s for neighbor %I.",
ifa->iface->name, n->ip);
......@@ -557,11 +554,9 @@ neighbor_timer_hook(timer * timer)
void
ospf_neigh_remove(struct ospf_neighbor *n)
{
struct ospf_iface *ifa;
struct proto *p;
struct ospf_iface *ifa = n->ifa;
struct proto *p = &ifa->oa->po->proto;
ifa = n->ifa;
p = (struct proto *) (ifa->proto);
neigh_chstate(n, NEIGHBOR_DOWN);
rem_node(NODE n);
rfree(n->pool);
......
......@@ -41,11 +41,16 @@
* describes the link-state database. It allows fast search, addition
* and deletion. Each LSA is kept in two pieces: header and body. Both of them are
* kept in the endianity of the CPU.
*
* The heart beat of ospf is ospf_disp(). It is called at regular intervals
* (&proto_ospf->tick). It is responsible for aging and flushing of LSAs in
* the database, for routing table calculaction and it call area_disp() of every
* ospf_area.
*
* Every area has its own area_disp() which is
* responsible for late originating of router LSA, calculating
* of the routing table and it also ages and flushes the LSAs. This
* function is called in regular intervals from ospf_disp()
* The function area_disp() is
* responsible for late originating of router LSA and network LSA
* and for cleanup after routing table calculation process in
* the area.
* To every &ospf_iface, we connect one or more
* &ospf_neighbor's -- a structure containing many timers and queues
* for building adjacency and for exchange of routing messages.
......@@ -122,6 +127,9 @@ ospf_start(struct proto *p)
init_list(&(po->area_list));
fib_init(&po->rtf, p->pool, sizeof(ort), 16, ospf_rt_initort);
po->areano = 0;
po->gr = ospf_top_new(p->pool);
po->cleanup = 1;
s_init_list(&(po->lsal));
if (EMPTY_LIST(c->area_list))
{
log(L_ERR "Cannot start, no OSPF areas configured!");
......@@ -135,8 +143,6 @@ ospf_start(struct proto *p)
po->areano++;
oa->stub = ac->stub;
oa->areaid = ac->areaid;
oa->gr = ospf_top_new(p->pool);
s_init_list(&(oa->lsal));
oa->rt = NULL;
oa->po = po;
add_area_nets(oa, ac);
......@@ -181,13 +187,9 @@ ospf_dump(struct proto *p)
}
}
WALK_LIST(NODE oa, po->area_list)
{
OSPF_TRACE(D_EVENTS, "LSA graph dump for area \"%I\" start:", oa->areaid);
ospf_top_dump(oa->gr, p);
OSPF_TRACE(D_EVENTS, "LSA graph dump for area \"%I\" finished",
oa->areaid);
}
OSPF_TRACE(D_EVENTS, "LSA graph dump start:");
ospf_top_dump(po->gr, p);
OSPF_TRACE(D_EVENTS, "LSA graph dump finished");
neigh_dump_all();
}
......@@ -293,9 +295,9 @@ schedule_rtcalc(struct proto_ospf *po)
}
/**
* area_disp - invokes link-state database aging, origination of
* router LSA and routing table calculation
* @timer: it's called every @ospf_area->tick seconds
* area_disp - invokes origination of
* router LSA and routing table cleanup
* @oa: ospf area
*
* It invokes aging and when @ospf_area->origrt is set to 1, start
* function for origination of router LSA and network LSAs.
......@@ -316,11 +318,13 @@ area_disp(struct ospf_area *oa)
if (ifa->orignet && (ifa->oa == oa))
originate_net_lsa(ifa);
}
/* Age LSA DB */
ospf_age(oa);
}
/**
* ospf_disp - invokes routing table calctulation, aging and also area_disp()
* @timer: timer usually called every @proto_ospf->tick second, @timer->data
* point to @proto_ospf
*/
void
ospf_disp(timer * timer)
{
......@@ -330,10 +334,12 @@ ospf_disp(timer * timer)
WALK_LIST(oa, po->area_list)
area_disp(oa);
/* Age LSA DB */
ospf_age(po);
/* Calculate routing table */
if (po->calcrt)
ospf_rt_spf (po);