summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
Diffstat (limited to 'proto')
-rw-r--r--proto/ospf/ospf.c157
-rw-r--r--proto/ospf/ospf.h7
2 files changed, 88 insertions, 76 deletions
diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c
index 831f1837..59b36145 100644
--- a/proto/ospf/ospf.c
+++ b/proto/ospf/ospf.c
@@ -60,79 +60,6 @@ neigh_chstate(struct ospf_neighbor *n, u8 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
@@ -581,6 +508,90 @@ ospf_int_sm(struct ospf_iface *ifa, int event)
}
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 ;
+ }
+
+ if(ifa->iface->mtu<size)
+ {
+ debug("%s: Received dbdes larger than MTU from (%u)!\n", p->name, nrid);
+ return ;
+ }
+
+ 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:
+ ospf_neigh_sm(n, INM_2WAYREC);
+ if(n->state!=NEIGHBOR_EXSTART) return;
+ case NEIGHBOR_EXSTART:
+ if(size!=sizeof(struct ospf_dbdes_packet))
+ {
+ debug("%s: Received bad dbdes from %u in exstart state.\n",
+ p->name, nrid);
+ return;
+ }
+
+ if(ps->imms==(DBDES_I|DBDES_M|DBDES_MS) && (n->rid > myrid) &&
+ (size == sizeof(struct ospf_dbdes_packet)))
+ {
+ /* I'm slave! */
+ n->dds=ps->ddseq;
+ n->options=ps->options;
+ n->myimms=(n->myimms && DBDES_M);
+ n->ddr=ps->ddseq;
+ n->imms=ps->imms;
+ debug("%s: I'm slave to %u. \n", p->name, nrid);
+ ospf_neigh_sm(n, INM_NEGDONE);
+ }
+ if(((ps->imms | DBDES_M)== DBDES_M) && (n->rid < myrid) &&
+ (n->dds == ps->ddseq) && (size == sizeof(struct ospf_dbdes_packet)))
+ {
+ /* I'm master! */
+ n->options=ps->options;
+ n->ddr=ps->ddseq;
+ n->imms=ps->imms;
+ debug("%s: I'm master to %u. \n", p->name, nrid);
+ ospf_neigh_sm(n, INM_NEGDONE);
+ }
+
+ break;
+ case NEIGHBOR_EXCHANGE:
+ if((ps->imms==n->imms) && (ps->options=n->options) &&
+ (ps->ddseq==n->dds))
+ {
+ /* Duplicate packet */
+ debug("%s: Received duplicate dbdes from (%u)!\n", p->name, nrid);
+ return;
+ }
+
+ break;
+ case NEIGHBOR_LOADING:
+ case NEIGHBOR_FULL:
+ break;
+ }
+}
+
+void
ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p,
struct ospf_iface *ifa, int size)
{
diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h
index c3d49029..15a6e2cf 100644
--- a/proto/ospf/ospf.h
+++ b/proto/ospf/ospf.h
@@ -153,9 +153,10 @@ struct ospf_neighbor
#define NEIGHBOR_FULL 7
timer *inactim; /* Inactivity timer */
u8 imms; /* I, M, Master/slave */
- u8 myimms;
- u32 dds; /* DD Sequence number being sentg */
- u32 ddr; /* last Dat Des packet */
+ u32 dds; /* DD Sequence number being sent */
+ u32 ddr; /* last Dat Des packet received */
+ u8 myimms; /* I, M MS received */
+ u8 myoptions; /* Options received */
u32 rid; /* Router ID */
u8 priority; /* Priority */
u8 options; /* Options */