summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--proto/ospf/dbdes.c7
-rw-r--r--proto/ospf/lsalib.c47
-rw-r--r--proto/ospf/lsalib.h3
-rw-r--r--proto/ospf/lsreq.c3
-rw-r--r--proto/ospf/lsupd.c60
-rw-r--r--proto/ospf/topology.c63
-rw-r--r--proto/ospf/topology.h3
7 files changed, 139 insertions, 47 deletions
diff --git a/proto/ospf/dbdes.c b/proto/ospf/dbdes.c
index c6aba36..16cf817 100644
--- a/proto/ospf/dbdes.c
+++ b/proto/ospf/dbdes.c
@@ -76,7 +76,7 @@ ospf_dbdes_tx(struct ospf_neighbor *n)
debug("\t%04x %08x %08x %p\n", en->lsa.type, en->lsa.id,
en->lsa.rt, en->lsa_body);
- if(sn->next==NULL)
+ if(sn==STAIL(n->ifa->oa->lsal))
{
break; /* Should set some flag? */
}
@@ -85,7 +85,7 @@ ospf_dbdes_tx(struct ospf_neighbor *n)
}
i--;
- if(sn->next==NULL)
+ if(sn==STAIL(n->ifa->oa->lsal))
{
DBG("Number of LSA NOT sent: %d\n", i);
DBG("M bit unset.\n");
@@ -128,7 +128,7 @@ ospf_dbdes_tx(struct ospf_neighbor *n)
}
sk_send_to(ifa->ip_sk,length, n->ip, OSPF_PROTO);
- debug("%s: DB_DES sent for %u.\n", p->name, n->rid);
+ debug("%s: DB_DES sent to %u.\n", p->name, n->rid);
if(n->myimms.bit.ms) tm_start(n->rxmt_timer,ifa->rxmtint);
else
{
@@ -199,6 +199,7 @@ ospf_dbdes_reqladd(struct ospf_dbdes_packet *ps, struct proto *p,
ntohlsah(plsa+i, &(sn->lsa));
s_add_tail(&(n->lsrql), SNODE sn);
}
+ /* FIXME and the next part of condition? */
}
}
}
diff --git a/proto/ospf/lsalib.c b/proto/ospf/lsalib.c
index a7ef804..aa7e1f9 100644
--- a/proto/ospf/lsalib.c
+++ b/proto/ospf/lsalib.c
@@ -309,11 +309,52 @@ lsa_comp(struct ospf_lsa_header *l1, struct ospf_lsa_header *l2)
{
if(l1->checksum=!l2->checksum)
return l1->checksum<l2->checksum ? CMP_OLDER : CMP_NEWER;
- if(l1->age==MAXAGE) return CMP_NEWER;
- if(l2->age==MAXAGE) return CMP_OLDER;
- if(abs(l1->age-l2->age)>MAXAGEDIFF)
+ if(l1->age==LSA_MAXAGE) return CMP_NEWER;
+ if(l2->age==LSA_MAXAGE) return CMP_OLDER;
+ if(abs(l1->age-l2->age)>LSA_MAXAGEDIFF)
return l1->age<l2->age ? CMP_NEWER : CMP_OLDER;
}
return CMP_SAME;
}
+/* LSA can be temporarrily, but body must be mb_alloced. */
+struct top_hash_entry *
+lsa_install_new(struct ospf_lsa_header *lsa, void *body, struct ospf_area *oa)
+{
+ int change=0,i;
+ struct top_hash_entry *en;
+
+ if((en=ospf_hash_find_header(oa->gr,lsa))==NULL)
+ {
+ en=ospf_hash_get_header(oa->gr,lsa);
+ change=1;
+ s_add_tail(&oa->lsal, SNODE en);
+ }
+ else
+ {
+ if(en->lsa.options!=lsa->options) change=1;
+ if((en->lsa.age==LSA_MAXAGE)||(lsa->age==LSA_MAXAGE)) change=1;
+ if(en->lsa.length!=lsa->length) change=1;
+ else
+ {
+ u8 *k=en->lsa_body,*l=body;
+ for(i=0;i<lsa->length;i++)
+ {
+ if(*(k+i)!=*(l+i))
+ {
+ change=1;
+ break;
+ }
+ }
+ s_rem_node(SNODE en);
+ s_add_tail(&oa->lsal, SNODE en);
+ }
+ }
+ en->inst_t=now;
+ if(en->lsa_body!=NULL)mb_free(en->lsa_body);
+ en->lsa_body=body;
+ memcpy(&en->lsa,lsa,sizeof(struct ospf_lsa_header));
+
+ /* FIXME decide if route calcualtion must be done and how */
+ return en;
+}
diff --git a/proto/ospf/lsalib.h b/proto/ospf/lsalib.h
index 5332d2e..bba8c26 100644
--- a/proto/ospf/lsalib.h
+++ b/proto/ospf/lsalib.h
@@ -17,10 +17,11 @@ void ntohlsab(void *n, void *h, u8 type, u16 len);
void lsasum_calculate(struct ospf_lsa_header *header, void *body,
struct proto_ospf *p);
u16 lsasum_check(struct ospf_lsa_header *h,void *body,struct proto_ospf *po);
-
#define CMP_NEWER 1
#define CMP_SAME 0
#define CMP_OLDER -1
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);
#endif /* _BIRD_OSPF_LSALIB_H_ */
diff --git a/proto/ospf/lsreq.c b/proto/ospf/lsreq.c
index f894c66..716724a 100644
--- a/proto/ospf/lsreq.c
+++ b/proto/ospf/lsreq.c
@@ -45,7 +45,8 @@ ospf_lsreq_tx(struct ospf_neighbor *n)
DBG("Requesting %uth LSA: Type: %u, Id: %u, RT: %u\n",i, en->lsa.type,
en->lsa.id, en->lsa.rt);
lsh++;
- if((sn=sn->next)==NULL) break;
+ if(sn==STAIL(n->lsrql)) break;
+ sn=sn->next;
}
length=sizeof(struct ospf_lsreq_packet)+(j-i)*sizeof(struct ospf_lsreq_header);
diff --git a/proto/ospf/lsupd.c b/proto/ospf/lsupd.c
index 8ff3959..950a1f8 100644
--- a/proto/ospf/lsupd.c
+++ b/proto/ospf/lsupd.c
@@ -84,7 +84,7 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
struct ospf_iface *ifa, u16 size)
{
u32 area,nrid,myrid;
- struct ospf_neighbor *n;
+ struct ospf_neighbor *n,*ntmp;
struct ospf_lsa_header *lsa;
struct ospf_area *oa;
struct proto_ospf *po=(struct proto_ospf *)p;
@@ -132,9 +132,24 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
continue;
}
ntohlsah(lsa,&lsatmp);
- DBG("Processing update Type: %u ID: %u RT: %u\n",lsa->type,
- ntohl(lsa->id), ntohl(lsa->rt));
+ DBG("Processing update Type: %u ID: %u RT: %u\n",lsatmp.type,
+ lsatmp.id, lsatmp.rt);
lsadb=ospf_hash_find_header(oa->gr, &lsatmp);
+
+ /* Remove it from link state request list */
+ WALK_LIST(NODE ifa,po->iface_list)
+ WALK_LIST(NODE ntmp,ifa->neigh_list)
+ {
+ struct top_hash_entry *en;
+ if((en=ospf_hash_find_header(ntmp->lsrqh,&lsatmp))!=NULL)
+ {
+ s_rem_node(SNODE en);
+ DBG("Removing from lsreq list for neigh %u\n", ntmp->rid);
+ ospf_hash_delete(ntmp->lsrqh,en);
+ if(EMPTY_SLIST(ntmp->lsrql)) ospf_neigh_sm(ntmp, INM_LOADDONE);
+ }
+ }
+
if((lsatmp.age==LSA_MAXAGE)&&(lsadb==NULL))
{
struct ospf_neighbor *n=NULL;
@@ -142,8 +157,9 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
int flag=0;
WALK_LIST(NODE ifa,po->iface_list)
- WALK_LIST(NODE n,ifa->neigh_list)
- if((n->state==NEIGHBOR_EXCHANGE)&&(n->state==NEIGHBOR_LOADING))
+ WALK_LIST(NODE ntmp,ifa->neigh_list)
+ if((ntmp->state==NEIGHBOR_EXCHANGE)&&
+ (ntmp->state==NEIGHBOR_LOADING))
flag=1;
if(flag==0)
@@ -156,30 +172,32 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
{
struct ospf_neighbor *n=NULL;
struct ospf_iface *ifa=NULL;
+ void *body;
/* FIXME self originated? */
if(lsadb && ((lsadb->inst_t-now)<MINLSARRIVAL)) continue;
/* Remove old from all ret lists */
- WALK_LIST(NODE ifa,po->iface_list)
- WALK_LIST(NODE n,ifa->neigh_list)
- {
- struct top_hash_entry *en;
- if((en=ospf_hash_find_header(n->lsrth,&lsadb->lsa))!=NULL)
- s_rem_node(SNODE en);
- }
+ if(lsadb)
+ WALK_LIST(NODE ifa,po->iface_list)
+ WALK_LIST(NODE ntmp,ifa->neigh_list)
+ {
+ struct top_hash_entry *en;
+ if((en=ospf_hash_find_header(ntmp->lsrth,&lsadb->lsa))!=NULL)
+ {
+ s_rem_node(SNODE en);
+ ospf_hash_delete(ntmp->lsrth,en);
+ }
+ }
/* Install new */
- memcpy(&lsadb->lsa,&lsatmp,sizeof(struct ospf_lsa_header));
- lsadb->inst_t=now;
- if(lsadb->lsa_body!=NULL) mb_free(lsadb->lsa_body);
- lsadb->lsa_body=mb_alloc(p->pool,lsadb->lsa.length-
- sizeof(struct ospf_lsa_header));
- ntohlsab(lsa+1,lsadb->lsa_body,lsadb->lsa.type,lsadb->lsa.length);
-
- /* FIXME lsa_flood(n,lsadb) */
- /* FIXME ack_lsa() */
+ DBG("Allocatin body, size: %u\n",lsatmp.length-sizeof(struct ospf_lsa_header));
+ body=mb_alloc(p->pool,lsatmp.length-sizeof(struct ospf_lsa_header));
+ ntohlsab(lsa+1,body,lsatmp.type,lsatmp.length-sizeof(struct ospf_lsa_header));
+ lsadb=lsa_install_new(&lsatmp,body, oa);
+ DBG("New installed\n");
+
continue;
}
diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c
index e166b4a..371434b 100644
--- a/proto/ospf/topology.c
+++ b/proto/ospf/topology.c
@@ -22,8 +22,8 @@
#define HASH_LO_STEP 2
#define HASH_LO_MIN 8
-unsigned int
-make_rt_lsa(struct ospf_area *oa, struct proto_ospf *p)
+void *
+originate_rt_lsa_body(struct ospf_area *oa, u16 *length, struct proto_ospf *p)
{
struct ospf_iface *ifa;
int j=0,k=0,v=0,e=0,b=0;
@@ -32,8 +32,9 @@ make_rt_lsa(struct ospf_area *oa, struct proto_ospf *p)
struct ospf_lsa_rt_link *ln;
struct ospf_neighbor *neigh;
struct top_hash_entry *old;
+ struct proto_ospf *po=(struct proto_ospf *)p;
- old=oa->rt;
+ DBG("%s: Originating RT_lsa body for area \"%d\".\n", po->proto.name, oa->areaid);
WALK_LIST (ifa, p->iface_list) i++;
{
@@ -145,9 +146,9 @@ make_rt_lsa(struct ospf_area *oa, struct proto_ospf *p)
ln=(ln+1);
}
rt->links=i;
- if(old->lsa_body!=NULL) mb_free(old->lsa_body);
- old->lsa_body=rt;
- return i*sizeof(struct ospf_lsa_rt_link)+sizeof(struct ospf_lsa_rt);
+ *length=i*sizeof(struct ospf_lsa_rt_link)+sizeof(struct ospf_lsa_rt)+
+ sizeof(struct ospf_lsa_header);
+ return rt;
}
@@ -179,23 +180,42 @@ addifa_rtlsa(struct ospf_iface *ifa)
oa->areaid=ifa->an;
oa->gr=ospf_top_new(po);
s_init_list(&(oa->lsal));
- oa->rt=ospf_hash_get(oa->gr, rtid, rtid, LSA_T_RT);
- s_add_head(&(oa->lsal), (snode *)oa->rt);
- ((snode *)oa->rt)->next=NULL;
- lsa=&(oa->rt->lsa);
- oa->rt->lsa_body=NULL;
- lsa->age=0;
- lsa->sn=LSA_INITSEQNO; /* FIXME Check it latter */
+ oa->rt=NULL;
po->areano++;
DBG("%s: New OSPF area \"%d\" added.\n", po->proto.name, ifa->an);
}
ifa->oa=oa;
-
- oa->rt->lsa.length=make_rt_lsa(oa, po)+sizeof(struct ospf_lsa_header);
- oa->rt->lsa.checksum=0;
- lsasum_calculate(&(oa->rt->lsa),oa->rt->lsa_body,po);
- /*FIXME lsa_flood(oa->rt) */
+
+ oa->rt=originate_rt_lsa(oa,po);
+}
+
+struct top_hash_entry *
+originate_rt_lsa(struct ospf_area *oa, struct proto_ospf *po)
+{
+ struct ospf_lsa_header lsa;
+ u32 rtid=po->proto.cf->global->router_id;
+ struct top_hash_entry *en;
+ void *body;
+
+ DBG("%s: Originating RT_lsa for area \"%d\".\n", po->proto.name, oa->areaid);
+
+ lsa.age=0;
+ lsa.id=rtid;
+ lsa.type=LSA_T_RT;
+ lsa.rt=rtid;
+ if(oa->rt==NULL)
+ {
+ lsa.sn=LSA_INITSEQNO;
+ }
+ else
+ {
+ lsa.sn=oa->rt->lsa.sn+1;
+ }
+ body=originate_rt_lsa_body(oa, &lsa.length, po);
+ lsasum_calculate(&lsa,body,po);
+ en=lsa_install_new(&lsa, body, oa);
+ return en;
}
@@ -296,6 +316,13 @@ ospf_hash_find_header(struct top_graph *f, struct ospf_lsa_header *h)
{
return ospf_hash_find(f,h->id,h->rt,h->type);
}
+
+struct top_hash_entry *
+ospf_hash_get_header(struct top_graph *f, struct ospf_lsa_header *h)
+{
+ return ospf_hash_get(f,h->id,h->rt,h->type);
+}
+
struct top_hash_entry *
ospf_hash_find(struct top_graph *f, u32 lsa, u32 rtr, u32 type)
{
diff --git a/proto/ospf/topology.h b/proto/ospf/topology.h
index d0e9ad9..e146c6f 100644
--- a/proto/ospf/topology.h
+++ b/proto/ospf/topology.h
@@ -32,9 +32,12 @@ struct top_graph *ospf_top_new(struct proto_ospf *);
void ospf_top_free(struct top_graph *);
void ospf_top_dump(struct top_graph *);
struct top_hash_entry *ospf_hash_find_header(struct top_graph *f, struct ospf_lsa_header *h);
+struct top_hash_entry *ospf_hash_get_header(struct top_graph *f, struct ospf_lsa_header *h);
struct top_hash_entry *ospf_hash_find(struct top_graph *, u32 lsa, u32 rtr, u32 type);
struct top_hash_entry *ospf_hash_get(struct top_graph *, u32 lsa, u32 rtr, u32 type);
void ospf_hash_delete(struct top_graph *, struct top_hash_entry *);
void addifa_rtlsa(struct ospf_iface *ifa);
+struct top_hash_entry *originate_rt_lsa(struct ospf_area *oa,
+ struct proto_ospf *po);
#endif /* _BIRD_OSPF_TOPOLOGY_H_ */