0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 09:41:54 +00:00

(Backup) Designated Router election added.

This commit is contained in:
Ondrej Filip 1999-08-09 17:58:01 +00:00
parent 8c51f96acf
commit e83dc0d7e7
2 changed files with 165 additions and 49 deletions

View File

@ -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)
{
; /* Backup Seen Event *
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)
{
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 *

View File

@ -110,6 +110,7 @@ struct ospf_hello_packet {
struct ospf_neighbor
{
node n;
struct ospf_iface *ifa;
int state;
#define NEIGHBOR_DOWN 0