]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Sending of lspd as responce to lsreq done.
authorOndrej Filip <feela@network.cz>
Fri, 31 Mar 2000 00:21:41 +0000 (00:21 +0000)
committerOndrej Filip <feela@network.cz>
Fri, 31 Mar 2000 00:21:41 +0000 (00:21 +0000)
proto/ospf/Makefile
proto/ospf/dbdes.c
proto/ospf/lsalib.c [new file with mode: 0644]
proto/ospf/lsalib.h [new file with mode: 0644]
proto/ospf/lsreq.c
proto/ospf/lsupd.c
proto/ospf/lsupd.h
proto/ospf/ospf.h

index a7658f7fb2f5f7054cffb87b7b6fe736051dc2c4..632c3b6aa748c209d20985d127ecb280f1ee473b 100644 (file)
@@ -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
 
index 9236da75a3bc2324f6980c082885a1754f4e7630..3a8a9a130b51d40d6384cb273ee858c1150a9fb2 100644 (file)
@@ -8,32 +8,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)
 {
diff --git a/proto/ospf/lsalib.c b/proto/ospf/lsalib.c
new file mode 100644 (file)
index 0000000..f74cb76
--- /dev/null
@@ -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 (file)
index 0000000..e759aa0
--- /dev/null
@@ -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_ */
index 91bc9884f5ed467dddb08ddf1af0be092f8477b2..682971845336e68f07a70d6208cc56247ce00981 100644 (file)
@@ -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);
 }
 
index 5f533113e06c5c949cfdb493a325a0c503b112d0..515626bd425308dd67a6471e79f1d139837dcb29 100644 (file)
@@ -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)
index 1aee1dce8afc861897504c3a00f221385219976a..369eb76ce31584097ec07bc87df7d8274e9383ae 100644 (file)
@@ -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);
 
index bc37fc48f398483524b0398c6b5276a1478c4baf..c07d3347431b0e2a4b836eaa8a672744be393497 100644 (file)
@@ -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_ */