summaryrefslogtreecommitdiffstats
path: root/proto
diff options
context:
space:
mode:
Diffstat (limited to 'proto')
-rw-r--r--proto/ospf/Makefile2
-rw-r--r--proto/ospf/dbdes.c26
-rw-r--r--proto/ospf/lsalib.c222
-rw-r--r--proto/ospf/lsalib.h18
-rw-r--r--proto/ospf/lsreq.c24
-rw-r--r--proto/ospf/lsupd.c48
-rw-r--r--proto/ospf/lsupd.h1
-rw-r--r--proto/ospf/ospf.h15
8 files changed, 318 insertions, 38 deletions
diff --git a/proto/ospf/Makefile b/proto/ospf/Makefile
index a7658f7..632c3b6 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 lsreq.c
+source=ospf.c topology.c packet.c hello.c neighbor.c iface.c dbdes.c lsreq.c lsupd.c lsack.c lsalib.c
root-rel=../../
dir-name=proto/ospf
diff --git a/proto/ospf/dbdes.c b/proto/ospf/dbdes.c
index 9236da7..3a8a9a1 100644
--- a/proto/ospf/dbdes.c
+++ b/proto/ospf/dbdes.c
@@ -9,32 +9,6 @@
#include "ospf.h"
void
-htonlsah(struct ospf_lsa_header *h, struct ospf_lsa_header *n)
-{
- n->age=htons(h->age);
- n->options=h->options;
- n->type=h->type;
- n->id=htonl(h->id);
- n->rt=htonl(h->rt);
- n->sn=htonl(h->sn);
- n->checksum=htons(h->checksum);
- n->length=htons(h->length);
-};
-
-void
-ntohlsah(struct ospf_lsa_header *n, struct ospf_lsa_header *h)
-{
- h->age=ntohs(n->age);
- h->options=n->options;
- h->type=n->type;
- h->id=ntohl(n->id);
- h->rt=ntohl(n->rt);
- h->sn=ntohl(n->sn);
- h->checksum=ntohs(n->checksum);
- h->length=ntohs(n->length);
-};
-
-void
ospf_dbdes_tx(struct ospf_neighbor *n)
{
struct ospf_dbdes_packet *pkt;
diff --git a/proto/ospf/lsalib.c b/proto/ospf/lsalib.c
new file mode 100644
index 0000000..f74cb76
--- /dev/null
+++ b/proto/ospf/lsalib.c
@@ -0,0 +1,222 @@
+/*
+ * BIRD -- OSPF
+ *
+ * (c) 1999-2000 Ondrej Filip <feela@network.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include "ospf.h"
+
+void
+htonlsah(struct ospf_lsa_header *h, struct ospf_lsa_header *n)
+{
+ n->age=htons(h->age);
+ n->options=h->options;
+ n->type=h->type;
+ n->id=htonl(h->id);
+ n->rt=htonl(h->rt);
+ n->sn=htonl(h->sn);
+ n->checksum=htons(h->checksum);
+ n->length=htons(h->length);
+};
+
+void
+ntohlsah(struct ospf_lsa_header *n, struct ospf_lsa_header *h)
+{
+ h->age=ntohs(n->age);
+ h->options=n->options;
+ h->type=n->type;
+ h->id=ntohl(n->id);
+ h->rt=ntohl(n->rt);
+ h->sn=ntohl(n->sn);
+ h->checksum=ntohs(n->checksum);
+ h->length=ntohs(n->length);
+};
+
+void
+htonlsab(void *h, void *n, u8 type, u16 len)
+{
+ unsigned int i;
+ switch(type)
+ {
+ case LSA_T_RT:
+ {
+ struct ospf_lsa_rt *hrt, *nrt;
+ struct ospf_lsa_rt_link *hrtl,*nrtl;
+
+ nrt=n;
+ hrt=h;
+
+ nrt->VEB=hrt->VEB;
+ nrt->padding=0;
+ nrt->links=htons(hrt->links);
+ nrtl=(struct ospf_lsa_rt_link *)(nrt+1);
+ hrtl=(struct ospf_lsa_rt_link *)(hrt+1);
+ for(i=0;i<hrt->links;i++)
+ {
+ (nrtl+i)->id=htonl((hrtl+i)->id);
+ (nrtl+i)->data=htonl((hrtl+i)->data);
+ (nrtl+i)->type=(hrtl+i)->type;
+ (nrtl+i)->notos=(hrtl+i)->notos;
+ (nrtl+i)->metric=htons((hrtl+i)->metric);
+ }
+ break;
+ }
+ case LSA_T_NET:
+ {
+ u32 *hid,*nid;
+
+ nid=n;
+ hid=h;
+
+ for(i=0;i<(len/sizeof(u32));i++)
+ {
+ *(nid+i)=htonl(*(hid+i));
+ }
+ break;
+ }
+ case LSA_T_SUM_NET:
+ case LSA_T_SUM_RT:
+ {
+ struct ospf_lsa_summ *hs, *ns;
+ struct ospf_lsa_summ_net *hn, *nn;
+
+ hs=h;
+ ns=n;
+
+ ns->netmask=htonl(hs->netmask);
+
+ hn=(struct ospf_lsa_summ_net *)(hs+1);
+ nn=(struct ospf_lsa_summ_net *)(ns+1);
+
+ for(i=0;i<((len-sizeof(struct ospf_lsa_summ))/
+ sizeof(struct ospf_lsa_summ_net));i++)
+ {
+ (nn+i)->tos=(hn+i)->tos;
+ (nn+i)->metric=htons((hn+i)->metric);
+ (nn+i)->padding=0;
+ }
+ break;
+ }
+ case LSA_T_EXT:
+ {
+ struct ospf_lsa_ext *he, *ne;
+ struct ospf_lsa_ext_tos *ht, *nt;
+
+ he=h;
+ ne=n;
+
+ ne->netmask=htonl(he->netmask);
+
+ ht=(struct ospf_lsa_ext_tos *)(he+1);
+ nt=(struct ospf_lsa_ext_tos *)(ne+1);
+
+ for(i=0;i<((len-sizeof(struct ospf_lsa_ext))/
+ sizeof(struct ospf_lsa_ext_tos));i++)
+ {
+ (nt+i)->etos=(ht+i)->etos;
+ (nt+i)->padding=0;
+ (nt+i)->metric=htons((ht+i)->metric);
+ (nt+i)->fwaddr=htonl((ht+i)->fwaddr);
+ (nt+i)->tag=htonl((ht+i)->tag);
+ }
+ break;
+ }
+ default: die("(hton): Unknown LSA\n");
+ }
+};
+
+void
+ntohlsab(void *n, void *h, u8 type, u16 len)
+{
+ unsigned int i;
+ switch(type)
+ {
+ case LSA_T_RT:
+ {
+ struct ospf_lsa_rt *hrt, *nrt;
+ struct ospf_lsa_rt_link *hrtl,*nrtl;
+
+ nrt=n;
+ hrt=h;
+
+ hrt->VEB=nrt->VEB;
+ hrt->padding=0;
+ hrt->links=ntohs(nrt->links);
+ nrtl=(struct ospf_lsa_rt_link *)(nrt+1);
+ hrtl=(struct ospf_lsa_rt_link *)(hrt+1);
+ for(i=0;i<hrt->links;i++)
+ {
+ (hrtl+i)->id=ntohl((nrtl+i)->id);
+ (hrtl+i)->data=ntohl((nrtl+i)->data);
+ (hrtl+i)->type=(nrtl+i)->type;
+ (hrtl+i)->notos=(nrtl+i)->notos;
+ (hrtl+i)->metric=ntohs((nrtl+i)->metric);
+ }
+ break;
+ }
+ case LSA_T_NET:
+ {
+ u32 *hid,*nid;
+
+ hid=h;
+ nid=n;
+
+ for(i=0;i<(len/sizeof(u32));i++)
+ {
+ *(hid+i)=ntohl(*(nid+i));
+ }
+ break;
+ }
+ case LSA_T_SUM_NET:
+ case LSA_T_SUM_RT:
+ {
+ struct ospf_lsa_summ *hs, *ns;
+ struct ospf_lsa_summ_net *hn, *nn;
+
+ hs=h;
+ ns=n;
+
+ hs->netmask=ntohl(ns->netmask);
+
+ hn=(struct ospf_lsa_summ_net *)(hs+1);
+ nn=(struct ospf_lsa_summ_net *)(ns+1);
+
+ for(i=0;i<((len-sizeof(struct ospf_lsa_summ))/
+ sizeof(struct ospf_lsa_summ_net));i++)
+ {
+ (hn+i)->tos=(nn+i)->tos;
+ (hn+i)->metric=ntohs((nn+i)->metric);
+ (hn+i)->padding=0;
+ }
+ break;
+ }
+ case LSA_T_EXT:
+ {
+ struct ospf_lsa_ext *he, *ne;
+ struct ospf_lsa_ext_tos *ht, *nt;
+
+ he=h;
+ ne=n;
+
+ he->netmask=ntohl(ne->netmask);
+
+ ht=(struct ospf_lsa_ext_tos *)(he+1);
+ nt=(struct ospf_lsa_ext_tos *)(ne+1);
+
+ for(i=0;i<((len-sizeof(struct ospf_lsa_ext))/
+ sizeof(struct ospf_lsa_ext_tos));i++)
+ {
+ (ht+i)->etos=(nt+i)->etos;
+ (ht+i)->padding=0;
+ (ht+i)->metric=ntohs((nt+i)->metric);
+ (ht+i)->fwaddr=ntohl((nt+i)->fwaddr);
+ (ht+i)->tag=ntohl((nt+i)->tag);
+ }
+ break;
+ }
+ default: die("(ntoh): Unknown LSA\n");
+ }
+};
+
diff --git a/proto/ospf/lsalib.h b/proto/ospf/lsalib.h
new file mode 100644
index 0000000..e759aa0
--- /dev/null
+++ b/proto/ospf/lsalib.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_LSALIB_H_
+#define _BIRD_OSPF_LSALIB_H_
+
+void htonlsah(struct ospf_lsa_header *h, struct ospf_lsa_header *n);
+void ntohlsah(struct ospf_lsa_header *n, struct ospf_lsa_header *h);
+void htonlsab(void *h, void *n, u8 type, u16 len);
+void ntohlsab(void *n, void *h, u8 type, u16 len);
+
+#endif /* _BIRD_OSPF_LSALIB_H_ */
diff --git a/proto/ospf/lsreq.c b/proto/ospf/lsreq.c
index 91bc988..6829718 100644
--- a/proto/ospf/lsreq.c
+++ b/proto/ospf/lsreq.c
@@ -42,9 +42,9 @@ ospf_lsreq_tx(struct ospf_neighbor *n)
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);
+ lsh++;
if((sn=sn->next)==NULL) break;
}
@@ -77,6 +77,9 @@ ospf_lsreq_rx(struct ospf_lsreq_packet *ps, struct proto *p,
u32 nrid, myrid;
struct ospf_neighbor *n;
struct ospf_lsreq_header *lsh;
+ struct l_lsr_head *llsh;
+ list uplist;
+ slab *upslab;
int length;
u8 i;
@@ -94,17 +97,28 @@ ospf_lsreq_rx(struct ospf_lsreq_packet *ps, struct proto *p,
length=htons(ps->ospf_packet.length);
lsh=(void *)(ps+1);
+ init_list(&uplist);
+ upslab=sl_new(p->pool,sizeof(struct l_lsr_head));
+
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);
- if(ospf_hash_find(n->ifa->oa->gr, lsh->id, lsh->rt, lsh->type)==NULL)
+ DBG("Processing LSA: ID=%u, Type=%u, Router=%u\n", lsh->id,
+ ntohl(lsh->type), ntohl(lsh->rt));
+ llsh=sl_alloc(upslab);
+ llsh->lsh.id=ntohl(lsh->id);
+ llsh->lsh.rt=ntohl(lsh->rt);
+ llsh->lsh.type=ntohl(lsh->type);
+ add_tail(&uplist, NODE llsh);
+ if(ospf_hash_find(n->ifa->oa->gr, llsh->lsh.id, llsh->lsh.rt,
+ llsh->lsh.type)==NULL)
{
ospf_neigh_sm(n,INM_BADLSREQ);
+ rfree(upslab);
return;
}
- /* FIXME Go on */
}
+ ospf_lsupd_tx_list(n, &uplist);
+ rfree(upslab);
}
diff --git a/proto/ospf/lsupd.c b/proto/ospf/lsupd.c
index 5f53311..515626b 100644
--- a/proto/ospf/lsupd.c
+++ b/proto/ospf/lsupd.c
@@ -14,6 +14,54 @@ ospf_lsupd_tx(struct ospf_neighbor *n)
/* FIXME Go on! */
}
+void /* I send all I received in LSREQ */
+ospf_lsupd_tx_list(struct ospf_neighbor *n, list *l)
+{
+ struct l_lsr_head *llsh;
+ u16 len;
+ u32 lsano;
+ struct top_hash_entry *en;
+ struct ospf_lsupd_packet *pk;
+ struct ospf_packet *op;
+ void *pktpos;
+
+ if(HEAD(*l)==NULL) return;
+
+ pk=(struct ospf_lsupd_packet *)n->ifa->ip_sk->tbuf;
+ op=(struct ospf_packet *)n->ifa->ip_sk->tbuf;
+
+ fill_ospf_pkt_hdr(n->ifa, pk, LSUPD);
+ len=SIPH+sizeof(struct ospf_lsupd_packet);
+ lsano=0;
+ pktpos=(pk+1);
+
+ WALK_LIST(llsh, *l)
+ {
+ en=ospf_hash_find(n->ifa->oa->gr,llsh->lsh.id,llsh->lsh.rt,llsh->lsh.type);
+ if((len+sizeof(struct ospf_lsa_header)+en->body_len)>n->ifa->iface->mtu)
+ {
+ pk->lsano=htonl(lsano);
+ op->length=htons(len);
+ ospf_pkt_finalize(n->ifa, op);
+ sk_send_to(n->ifa->ip_sk,len, n->ip, OSPF_PROTO);
+
+ fill_ospf_pkt_hdr(n->ifa, pk, LSUPD);
+ len=SIPH+sizeof(struct ospf_lsupd_packet);
+ lsano=0;
+ pktpos=(pk+1);
+ }
+ htonlsah(&(en->lsa), pktpos);
+ pktpos=pktpos+sizeof(struct ospf_lsa_header);
+ htonlsab(en->lsa_body, pktpos, en->lsa.type, en->lsa.length);
+ pktpos=pktpos+en->body_len;
+ len=len+en->body_len+sizeof(struct ospf_lsa_header);
+ }
+ pk->lsano=htonl(lsano);
+ op->length=htons(len);
+ ospf_pkt_finalize(n->ifa, op);
+ sk_send_to(n->ifa->ip_sk,len, n->ip, OSPF_PROTO);
+}
+
void
ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
struct ospf_iface *ifa, u16 size)
diff --git a/proto/ospf/lsupd.h b/proto/ospf/lsupd.h
index 1aee1dc..369eb76 100644
--- a/proto/ospf/lsupd.h
+++ b/proto/ospf/lsupd.h
@@ -11,6 +11,7 @@
#define _BIRD_OSPF_LSUPD_H_
void ospf_lsupd_tx(struct ospf_neighbor *n);
+void ospf_lsupd_tx_list(struct ospf_neighbor *n, list *l);
void ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
struct ospf_iface *ifa, u16 size);
diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h
index bc37fc4..c07d334 100644
--- a/proto/ospf/ospf.h
+++ b/proto/ospf/ospf.h
@@ -207,11 +207,6 @@ struct ospf_lsa_rt_link_tos { /* Actually we ignore TOS. This is useless */
u16 metric;
};
-
-struct ospf_lsa_net {
- u32 netmask;
-};
-
struct ospf_lsa_summ {
u32 netmask;
};
@@ -229,7 +224,7 @@ struct ospf_lsa_ext {
struct ospf_lsa_ext_tos {
u8 etos;
u8 padding;
- u16 mertic;
+ u16 metric;
u32 fwaddr;
u32 tag;
};
@@ -246,6 +241,11 @@ struct ospf_lsreq_header {
u32 rt; /* Advertising router */
};
+struct l_lsr_head {
+ node n;
+ struct ospf_lsreq_header lsh;
+};
+
struct ospf_lsupd_packet {
struct ospf_packet ospf_packet;
u32 lsano; /* Number of LSA's */
@@ -345,5 +345,8 @@ static void ospf_postconfig(struct proto_config *c);
#include "proto/ospf/topology.h"
#include "proto/ospf/dbdes.h"
#include "proto/ospf/lsreq.h"
+#include "proto/ospf/lsupd.h"
+#include "proto/ospf/lsack.h"
+#include "proto/ospf/lsalib.h"
#endif /* _BIRD_OSPF_H_ */