Huge changes. Neighbor and interface state machines rewritten.
It should be cleaner now, I'm preparing for file splitting. Maybe I added some minor bugs. :-(
This commit is contained in:
parent
f942a589ef
commit
96f1b8ba10
2 changed files with 348 additions and 96 deletions
|
@ -255,16 +255,195 @@ electdr(list nl)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
backupseen(struct ospf_iface *ifa)
|
install_inactim(struct ospf_neighbor *n)
|
||||||
{
|
{
|
||||||
struct proto *p;
|
struct proto *p;
|
||||||
struct ospf_neighbor *neigh,*ndr,*nbdr,me;
|
struct ospf_iface *ifa;
|
||||||
u32 myid;
|
|
||||||
|
|
||||||
|
ifa=n->ifa;
|
||||||
p=(struct proto *)(ifa->proto);
|
p=(struct proto *)(ifa->proto);
|
||||||
|
|
||||||
tm_stop(ifa->wait_timer);
|
if(n->inactim==NULL)
|
||||||
DBG("%s: Stoping wait timer\n",p->name);
|
{
|
||||||
|
n->inactim=tm_new(p->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_waittim(struct ospf_iface *ifa)
|
||||||
|
{
|
||||||
|
tm_start(ifa->wait_timer,ifa->waitint);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
can_do_adj(struct ospf_neighbor *n)
|
||||||
|
{
|
||||||
|
struct ospf_iface *ifa;
|
||||||
|
struct proto *p;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ifa=n->ifa;
|
||||||
|
p=(struct proto *)(ifa->proto);
|
||||||
|
i=0;
|
||||||
|
|
||||||
|
switch(ifa->type)
|
||||||
|
{
|
||||||
|
case OSPF_IT_PTP:
|
||||||
|
case OSPF_IT_VLINK:
|
||||||
|
i=1;
|
||||||
|
break;
|
||||||
|
case OSPF_IT_BCAST:
|
||||||
|
case OSPF_IT_NBMA:
|
||||||
|
switch(ifa->state)
|
||||||
|
{
|
||||||
|
case OSPF_IS_DOWN:
|
||||||
|
die("%s: Iface %s in down state?", p->name, ifa->iface->name);
|
||||||
|
break;
|
||||||
|
case OSPF_IS_WAITING:
|
||||||
|
DBG("%s: Neighbor? on iface %s\n",p->name, ifa->iface->name);
|
||||||
|
break;
|
||||||
|
case OSPF_IS_DROTHER:
|
||||||
|
if(((n->rid==ifa->drid) || (n->rid==ifa->bdrid))
|
||||||
|
&& (n->state==NEIGHBOR_2WAY)) i=1;
|
||||||
|
break;
|
||||||
|
case OSPF_IS_PTP:
|
||||||
|
case OSPF_IS_BACKUP:
|
||||||
|
case OSPF_IS_DR:
|
||||||
|
if(n->state==NEIGHBOR_2WAY) i=1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
die("%s: Iface %s in unknown state?",p->name, ifa->iface->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
die("%s: Iface %s is unknown type?",p->name, ifa->iface->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DBG("%s: Iface %s can_do_adj=%d\n",p->name, ifa->iface->name,i);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ospf_neigh_sm(struct ospf_neighbor *n, int event)
|
||||||
|
/* Interface state machine */
|
||||||
|
{
|
||||||
|
struct proto *p;
|
||||||
|
|
||||||
|
p=(struct proto *)(n->ifa->proto);
|
||||||
|
|
||||||
|
switch(event)
|
||||||
|
{
|
||||||
|
case INM_START:
|
||||||
|
neigh_chstate(n,NEIGHBOR_ATTEMPT);
|
||||||
|
/* FIXME No NBMA now */
|
||||||
|
break;
|
||||||
|
case INM_HELLOREC:
|
||||||
|
switch(n->state)
|
||||||
|
{
|
||||||
|
case NEIGHBOR_ATTEMPT:
|
||||||
|
case NEIGHBOR_DOWN:
|
||||||
|
neigh_chstate(n,NEIGHBOR_INIT);
|
||||||
|
default:
|
||||||
|
restart_inactim(n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case INM_2WAYREC:
|
||||||
|
if(n->state==NEIGHBOR_INIT)
|
||||||
|
{
|
||||||
|
/* Can In build adjacency? */
|
||||||
|
neigh_chstate(n,NEIGHBOR_2WAY);
|
||||||
|
if(can_do_adj(n))
|
||||||
|
{
|
||||||
|
neigh_chstate(n,NEIGHBOR_EXSTART);
|
||||||
|
tryadj(n,p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case INM_NEGDONE:
|
||||||
|
if(n->state==NEIGHBOR_EXSTART)
|
||||||
|
{
|
||||||
|
neigh_chstate(n,NEIGHBOR_EXCHANGE);
|
||||||
|
/* FIXME Go on... */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case INM_EXDONE:
|
||||||
|
break;
|
||||||
|
case INM_LOADDONE:
|
||||||
|
break;
|
||||||
|
case INM_ADJOK:
|
||||||
|
switch(n->state)
|
||||||
|
{
|
||||||
|
case NEIGHBOR_2WAY:
|
||||||
|
/* Can In build adjacency? */
|
||||||
|
if(can_do_adj(n))
|
||||||
|
{
|
||||||
|
neigh_chstate(n,NEIGHBOR_EXSTART);
|
||||||
|
tryadj(n,p);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if(n->state>=NEIGHBOR_EXSTART)
|
||||||
|
if(!can_do_adj(n))
|
||||||
|
{
|
||||||
|
neigh_chstate(n,NEIGHBOR_2WAY);
|
||||||
|
/* FIXME Stop timers, kill database... */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case INM_SEQMIS:
|
||||||
|
case INM_BADLSREQ:
|
||||||
|
if(n->state>=NEIGHBOR_EXCHANGE)
|
||||||
|
{
|
||||||
|
neigh_chstate(n,NEIGHBOR_EXSTART);
|
||||||
|
/* Go on....*/
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case INM_KILLNBR:
|
||||||
|
case INM_LLDOWN:
|
||||||
|
case INM_INACTTIM:
|
||||||
|
neigh_chstate(n,NEIGHBOR_DOWN);
|
||||||
|
break;
|
||||||
|
case INM_1WAYREC:
|
||||||
|
if(n->state>=NEIGHBOR_2WAY)
|
||||||
|
{
|
||||||
|
neigh_chstate(n,NEIGHBOR_DOWN);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
die("%s: INM - Unknown event?",p->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
bdr_election(struct ospf_iface *ifa, struct proto *p)
|
||||||
|
{
|
||||||
|
struct ospf_neighbor *neigh,*ndr,*nbdr,me;
|
||||||
|
u32 myid, ndrid, nbdrid;
|
||||||
|
int doadj;
|
||||||
|
|
||||||
|
p=(struct proto *)(ifa->proto);
|
||||||
|
|
||||||
DBG("%s: (B)DR election.\n",p->name);
|
DBG("%s: (B)DR election.\n",p->name);
|
||||||
|
|
||||||
|
@ -297,11 +476,18 @@ backupseen(struct ospf_iface *ifa)
|
||||||
nbdr=electbdr(ifa->neigh_list);
|
nbdr=electbdr(ifa->neigh_list);
|
||||||
ndr=electdr(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;
|
if(ndr==NULL) ifa->drid=0;
|
||||||
else ifa->bdrid=me.bdr=nbdr->rid;
|
if(ndr==NULL) ndrid=0;
|
||||||
|
else ndrid=ndr->rid;
|
||||||
|
|
||||||
|
if(nbdr==NULL) nbdrid=0;
|
||||||
|
else nbdrid=nbdr->rid;
|
||||||
|
|
||||||
|
doadj=0;
|
||||||
|
if((ifa->drid!=ndrid) || (ifa->bdrid!=nbdrid)) doadj=1;
|
||||||
|
ifa->drid=ndrid;
|
||||||
|
ifa->bdrid=nbdrid;
|
||||||
|
|
||||||
DBG("%s: DR=%u, BDR=%u\n",p->name, ifa->drid, ifa->bdrid);
|
DBG("%s: DR=%u, BDR=%u\n",p->name, ifa->drid, ifa->bdrid);
|
||||||
|
|
||||||
|
@ -313,6 +499,85 @@ backupseen(struct ospf_iface *ifa)
|
||||||
}
|
}
|
||||||
|
|
||||||
rem_node(NODE &me);
|
rem_node(NODE &me);
|
||||||
|
|
||||||
|
if(doadj)
|
||||||
|
{
|
||||||
|
WALK_LIST (neigh, ifa->neigh_list)
|
||||||
|
{
|
||||||
|
ospf_neigh_sm(neigh, INM_ADJOK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
downint(struct ospf_iface *ifa)
|
||||||
|
{
|
||||||
|
/* FIXME: Delete all neighbors! */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ospf_int_sm(struct ospf_iface *ifa, int event)
|
||||||
|
{
|
||||||
|
struct proto *p;
|
||||||
|
|
||||||
|
p=(struct proto *)(ifa->proto);
|
||||||
|
|
||||||
|
DBG("%s: SM on iface %s. Event is %d.\n",
|
||||||
|
p->name, ifa->iface->name, event);
|
||||||
|
|
||||||
|
switch(event)
|
||||||
|
{
|
||||||
|
case ISM_UP:
|
||||||
|
if(ifa->state==OSPF_IS_DOWN)
|
||||||
|
{
|
||||||
|
restart_hellotim(ifa);
|
||||||
|
if((ifa->type==OSPF_IT_PTP) || (ifa->type==OSPF_IT_VLINK))
|
||||||
|
{
|
||||||
|
iface_chstate(ifa, OSPF_IS_PTP);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(ifa->priority==0)
|
||||||
|
{
|
||||||
|
iface_chstate(ifa, OSPF_IS_DROTHER);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iface_chstate(ifa, OSPF_IS_WAITING);
|
||||||
|
restart_waittim(ifa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ISM_BACKS:
|
||||||
|
case ISM_WAITF:
|
||||||
|
if(ifa->state==OSPF_IS_WAITING)
|
||||||
|
{
|
||||||
|
bdr_election(ifa ,p);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ISM_NEICH:
|
||||||
|
if((ifa->state==OSPF_IS_DROTHER) || (ifa->state==OSPF_IS_DR) ||
|
||||||
|
(ifa->state==OSPF_IS_BACKUP))
|
||||||
|
{
|
||||||
|
bdr_election(ifa ,p);
|
||||||
|
}
|
||||||
|
case ISM_DOWN:
|
||||||
|
iface_chstate(ifa, OSPF_IS_DOWN);
|
||||||
|
downint(ifa);
|
||||||
|
break;
|
||||||
|
case ISM_LOOP: /* Useless? */
|
||||||
|
iface_chstate(ifa, OSPF_IS_LOOP);
|
||||||
|
downint(ifa);
|
||||||
|
break;
|
||||||
|
case ISM_UNLOOP:
|
||||||
|
iface_chstate(ifa, OSPF_IS_DOWN);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
die("%s: ISM - Unknown event?",p->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -364,12 +629,6 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p,
|
||||||
log("%s: New neighbor found: %u.", p->name,nrid);
|
log("%s: New neighbor found: %u.", p->name,nrid);
|
||||||
n=mb_alloc(p->pool, sizeof(struct ospf_neighbor));
|
n=mb_alloc(p->pool, sizeof(struct ospf_neighbor));
|
||||||
add_tail(&ifa->neigh_list, NODE n);
|
add_tail(&ifa->neigh_list, NODE n);
|
||||||
n->inactim=tm_new(p->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->rid=nrid;
|
n->rid=nrid;
|
||||||
n->dr=ntohl(ps->dr);
|
n->dr=ntohl(ps->dr);
|
||||||
n->bdr=ntohl(ps->bdr);
|
n->bdr=ntohl(ps->bdr);
|
||||||
|
@ -377,98 +636,70 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p,
|
||||||
n->options=ps->options;
|
n->options=ps->options;
|
||||||
n->ifa=ifa;
|
n->ifa=ifa;
|
||||||
n->adj=0;
|
n->adj=0;
|
||||||
neigh_chstate(n,NEIGHBOR_INIT);
|
neigh_chstate(n,NEIGHBOR_DOWN);
|
||||||
|
install_inactim(n);
|
||||||
}
|
}
|
||||||
tm_start(n->inactim,ifa->deadc*ifa->helloint);
|
ospf_neigh_sm(n, INM_HELLOREC);
|
||||||
|
|
||||||
twoway=0;
|
|
||||||
pnrid=(u32 *)((struct ospf_hello_packet *)(ps+1));
|
pnrid=(u32 *)((struct ospf_hello_packet *)(ps+1));
|
||||||
|
|
||||||
|
twoway=0;
|
||||||
for(i=0;i<size-(sizeof(struct ospf_hello_packet));i++)
|
for(i=0;i<size-(sizeof(struct ospf_hello_packet));i++)
|
||||||
{
|
{
|
||||||
if(ntohl(*(pnrid+i))==p->cf->global->router_id)
|
if(ntohl(*(pnrid+i))==p->cf->global->router_id)
|
||||||
{
|
{
|
||||||
twoway=1;
|
|
||||||
DBG("%s: Twoway received. %u\n", p->name, nrid);
|
DBG("%s: Twoway received. %u\n", p->name, nrid);
|
||||||
|
ospf_neigh_sm(n, INM_2WAYREC);
|
||||||
|
twoway=1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(twoway)
|
if(!twoway) ospf_neigh_sm(n, INM_1WAYREC);
|
||||||
{
|
|
||||||
if(n->state<NEIGHBOR_2WAY) neigh_chstate(n,NEIGHBOR_2WAY);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(n->state>=NEIGHBOR_2WAY)
|
|
||||||
{
|
|
||||||
/* FIXME Delete all learnt */
|
|
||||||
neigh_chstate(n,NEIGHBOR_INIT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check priority change */
|
/* Check priority change */
|
||||||
if(n->priority!=(n->priority=ps->priority))
|
if(n->priority!=(n->priority=ps->priority))
|
||||||
{
|
{
|
||||||
/* FIXME NeighborChange */;
|
ospf_int_sm(ifa, ISM_NEICH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check neighbor's designed router idea */
|
/* Check neighbor's designed router idea */
|
||||||
if((n->rid!=ntohl(ps->dr)) && (ntohl(ps->bdr)==0) &&
|
if((n->rid!=ntohl(ps->dr)) && (ntohl(ps->bdr)==0) &&
|
||||||
(ifa->state==OSPF_IS_WAITING) && (n->state>=NEIGHBOR_2WAY))
|
(n->state>=NEIGHBOR_2WAY))
|
||||||
{
|
{
|
||||||
backupseen(ifa);
|
ospf_int_sm(ifa, ISM_BACKS);
|
||||||
|
DBG("BACKS");
|
||||||
}
|
}
|
||||||
if((n->rid==ntohl(ps->dr)) && (n->dr!=ntohl(ps->dr)))
|
if((n->rid==ntohl(ps->dr)) && (n->dr!=ntohl(ps->dr)))
|
||||||
{
|
{
|
||||||
/* FIXME NeighborChange */;
|
ospf_int_sm(ifa, ISM_NEICH);
|
||||||
}
|
}
|
||||||
if((n->rid==n->dr) && (n->dr!=ntohl(ps->dr)))
|
if((n->rid==n->dr) && (n->dr!=ntohl(ps->dr)))
|
||||||
{
|
{
|
||||||
/* FIXME NeighborChange */;
|
ospf_int_sm(ifa, ISM_NEICH);
|
||||||
}
|
}
|
||||||
n->dr=ntohl(ps->dr); /* And update it */
|
n->dr=ntohl(ps->dr); /* And update it */
|
||||||
|
|
||||||
/* Check neighbor's backup designed router idea */
|
/* Check neighbor's backup designed router idea */
|
||||||
if((n->rid==ntohl(ps->bdr)) && (ifa->state==OSPF_IS_WAITING)
|
if((n->rid==ntohl(ps->bdr)) && (n->state>=NEIGHBOR_2WAY))
|
||||||
&& (n->state>=NEIGHBOR_2WAY))
|
|
||||||
{
|
{
|
||||||
backupseen(ifa);
|
ospf_int_sm(ifa, ISM_BACKS);
|
||||||
|
DBG("BACKS");
|
||||||
}
|
}
|
||||||
if((n->rid==ntohl(ps->bdr)) && (n->bdr!=ntohl(ps->bdr)))
|
if((n->rid==ntohl(ps->bdr)) && (n->bdr!=ntohl(ps->bdr)))
|
||||||
{
|
{
|
||||||
/* FIXME NeighborChange */;
|
ospf_int_sm(ifa, ISM_NEICH);
|
||||||
}
|
}
|
||||||
if((n->rid==n->bdr) && (n->bdr!=ntohl(ps->bdr)))
|
if((n->rid==n->bdr) && (n->bdr!=ntohl(ps->bdr)))
|
||||||
{
|
{
|
||||||
/* FIXME NeighborChange */;
|
ospf_int_sm(ifa, ISM_NEICH);
|
||||||
}
|
}
|
||||||
n->bdr=ntohl(ps->bdr); /* And update it */
|
n->bdr=ntohl(ps->bdr); /* And update it */
|
||||||
|
|
||||||
|
ospf_neigh_sm(n, INM_HELLOREC);
|
||||||
switch(ifa->state)
|
|
||||||
{
|
|
||||||
case OSPF_IS_DOWN:
|
|
||||||
die("%s: Iface %s in down state?", p->name, ifa->iface->name);
|
|
||||||
break;
|
|
||||||
case OSPF_IS_WAITING:
|
|
||||||
DBG("%s: Neighbor? on iface %s\n",p->name, ifa->iface->name);
|
|
||||||
break;
|
|
||||||
case OSPF_IS_DROTHER:
|
|
||||||
if(((n->rid==ifa->drid) || (n->rid==ifa->bdrid))
|
|
||||||
&& (n->state==NEIGHBOR_2WAY)) tryadj(n,p);
|
|
||||||
break;
|
|
||||||
case OSPF_IS_PTP:
|
|
||||||
case OSPF_IS_BACKUP:
|
|
||||||
case OSPF_IS_DR:
|
|
||||||
if(n->state==NEIGHBOR_2WAY) tryadj(n,p);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
die("%s: Iface %s in unknown state?",p->name, ifa->iface->name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ospf_rx_hook(sock *sk, int size)
|
ospf_rx_hook(sock *sk, int size)
|
||||||
{
|
{
|
||||||
|
@ -697,8 +928,8 @@ ospf_iface_clasify(struct iface *ifa)
|
||||||
if((ifa->flags & (IF_MULTIACCESS|IF_MULTICAST))==
|
if((ifa->flags & (IF_MULTIACCESS|IF_MULTICAST))==
|
||||||
(IF_MULTIACCESS|IF_MULTICAST))
|
(IF_MULTIACCESS|IF_MULTICAST))
|
||||||
{
|
{
|
||||||
DBG(" OSPF: Clasifying BROADCAST.\n");
|
DBG(" OSPF: Clasifying BCAST.\n");
|
||||||
return OSPF_IT_BROADCAST;
|
return OSPF_IT_BCAST;
|
||||||
}
|
}
|
||||||
if((ifa->flags & (IF_MULTIACCESS|IF_MULTICAST))==
|
if((ifa->flags & (IF_MULTIACCESS|IF_MULTICAST))==
|
||||||
IF_MULTIACCESS)
|
IF_MULTIACCESS)
|
||||||
|
@ -799,12 +1030,11 @@ wait_timer_hook(timer *timer)
|
||||||
p=(struct proto *)(ifa->proto);
|
p=(struct proto *)(ifa->proto);
|
||||||
debug("%s: Wait timer fired on interface %s.\n",
|
debug("%s: Wait timer fired on interface %s.\n",
|
||||||
p->name, ifa->iface->name);
|
p->name, ifa->iface->name);
|
||||||
if(ifa->state=OSPF_IS_WAITING) backupseen(ifa);
|
ospf_int_sm(ifa, ISM_WAITF);
|
||||||
else die("%s: Wait timer fired I'm not in WAITING state?", p->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ospf_add_timers(struct ospf_iface *ifa, pool *pool, u16 wait)
|
ospf_add_timers(struct ospf_iface *ifa, pool *pool)
|
||||||
{
|
{
|
||||||
struct proto *p;
|
struct proto *p;
|
||||||
|
|
||||||
|
@ -816,7 +1046,7 @@ ospf_add_timers(struct ospf_iface *ifa, pool *pool, u16 wait)
|
||||||
if(ifa->helloint==0) ifa->helloint=HELLOINT_D;
|
if(ifa->helloint==0) ifa->helloint=HELLOINT_D;
|
||||||
ifa->hello_timer->hook=hello_timer_hook;
|
ifa->hello_timer->hook=hello_timer_hook;
|
||||||
ifa->hello_timer->recurrent=ifa->helloint;
|
ifa->hello_timer->recurrent=ifa->helloint;
|
||||||
tm_start(ifa->hello_timer,ifa->helloint);
|
DBG("%s: Installing hello timer. (%u)\n", p->name, ifa->helloint);
|
||||||
|
|
||||||
ifa->rxmt_timer=tm_new(pool);
|
ifa->rxmt_timer=tm_new(pool);
|
||||||
ifa->rxmt_timer->data=ifa;
|
ifa->rxmt_timer->data=ifa;
|
||||||
|
@ -824,21 +1054,15 @@ ospf_add_timers(struct ospf_iface *ifa, pool *pool, u16 wait)
|
||||||
if(ifa->rxmtint==0) ifa->rxmtint=RXMTINT_D;
|
if(ifa->rxmtint==0) ifa->rxmtint=RXMTINT_D;
|
||||||
ifa->rxmt_timer->hook=rxmt_timer_hook;
|
ifa->rxmt_timer->hook=rxmt_timer_hook;
|
||||||
ifa->rxmt_timer->recurrent=ifa->rxmtint;
|
ifa->rxmt_timer->recurrent=ifa->rxmtint;
|
||||||
|
DBG("%s: Installing rxmt timer. (%u)\n", p->name, ifa->rxmtint);
|
||||||
|
|
||||||
DBG("%s: Installing hello timer. (%u)\n", p->name, ifa->helloint);
|
|
||||||
if((ifa->type!=OSPF_IT_PTP))
|
|
||||||
{
|
|
||||||
/* Install wait timer on NOT-PtP interfaces */
|
|
||||||
ifa->wait_timer=tm_new(pool);
|
ifa->wait_timer=tm_new(pool);
|
||||||
ifa->wait_timer->data=ifa;
|
ifa->wait_timer->data=ifa;
|
||||||
ifa->wait_timer->randomize=0;
|
ifa->wait_timer->randomize=0;
|
||||||
ifa->wait_timer->hook=wait_timer_hook;
|
ifa->wait_timer->hook=wait_timer_hook;
|
||||||
ifa->wait_timer->recurrent=0;
|
ifa->wait_timer->recurrent=0;
|
||||||
ifa->state=OSPF_IS_WAITING;
|
if(ifa->waitint==0) ifa->waitint= WAIT_DMH*ifa->helloint;
|
||||||
tm_start(ifa->wait_timer,(wait!=0 ? wait : WAIT_DMH*ifa->helloint));
|
DBG("%s: Installing wait timer. (%u)\n", p->name, ifa->waitint);
|
||||||
DBG("%s: Installing wait timer. (%u)\n", p->name, (wait!=0 ? wait : WAIT_DMH*ifa->helloint));
|
|
||||||
}
|
|
||||||
else ifa->state=OSPF_IS_PTP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -917,11 +1141,12 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface)
|
||||||
|
|
||||||
init_list(&(ifa->neigh_list));
|
init_list(&(ifa->neigh_list));
|
||||||
}
|
}
|
||||||
/* FIXME: NBMA? */
|
|
||||||
/* FIXME: This should read config */
|
/* FIXME: This should read config */
|
||||||
ifa->helloint=0;
|
ifa->helloint=0;
|
||||||
ospf_add_timers(ifa,p->pool,0);
|
ifa->waitint=0;
|
||||||
|
ospf_add_timers(ifa,p->pool);
|
||||||
add_tail(&((struct proto_ospf *)p)->iface_list, NODE ifa);
|
add_tail(&((struct proto_ospf *)p)->iface_list, NODE ifa);
|
||||||
|
ospf_int_sm(ifa, ISM_UP);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(flags & IF_CHANGE_DOWN)
|
if(flags & IF_CHANGE_DOWN)
|
||||||
|
@ -929,7 +1154,7 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface)
|
||||||
if((ifa=find_iface((struct proto_ospf *)p, iface))!=NULL)
|
if((ifa=find_iface((struct proto_ospf *)p, iface))!=NULL)
|
||||||
{
|
{
|
||||||
debug(" OSPF: killing interface %s.\n", iface->name);
|
debug(" OSPF: killing interface %s.\n", iface->name);
|
||||||
/* FIXME: This should delete ifaces */
|
ospf_int_sm(ifa, ISM_DOWN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ struct ospf_iface {
|
||||||
interface. LSAs contained in the update */
|
interface. LSAs contained in the update */
|
||||||
u8 priority; /* A router priority for DR election */
|
u8 priority; /* A router priority for DR election */
|
||||||
u16 helloint; /* number of seconds between hello sending */
|
u16 helloint; /* number of seconds between hello sending */
|
||||||
|
u16 waitint; /* number of sec before changing state from wait */
|
||||||
u32 deadc; /* after "deadint" missing hellos is router dead */
|
u32 deadc; /* after "deadint" missing hellos is router dead */
|
||||||
u16 autype;
|
u16 autype;
|
||||||
u8 aukey[8];
|
u8 aukey[8];
|
||||||
|
@ -53,16 +54,18 @@ struct ospf_iface {
|
||||||
ip_addr bdrip; /* Backup DR */
|
ip_addr bdrip; /* Backup DR */
|
||||||
u32 bdrid;
|
u32 bdrid;
|
||||||
u8 type; /* OSPF view of type */
|
u8 type; /* OSPF view of type */
|
||||||
#define OSPF_IT_BROADCAST 0
|
#define OSPF_IT_BCAST 0
|
||||||
#define OSPF_IT_NBMA 1
|
#define OSPF_IT_NBMA 1
|
||||||
#define OSPF_IT_PTP 2
|
#define OSPF_IT_PTP 2
|
||||||
|
#define OSPF_IT_VLINK 3
|
||||||
u8 state; /* Interface state machine */
|
u8 state; /* Interface state machine */
|
||||||
#define OSPF_IS_DOWN 0 /* Should never happen */
|
#define OSPF_IS_DOWN 0 /* Not working */
|
||||||
#define OSPF_IS_WAITING 1 /* Waiting for Wait timer */
|
#define OSPF_IS_LOOP 1 /* Should never happen */
|
||||||
#define OSPF_IS_PTP 2 /* PTP operational */
|
#define OSPF_IS_WAITING 2 /* Waiting for Wait timer */
|
||||||
#define OSPF_IS_DROTHER 3 /* I'm on BCAST or NBMA and I'm not DR */
|
#define OSPF_IS_PTP 3 /* PTP operational */
|
||||||
#define OSPF_IS_BACKUP 4 /* I'm BDR */
|
#define OSPF_IS_DROTHER 4 /* I'm on BCAST or NBMA and I'm not DR */
|
||||||
#define OSPF_IS_DR 5 /* I'm DR */
|
#define OSPF_IS_BACKUP 5 /* I'm BDR */
|
||||||
|
#define OSPF_IS_DR 6 /* I'm DR */
|
||||||
timer *wait_timer; /* WAIT timer */
|
timer *wait_timer; /* WAIT timer */
|
||||||
timer *hello_timer; /* HELLOINT timer */
|
timer *hello_timer; /* HELLOINT timer */
|
||||||
timer *rxmt_timer; /* RXMT timer */
|
timer *rxmt_timer; /* RXMT timer */
|
||||||
|
@ -73,8 +76,8 @@ struct ospf_iface {
|
||||||
#define PRIORITY_D 1
|
#define PRIORITY_D 1
|
||||||
#define HELLOINT_D 10
|
#define HELLOINT_D 10
|
||||||
#define DEADC_D 4
|
#define DEADC_D 4
|
||||||
#define WAIT_DMH 2 /* Value of Wait timer - not found it in RFC
|
#define WAIT_DMH 3 /* Value of Wait timer - not found it in RFC
|
||||||
* - using 2*HELLO
|
* - using 3*HELLO
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -161,4 +164,28 @@ struct ospf_neighbor
|
||||||
u8 adj; /* built adjacency? */
|
u8 adj; /* built adjacency? */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Definitions for interface state machine */
|
||||||
|
#define ISM_UP 0 /* Interface Up */
|
||||||
|
#define ISM_WAITF 1 /* Wait timer fired */
|
||||||
|
#define ISM_BACKS 2 /* Backup seen */
|
||||||
|
#define ISM_NEICH 3 /* Neighbor change */
|
||||||
|
#define ISM_LOOP 4 /* Loop indicated */
|
||||||
|
#define ISM_UNLOOP 5 /* Unloop indicated */
|
||||||
|
#define ISM_DOWN 6 /* Interface down */
|
||||||
|
|
||||||
|
/* Definitions for neighbor state machine */
|
||||||
|
#define INM_HELLOREC 0 /* Hello Received */
|
||||||
|
#define INM_START 1 /* Neighbor start - for NBMA */
|
||||||
|
#define INM_2WAYREC 2 /* 2-Way received */
|
||||||
|
#define INM_NEGDONE 3 /* Negotiation done */
|
||||||
|
#define INM_EXDONE 4 /* Exchange done */
|
||||||
|
#define INM_BADLSREQ 5 /* Bad LS Request */
|
||||||
|
#define INM_LOADDONE 6 /* Load done */
|
||||||
|
#define INM_ADJOK 7 /* AdjOK? */
|
||||||
|
#define INM_SEQMIS 8 /* Sequence number mismatch */
|
||||||
|
#define INM_1WAYREC 9 /* 1-Way */
|
||||||
|
#define INM_KILLNBR 10 /* Kill Neigbor */
|
||||||
|
#define INM_INACTTIM 11 /* Inactivity timer */
|
||||||
|
#define INM_LLDOWN 12 /* Line down */
|
||||||
|
|
||||||
#endif /* _BIRD_OSPF_H_ */
|
#endif /* _BIRD_OSPF_H_ */
|
||||||
|
|
Loading…
Reference in a new issue