diff options
Diffstat (limited to 'proto/ospf')
-rw-r--r-- | proto/ospf/dbdes.c | 25 | ||||
-rw-r--r-- | proto/ospf/dbdes.h | 1 | ||||
-rw-r--r-- | proto/ospf/hello.c | 110 | ||||
-rw-r--r-- | proto/ospf/hello.h | 14 | ||||
-rw-r--r-- | proto/ospf/iface.c | 47 | ||||
-rw-r--r-- | proto/ospf/iface.h | 1 | ||||
-rw-r--r-- | proto/ospf/lsalib.c | 2 | ||||
-rw-r--r-- | proto/ospf/lsreq.c | 43 | ||||
-rw-r--r-- | proto/ospf/lsreq.h | 1 | ||||
-rw-r--r-- | proto/ospf/lsupd.c | 196 | ||||
-rw-r--r-- | proto/ospf/neighbor.c | 121 | ||||
-rw-r--r-- | proto/ospf/neighbor.h | 7 | ||||
-rw-r--r-- | proto/ospf/ospf.c | 5 | ||||
-rw-r--r-- | proto/ospf/ospf.h | 1 | ||||
-rw-r--r-- | proto/ospf/packet.c | 2 |
15 files changed, 273 insertions, 303 deletions
diff --git a/proto/ospf/dbdes.c b/proto/ospf/dbdes.c index 1f9dd55..0bc158b 100644 --- a/proto/ospf/dbdes.c +++ b/proto/ospf/dbdes.c @@ -134,15 +134,12 @@ ospf_dbdes_tx(struct ospf_neighbor *n) sk_send_to(ifa->ip_sk,length, n->ip, OSPF_PROTO); OSPF_TRACE(D_PACKETS, "DB_DES (M) sent to %I via %s.", n->ip, ifa->iface->name); - if(n->myimms.bit.ms) tm_start(n->rxmt_timer,ifa->rxmtint); - else + if(! n->myimms.bit.ms) { if((n->myimms.bit.m==0) && (n->imms.bit.m==0) && (n->state==NEIGHBOR_EXCHANGE)) { ospf_neigh_sm(n, INM_EXDONE); - if(n->myimms.bit.ms) tm_stop(n->rxmt_timer); - else tm_start(n->rxmt_timer,ifa->rxmtint); } } break; @@ -154,25 +151,6 @@ ospf_dbdes_tx(struct ospf_neighbor *n) } void -rxmt_timer_hook(timer *timer) -{ - struct ospf_iface *ifa; - struct proto *p; - struct ospf_neighbor *n; - - n=(struct ospf_neighbor *)timer->data; - ifa=n->ifa; - p=(struct proto *)(ifa->proto); - DBG("%s: RXMT timer fired on interface %s for neigh: %I.\n", - p->name, ifa->iface->name, n->ip); - if(n->state<NEIGHBOR_LOADING) ospf_dbdes_tx(n); - else - { - tm_stop(n->rxmt_timer); - } -} - -void ospf_dbdes_reqladd(struct ospf_dbdes_packet *ps, struct proto *p, struct ospf_neighbor *n) { @@ -258,7 +236,6 @@ ospf_dbdes_rx(struct ospf_dbdes_packet *ps, struct proto *p, n->imms.byte=ps->imms.byte; OSPF_TRACE(D_PACKETS, "I'm slave to %I.", n->ip); ospf_neigh_sm(n, INM_NEGDONE); - tm_stop(n->rxmt_timer); ospf_dbdes_tx(n); break; } diff --git a/proto/ospf/dbdes.h b/proto/ospf/dbdes.h index 68549c8..2cdb216 100644 --- a/proto/ospf/dbdes.h +++ b/proto/ospf/dbdes.h @@ -11,7 +11,6 @@ #define _BIRD_OSPF_DBDES_H_ void ospf_dbdes_tx(struct ospf_neighbor *n); -void rxmt_timer_hook(timer *timer); void ospf_dbdes_rx(struct ospf_dbdes_packet *ps, struct proto *p, struct ospf_iface *ifa, u16 size); diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c index e6dc7ab..2f7baac 100644 --- a/proto/ospf/hello.c +++ b/proto/ospf/hello.c @@ -1,7 +1,7 @@ /* * BIRD -- OSPF * - * (c) 1999 - 2000 Ondrej Filip <feela@network.cz> + * (c) 1999 - 2004 Ondrej Filip <feela@network.cz> * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -9,52 +9,7 @@ #include "ospf.h" void -install_inactim(struct ospf_neighbor *n) -{ - struct proto *p; - struct ospf_iface *ifa; - - ifa=n->ifa; - p=(struct proto *)(ifa->proto); - - if(n->inactim==NULL) - { - n->inactim=tm_new(n->pool); - n->inactim->data=n; - n->inactim->randomize=0; - n->inactim->hook=neighbor_timer_hook; - n->inactim->recurrent=0; - DBG("%s: Installing inactivity timer.\n", p->name); - } -} - -void -restart_inactim(struct ospf_neighbor *n) -{ - tm_start(n->inactim,n->ifa->deadc*n->ifa->helloint); -} - -void -restart_hellotim(struct ospf_iface *ifa) -{ - tm_start(ifa->hello_timer,ifa->helloint); -} - -void -restart_polltim(struct ospf_iface *ifa) -{ - if(ifa->poll_timer) - tm_start(ifa->poll_timer,ifa->pollint); -} - -void -restart_waittim(struct ospf_iface *ifa) -{ - tm_start(ifa->wait_timer,ifa->waitint); -} - -void -ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p, +ospf_hello_receive(struct ospf_hello_packet *ps, struct proto *p, struct ospf_iface *ifa, int size, ip_addr faddr) { u32 nrid, *pnrid; @@ -131,10 +86,9 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p, } OSPF_TRACE(D_EVENTS, "New neighbor found: %I on %s.", faddr, ifa->iface->name); - pool=rp_new(p->pool, "OSPF Neighbor"); - n=mb_allocz(pool, sizeof(struct ospf_neighbor)); - n->pool=pool; - add_tail(&ifa->neigh_list, NODE n); + + n = ospf_neighbor_new(ifa); + n->rid=nrid; n->ip=faddr; n->dr=ps->dr; @@ -143,30 +97,6 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p, ipa_ntoh(n->bdr); n->priority=ps->priority; n->options=ps->options; - n->ifa=ifa; - n->adj=0; - n->ldbdes=mb_alloc(pool, ifa->iface->mtu); - n->state=NEIGHBOR_DOWN; - install_inactim(n); - n->rxmt_timer=tm_new(pool); - n->rxmt_timer->data=n; - n->rxmt_timer->randomize=0; - n->rxmt_timer->hook=rxmt_timer_hook; - n->rxmt_timer->recurrent=ifa->rxmtint; - DBG("%s: Installing rxmt timer.\n", p->name); - n->lsrr_timer=tm_new(pool); - n->lsrr_timer->data=n; - n->lsrr_timer->randomize=0; - n->lsrr_timer->hook=lsrr_timer_hook; - n->lsrr_timer->recurrent=ifa->rxmtint; - DBG("%s: Installing lsrr timer.\n", p->name); - init_list(&n->ackl); - n->ackd_timer=tm_new(pool); - n->ackd_timer->data=n; - n->ackd_timer->randomize=0; - n->ackd_timer->hook=ackd_timer_hook; - n->ackd_timer->recurrent=ifa->rxmtint/2; - DBG("%s: Installing ackd timer.\n", p->name); } ospf_neigh_sm(n, INM_HELLOREC); @@ -220,25 +150,13 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p, if(ifa->type!=OSPF_IT_NBMA) { - if((ifa->priority==0)&&(n->priority>0)) hello_send(NULL,0, n); + if((ifa->priority==0)&&(n->priority>0)) ospf_hello_send(NULL, 0, n); } ospf_neigh_sm(n, INM_HELLOREC); } void -poll_timer_hook(timer *timer) -{ - hello_send(timer,1, NULL); -} - -void -hello_timer_hook(timer *timer) -{ - hello_send(timer,0, NULL); -} - -void -hello_send(timer *timer,int poll, struct ospf_neighbor *dirn) +ospf_hello_send(timer *timer,int poll, struct ospf_neighbor *dirn) { struct ospf_iface *ifa; struct ospf_hello_packet *pkt; @@ -350,17 +268,3 @@ hello_send(timer *timer,int poll, struct ospf_neighbor *dirn) } OSPF_TRACE(D_PACKETS, "Hello sent via %s",ifa->iface->name); } - -void -wait_timer_hook(timer *timer) -{ - struct ospf_iface *ifa; - struct proto *p; - - ifa=(struct ospf_iface *)timer->data; - p=(struct proto *)(ifa->proto); - OSPF_TRACE(D_EVENTS, "Wait timer fired on interface %s.", - ifa->iface->name); - ospf_int_sm(ifa, ISM_WAITF); -} - diff --git a/proto/ospf/hello.h b/proto/ospf/hello.h index 4a5d504..a3e4a92 100644 --- a/proto/ospf/hello.h +++ b/proto/ospf/hello.h @@ -1,7 +1,7 @@ /* * BIRD -- OSPF * - * (c) 1999 - 2000 Ondrej Filip <feela@network.cz> + * (c) 1999 - 2004 Ondrej Filip <feela@network.cz> * * Can be freely distributed and used under the terms of the GNU GPL. * @@ -10,16 +10,8 @@ #ifndef _BIRD_OSPF_HELLO_H_ #define _BIRD_OSPF_HELLO_H_ -void install_inactim(struct ospf_neighbor *n); -void restart_inactim(struct ospf_neighbor *n); -void restart_hellotim(struct ospf_iface *ifa); -void restart_polltim(struct ospf_iface *ifa); -void restart_waittim(struct ospf_iface *ifa); -void ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p, +void ospf_hello_receive(struct ospf_hello_packet *ps, struct proto *p, struct ospf_iface *ifa, int size, ip_addr faddr); -void hello_timer_hook(timer *timer); -void poll_timer_hook(timer *timer); -void wait_timer_hook(timer *timer); -void hello_send(timer *timer,int poll, struct ospf_neighbor *dirn); +void ospf_hello_send(timer *timer,int poll, struct ospf_neighbor *dirn); #endif /* _BIRD_OSPF_HELLO_H_ */ diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c index 113461d..30eb40b 100644 --- a/proto/ospf/iface.c +++ b/proto/ospf/iface.c @@ -1,7 +1,7 @@ /* * BIRD -- OSPF * - * (c) 1999 - 2000 Ondrej Filip <feela@network.cz> + * (c) 1999 - 2004 Ondrej Filip <feela@network.cz> * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -16,6 +16,32 @@ char *ospf_ism[]={ "interface up", "wait timer fired", "backup seen", char *ospf_it[]={ "broadcast", "nbma", "point-to-point", "virtual link" }; +void +poll_timer_hook(timer *timer) +{ + ospf_hello_send(timer, 1, NULL); +} + +void +hello_timer_hook(timer *timer) +{ + ospf_hello_send(timer, 0, NULL); +} + +void +wait_timer_hook(timer *timer) +{ + struct ospf_iface *ifa; + struct proto *p; + + ifa=(struct ospf_iface *)timer->data; + p=(struct proto *)(ifa->proto); + OSPF_TRACE(D_EVENTS, "Wait timer fired on interface %s.", + ifa->iface->name); + ospf_int_sm(ifa, ISM_WAITF); +} + + /** * iface_chstate - handle changes of interface state * @ifa: OSPF interface @@ -135,8 +161,11 @@ ospf_int_sm(struct ospf_iface *ifa, int event) if(ifa->state==OSPF_IS_DOWN) { /* Now, nothing should be adjacent */ - restart_hellotim(ifa); - restart_polltim(ifa); + tm_start(ifa->hello_timer,ifa->helloint); + + if(ifa->poll_timer) + tm_start(ifa->poll_timer,ifa->pollint); + if((ifa->type==OSPF_IT_PTP) || (ifa->type==OSPF_IT_VLINK)) { iface_chstate(ifa, OSPF_IS_PTP); @@ -149,8 +178,8 @@ ospf_int_sm(struct ospf_iface *ifa, int event) } else { - iface_chstate(ifa, OSPF_IS_WAITING); - restart_waittim(ifa); + iface_chstate(ifa, OSPF_IS_WAITING); + tm_start(ifa->wait_timer,ifa->waitint); } } } @@ -480,3 +509,11 @@ schedule_net_lsa(struct ospf_iface *ifa) { ifa->orignet=1; } + +void +ospf_iface_shutdown(struct ospf_iface *ifa) +{ + init_list(&ifa->neigh_list); + hello_timer_hook(ifa->hello_timer); +} + diff --git a/proto/ospf/iface.h b/proto/ospf/iface.h index 350f531..e78a1f8 100644 --- a/proto/ospf/iface.h +++ b/proto/ospf/iface.h @@ -22,6 +22,7 @@ void ospf_iface_default(struct ospf_iface *ifa); struct ospf_iface *find_iface(struct proto_ospf *p, struct iface *what); void ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface); void ospf_iface_info(struct ospf_iface *ifa); +void ospf_iface_shutdown(struct ospf_iface *ifa); void ospf_ifa_add(struct object_lock *lock); void schedule_net_lsa(struct ospf_iface *ifa); diff --git a/proto/ospf/lsalib.c b/proto/ospf/lsalib.c index 1e97709..1a9653c 100644 --- a/proto/ospf/lsalib.c +++ b/proto/ospf/lsalib.c @@ -420,7 +420,7 @@ 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) { - /* LSA can be temporarrily, but body must be mb_alloced. */ + /* LSA can be temporarrily, but body must be mb_allocated. */ struct proto *p=&oa->po->proto; int change=0; unsigned i; diff --git a/proto/ospf/lsreq.c b/proto/ospf/lsreq.c index 5d387ee..3b5ac4b 100644 --- a/proto/ospf/lsreq.c +++ b/proto/ospf/lsreq.c @@ -59,49 +59,6 @@ ospf_lsreq_tx(struct ospf_neighbor *n) } void -lsrr_timer_hook(timer *timer) -{ - struct ospf_iface *ifa; - struct proto *p; - struct ospf_neighbor *n; - struct top_hash_entry *en; - - n=(struct ospf_neighbor *)timer->data; - ifa=n->ifa; - p=(struct proto *)(ifa->proto); - - DBG("%s: LSRR timer fired on interface %s for neigh: %I.\n", - p->name, ifa->iface->name, n->rid); - if(n->state<NEIGHBOR_FULL) ospf_lsreq_tx(n); - else - { - if(!EMPTY_SLIST(n->lsrtl)) - { - list uplist; - slab *upslab; - struct l_lsr_head *llsh; - - init_list(&uplist); - upslab=sl_new(n->pool,sizeof(struct l_lsr_head)); - - WALK_SLIST(SNODE en,n->lsrtl) - { - if((SNODE en)->next==(SNODE en)) bug("RTList is cycled"); - llsh=sl_alloc(upslab); - llsh->lsh.id=en->lsa.id; - llsh->lsh.rt=en->lsa.rt; - llsh->lsh.type=en->lsa.type; - DBG("Working on ID: %I, RT: %I, Type: %u\n", - en->lsa.id, en->lsa.rt, en->lsa.type); - add_tail(&uplist, NODE llsh); - } - ospf_lsupd_tx_list(n, &uplist); - rfree(upslab); - } - } -} - -void ospf_lsreq_rx(struct ospf_lsreq_packet *ps, struct proto *p, struct ospf_iface *ifa, u16 size) { diff --git a/proto/ospf/lsreq.h b/proto/ospf/lsreq.h index 46d5b92..ab51c5c 100644 --- a/proto/ospf/lsreq.h +++ b/proto/ospf/lsreq.h @@ -11,7 +11,6 @@ #define _BIRD_OSPF_LSREQ_H_ void ospf_lsreq_tx(struct ospf_neighbor *n); -void lsrr_timer_hook(timer *timer); void ospf_lsreq_rx(struct ospf_lsreq_packet *ps, struct proto *p, struct ospf_iface *ifa, u16 size); diff --git a/proto/ospf/lsupd.c b/proto/ospf/lsupd.c index a8896d6..aa452be 100644 --- a/proto/ospf/lsupd.c +++ b/proto/ospf/lsupd.c @@ -1,13 +1,30 @@ /* * BIRD -- OSPF * - * (c) 2000 Ondrej Filip <feela@network.cz> + * (c) 2000-2004 Ondrej Filip <feela@network.cz> * * Can be freely distributed and used under the terms of the GNU GPL. */ #include "ospf.h" +/** + * flood_lsa - send received or generated lsa to the neighbors + * @n: neighbor than sent this lsa (or NULL if generated) + * @hn: LSA header + * @hh: LSA header + * @po: actual instance of OSPF protocol + * @iff: interface which received this LSA (or NULL if LSA is generated) + * @oa: ospf_area which is the LSA generated for + * @rtl: add this LSA into retransmission list + * + * Calculation of internal paths in an area is described in 16.1 of RFC 2328. + * It's based on Dijkstra's shortest path tree algorithms. + * RFC recommends to add ASBR routers into routing table. I don't do this + * and latter parts of routing table calculation look directly into LSA + * Database. This function is invoked from area_disp(). + */ + int flood_lsa(struct ospf_neighbor *n, struct ospf_lsa_header *hn, struct ospf_lsa_header *hh, struct proto_ospf *po, struct ospf_iface *iff, @@ -74,8 +91,10 @@ flood_lsa(struct ospf_neighbor *n, struct ospf_lsa_header *hn, } } } + if(nn==n) continue; - if(rtl!=0) + + if(rtl) { if((en=ospf_hash_find_header(nn->lsrth, hh))==NULL) { @@ -100,15 +119,16 @@ flood_lsa(struct ospf_neighbor *n, struct ospf_lsa_header *hn, ospf_hash_delete(nn->lsrth, en); } } + ret=1; } - if(ret==0) continue; + if(ret==0) continue; /* pg 150 (2) */ if(ifa==iff) { - if((n->rid==iff->drid)||n->rid==iff->bdrid) continue; - if(iff->state==OSPF_IS_BACKUP) continue; + if((n->rid==iff->drid)||n->rid==iff->bdrid) continue; /* pg 150 (3) */ + if(iff->state==OSPF_IS_BACKUP) continue; /* pg 150 (4) */ retval=1; } @@ -127,21 +147,26 @@ flood_lsa(struct ospf_neighbor *n, struct ospf_lsa_header *hn, fill_ospf_pkt_hdr(ifa, pk, LSUPD_P); pk->lsano=htonl(1); - if(hn!=NULL) + + if(hn) { + struct ospf_lsa_header *lh = (struct ospf_lsa_header *)(pk+1); + u16 age = ntohs(lh->age); + memcpy(pk+1,hn,ntohs(hn->length)); len=sizeof(struct ospf_lsupd_packet)+ntohs(hn->length); + age += ifa->inftransdelay; + if(age>LSA_MAXAGE) age = LSA_MAXAGE; + lh->age = htons(age); } else { u8 *help; struct top_hash_entry *en; - struct ospf_lsa_header *lh; - u16 age; + struct ospf_lsa_header *lh = (struct ospf_lsa_header *)(pk+1); + u16 age = hh->age; - lh=(struct ospf_lsa_header *)(pk+1); htonlsah(hh,lh); - age=hh->age; age+=ifa->inftransdelay; if(age>LSA_MAXAGE) age=LSA_MAXAGE; lh->age=htons(age); @@ -151,6 +176,7 @@ flood_lsa(struct ospf_neighbor *n, struct ospf_lsa_header *hn, -sizeof(struct ospf_lsa_header)); len=hh->length+sizeof(struct ospf_lsupd_packet); } + op->length=htons(len); ospf_pkt_finalize(ifa, op); OSPF_TRACE(D_PACKETS, "LS upd flooded via %s", ifa->iface->name); @@ -263,136 +289,141 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p, nrid); return ; } + if(n->state<NEIGHBOR_EXCHANGE) { - OSPF_TRACE(D_PACKETS,"Received lsupd in lesser state than EXCHANGE from (%I)", + OSPF_TRACE(D_PACKETS, "Received lsupd in lesser state than EXCHANGE from (%I)", n->ip); return; } + if(size<=(sizeof(struct ospf_lsupd_packet)+sizeof(struct ospf_lsa_header))) { - OSPF_TRACE(D_PACKETS, "Received lsupd from %I is too short!", n->ip); + log(L_WARN "Received lsupd from %I is too short!", n->ip); return; } OSPF_TRACE(D_PACKETS, "Received LS upd from %I", n->ip); - ospf_neigh_sm(n, INM_HELLOREC); + ospf_neigh_sm(n, INM_HELLOREC); /* Questionable */ lsa=(struct ospf_lsa_header *)(ps+1); area=htonl(ps->ospf_packet.areaid); oa=ospf_find_area((struct proto_ospf *)p,area); - for(i=0;i<ntohl(ps->lsano);i++, + + for(i=0; i<ntohl(ps->lsano); i++, lsa=(struct ospf_lsa_header *)(((u8 *)lsa)+ntohs(lsa->length))) { struct ospf_lsa_header lsatmp; struct top_hash_entry *lsadb; - u16 lenn; int diff=((u8 *)lsa)-((u8 *)ps); - u16 chsum; - - if(((diff+sizeof(struct ospf_lsa_header))>=size) || - ((ntohs(lsa->length)+diff)>size)) - log("%s: Received lsupd from %I is too short.", p->name,n->ip); + u16 chsum, lenn = ntohs(lsa->length); - lenn=ntohs(lsa->length); + if(((diff+sizeof(struct ospf_lsa_header))>=size) || ((lenn+diff)>size)) + { + log(L_WARN "Received lsupd from %I is too short!", n->ip); + ospf_neigh_sm(n, INM_BADLSREQ); + break; + } if((lenn<=sizeof(struct ospf_lsa_header))||(lenn!=(4*(lenn/4)))) { - log("Received LSA with bad length"); - ospf_neigh_sm(n,INM_BADLSREQ); + log(L_WARN "Received LSA from %I with bad length", n->ip); + ospf_neigh_sm(n, INM_BADLSREQ); break; } + /* pg 143 (1) */ chsum=lsa->checksum; if(chsum!=lsasum_check(lsa,NULL,po)) { - log("Received bad lsa checksum from %I",n->rid); + log(L_WARN "Received bad lsa checksum from %I", n->ip); continue; } + /* pg 143 (2) */ if((lsa->type<LSA_T_RT)||(lsa->type>LSA_T_EXT)) { - log("Unknown LSA type from %I",n->rid); + log(L_WARN "Unknown LSA type from %I", n->ip); continue; } + /* pg 143 (3) */ if((lsa->type==LSA_T_EXT)&&oa->stub) { - log("Received External LSA in stub area from %I",n->rid); + log(L_WARN "Received External LSA in stub area from %I", n->ip); continue; } + ntohlsah(lsa,&lsatmp); + DBG("Update Type: %u ID: %I RT: %I, Sn: 0x%08x Age: %u, Sum: %u\n", lsatmp.type, lsatmp.id, lsatmp.rt, lsatmp.sn, lsatmp.age, lsatmp.checksum); + lsadb=ospf_hash_find_header(oa->gr, &lsatmp); + +#ifdef LOCAL_DEBUG if(lsadb) DBG("I have Type: %u ID: %I RT: %I, Sn: 0x%08x Age: %u, Sum: %u\n", lsadb->lsa.type, lsadb->lsa.id, lsadb->lsa.rt, lsadb->lsa.sn, lsadb->lsa.age, lsadb->lsa.checksum); +#endif /* pg 143 (4) */ - if((lsatmp.age==LSA_MAXAGE)&&(lsadb==NULL)) + if((lsatmp.age==LSA_MAXAGE)&&(lsadb==NULL)&&can_flush_lsa(oa)) { - int flag=0; - struct ospf_iface *ifatmp; - - if(can_flush_lsa(oa)) - { - ospf_lsack_direct_tx(n,lsa); - continue; - } + ospf_lsack_direct_tx(n,lsa); + continue; } + /* pg 144 (5) */ if((lsadb==NULL)||(lsa_comp(&lsatmp,&lsadb->lsa)==CMP_NEWER)) { - struct ospf_iface *ift=NULL; - void *body; - struct ospf_iface *nifa; - int self=0; - - DBG("PG143(5): Received LSA is newer\n"); - - if(lsatmp.rt==p->cf->global->router_id) self=1; - - if(lsatmp.type==LSA_T_NET) - { - WALK_LIST(nifa,po->iface_list) - { - if(ipa_compare(nifa->iface->addr->ip,ipa_from_u32(lsatmp.id))==0) - { - self=1; - break; - } - } - } - - if(self) - { - struct top_hash_entry *en; - - if((lsatmp.age==LSA_MAXAGE)&&(lsatmp.sn==LSA_MAXSEQNO)) - { - ospf_lsack_direct_tx(n,lsa); - continue; - } - - lsatmp.age=LSA_MAXAGE; - lsatmp.sn=LSA_MAXSEQNO; - lsa->age=htons(LSA_MAXAGE); - lsa->sn=htonl(LSA_MAXSEQNO); - OSPF_TRACE(D_EVENTS, "Premature aging self originated lsa."); - OSPF_TRACE(D_EVENTS, "Type: %d, Id: %I, Rt: %I",lsatmp.type, - lsatmp.id, lsatmp.rt); - lsasum_check(lsa,(lsa+1),po); - lsatmp.checksum=ntohs(lsa->checksum); - flood_lsa(NULL,lsa,&lsatmp,po,NULL,oa,0); - if(en=ospf_hash_find_header(oa->gr,&lsatmp)) - { - flood_lsa(NULL,NULL,&en->lsa,po,NULL,oa,1); - } - continue; - } + struct ospf_iface *ift=NULL; + void *body; + struct ospf_iface *nifa; + int self = (lsatmp.rt == p->cf->global->router_id); + + DBG("PG143(5): Received LSA is newer\n"); + + if(lsatmp.type==LSA_T_NET) + { + WALK_LIST(nifa,po->iface_list) + { + if(ipa_compare(nifa->iface->addr->ip,ipa_from_u32(lsatmp.id))==0) + { + self=1; + break; + } + } + } + + if(self) + { + struct top_hash_entry *en; + + if((lsatmp.age==LSA_MAXAGE)&&(lsatmp.sn==LSA_MAXSEQNO)) + { + ospf_lsack_direct_tx(n,lsa); + continue; + } + + lsatmp.age=LSA_MAXAGE; + lsatmp.sn=LSA_MAXSEQNO; + lsa->age=htons(LSA_MAXAGE); + lsa->sn=htonl(LSA_MAXSEQNO); + OSPF_TRACE(D_EVENTS, "Premature aging self originated lsa."); + OSPF_TRACE(D_EVENTS, "Type: %d, Id: %I, Rt: %I",lsatmp.type, + lsatmp.id, lsatmp.rt); + lsasum_check(lsa,(lsa+1),po); + lsatmp.checksum=ntohs(lsa->checksum); + flood_lsa(NULL,lsa,&lsatmp,po,NULL,oa,0); + if(en=ospf_hash_find_header(oa->gr,&lsatmp)) + { + flood_lsa(NULL,NULL,&en->lsa,po,NULL,oa,1); + } + continue; + } /* pg 144 (5a) */ if(lsadb && ((now-lsadb->inst_t)<=MINLSARRIVAL)) @@ -488,6 +519,7 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p, ospf_lsupd_tx_list(n, &l); } } + if(n->state==NEIGHBOR_LOADING) { ospf_lsreq_tx(n); /* Send me another part of database */ diff --git a/proto/ospf/neighbor.c b/proto/ospf/neighbor.c index f2bb636..61bf555 100644 --- a/proto/ospf/neighbor.c +++ b/proto/ospf/neighbor.c @@ -1,7 +1,7 @@ /* * BIRD -- OSPF * - * (c) 1999 - 2000 Ondrej Filip <feela@network.cz> + * (c) 1999 - 2004 Ondrej Filip <feela@network.cz> * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -22,6 +22,60 @@ const char *ospf_inm[]={ "hello received", "neighbor start", "2-way received", "adjacency ok?", "sequence mismatch", "1-way received", "kill neighbor", "inactivity timer", "line down" }; + +void neighbor_timer_hook(timer *timer); +void rxmt_timer_hook(timer *timer); + + + +struct ospf_neighbor * +ospf_neighbor_new(struct ospf_iface *ifa) +{ + struct proto *p = (struct proto *)(ifa->proto); + struct pool *pool = rp_new(p->pool, "OSPF Neighbor"); + struct ospf_neighbor *n = mb_allocz(pool, sizeof(struct ospf_neighbor)); + + n->pool = pool; + n->ifa = ifa; + add_tail(&ifa->neigh_list, NODE n); + n->adj = 0; + n->ldbdes=mb_alloc(pool, ifa->iface->mtu); + n->state=NEIGHBOR_DOWN; + + n->inactim = tm_new(pool); + n->inactim->data = n; + n->inactim->randomize = 0; + n->inactim->hook = neighbor_timer_hook; + n->inactim->recurrent = 0; + DBG("%s: Installing inactivity timer.\n", p->name); + + n->rxmt_timer = tm_new(pool); + n->rxmt_timer->data = n; + n->rxmt_timer->randomize = 0; + n->rxmt_timer->hook = rxmt_timer_hook; + n->rxmt_timer->recurrent = ifa->rxmtint; + s_init_list(&(n->lsrql)); + n->lsrqh = ospf_top_new(pool, n->ifa->proto); + s_init_list(&(n->lsrtl)); + n->lsrth = ospf_top_new(pool, 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->rxmt_timer,n->ifa->rxmtint); + DBG("%s: Installing rxmt timer.\n", p->name); + + n->ackd_timer = tm_new(pool); + n->ackd_timer->data = n; + n->ackd_timer->randomize = 0; + n->ackd_timer->hook = ackd_timer_hook; + n->ackd_timer->recurrent = ifa->rxmtint/2; + init_list(&n->ackl); + tm_start(n->ackd_timer,n->ifa->rxmtint/2); + DBG("%s: Installing ackd timer.\n", p->name); + + return(n); +} + /** * neigh_chstate - handles changes related to new or lod state of neighbor * @n: OSPF neighbor @@ -67,11 +121,6 @@ neigh_chstate(struct ospf_neighbor *n, u8 state) schedule_rt_lsa(ifa->oa); schedule_net_lsa(ifa); } - if(oldstate>=NEIGHBOR_EXSTART && state<NEIGHBOR_EXSTART) - { - /* Stop RXMT timer */ - tm_stop(n->rxmt_timer); - } if(state==NEIGHBOR_EXSTART) { if(n->adj==0) /* First time adjacency */ @@ -83,10 +132,7 @@ neigh_chstate(struct ospf_neighbor *n, u8 state) n->myimms.bit.ms=1; n->myimms.bit.m=1; n->myimms.bit.i=1; - tm_start(n->rxmt_timer,1); /* Or some other number ? */ } - if(state<NEIGHBOR_EXCHANGE) tm_stop(n->lsrr_timer); - if(state<NEIGHBOR_EXSTART) tm_stop(n->rxmt_timer); if(state>NEIGHBOR_EXSTART) n->myimms.bit.i=0; } } @@ -246,9 +292,9 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event) { case NEIGHBOR_ATTEMPT: case NEIGHBOR_DOWN: - neigh_chstate(n,NEIGHBOR_INIT); + neigh_chstate(n, NEIGHBOR_INIT); default: - restart_inactim(n); + tm_start(n->inactim, n->ifa->deadc*n->ifa->helloint); /* Restart inactivity timer */ break; } break; @@ -268,17 +314,6 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event) rem_node(NODE no); mb_free(no); } - s_init_list(&(n->lsrql)); - if(n->lsrqh) ospf_top_free(n->lsrqh); - n->lsrqh=ospf_top_new(n->pool, n->ifa->proto); - s_init_list(&(n->lsrtl)); - if(n->lsrth) ospf_top_free(n->lsrth); - n->lsrth=ospf_top_new(n->pool, 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); - tm_start(n->ackd_timer,n->ifa->rxmtint/2); } else bug("NEGDONE and I'm not in EXSTART?"); break; @@ -531,3 +566,45 @@ ospf_sh_neigh_info(struct ospf_neighbor *n) cli_msg(-1013,"%-1I\t%3u\t%s/%s\t%-5s\t%-1I\t%-10s",n->rid, n->priority, ospf_ns[n->state], pos, etime, n->ip,ifa->iface->name); } + +void +rxmt_timer_hook(timer *timer) +{ + struct ospf_neighbor *n = (struct ospf_neighbor *)timer->data; + struct ospf_iface *ifa = n->ifa; + struct proto *p = (struct proto *)(ifa->proto); + struct top_hash_entry *en; + + DBG("%s: RXMT timer fired on interface %s for neigh: %I.\n", + p->name, ifa->iface->name, n->ip); + if (n->state < NEIGHBOR_LOADING) ospf_dbdes_tx(n); + + if(n->state < NEIGHBOR_FULL) ospf_lsreq_tx(n); + else + { + if(!EMPTY_SLIST(n->lsrtl)) + { + list uplist; + slab *upslab; + struct l_lsr_head *llsh; + + init_list(&uplist); + upslab=sl_new(n->pool,sizeof(struct l_lsr_head)); + + WALK_SLIST(SNODE en,n->lsrtl) + { + if((SNODE en)->next==(SNODE en)) bug("RTList is cycled"); + llsh=sl_alloc(upslab); + llsh->lsh.id=en->lsa.id; + llsh->lsh.rt=en->lsa.rt; + llsh->lsh.type=en->lsa.type; + DBG("Working on ID: %I, RT: %I, Type: %u\n", + en->lsa.id, en->lsa.rt, en->lsa.type); + add_tail(&uplist, NODE llsh); + } + ospf_lsupd_tx_list(n, &uplist); + rfree(upslab); + } + } +} + diff --git a/proto/ospf/neighbor.h b/proto/ospf/neighbor.h index f68c69a..c3ecd6b 100644 --- a/proto/ospf/neighbor.h +++ b/proto/ospf/neighbor.h @@ -1,7 +1,7 @@ /* * BIRD -- OSPF * - * (c) 1999 - 2000 Ondrej Filip <feela@network.cz> + * (c) 1999 - 2004 Ondrej Filip <feela@network.cz> * * Can be freely distributed and used under the terms of the GNU GPL. * @@ -10,18 +10,17 @@ #ifndef _BIRD_OSPF_NEIGHBOR_H_ #define _BIRD_OSPF_NEIGHBOR_H_ +struct ospf_neighbor *ospf_neighbor_new(struct ospf_iface *ifa); void neigh_chstate(struct ospf_neighbor *n, u8 state); struct ospf_neighbor *electbdr(list nl); struct ospf_neighbor *electdr(list nl); -int can_do_adj(struct ospf_neighbor *n); -void tryadj(struct ospf_neighbor *n, struct proto *p); void ospf_neigh_sm(struct ospf_neighbor *n, int event); void bdr_election(struct ospf_iface *ifa); struct ospf_neighbor *find_neigh(struct ospf_iface *ifa, u32 rid); struct ospf_neighbor *find_neigh_noifa(struct proto_ospf *po, u32 rid); struct ospf_area *ospf_find_area(struct proto_ospf *po, u32 aid); -void neighbor_timer_hook(timer *timer); void ospf_neigh_remove(struct ospf_neighbor *n); void ospf_sh_neigh_info(struct ospf_neighbor *n); + #endif /* _BIRD_OSPF_NEIGHBOR_H_ */ diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index dbe3b18..ba40e31 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -364,10 +364,7 @@ ospf_shutdown(struct proto *p) /* And send to all my neighbors 1WAY */ WALK_LIST(ifa, po->iface_list) - { - init_list(&ifa->neigh_list); - hello_timer_hook(ifa->hello_timer); - } + ospf_iface_shutdown(ifa); return PS_DOWN; } diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 9373148..5144150 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -356,7 +356,6 @@ struct ospf_neighbor struct top_graph *lsrth; void *ldbdes; /* Last database description packet */ timer *rxmt_timer; /* RXMT timer */ - timer *lsrr_timer; /* Link state request retransmition timer */ list ackl; timer *ackd_timer; /* Delayed ack timer */ }; diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c index 750f3a3..8ee6cba 100644 --- a/proto/ospf/packet.c +++ b/proto/ospf/packet.c @@ -175,7 +175,7 @@ ospf_rx_hook (sock * sk, int size) { case HELLO_P: DBG ("%s: Hello received.\n", p->name); - ospf_hello_rx ((struct ospf_hello_packet *) ps, p, ifa, size, + ospf_hello_receive((struct ospf_hello_packet *) ps, p, ifa, size, sk->faddr); break; case DBDES_P: |