diff options
Diffstat (limited to 'proto/ospf')
-rw-r--r-- | proto/ospf/ospf.c | 145 | ||||
-rw-r--r-- | proto/ospf/ospf.h | 44 |
2 files changed, 150 insertions, 39 deletions
diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 21b4e32..ce08bc2 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -24,7 +24,30 @@ #include "ospf.h" 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 proto *p; @@ -37,6 +60,79 @@ neigh_chstate(struct ospf_neighbor *n, int 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) */ void @@ -46,11 +142,11 @@ tryadj(struct ospf_neighbor *n, struct proto *p) neigh_chstate(n,NEIGHBOR_EXSTART); if(n->adj==0) /* First time adjacency */ { - n->dds=random_u32; + n->dds=random_u32(); } n->dds++; - n->ms=NEIGHBOR_MASTER; - /* FIXME Go on, start to send DD packets */ + n->myimms=(DBDES_MS | DBDES_M|DBDES_I ); + tm_start(n->ifa->rxmt_timer,1); /* Or some other number ? */ } /* 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 */ u32 nrid, *pnrid; struct ospf_neighbor *neigh,*n; - int i,twoway; + u8 i,twoway; 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); 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; } - n=NULL; - WALK_LIST (neigh, ifa->neigh_list) - { - if(neigh->rid==nrid) - { - n=neigh; - break; - } - } - - if(n==NULL) + if((n=find_neigh(ifa, nrid))==NULL) { log("%s: New neighbor found: %u.", p->name,nrid); 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_iface *ifa; struct proto *p; - int i; + u8 i; u8 *pu8; @@ -407,7 +493,7 @@ ospf_rx_hook(sock *sk, int size) 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: Discarding",p->name); @@ -474,6 +560,7 @@ ospf_rx_hook(sock *sk, int size) break; case DBDES: DBG("%s: Database description received.\n", p->name); + ospf_dbdes_rx((struct ospf_dbdes_packet *)ps, p, ifa, size); break; case LSREQ: 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 * depending on config */ -int +u8 is_good_iface(struct proto *p, struct iface *iface) { 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 */ -int +u8 ospf_iface_clasify(struct iface *ifa) { /* FIXME: Latter I'll use config - this is incorrect */ @@ -653,7 +740,7 @@ hello_timer_hook(timer *timer) struct ospf_neighbor *neigh; u16 length; u32 *pp; - int i; + u8 i; ifa=(struct ospf_iface *)timer->data; p=(struct proto *)(ifa->proto); @@ -680,7 +767,7 @@ hello_timer_hook(timer *timer) /* Fill all neighbors */ 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) { *(pp+i)=htonl(neigh->rid); @@ -717,7 +804,7 @@ wait_timer_hook(timer *timer) } 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; @@ -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->recurrent=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); if((ifa->type!=OSPF_IT_PTP)) { @@ -749,7 +844,7 @@ ospf_add_timers(struct ospf_iface *ifa, pool *pool, int wait) void ospf_iface_default(struct ospf_iface *ifa) { - int i; + u8 i; ifa->area=0; /* FIXME: Read from config */ ifa->cost=COST_D; diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 7ba566f..a9860cf 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -38,8 +38,8 @@ struct ospf_iface { list neigh_list; /* List of neigbours */ u32 area; /* OSPF Area */ u16 cost; /* Cost of iface */ - int rxmtint; /* number of seconds between LSA retransmissions */ - int iftransdelay; /* The estimated number of seconds it takes to + u16 rxmtint; /* number of seconds between LSA retransmissions */ + u16 iftransdelay; /* The estimated number of seconds it takes to transmit a Link State Update Packet over this interface. LSAs contained in the update */ u8 priority; /* A router priority for DR election */ @@ -52,11 +52,11 @@ struct ospf_iface { u32 drid; ip_addr bdrip; /* Backup DR */ u32 bdrid; - int type; /* OSPF view of type */ + u8 type; /* OSPF view of type */ #define OSPF_IT_BROADCAST 0 #define OSPF_IT_NBMA 1 #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_WAITING 1 /* Waiting for Wait timer */ #define OSPF_IS_PTP 2 /* PTP operational */ @@ -65,6 +65,7 @@ struct ospf_iface { #define OSPF_IS_DR 5 /* I'm DR */ timer *wait_timer; /* WAIT timer */ timer *hello_timer; /* HELLOINT timer */ + timer *rxmt_timer; /* RXMT timer */ /* Default values for interface parameters */ #define COST_D 10 #define RXMTINT_D 5 @@ -81,7 +82,7 @@ struct ospf_patt { struct iface_patt i; u16 cost; - byte mode; + u8 mode; }; struct ospf_packet { @@ -111,18 +112,34 @@ struct ospf_hello_packet { u32 bdr; }; -struct ospf_ddseq_packet { +struct ospf_dbdes_packet { struct ospf_packet ospf_packet; u16 iface_mtu; - u16 options; - u32 ddseq_no; + u8 options; + 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 { node n; struct ospf_iface *ifa; - int state; + u8 state; #define NEIGHBOR_DOWN 0 #define NEIGHBOR_ATTEMPT 1 #define NEIGHBOR_INIT 2 @@ -132,14 +149,13 @@ struct ospf_neighbor #define NEIGHBOR_LOADING 6 #define NEIGHBOR_FULL 7 timer *inactim; /* Inactivity timer */ - byte ms; /* Master/slave */ -#define NEIGHBOR_SLAVE 0 -#define NEIGHBOR_MASTER 1 + u8 imms; /* I, M, Master/slave */ + u8 myimms; u32 dds; /* DD Sequence number being sentg */ u32 ddr; /* last Dat Des packet */ u32 rid; /* Router ID */ - byte priority; /* Priority */ - byte options; /* Options */ + u8 priority; /* Priority */ + u8 options; /* Options */ u32 dr; /* Neigbour's idea of DR */ u32 bdr; /* Neigbour's idea of BDR */ u8 adj; /* built adjacency? */ |