diff options
Diffstat (limited to 'proto/ospf')
-rw-r--r-- | proto/ospf/ospf.c | 213 | ||||
-rw-r--r-- | proto/ospf/ospf.h | 1 |
2 files changed, 165 insertions, 49 deletions
diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index a5ec2d1..a435686 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -46,7 +46,7 @@ neighbor_timer_hook(timer *timer) n=(struct ospf_neighbor *)timer->data; ifa=n->ifa; p=(struct proto *)(ifa->proto); - debug("%s: Inactivity timer fired on interface %s for neighbor %d.\n", + debug("%s: Inactivity timer fired on interface %s for neighbor %u.\n", p->name, ifa->iface->name, n->rid); tm_stop(n->inactim); rfree(n->inactim); @@ -55,13 +55,151 @@ neighbor_timer_hook(timer *timer) debug("%s: Deleting neigbor.\n", p->name); } -/* void -backupseen() +iface_chstate(struct ospf_iface *ifa, u8 state) +{ + struct proto *p; + + p=(struct proto *)(ifa->proto); + debug("%s: Changing state of iface: %s from %u into %u.\n", + p->name, ifa->iface->name, ifa->state, state); + ifa->state=state; +} + +struct ospf_neighbor * +electbdr(list nl) { - ; /* Backup Seen Event * + struct ospf_neighbor *neigh,*n1,*n2; + + n1=NULL; + n2=NULL; + WALK_LIST (neigh, nl) /* First try those decl. themselves */ + { + if(neigh->state>=NEIGHBOR_2WAY) /* Higher than 2WAY */ + if(neigh->priority>0) /* Eligible */ + if(neigh->rid!=neigh->dr) /* And not declaring itself DR */ + { + if(neigh->rid==neigh->bdr) /* Declaring BDR */ + { + if(n1!=NULL) + { + if(neigh->priority>n1->priority) n1=neigh; + else if(neigh->priority==n1->priority) + if(neigh->rid>n1->rid) n1=neigh; + } + else + { + n1=neigh; + } + } + else /* And NOT declaring BDR */ + { + if(n2!=NULL) + { + if(neigh->priority>n2->priority) n2=neigh; + else if(neigh->priority==n2->priority) + if(neigh->rid>n2->rid) n2=neigh; + } + else + { + n2=neigh; + } + } + } + } + if(n1==NULL) n1=n2; + + return(n1); +} + +struct ospf_neighbor * +electdr(list nl) +{ + struct ospf_neighbor *neigh,*n; + + n=NULL; + WALK_LIST (neigh, nl) /* And now DR */ + { + if(neigh->state>=NEIGHBOR_2WAY) /* Higher than 2WAY */ + if(neigh->priority>0) /* Eligible */ + if(neigh->rid==neigh->dr) /* And declaring itself DR */ + { + if(n!=NULL) + { + if(neigh->priority>n->priority) n=neigh; + else if(neigh->priority==n->priority) + if(neigh->rid>n->rid) n=neigh; + } + else + { + n=neigh; + } + } + } + + return(n); +} + +void +backupseen(struct ospf_iface *ifa) +{ + struct proto *p; + struct ospf_neighbor *neigh,*ndr,*nbdr,me; + u32 myid; + + p=(struct proto *)(ifa->proto); + + DBG("%s: (B)DR election.\n",p->name); + + myid=p->cf->global->router_id; + + me.state=NEIGHBOR_2WAY; + me.rid=myid; + me.priority=ifa->priority; + me.dr=ifa->drid; + me.bdr=ifa->bdrid; + + add_tail(&ifa->neigh_list, NODE &me); + + nbdr=electbdr(ifa->neigh_list); + ndr=electdr(ifa->neigh_list); + + if(ndr==NULL) ndr=nbdr; + + if(((ifa->drid==myid) && (ndr!=myid)) + || ((ifa->drid!=myid) && (ndr==myid)) + || ((ifa->bdrid==myid) && (nbdr!=myid)) + || ((ifa->bdrid!=myid) && (nbdr==myid))) + { + if(ndr==NULL) ifa->drid=me.dr=0; + else ifa->drid=me.dr=ndr->rid; + + if(nbdr==NULL) ifa->bdrid=me.bdr=0; + else ifa->bdrid=me.bdr=nbdr->rid; + + nbdr=electbdr(ifa->neigh_list); + ndr=electdr(ifa->neigh_list); + } + if(ndr==NULL) ifa->drid=0; + else ifa->drid=ndr->rid; + + if(nbdr==NULL) ifa->bdrid=0; + else ifa->bdrid=me.bdr=nbdr->rid; + + DBG("%s: DR=%u, BDR=%u\n",p->name, ifa->drid, ifa->bdrid); + + tm_stop(ifa->wait_timer); + DBG("%s: Stoping wait timer\n",p->name); + + if(myid==ifa->drid) iface_chstate(ifa, OSPF_IS_DR); + else + { + if(myid==ifa->bdrid) iface_chstate(ifa, OSPF_IS_BACKUP); + else iface_chstate(ifa, OSPF_IS_DROTHER); + } + + rem_node(NODE &me); } -*/ void ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p, @@ -77,7 +215,7 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p, if(ipa_mklen(ipa_ntoh(ps->netmask))!=ifa->iface->addr->pxlen) { ip_ntop(ps->netmask,sip); - log("%s: Bad OSPF packet from %d received: bad netmask %s.", + log("%s: Bad OSPF packet from %u received: bad netmask %s.", p->name, nrid, sip); log("%s: Discarding",p->name); return; @@ -85,7 +223,7 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p, if(ntohs(ps->helloint)!=ifa->helloint) { - log("%s: Bad OSPF packet from %d received: hello interval mismatch.", + log("%s: Bad OSPF packet from %u received: hello interval mismatch.", p->name, nrid); log("%s: Discarding",p->name); return; @@ -93,7 +231,7 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p, if(ntohl(ps->deadint)!=ifa->helloint*ifa->deadc) { - log("%s: Bad OSPF packet from %d received: dead interval mismatch.", + log("%s: Bad OSPF packet from %u received: dead interval mismatch.", p->name, nrid); log("%s: Discarding",p->name); return; @@ -102,7 +240,7 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p, if(ps->options!=ifa->options) { - log("%s: Bad OSPF packet from %d received: options mismatch.", + log("%s: Bad OSPF packet from %u received: options mismatch.", p->name, nrid); /* FIXME: This not good */ log("%s: Discarding",p->name); return; @@ -120,7 +258,7 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p, if(n==NULL) { - log("%s: New neighbor found: %d.",p->name,nrid); + log("%s: New neighbor found: %u.",p->name,nrid); n=mb_alloc(p->pool, sizeof(struct ospf_neighbor)); add_tail(&ifa->neigh_list, NODE n); n->inactim=tm_new(p->pool); @@ -146,7 +284,7 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p, if(ntohl(*(pnrid+i))==p->cf->global->router_id) { twoway=1; - DBG("%s: Twoway received. %d\n", p->name, nrid); + DBG("%s: Twoway received. %u\n", p->name, nrid); break; } } @@ -172,9 +310,9 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p, /* Check neighbor's designed router idea */ if((n->rid!=ntohl(ps->dr)) && (ntohl(ps->bdr)==0) && - (ifa->state==OSPF_IS_WAITING)) + (ifa->state==OSPF_IS_WAITING) && (n->state>=NEIGHBOR_2WAY)) { - /* FIXME BackupSeen */; + backupseen(ifa); } if((n->rid==ntohl(ps->dr)) && (n->dr!=ntohl(ps->dr))) { @@ -187,9 +325,10 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p, n->dr=ntohl(ps->dr); /* And update it */ /* Check neighbor's backup designed router idea */ - if((n->rid==ntohl(ps->bdr)) && (ifa->state==OSPF_IS_WAITING)) + if((n->rid==ntohl(ps->bdr)) && (ifa->state==OSPF_IS_WAITING) + && (n->state>=NEIGHBOR_2WAY)) { - /* FIXME BackupSeen */; + backupseen(ifa); } if((n->rid==ntohl(ps->bdr)) && (n->bdr!=ntohl(ps->bdr))) { @@ -278,7 +417,7 @@ ospf_rx_hook(sock *sk, int size) if(size < sizeof(struct ospf_packet)) { - log("%s: Bad packet received: too short (%d bytes)", p->name, size); + log("%s: Bad packet received: too short (%u bytes)", p->name, size); log("%s: Discarding",p->name); return(1); } @@ -292,7 +431,7 @@ ospf_rx_hook(sock *sk, int size) if(ps->version!=OSPF_VERSION) { - log("%s: Bad packet received: version %d", p->name, ps->version); + log("%s: Bad packet received: version %u", p->name, ps->version); log("%s: Discarding",p->name); return(1); } @@ -317,9 +456,9 @@ ospf_rx_hook(sock *sk, int size) /* Dump packet */ pu8=(u8 *)(sk->rbuf+5*4); for(i=0;i<ntohs(ps->length);i+=4) - debug("%s: received %d,%d,%d,%d\n",p->name, pu8[i+0], pu8[i+1], pu8[i+2], + debug("%s: received %u,%u,%u,%u\n",p->name, pu8[i+0], pu8[i+1], pu8[i+2], pu8[i+3]); - debug("%s: received size: %d\n",p->name,size); + debug("%s: received size: %u\n",p->name,size); switch(ps->type) { @@ -337,7 +476,7 @@ ospf_rx_hook(sock *sk, int size) case LSACK: break; default: - log("%s: Bad packet received: wrong type %d", p->name, ps->type); + log("%s: Bad packet received: wrong type %u", p->name, ps->type); log("%s: Discarding",p->name); return(1); }; @@ -537,32 +676,8 @@ wait_timer_hook(timer *timer) p=(struct proto *)(ifa->proto); debug("%s: Wait timer fired on interface %s.\n", p->name, ifa->iface->name); - if(ifa->state=OSPF_IS_WAITING) - { - /* - * Wait time fired. Now we must change state - * to DR or DROTHER depending on priority - * FIXME: I can be also BDR - */ - if(ifa->priority!=0) - { - debug("%s: Changing state into DR.\n", p->name); - - ifa->state=OSPF_IS_DR; - ifa->drip=ifa->iface->addr->ip; - ifa->drid=p->cf->global->router_id; - /* FIXME: Set ifa->drid */ - } - else - { - debug("%s: Changing state into DROTHER.\n",p->name); - ifa->state=OSPF_IS_DROTHER; - } - } - else - { - die("%s: Wait timer fired I'm not in WAITING state?", p->name); - } + if(ifa->state=OSPF_IS_WAITING) backupseen(ifa); + else die("%s: Wait timer fired I'm not in WAITING state?", p->name); } void @@ -579,7 +694,7 @@ ospf_add_timers(struct ospf_iface *ifa, pool *pool, int wait) ifa->hello_timer->hook=hello_timer_hook; ifa->hello_timer->recurrent=ifa->helloint; tm_start(ifa->hello_timer,ifa->helloint); - DBG("%s: Installing hello timer. (%d)\n", p->name, ifa->helloint); + DBG("%s: Installing hello timer. (%u)\n", p->name, ifa->helloint); if((ifa->type!=OSPF_IT_PTP)) { /* Install wait timer on NOT-PtP interfaces */ @@ -590,7 +705,7 @@ ospf_add_timers(struct ospf_iface *ifa, pool *pool, int wait) ifa->wait_timer->recurrent=0; ifa->state=OSPF_IS_WAITING; tm_start(ifa->wait_timer,(wait!=0 ? wait : WAIT_DMH*ifa->helloint)); - DBG("%s: Installing wait timer. (%d)\n", p->name, (wait!=0 ? wait : WAIT_DMH*ifa->helloint)); + DBG("%s: Installing wait timer. (%u)\n", p->name, (wait!=0 ? wait : WAIT_DMH*ifa->helloint)); } else ifa->state=OSPF_IS_PTP; } @@ -712,7 +827,7 @@ ospf_dump(struct proto *p) DBG(p->name); DBG(": Dump.\n"); - debug(" -AreaID: %d\n", c->area ); + debug(" -AreaID: %u\n", c->area ); } static struct proto * diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 164bed3..ca563a4 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -110,6 +110,7 @@ struct ospf_hello_packet { struct ospf_neighbor { + node n; struct ospf_iface *ifa; int state; #define NEIGHBOR_DOWN 0 |