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,
|
debug("\t%04x %08x %08x %p\n", en->lsa.type, en->lsa.id,
|
||||||
en->lsa.rt, en->lsa_body);
|
en->lsa.rt, en->lsa_body);
|
||||||
|
|
||||||
if(sn->next==NULL)
|
if(sn==STAIL(n->ifa->oa->lsal))
|
||||||
{
|
{
|
||||||
break; /* Should set some flag? */
|
break; /* Should set some flag? */
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ ospf_dbdes_tx(struct ospf_neighbor *n)
|
||||||
}
|
}
|
||||||
i--;
|
i--;
|
||||||
|
|
||||||
if(sn->next==NULL)
|
if(sn==STAIL(n->ifa->oa->lsal))
|
||||||
{
|
{
|
||||||
DBG("Number of LSA NOT sent: %d\n", i);
|
DBG("Number of LSA NOT sent: %d\n", i);
|
||||||
DBG("M bit unset.\n");
|
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);
|
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);
|
if(n->myimms.bit.ms) tm_start(n->rxmt_timer,ifa->rxmtint);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -199,6 +199,7 @@ ospf_dbdes_reqladd(struct ospf_dbdes_packet *ps, struct proto *p,
|
||||||
ntohlsah(plsa+i, &(sn->lsa));
|
ntohlsah(plsa+i, &(sn->lsa));
|
||||||
s_add_tail(&(n->lsrql), SNODE sn);
|
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)
|
if(l1->checksum=!l2->checksum)
|
||||||
return l1->checksum<l2->checksum ? CMP_OLDER : CMP_NEWER;
|
return l1->checksum<l2->checksum ? CMP_OLDER : CMP_NEWER;
|
||||||
if(l1->age==MAXAGE) return CMP_NEWER;
|
if(l1->age==LSA_MAXAGE) return CMP_NEWER;
|
||||||
if(l2->age==MAXAGE) return CMP_OLDER;
|
if(l2->age==LSA_MAXAGE) return CMP_OLDER;
|
||||||
if(abs(l1->age-l2->age)>MAXAGEDIFF)
|
if(abs(l1->age-l2->age)>LSA_MAXAGEDIFF)
|
||||||
return l1->age<l2->age ? CMP_NEWER : CMP_OLDER;
|
return l1->age<l2->age ? CMP_NEWER : CMP_OLDER;
|
||||||
}
|
}
|
||||||
return CMP_SAME;
|
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,
|
void lsasum_calculate(struct ospf_lsa_header *header, void *body,
|
||||||
struct proto_ospf *p);
|
struct proto_ospf *p);
|
||||||
u16 lsasum_check(struct ospf_lsa_header *h,void *body,struct proto_ospf *po);
|
u16 lsasum_check(struct ospf_lsa_header *h,void *body,struct proto_ospf *po);
|
||||||
|
|
||||||
#define CMP_NEWER 1
|
#define CMP_NEWER 1
|
||||||
#define CMP_SAME 0
|
#define CMP_SAME 0
|
||||||
#define CMP_OLDER -1
|
#define CMP_OLDER -1
|
||||||
int lsa_comp(struct ospf_lsa_header *l1, struct ospf_lsa_header *l2);
|
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_ */
|
#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,
|
DBG("Requesting %uth LSA: Type: %u, Id: %u, RT: %u\n",i, en->lsa.type,
|
||||||
en->lsa.id, en->lsa.rt);
|
en->lsa.id, en->lsa.rt);
|
||||||
lsh++;
|
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);
|
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)
|
struct ospf_iface *ifa, u16 size)
|
||||||
{
|
{
|
||||||
u32 area,nrid,myrid;
|
u32 area,nrid,myrid;
|
||||||
struct ospf_neighbor *n;
|
struct ospf_neighbor *n,*ntmp;
|
||||||
struct ospf_lsa_header *lsa;
|
struct ospf_lsa_header *lsa;
|
||||||
struct ospf_area *oa;
|
struct ospf_area *oa;
|
||||||
struct proto_ospf *po=(struct proto_ospf *)p;
|
struct proto_ospf *po=(struct proto_ospf *)p;
|
||||||
|
@ -132,9 +132,24 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ntohlsah(lsa,&lsatmp);
|
ntohlsah(lsa,&lsatmp);
|
||||||
DBG("Processing update Type: %u ID: %u RT: %u\n",lsa->type,
|
DBG("Processing update Type: %u ID: %u RT: %u\n",lsatmp.type,
|
||||||
ntohl(lsa->id), ntohl(lsa->rt));
|
lsatmp.id, lsatmp.rt);
|
||||||
lsadb=ospf_hash_find_header(oa->gr, &lsatmp);
|
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))
|
if((lsatmp.age==LSA_MAXAGE)&&(lsadb==NULL))
|
||||||
{
|
{
|
||||||
struct ospf_neighbor *n=NULL;
|
struct ospf_neighbor *n=NULL;
|
||||||
|
@ -142,8 +157,9 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
|
||||||
int flag=0;
|
int flag=0;
|
||||||
|
|
||||||
WALK_LIST(NODE ifa,po->iface_list)
|
WALK_LIST(NODE ifa,po->iface_list)
|
||||||
WALK_LIST(NODE n,ifa->neigh_list)
|
WALK_LIST(NODE ntmp,ifa->neigh_list)
|
||||||
if((n->state==NEIGHBOR_EXCHANGE)&&(n->state==NEIGHBOR_LOADING))
|
if((ntmp->state==NEIGHBOR_EXCHANGE)&&
|
||||||
|
(ntmp->state==NEIGHBOR_LOADING))
|
||||||
flag=1;
|
flag=1;
|
||||||
|
|
||||||
if(flag==0)
|
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_neighbor *n=NULL;
|
||||||
struct ospf_iface *ifa=NULL;
|
struct ospf_iface *ifa=NULL;
|
||||||
|
void *body;
|
||||||
|
|
||||||
/* FIXME self originated? */
|
/* FIXME self originated? */
|
||||||
|
|
||||||
if(lsadb && ((lsadb->inst_t-now)<MINLSARRIVAL)) continue;
|
if(lsadb && ((lsadb->inst_t-now)<MINLSARRIVAL)) continue;
|
||||||
|
|
||||||
/* Remove old from all ret lists */
|
/* Remove old from all ret lists */
|
||||||
|
if(lsadb)
|
||||||
WALK_LIST(NODE ifa,po->iface_list)
|
WALK_LIST(NODE ifa,po->iface_list)
|
||||||
WALK_LIST(NODE n,ifa->neigh_list)
|
WALK_LIST(NODE ntmp,ifa->neigh_list)
|
||||||
{
|
{
|
||||||
struct top_hash_entry *en;
|
struct top_hash_entry *en;
|
||||||
if((en=ospf_hash_find_header(n->lsrth,&lsadb->lsa))!=NULL)
|
if((en=ospf_hash_find_header(ntmp->lsrth,&lsadb->lsa))!=NULL)
|
||||||
|
{
|
||||||
s_rem_node(SNODE en);
|
s_rem_node(SNODE en);
|
||||||
|
ospf_hash_delete(ntmp->lsrth,en);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Install new */
|
/* Install new */
|
||||||
memcpy(&lsadb->lsa,&lsatmp,sizeof(struct ospf_lsa_header));
|
DBG("Allocatin body, size: %u\n",lsatmp.length-sizeof(struct ospf_lsa_header));
|
||||||
lsadb->inst_t=now;
|
body=mb_alloc(p->pool,lsatmp.length-sizeof(struct ospf_lsa_header));
|
||||||
if(lsadb->lsa_body!=NULL) mb_free(lsadb->lsa_body);
|
ntohlsab(lsa+1,body,lsatmp.type,lsatmp.length-sizeof(struct ospf_lsa_header));
|
||||||
lsadb->lsa_body=mb_alloc(p->pool,lsadb->lsa.length-
|
lsadb=lsa_install_new(&lsatmp,body, oa);
|
||||||
sizeof(struct ospf_lsa_header));
|
DBG("New installed\n");
|
||||||
ntohlsab(lsa+1,lsadb->lsa_body,lsadb->lsa.type,lsadb->lsa.length);
|
|
||||||
|
|
||||||
/* FIXME lsa_flood(n,lsadb) */
|
|
||||||
/* FIXME ack_lsa() */
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
#define HASH_LO_STEP 2
|
#define HASH_LO_STEP 2
|
||||||
#define HASH_LO_MIN 8
|
#define HASH_LO_MIN 8
|
||||||
|
|
||||||
unsigned int
|
void *
|
||||||
make_rt_lsa(struct ospf_area *oa, struct proto_ospf *p)
|
originate_rt_lsa_body(struct ospf_area *oa, u16 *length, struct proto_ospf *p)
|
||||||
{
|
{
|
||||||
struct ospf_iface *ifa;
|
struct ospf_iface *ifa;
|
||||||
int j=0,k=0,v=0,e=0,b=0;
|
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_lsa_rt_link *ln;
|
||||||
struct ospf_neighbor *neigh;
|
struct ospf_neighbor *neigh;
|
||||||
struct top_hash_entry *old;
|
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++;
|
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);
|
ln=(ln+1);
|
||||||
}
|
}
|
||||||
rt->links=i;
|
rt->links=i;
|
||||||
if(old->lsa_body!=NULL) mb_free(old->lsa_body);
|
*length=i*sizeof(struct ospf_lsa_rt_link)+sizeof(struct ospf_lsa_rt)+
|
||||||
old->lsa_body=rt;
|
sizeof(struct ospf_lsa_header);
|
||||||
return i*sizeof(struct ospf_lsa_rt_link)+sizeof(struct ospf_lsa_rt);
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,23 +180,42 @@ addifa_rtlsa(struct ospf_iface *ifa)
|
||||||
oa->areaid=ifa->an;
|
oa->areaid=ifa->an;
|
||||||
oa->gr=ospf_top_new(po);
|
oa->gr=ospf_top_new(po);
|
||||||
s_init_list(&(oa->lsal));
|
s_init_list(&(oa->lsal));
|
||||||
oa->rt=ospf_hash_get(oa->gr, rtid, rtid, LSA_T_RT);
|
oa->rt=NULL;
|
||||||
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 */
|
|
||||||
po->areano++;
|
po->areano++;
|
||||||
DBG("%s: New OSPF area \"%d\" added.\n", po->proto.name, ifa->an);
|
DBG("%s: New OSPF area \"%d\" added.\n", po->proto.name, ifa->an);
|
||||||
}
|
}
|
||||||
|
|
||||||
ifa->oa=oa;
|
ifa->oa=oa;
|
||||||
|
|
||||||
oa->rt->lsa.length=make_rt_lsa(oa, po)+sizeof(struct ospf_lsa_header);
|
oa->rt=originate_rt_lsa(oa,po);
|
||||||
oa->rt->lsa.checksum=0;
|
}
|
||||||
lsasum_calculate(&(oa->rt->lsa),oa->rt->lsa_body,po);
|
|
||||||
/*FIXME lsa_flood(oa->rt) */
|
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);
|
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 *
|
struct top_hash_entry *
|
||||||
ospf_hash_find(struct top_graph *f, u32 lsa, u32 rtr, u32 type)
|
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_free(struct top_graph *);
|
||||||
void ospf_top_dump(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_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_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);
|
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 ospf_hash_delete(struct top_graph *, struct top_hash_entry *);
|
||||||
void addifa_rtlsa(struct ospf_iface *ifa);
|
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_ */
|
#endif /* _BIRD_OSPF_TOPOLOGY_H_ */
|
||||||
|
|
Loading…
Reference in a new issue