summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--proto/ospf/Makefile2
-rw-r--r--proto/ospf/dbdes.c16
-rw-r--r--proto/ospf/hello.c6
-rw-r--r--proto/ospf/lsreq.c104
-rw-r--r--proto/ospf/lsreq.h18
-rw-r--r--proto/ospf/neighbor.c3
-rw-r--r--proto/ospf/ospf.h20
-rw-r--r--proto/ospf/packet.c1
-rw-r--r--proto/ospf/topology.c1
9 files changed, 165 insertions, 6 deletions
diff --git a/proto/ospf/Makefile b/proto/ospf/Makefile
index 6b787c6..a7658f7 100644
--- a/proto/ospf/Makefile
+++ b/proto/ospf/Makefile
@@ -1,4 +1,4 @@
-source=ospf.c topology.c packet.c hello.c neighbor.c iface.c dbdes.c
+source=ospf.c topology.c packet.c hello.c neighbor.c iface.c dbdes.c lsreq.c
root-rel=../../
dir-name=proto/ospf
diff --git a/proto/ospf/dbdes.c b/proto/ospf/dbdes.c
index c6dabc5..4e0f2a4 100644
--- a/proto/ospf/dbdes.c
+++ b/proto/ospf/dbdes.c
@@ -184,7 +184,7 @@ rxmt_timer_hook(timer *timer)
n=(struct ospf_neighbor *)timer->data;
ifa=n->ifa;
p=(struct proto *)(ifa->proto);
- debug("%s: RXMT timer fired on interface %s for nigh: %d.\n",
+ debug("%s: RXMT timer fired on interface %s for neigh: %u.\n",
p->name, ifa->iface->name, n->rid);
if(n->state<NEIGHBOR_LOADING) ospf_dbdes_tx(n);
else
@@ -221,19 +221,29 @@ ospf_dbdes_reqladd(struct ospf_dbdes_packet *ps, struct proto *p,
struct ospf_lsa_header *plsa,lsa;
struct top_hash_entry *he,*sn;
struct top_graph *gr;
+ struct ospf_packet *op;
+ int i,j;
gr=n->ifa->oa->gr;
+ op=(struct ospf_packet *)ps;
plsa=(void *)(ps+1);
- ntohlsah(plsa, &lsa);
+
+ j=(ntohs(op->length)-sizeof(struct ospf_dbdes_packet))/
+ sizeof( struct ospf_lsa_header);
+
+ for(i=0;i<j;i++)
+ {
+ ntohlsah(plsa+i, &lsa);
/* FIXME Test Checksum */
if(((he=ospf_hash_find(gr,lsa.id,lsa.rt,lsa.type))==NULL)||
(lsa_comp(&lsa, &(he->lsa))==1))
{
sn=sl_alloc(gr->hash_slab);
- ntohlsah(plsa, &(sn->lsa));
+ ntohlsah(plsa+i, &(sn->lsa));
s_add_tail(&(n->lsrql), SNODE sn);
}
+ }
}
void
diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c
index e025ae4..77d114c 100644
--- a/proto/ospf/hello.c
+++ b/proto/ospf/hello.c
@@ -112,6 +112,12 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p,
n->rxmt_timer->hook=rxmt_timer_hook;
n->rxmt_timer->recurrent=ifa->rxmtint;
DBG("%s: Installing rxmt timer.\n", p->name);
+ n->lsrr_timer=tm_new(p->pool);
+ n->lsrr_timer->data=n;
+ n->lsrr_timer->randomize=0;
+ n->lsrr_timer->hook=lsrr_timer_hook;
+ n->lsrr_timer->recurrent=ifa->rxmtint;
+ DBG("%s: Installing lsrr timer.\n", p->name);
}
ospf_neigh_sm(n, INM_HELLOREC);
diff --git a/proto/ospf/lsreq.c b/proto/ospf/lsreq.c
new file mode 100644
index 0000000..a0a8685
--- /dev/null
+++ b/proto/ospf/lsreq.c
@@ -0,0 +1,104 @@
+/*
+ * BIRD -- OSPF
+ *
+ * (c) 2000 Ondrej Filip <feela@network.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include "ospf.h"
+
+void
+ospf_lsreq_tx(struct ospf_neighbor *n)
+{
+ snode *sn;
+ struct top_hash_entry *en;
+ struct ospf_lsreq_packet *pk;
+ struct ospf_packet *op;
+ struct ospf_lsreq_header *lsh;
+ u16 length;
+ int i,j;
+
+ pk=(struct ospf_lsreq_packet *)n->ifa->ip_sk->tbuf;
+ op=(struct ospf_packet *)n->ifa->ip_sk->tbuf;
+
+ fill_ospf_pkt_hdr(n->ifa, pk, LSREQ);
+
+ s_init(&(n->lsrqi), &(n->lsrql));
+ sn=s_get(&(n->lsrqi));
+ if(sn==NULL) return;
+ /* FIXME above I don't need iterator and slist */
+
+ i=j=(n->ifa->iface->mtu-SIPH-sizeof(struct ospf_lsreq_packet))/
+ sizeof(struct ospf_lsreq_header); /* FIXME IP header! */
+ lsh=(struct ospf_lsreq_header *)(pk+1);
+
+ for(;i>0;i--)
+ {
+ en=(struct top_hash_entry *)sn;
+ lsh->padd1=0; lsh->padd2=0;
+ lsh->type=en->lsa.type;
+ lsh->rt=htonl(en->lsa.rt);
+ lsh->id=htonl(en->lsa.id);
+ lsh++;
+ DBG("Requesting %uth LSA: Type: %u, Id: %u, RT: %u\n",i, en->lsa.type,
+ en->lsa.id, en->lsa.rt);
+ if((sn=sn->next)==NULL) break;
+ }
+
+ length=sizeof(struct ospf_lsreq_packet)+(j-i)*sizeof(struct ospf_lsreq_header);
+ op->length=htons(length);
+ ospf_pkt_finalize(n->ifa, op);
+ sk_send_to(n->ifa->ip_sk,length, n->ip, OSPF_PROTO);
+ DBG("Lsreq send to: %u\n", n->rid);
+}
+
+void
+lsrr_timer_hook(timer *timer)
+{
+ struct ospf_iface *ifa;
+ struct proto *p;
+ struct ospf_neighbor *n;
+
+ n=(struct ospf_neighbor *)timer->data;
+ ifa=n->ifa;
+ p=(struct proto *)(ifa->proto);
+ debug("%s: LSRR timer fired on interface %s for neigh: %u.\n",
+ p->name, ifa->iface->name, n->rid);
+ ospf_lsreq_tx(n);
+}
+
+void
+ospf_lsreq_rx(struct ospf_lsreq_packet *ps, struct proto *p,
+ struct ospf_iface *ifa, u16 size)
+{
+ u32 nrid, myrid;
+ struct ospf_neighbor *n;
+ struct ospf_lsreq_header *lsh;
+ int length;
+ u8 i;
+
+ nrid=ntohl(ps->ospf_packet.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(n->state<NEIGHBOR_EXCHANGE) debug("%s: Ignoring it.\n", p->name);
+
+ length=htons(ps->ospf_packet.length);
+ lsh=(void *)(ps+1);
+ for(i=0;i<(length-sizeof(struct ospf_lsreq_packet))/
+ sizeof(struct ospf_lsreq_header);i++);
+ {
+ DBG("Processing LSA: ID=%u, Type=%u, Router=%u\n", lsh->id, lsh->type,
+ lsh->rt);
+ /* FIXME Go on */
+ }
+
+}
+
diff --git a/proto/ospf/lsreq.h b/proto/ospf/lsreq.h
new file mode 100644
index 0000000..46d5b92
--- /dev/null
+++ b/proto/ospf/lsreq.h
@@ -0,0 +1,18 @@
+/*
+ * BIRD -- OSPF
+ *
+ * (c) 2000 Ondrej Filip <feela@network.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ *
+ */
+
+#ifndef _BIRD_OSPF_LSREQ_H_
+#define _BIRD_OSPF_LSREQ_H_
+
+void ospf_lsreq_tx(struct ospf_neighbor *n);
+void lsrr_timer_hook(timer *timer);
+void ospf_lsreq_rx(struct ospf_lsreq_packet *ps, struct proto *p,
+ struct ospf_iface *ifa, u16 size);
+
+#endif /* _BIRD_OSPF_LSREQ_H_ */
diff --git a/proto/ospf/neighbor.c b/proto/ospf/neighbor.c
index d08e58c..0f4bbcf 100644
--- a/proto/ospf/neighbor.c
+++ b/proto/ospf/neighbor.c
@@ -210,8 +210,11 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event)
s_init_list(&(n->lsrql));
s_init_list(&(n->lsrtl));
s_init(&(n->dbsi), &(n->ifa->oa->lsal));
+ s_init(&(n->lsrqi), &(n->lsrql));
+ tm_start(n->lsrr_timer,n->ifa->rxmtint);
/*ospf_dbdes_tx(n);*/
}
+ else die("NEGDONE and I'm not in EXSTART?\n");
break;
case INM_EXDONE:
neigh_chstate(n,NEIGHBOR_LOADING);
diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h
index 06ca56d..0301154 100644
--- a/proto/ospf/ospf.h
+++ b/proto/ospf/ospf.h
@@ -11,6 +11,8 @@
#define LOCAL_DEBUG
+#define SIPH 64 /* FIXME Size Of IP header */
+
#include <string.h>
#include "nest/bird.h"
@@ -232,6 +234,18 @@ struct ospf_lsa_ext_tos {
u32 tag;
};
+struct ospf_lsreq_packet {
+ struct ospf_packet ospf_packet;
+};
+
+struct ospf_lsreq_header {
+ u16 padd1;
+ u8 padd2;
+ u8 type;
+ u32 id;
+ u32 rt; /* Advertising router */
+};
+
struct ospf_neighbor
{
node n;
@@ -258,12 +272,13 @@ struct ospf_neighbor
u32 bdr; /* Neigbour's idea of BDR */
u8 adj; /* built adjacency? */
siterator dbsi; /* Database summary list iterator */
- slist lsrql; /* Link state request */ /* FIXME add top_gr hashing? */
+ slist lsrql; /* Link state request */ /* FIXME add hashing? */
siterator lsrqi;
slist lsrtl; /* Link state retransmission list */
siterator lsrti;
void *ldbdes; /* Last database description packet */
- timer *rxmt_timer; /* RXMT timer */
+ timer *rxmt_timer; /* RXMT timer */
+ timer *lsrr_timer; /* Link state requiest retransmition timer */
};
/* Definitions for interface state machine */
@@ -318,5 +333,6 @@ static void ospf_postconfig(struct proto_config *c);
#include "proto/ospf/neighbor.h"
#include "proto/ospf/topology.h"
#include "proto/ospf/dbdes.h"
+#include "proto/ospf/lsreq.h"
#endif /* _BIRD_OSPF_H_ */
diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c
index b0ab477..a176c44 100644
--- a/proto/ospf/packet.c
+++ b/proto/ospf/packet.c
@@ -141,6 +141,7 @@ ospf_rx_hook(sock *sk, int size)
break;
case LSREQ:
DBG("%s: Link state request received.\n", p->name);
+ ospf_lsreq_rx((struct ospf_lsreq_packet *)ps, p, ifa, size);
break;
case LSUPD:
DBG("%s: Link state update received.\n", p->name);
diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c
index fe236ba..15163f9 100644
--- a/proto/ospf/topology.c
+++ b/proto/ospf/topology.c
@@ -197,6 +197,7 @@ addifa_rtlsa(struct ospf_iface *ifa)
}
make_rt_lsa(oa, po);
+ /* FIXME length? */
/*FIXME seq no++ */
/*FIXME lsa_flood(oa->rt) */
}