Commit d8852b36 authored by Ondřej Filip's avatar Ondřej Filip

LSupdate processing improved. Now there is some bug in hashing. :-(

parent 921a93f2
......@@ -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? */
}
}
}
......
......@@ -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;
}
......@@ -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_ */
......@@ -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);
......
......@@ -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;
}
......
......@@ -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)
{
......
......@@ -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_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment