diff --git a/proto/ospf/lsack.c b/proto/ospf/lsack.c index 5870809b..f34f7760 100644 --- a/proto/ospf/lsack.c +++ b/proto/ospf/lsack.c @@ -37,3 +37,9 @@ ospf_lsack_rx(struct ospf_lsack_packet *ps, struct proto *p, /* FIXME Go on! */ } +void +add_ack_list(struct ospf_neighbor *n,struct ospf_lsa_header *lsa) +{ + /* FIXME Go on */ +} + diff --git a/proto/ospf/lsack.h b/proto/ospf/lsack.h index ed0ea21d..053e0b51 100644 --- a/proto/ospf/lsack.h +++ b/proto/ospf/lsack.h @@ -13,5 +13,6 @@ void ospf_lsack_tx(struct ospf_neighbor *n); void ospf_lsack_rx(struct ospf_lsack_packet *ps, struct proto *p, struct ospf_iface *ifa, u16 size); +void add_ack_list(struct ospf_neighbor *n,struct ospf_lsa_header *lsa); #endif /* _BIRD_OSPF_LSACK_H_ */ diff --git a/proto/ospf/lsreq.c b/proto/ospf/lsreq.c index 7fa85be0..f894c66f 100644 --- a/proto/ospf/lsreq.c +++ b/proto/ospf/lsreq.c @@ -25,7 +25,7 @@ ospf_lsreq_tx(struct ospf_neighbor *n) fill_ospf_pkt_hdr(n->ifa, pk, LSREQ); sn=SHEAD(n->lsrql); - if(sn==NULL) + if(EMPTY_SLIST(n->lsrql)) { if(n->state==NEIGHBOR_LOADING) ospf_neigh_sm(n, INM_LOADDONE); return; diff --git a/proto/ospf/lsupd.c b/proto/ospf/lsupd.c index 5c0d836d..8ff39590 100644 --- a/proto/ospf/lsupd.c +++ b/proto/ospf/lsupd.c @@ -87,6 +87,7 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p, struct ospf_neighbor *n; struct ospf_lsa_header *lsa; struct ospf_area *oa; + struct proto_ospf *po=(struct proto_ospf *)p; u16 length; u8 i; @@ -113,7 +114,9 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p, for(i=0;ilsano);i++, lsa=(struct ospf_lsa_header *)(((u8 *)lsa)+ntohs(lsa->length))) { - if(lsa->checksum!=lsasum_check(lsa,NULL,(struct proto_ospf *)p)) + struct ospf_lsa_header lsatmp; + struct top_hash_entry *lsadb; + if(lsa->checksum!=lsasum_check(lsa,NULL,po)) { log("Received bad lsa checksum from %u\n",n->rid); continue; @@ -128,9 +131,72 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p, log("Received External LSA in stub area from %u\n",n->rid); continue; } - /* FIXME Go on */ + ntohlsah(lsa,&lsatmp); DBG("Processing update Type: %u ID: %u RT: %u\n",lsa->type, ntohl(lsa->id), ntohl(lsa->rt)); + lsadb=ospf_hash_find_header(oa->gr, &lsatmp); + if((lsatmp.age==LSA_MAXAGE)&&(lsadb==NULL)) + { + struct ospf_neighbor *n=NULL; + struct ospf_iface *ifa=NULL; + 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)) + flag=1; + + if(flag==0) + { + add_ack_list(n,lsa); + continue; + } + } + if((lsadb==NULL)||(lsa_comp(&lsatmp,&lsadb->lsa)==CMP_NEWER)) + { + struct ospf_neighbor *n=NULL; + struct ospf_iface *ifa=NULL; + + /* FIXME self originated? */ + + if(lsadb && ((lsadb->inst_t-now)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); + } + + /* 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() */ + continue; + } + + /* FIXME pg144 (6)?? */ + + if(lsa_comp(&lsatmp,&lsadb->lsa)==CMP_SAME) + { + struct top_hash_entry *en; + if((en=ospf_hash_find_header(n->lsrth,&lsadb->lsa))!=NULL) + s_rem_node(SNODE en); + /* FIXME ack_lsa() */ + continue; + } + + if((lsadb->lsa.age==LSA_MAXAGE)&&(lsadb->lsa.sn==LSA_MAXSEQNO)) continue; + + /* FIXME lsa_send(n,lsa) */ } } diff --git a/proto/ospf/neighbor.c b/proto/ospf/neighbor.c index ae415e13..e57143e7 100644 --- a/proto/ospf/neighbor.c +++ b/proto/ospf/neighbor.c @@ -210,10 +210,11 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event) s_init_list(&(n->lsrql)); n->lsrqh=ospf_top_new(n->ifa->proto); s_init_list(&(n->lsrtl)); + n->lsrth=ospf_top_new(n->ifa->proto); s_init(&(n->dbsi), &(n->ifa->oa->lsal)); s_init(&(n->lsrqi), &(n->lsrql)); + s_init(&(n->lsrti), &(n->lsrtl)); tm_start(n->lsrr_timer,n->ifa->rxmtint); - /*ospf_dbdes_tx(n);*/ } else die("NEGDONE and I'm not in EXSTART?\n"); break; @@ -222,6 +223,7 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event) /* FIXME Go on */ break; case INM_LOADDONE: + neigh_chstate(n,NEIGHBOR_FULL); break; case INM_ADJOK: switch(n->state) diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index ee94f10d..9b653fe1 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -37,12 +37,12 @@ #endif -#define LSREFRESHTIME 1800 /* 30 minut */ +#define LSREFRESHTIME 1800 /* 30 minutes */ #define MINLSINTERVAL 5 #define MINLSARRIVAL 1 #define MAXAGE 3600 /* 1 hour */ -#define CHECKAGE 300 /* 5 min */ -#define MAXAGEDIFF 900 /* 15 min */ +#define CHECKAGE 300 /* 5 minutes */ +#define MAXAGEDIFF 900 /* 15 minutes */ #define LSINFINITY 0xffffff /*#define DEFAULTDES 0.0.0.0 FIXME: How to define it? */ #define INITSEQNUM 0x80000001 /* Initial Sequence Number */ @@ -285,6 +285,7 @@ struct ospf_neighbor siterator lsrqi; slist lsrtl; /* Link state retransmission list */ siterator lsrti; + struct top_graph *lsrth; void *ldbdes; /* Last database description packet */ timer *rxmt_timer; /* RXMT timer */ timer *lsrr_timer; /* Link state requiest retransmition timer */ diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c index e4982c27..e166b4ad 100644 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@ -291,6 +291,11 @@ ospf_top_rehash(struct top_graph *f, int step) ospf_top_ht_free(oldt); } +struct top_hash_entry * +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_find(struct top_graph *f, u32 lsa, u32 rtr, u32 type) { diff --git a/proto/ospf/topology.h b/proto/ospf/topology.h index 9ebd0ed7..d0e9ad9b 100644 --- a/proto/ospf/topology.h +++ b/proto/ospf/topology.h @@ -14,6 +14,7 @@ struct top_hash_entry { /* Index for fast mapping (type,rtrid,LSid)->vertex */ struct top_hash_entry *next; /* Next in hash chain */ struct ospf_lsa_header lsa; void *lsa_body; + bird_clock_t inst_t; /* Time of installation into DB */ }; struct top_graph { @@ -30,6 +31,7 @@ struct top_graph { 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_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 *);