DD packet receiving in ExStart.

This commit is contained in:
Ondrej Filip 1999-08-25 18:44:50 +00:00
parent 1af664158d
commit 2c1d1cc765
2 changed files with 150 additions and 39 deletions

View file

@ -24,7 +24,30 @@
#include "ospf.h" #include "ospf.h"
void void
neigh_chstate(struct ospf_neighbor *n, int state) rxmt_timer_hook(timer *timer)
{
struct ospf_iface *ifa;
struct proto *p;
ifa=(struct ospf_iface *)timer->data;
p=(struct proto *)(ifa->proto);
debug("%s: RXMT timer fired on interface %s.\n",
p->name, ifa->iface->name);
}
struct ospf_neighbor *
find_neigh(struct ospf_iface *ifa, u32 rid)
{
struct ospf_neighbor *n;
WALK_LIST (n, ifa->neigh_list)
if(n->rid == rid)
return n;
return NULL;
}
void
neigh_chstate(struct ospf_neighbor *n, u8 state)
{ {
struct ospf_iface *ifa; struct ospf_iface *ifa;
struct proto *p; struct proto *p;
@ -37,6 +60,79 @@ neigh_chstate(struct ospf_neighbor *n, int state)
n->state=state; n->state=state;
} }
void
ospf_dbdes_rx(struct ospf_dbdes_packet *ps, struct proto *p,
struct ospf_iface *ifa, u16 size)
{
u32 nrid, myrid;
struct ospf_neighbor *n;
u8 i;
nrid=ntohl(((struct ospf_packet *)ps)->routerid);
myrid=p->cf->global->router_id;
if((n=find_neigh(ifa, nrid))==NULL)
{
debug("%s: Received dbdes from unknown neigbor! (%u)\n", p->name,
nrid);
return ;
}
/* FIXME: Now, I should test MTU */
switch(n->state)
{
case NEIGHBOR_DOWN:
case NEIGHBOR_ATTEMPT:
case NEIGHBOR_2WAY:
debug("%s: Received dbdes from %u in bad state. (%u)\n", p->name, nrid);
return;
break;
case NEIGHBOR_INIT:
/*
* RFC2328 says, that I sould start SM with 2-Way received.
* It's to complicated right now. So I'll rather ignore it and
* wait for a hello packet. FIXME
*/
return;
break;
case NEIGHBOR_EXSTART:
if(size!=sizeof(struct ospf_dbdes_packet))
{
debug("%s: Received bas dbdes from %u in exstart state.\n",
p->name, nrid);
return;
}
if(ps->imms==(DBDES_I|DBDES_M|DBDES_MS) && n->rid > myrid)
{
/* I'm slave! */
n->dds=ps->ddseq;
n->options=ps->options;
n->myimms=(n->myimms && DBDES_M);
debug("%s: I'm slave to %u. \n", p->name, nrid);
/* FIXME Negotiation done */
}
if(((ps->imms | DBDES_M)== DBDES_M) && (n->rid < myrid) &&
(n->dds == ps->ddseq))
{
/* I'm master! */
n->options=ps->options;
debug("%s: I'm master to %u. \n", p->name, nrid);
/* FIXME Negotiation done */
}
break;
case NEIGHBOR_EXCHANGE:
break;
case NEIGHBOR_LOADING:
case NEIGHBOR_FULL:
break;
}
n->ddr=ps->ddseq;
n->imms=ps->imms;
}
/* Try to build neighbor adjacency (if does not exists) */ /* Try to build neighbor adjacency (if does not exists) */
void void
@ -46,11 +142,11 @@ tryadj(struct ospf_neighbor *n, struct proto *p)
neigh_chstate(n,NEIGHBOR_EXSTART); neigh_chstate(n,NEIGHBOR_EXSTART);
if(n->adj==0) /* First time adjacency */ if(n->adj==0) /* First time adjacency */
{ {
n->dds=random_u32; n->dds=random_u32();
} }
n->dds++; n->dds++;
n->ms=NEIGHBOR_MASTER; n->myimms=(DBDES_MS | DBDES_M|DBDES_I );
/* FIXME Go on, start to send DD packets */ tm_start(n->ifa->rxmt_timer,1); /* Or some other number ? */
} }
/* Neighbor is inactive for a long time. Remove it. */ /* Neighbor is inactive for a long time. Remove it. */
@ -226,11 +322,11 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p,
char sip[100]; /* FIXME: Should be smaller */ char sip[100]; /* FIXME: Should be smaller */
u32 nrid, *pnrid; u32 nrid, *pnrid;
struct ospf_neighbor *neigh,*n; struct ospf_neighbor *neigh,*n;
int i,twoway; u8 i,twoway;
nrid=ntohl(((struct ospf_packet *)ps)->routerid); nrid=ntohl(((struct ospf_packet *)ps)->routerid);
if(ipa_mklen(ipa_ntoh(ps->netmask))!=ifa->iface->addr->pxlen) if((unsigned)ipa_mklen(ipa_ntoh(ps->netmask))!=ifa->iface->addr->pxlen)
{ {
ip_ntop(ps->netmask,sip); ip_ntop(ps->netmask,sip);
log("%s: Bad OSPF packet from %u received: bad netmask %s.", log("%s: Bad OSPF packet from %u received: bad netmask %s.",
@ -263,17 +359,7 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p,
return; return;
} }
n=NULL; if((n=find_neigh(ifa, nrid))==NULL)
WALK_LIST (neigh, ifa->neigh_list)
{
if(neigh->rid==nrid)
{
n=neigh;
break;
}
}
if(n==NULL)
{ {
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));
@ -390,7 +476,7 @@ ospf_rx_hook(sock *sk, int size)
struct ospf_packet *ps; struct ospf_packet *ps;
struct ospf_iface *ifa; struct ospf_iface *ifa;
struct proto *p; struct proto *p;
int i; u8 i;
u8 *pu8; u8 *pu8;
@ -407,7 +493,7 @@ ospf_rx_hook(sock *sk, int size)
return(1); return(1);
} }
if(size < sizeof(struct ospf_packet)) if((unsigned)size < sizeof(struct ospf_packet))
{ {
log("%s: Bad OSPF packet received: too short (%u bytes)", p->name, size); log("%s: Bad OSPF packet received: too short (%u bytes)", p->name, size);
log("%s: Discarding",p->name); log("%s: Discarding",p->name);
@ -474,6 +560,7 @@ ospf_rx_hook(sock *sk, int size)
break; break;
case DBDES: case DBDES:
DBG("%s: Database description received.\n", p->name); DBG("%s: Database description received.\n", p->name);
ospf_dbdes_rx((struct ospf_dbdes_packet *)ps, p, ifa, size);
break; break;
case LSREQ: case LSREQ:
DBG("%s: Link state request received.\n", p->name); DBG("%s: Link state request received.\n", p->name);
@ -592,7 +679,7 @@ ospf_open_ip_socket(struct ospf_iface *ifa)
* This will later decide, wheter use iface for OSPF or not * This will later decide, wheter use iface for OSPF or not
* depending on config * depending on config
*/ */
int u8
is_good_iface(struct proto *p, struct iface *iface) is_good_iface(struct proto *p, struct iface *iface)
{ {
if(iface->flags & IF_UP) if(iface->flags & IF_UP)
@ -603,7 +690,7 @@ is_good_iface(struct proto *p, struct iface *iface)
} }
/* Of course, it's NOT true now */ /* Of course, it's NOT true now */
int u8
ospf_iface_clasify(struct iface *ifa) ospf_iface_clasify(struct iface *ifa)
{ {
/* FIXME: Latter I'll use config - this is incorrect */ /* FIXME: Latter I'll use config - this is incorrect */
@ -653,7 +740,7 @@ hello_timer_hook(timer *timer)
struct ospf_neighbor *neigh; struct ospf_neighbor *neigh;
u16 length; u16 length;
u32 *pp; u32 *pp;
int i; u8 i;
ifa=(struct ospf_iface *)timer->data; ifa=(struct ospf_iface *)timer->data;
p=(struct proto *)(ifa->proto); p=(struct proto *)(ifa->proto);
@ -680,7 +767,7 @@ hello_timer_hook(timer *timer)
/* Fill all neighbors */ /* Fill all neighbors */
i=0; i=0;
pp=(u32 *)(((byte *)pkt)+sizeof(struct ospf_hello_packet)); pp=(u32 *)(((u8 *)pkt)+sizeof(struct ospf_hello_packet));
WALK_LIST (neigh, ifa->neigh_list) WALK_LIST (neigh, ifa->neigh_list)
{ {
*(pp+i)=htonl(neigh->rid); *(pp+i)=htonl(neigh->rid);
@ -717,7 +804,7 @@ wait_timer_hook(timer *timer)
} }
void void
ospf_add_timers(struct ospf_iface *ifa, pool *pool, int wait) ospf_add_timers(struct ospf_iface *ifa, pool *pool, u16 wait)
{ {
struct proto *p; struct proto *p;
@ -730,6 +817,14 @@ ospf_add_timers(struct ospf_iface *ifa, pool *pool, int wait)
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); tm_start(ifa->hello_timer,ifa->helloint);
ifa->rxmt_timer=tm_new(pool);
ifa->rxmt_timer->data=ifa;
ifa->rxmt_timer->randomize=0;
if(ifa->rxmtint==0) ifa->rxmtint=RXMTINT_D;
ifa->rxmt_timer->hook=rxmt_timer_hook;
ifa->rxmt_timer->recurrent=ifa->rxmtint;
DBG("%s: Installing hello timer. (%u)\n", p->name, ifa->helloint); DBG("%s: Installing hello timer. (%u)\n", p->name, ifa->helloint);
if((ifa->type!=OSPF_IT_PTP)) if((ifa->type!=OSPF_IT_PTP))
{ {
@ -749,7 +844,7 @@ ospf_add_timers(struct ospf_iface *ifa, pool *pool, int wait)
void void
ospf_iface_default(struct ospf_iface *ifa) ospf_iface_default(struct ospf_iface *ifa)
{ {
int i; u8 i;
ifa->area=0; /* FIXME: Read from config */ ifa->area=0; /* FIXME: Read from config */
ifa->cost=COST_D; ifa->cost=COST_D;

View file

@ -38,8 +38,8 @@ struct ospf_iface {
list neigh_list; /* List of neigbours */ list neigh_list; /* List of neigbours */
u32 area; /* OSPF Area */ u32 area; /* OSPF Area */
u16 cost; /* Cost of iface */ u16 cost; /* Cost of iface */
int rxmtint; /* number of seconds between LSA retransmissions */ u16 rxmtint; /* number of seconds between LSA retransmissions */
int iftransdelay; /* The estimated number of seconds it takes to u16 iftransdelay; /* The estimated number of seconds it takes to
transmit a Link State Update Packet over this transmit a Link State Update Packet over this
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 */
@ -52,11 +52,11 @@ struct ospf_iface {
u32 drid; u32 drid;
ip_addr bdrip; /* Backup DR */ ip_addr bdrip; /* Backup DR */
u32 bdrid; u32 bdrid;
int type; /* OSPF view of type */ u8 type; /* OSPF view of type */
#define OSPF_IT_BROADCAST 0 #define OSPF_IT_BROADCAST 0
#define OSPF_IT_NBMA 1 #define OSPF_IT_NBMA 1
#define OSPF_IT_PTP 2 #define OSPF_IT_PTP 2
int state; /* Interface state machine */ u8 state; /* Interface state machine */
#define OSPF_IS_DOWN 0 /* Should never happen */ #define OSPF_IS_DOWN 0 /* Should never happen */
#define OSPF_IS_WAITING 1 /* Waiting for Wait timer */ #define OSPF_IS_WAITING 1 /* Waiting for Wait timer */
#define OSPF_IS_PTP 2 /* PTP operational */ #define OSPF_IS_PTP 2 /* PTP operational */
@ -65,6 +65,7 @@ struct ospf_iface {
#define OSPF_IS_DR 5 /* I'm DR */ #define OSPF_IS_DR 5 /* 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 */
/* Default values for interface parameters */ /* Default values for interface parameters */
#define COST_D 10 #define COST_D 10
#define RXMTINT_D 5 #define RXMTINT_D 5
@ -81,7 +82,7 @@ struct ospf_patt {
struct iface_patt i; struct iface_patt i;
u16 cost; u16 cost;
byte mode; u8 mode;
}; };
struct ospf_packet { struct ospf_packet {
@ -111,18 +112,34 @@ struct ospf_hello_packet {
u32 bdr; u32 bdr;
}; };
struct ospf_ddseq_packet { struct ospf_dbdes_packet {
struct ospf_packet ospf_packet; struct ospf_packet ospf_packet;
u16 iface_mtu; u16 iface_mtu;
u16 options; u8 options;
u32 ddseq_no; u8 imms; /* I, M, MS bits */
#define DBDES_MS 1
#define DBDES_M 2
#define DBDES_I 4
u32 ddseq;
}; };
struct ospf_lsaheader {
u16 lsage; /* LS Age */
u8 options;
u8 lstype;
u32 lsid;
u32 advr; /* Advertising router */
u32 lssn; /* LS Sequence number */
u16 checksum;
u16 length;
};
struct ospf_neighbor struct ospf_neighbor
{ {
node n; node n;
struct ospf_iface *ifa; struct ospf_iface *ifa;
int state; u8 state;
#define NEIGHBOR_DOWN 0 #define NEIGHBOR_DOWN 0
#define NEIGHBOR_ATTEMPT 1 #define NEIGHBOR_ATTEMPT 1
#define NEIGHBOR_INIT 2 #define NEIGHBOR_INIT 2
@ -132,14 +149,13 @@ struct ospf_neighbor
#define NEIGHBOR_LOADING 6 #define NEIGHBOR_LOADING 6
#define NEIGHBOR_FULL 7 #define NEIGHBOR_FULL 7
timer *inactim; /* Inactivity timer */ timer *inactim; /* Inactivity timer */
byte ms; /* Master/slave */ u8 imms; /* I, M, Master/slave */
#define NEIGHBOR_SLAVE 0 u8 myimms;
#define NEIGHBOR_MASTER 1
u32 dds; /* DD Sequence number being sentg */ u32 dds; /* DD Sequence number being sentg */
u32 ddr; /* last Dat Des packet */ u32 ddr; /* last Dat Des packet */
u32 rid; /* Router ID */ u32 rid; /* Router ID */
byte priority; /* Priority */ u8 priority; /* Priority */
byte options; /* Options */ u8 options; /* Options */
u32 dr; /* Neigbour's idea of DR */ u32 dr; /* Neigbour's idea of DR */
u32 bdr; /* Neigbour's idea of BDR */ u32 bdr; /* Neigbour's idea of BDR */
u8 adj; /* built adjacency? */ u8 adj; /* built adjacency? */