LSupdate processing improved. Now there is some bug in hashing. :-(
This commit is contained in:
parent
921a93f217
commit
d8852b362c
7 changed files with 138 additions and 46 deletions
|
@ -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);
|
||||
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");
|
||||
|
||||
/* FIXME lsa_flood(n,lsadb) */
|
||||
/* FIXME ack_lsa() */
|
||||
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_ */
|
||||
|
|
Loading…
Reference in a new issue