]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
LSupdate processing improved. Now there is some bug in hashing. :-(
authorOndrej Filip <feela@network.cz>
Tue, 4 Apr 2000 15:55:55 +0000 (15:55 +0000)
committerOndrej Filip <feela@network.cz>
Tue, 4 Apr 2000 15:55:55 +0000 (15:55 +0000)
proto/ospf/dbdes.c
proto/ospf/lsalib.c
proto/ospf/lsalib.h
proto/ospf/lsreq.c
proto/ospf/lsupd.c
proto/ospf/topology.c
proto/ospf/topology.h

index c6aba3630e03c54073201f94aa6abd08ac652e21..16cf817fd9cafcdf35044f086a893c66aa9c696b 100644 (file)
@@ -76,7 +76,7 @@ ospf_dbdes_tx(struct ospf_neighbor *n)
             debug("\t%04x %08x %08x %p\n", en->lsa.type, en->lsa.id,
               en->lsa.rt, en->lsa_body);
 
-           if(sn->next==NULL)
+           if(sn==STAIL(n->ifa->oa->lsal))
            {
              break;    /* Should set some flag? */
            }
@@ -85,7 +85,7 @@ ospf_dbdes_tx(struct ospf_neighbor *n)
          }
          i--;
 
-         if(sn->next==NULL)
+         if(sn==STAIL(n->ifa->oa->lsal))
          {
            DBG("Number of LSA NOT sent: %d\n", i);
            DBG("M bit unset.\n");
@@ -128,7 +128,7 @@ ospf_dbdes_tx(struct ospf_neighbor *n)
       }
 
       sk_send_to(ifa->ip_sk,length, n->ip, OSPF_PROTO);
-      debug("%s: DB_DES sent for %u.\n", p->name, n->rid);
+      debug("%s: DB_DES sent to %u.\n", p->name, n->rid);
       if(n->myimms.bit.ms) tm_start(n->rxmt_timer,ifa->rxmtint);
       else
       {
@@ -199,6 +199,7 @@ ospf_dbdes_reqladd(struct ospf_dbdes_packet *ps, struct proto *p,
         ntohlsah(plsa+i, &(sn->lsa));
         s_add_tail(&(n->lsrql), SNODE sn);
       }
+      /* FIXME and the next part of condition? */
     }
   }
 }
index a7ef8040d7df0dd34d110c4eb66367ff040f6efd..aa7e1f9f48a7be1db559be4ed6aa2507b55db06a 100644 (file)
@@ -309,11 +309,52 @@ lsa_comp(struct ospf_lsa_header *l1, struct ospf_lsa_header *l2)
     {
       if(l1->checksum=!l2->checksum)
         return l1->checksum<l2->checksum ? CMP_OLDER : CMP_NEWER;
-      if(l1->age==MAXAGE) return CMP_NEWER;
-      if(l2->age==MAXAGE) return CMP_OLDER;
-      if(abs(l1->age-l2->age)>MAXAGEDIFF)
+      if(l1->age==LSA_MAXAGE) return CMP_NEWER;
+      if(l2->age==LSA_MAXAGE) return CMP_OLDER;
+      if(abs(l1->age-l2->age)>LSA_MAXAGEDIFF)
         return l1->age<l2->age ? CMP_NEWER : CMP_OLDER;
     }
     return CMP_SAME;
 }
 
+/* LSA can be temporarrily, but body must be mb_alloced. */
+struct top_hash_entry *
+lsa_install_new(struct ospf_lsa_header *lsa, void *body, struct ospf_area *oa)
+{
+  int change=0,i;
+  struct top_hash_entry *en;
+
+  if((en=ospf_hash_find_header(oa->gr,lsa))==NULL)
+  {
+    en=ospf_hash_get_header(oa->gr,lsa);
+    change=1;
+    s_add_tail(&oa->lsal, SNODE en);
+  }
+  else
+  {
+    if(en->lsa.options!=lsa->options) change=1;
+    if((en->lsa.age==LSA_MAXAGE)||(lsa->age==LSA_MAXAGE)) change=1;
+    if(en->lsa.length!=lsa->length) change=1;
+    else
+    {
+      u8 *k=en->lsa_body,*l=body;
+      for(i=0;i<lsa->length;i++)
+      {
+        if(*(k+i)!=*(l+i))
+       {
+         change=1;
+         break;
+       }
+      }
+      s_rem_node(SNODE en);
+      s_add_tail(&oa->lsal, SNODE en);
+    }
+  }
+  en->inst_t=now;
+  if(en->lsa_body!=NULL)mb_free(en->lsa_body);
+  en->lsa_body=body;
+  memcpy(&en->lsa,lsa,sizeof(struct ospf_lsa_header));
+  
+  /* FIXME decide if route calcualtion must be done and how */
+  return en;
+}
index 5332d2efbc30189f7cfb5cce8a3bd2db3a374ad4..bba8c26bc3a97f08f7330ee35e6a5c1a80ec6c14 100644 (file)
@@ -17,10 +17,11 @@ void ntohlsab(void *n, void *h, u8 type, u16 len);
 void lsasum_calculate(struct ospf_lsa_header *header, void *body,
   struct proto_ospf *p);
 u16 lsasum_check(struct ospf_lsa_header *h,void *body,struct proto_ospf *po);
-
 #define CMP_NEWER 1
 #define CMP_SAME 0
 #define CMP_OLDER -1
 int lsa_comp(struct ospf_lsa_header *l1, struct ospf_lsa_header *l2);
+struct top_hash_entry *lsa_install_new(struct ospf_lsa_header *lsa, void *body,
+  struct ospf_area *oa);
 
 #endif /* _BIRD_OSPF_LSALIB_H_ */
index f894c66f11190c44b314c10a6238c6edf2607f7c..716724a766fbfb87ddbacd39f9381b0f17864fb0 100644 (file)
@@ -45,7 +45,8 @@ ospf_lsreq_tx(struct ospf_neighbor *n)
     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;
+    if(sn==STAIL(n->lsrql)) break;
+    sn=sn->next;
   }
 
   length=sizeof(struct ospf_lsreq_packet)+(j-i)*sizeof(struct ospf_lsreq_header);
index 8ff39590aafccabe3a0cb5b78b398f7ab60832ae..950a1f8d8974b037c3941409c83e01d06af17771 100644 (file)
@@ -84,7 +84,7 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
   struct ospf_iface *ifa, u16 size)
 {
   u32 area,nrid,myrid;
-  struct ospf_neighbor *n;
+  struct ospf_neighbor *n,*ntmp;
   struct ospf_lsa_header *lsa;
   struct ospf_area *oa;
   struct proto_ospf *po=(struct proto_ospf *)p;
@@ -132,9 +132,24 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
       continue;
     }
     ntohlsah(lsa,&lsatmp);
-    DBG("Processing update Type: %u ID: %u RT: %u\n",lsa->type,
-        ntohl(lsa->id), ntohl(lsa->rt));
+    DBG("Processing update Type: %u ID: %u RT: %u\n",lsatmp.type,
+        lsatmp.id, lsatmp.rt);
     lsadb=ospf_hash_find_header(oa->gr, &lsatmp);
+
+    /* Remove it from link state request list */
+    WALK_LIST(NODE ifa,po->iface_list)
+      WALK_LIST(NODE ntmp,ifa->neigh_list)
+      {
+        struct top_hash_entry *en;
+        if((en=ospf_hash_find_header(ntmp->lsrqh,&lsatmp))!=NULL)
+       {
+         s_rem_node(SNODE en);
+         DBG("Removing from lsreq list for neigh %u\n", ntmp->rid);
+         ospf_hash_delete(ntmp->lsrqh,en);
+         if(EMPTY_SLIST(ntmp->lsrql)) ospf_neigh_sm(ntmp, INM_LOADDONE);
+       }
+      }
+
     if((lsatmp.age==LSA_MAXAGE)&&(lsadb==NULL))
     {
       struct ospf_neighbor *n=NULL;
@@ -142,8 +157,9 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
       int flag=0;
 
       WALK_LIST(NODE ifa,po->iface_list)
-        WALK_LIST(NODE n,ifa->neigh_list)
-          if((n->state==NEIGHBOR_EXCHANGE)&&(n->state==NEIGHBOR_LOADING))
+        WALK_LIST(NODE ntmp,ifa->neigh_list)
+          if((ntmp->state==NEIGHBOR_EXCHANGE)&&
+            (ntmp->state==NEIGHBOR_LOADING))
             flag=1;
 
       if(flag==0)
@@ -156,30 +172,32 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
     {
        struct ospf_neighbor *n=NULL;
        struct ospf_iface *ifa=NULL;
+       void *body;
 
        /* FIXME self originated? */
 
       if(lsadb && ((lsadb->inst_t-now)<MINLSARRIVAL)) continue;
 
       /* Remove old from all ret lists */
-      WALK_LIST(NODE ifa,po->iface_list)
-        WALK_LIST(NODE n,ifa->neigh_list)
-       {
-         struct top_hash_entry *en;
-         if((en=ospf_hash_find_header(n->lsrth,&lsadb->lsa))!=NULL)
-           s_rem_node(SNODE en);
-       }
+      if(lsadb)
+        WALK_LIST(NODE ifa,po->iface_list)
+          WALK_LIST(NODE ntmp,ifa->neigh_list)
+         {
+           struct top_hash_entry *en;
+           if((en=ospf_hash_find_header(ntmp->lsrth,&lsadb->lsa))!=NULL)
+           {
+             s_rem_node(SNODE en);
+             ospf_hash_delete(ntmp->lsrth,en);
+           }
+         }
 
       /* Install new */
-      memcpy(&lsadb->lsa,&lsatmp,sizeof(struct ospf_lsa_header));
-      lsadb->inst_t=now;
-      if(lsadb->lsa_body!=NULL) mb_free(lsadb->lsa_body);
-      lsadb->lsa_body=mb_alloc(p->pool,lsadb->lsa.length-
-        sizeof(struct ospf_lsa_header));
-      ntohlsab(lsa+1,lsadb->lsa_body,lsadb->lsa.type,lsadb->lsa.length);
-
-      /* FIXME lsa_flood(n,lsadb) */
-      /* FIXME ack_lsa() */
+      DBG("Allocatin body, size: %u\n",lsatmp.length-sizeof(struct ospf_lsa_header));
+      body=mb_alloc(p->pool,lsatmp.length-sizeof(struct ospf_lsa_header));
+      ntohlsab(lsa+1,body,lsatmp.type,lsatmp.length-sizeof(struct ospf_lsa_header));
+      lsadb=lsa_install_new(&lsatmp,body, oa);
+      DBG("New installed\n");
+
       continue;
     }
 
index e166b4ad02b5995cfb79826738ae46cdcb7bab71..371434b8c33ee741524cc735197e03764850d222 100644 (file)
@@ -22,8 +22,8 @@
 #define HASH_LO_STEP 2
 #define HASH_LO_MIN 8
 
-unsigned int
-make_rt_lsa(struct ospf_area *oa, struct proto_ospf *p)
+void *
+originate_rt_lsa_body(struct ospf_area *oa, u16 *length, struct proto_ospf *p)
 {
   struct ospf_iface *ifa;
   int j=0,k=0,v=0,e=0,b=0;
@@ -32,8 +32,9 @@ make_rt_lsa(struct ospf_area *oa, struct proto_ospf *p)
   struct ospf_lsa_rt_link *ln;
   struct ospf_neighbor *neigh;
   struct top_hash_entry *old;
+  struct proto_ospf *po=(struct proto_ospf *)p;
 
-  old=oa->rt;
+  DBG("%s: Originating RT_lsa body for area \"%d\".\n", po->proto.name, oa->areaid);
 
   WALK_LIST (ifa, p->iface_list) i++;
   {
@@ -145,9 +146,9 @@ make_rt_lsa(struct ospf_area *oa, struct proto_ospf *p)
     ln=(ln+1);
   }
   rt->links=i;
-  if(old->lsa_body!=NULL) mb_free(old->lsa_body);
-  old->lsa_body=rt;
-  return i*sizeof(struct ospf_lsa_rt_link)+sizeof(struct ospf_lsa_rt);
+  *length=i*sizeof(struct ospf_lsa_rt_link)+sizeof(struct ospf_lsa_rt)+
+    sizeof(struct ospf_lsa_header);
+  return rt;
 }
        
 
@@ -179,23 +180,42 @@ addifa_rtlsa(struct ospf_iface *ifa)
     oa->areaid=ifa->an;
     oa->gr=ospf_top_new(po);
     s_init_list(&(oa->lsal));
-    oa->rt=ospf_hash_get(oa->gr, rtid, rtid, LSA_T_RT);
-    s_add_head(&(oa->lsal), (snode *)oa->rt);
-    ((snode *)oa->rt)->next=NULL;
-    lsa=&(oa->rt->lsa);
-    oa->rt->lsa_body=NULL;
-    lsa->age=0;
-    lsa->sn=LSA_INITSEQNO;     /* FIXME Check it latter */
+    oa->rt=NULL;
     po->areano++;
     DBG("%s: New OSPF area \"%d\" added.\n", po->proto.name, ifa->an);
   }
 
   ifa->oa=oa;
-  oa->rt->lsa.length=make_rt_lsa(oa, po)+sizeof(struct ospf_lsa_header);
-  oa->rt->lsa.checksum=0;
-  lsasum_calculate(&(oa->rt->lsa),oa->rt->lsa_body,po);
-  /*FIXME lsa_flood(oa->rt) */
+
+  oa->rt=originate_rt_lsa(oa,po);
+}
+
+struct top_hash_entry *
+originate_rt_lsa(struct ospf_area *oa, struct proto_ospf *po)
+{
+  struct ospf_lsa_header lsa;
+  u32 rtid=po->proto.cf->global->router_id;
+  struct top_hash_entry *en;
+  void *body;
+
+  DBG("%s: Originating RT_lsa for area \"%d\".\n", po->proto.name, oa->areaid);
+
+  lsa.age=0;
+  lsa.id=rtid;
+  lsa.type=LSA_T_RT;
+  lsa.rt=rtid;
+  if(oa->rt==NULL)
+  {
+    lsa.sn=LSA_INITSEQNO;
+  }
+  else
+  {
+    lsa.sn=oa->rt->lsa.sn+1;
+  }
+  body=originate_rt_lsa_body(oa, &lsa.length, po);
+  lsasum_calculate(&lsa,body,po);
+  en=lsa_install_new(&lsa, body, oa);
+  return en;
 }
 
   
@@ -296,6 +316,13 @@ ospf_hash_find_header(struct top_graph *f, struct ospf_lsa_header *h)
 {
   return ospf_hash_find(f,h->id,h->rt,h->type);
 }
+
+struct top_hash_entry *
+ospf_hash_get_header(struct top_graph *f, struct ospf_lsa_header *h)
+{
+  return ospf_hash_get(f,h->id,h->rt,h->type);
+}
+
 struct top_hash_entry *
 ospf_hash_find(struct top_graph *f, u32 lsa, u32 rtr, u32 type)
 {
index d0e9ad9b7150e21cfcfd0c5e19f94e8e3d431cf6..e146c6f3df5fd75a5f8537fae6fc647d252b0066 100644 (file)
@@ -32,9 +32,12 @@ struct top_graph *ospf_top_new(struct proto_ospf *);
 void ospf_top_free(struct top_graph *);
 void ospf_top_dump(struct top_graph *);
 struct top_hash_entry *ospf_hash_find_header(struct top_graph *f, struct ospf_lsa_header *h);
+struct top_hash_entry *ospf_hash_get_header(struct top_graph *f, struct ospf_lsa_header *h);
 struct top_hash_entry *ospf_hash_find(struct top_graph *, u32 lsa, u32 rtr, u32 type);
 struct top_hash_entry *ospf_hash_get(struct top_graph *, u32 lsa, u32 rtr, u32 type);
 void ospf_hash_delete(struct top_graph *, struct top_hash_entry *);
 void addifa_rtlsa(struct ospf_iface *ifa);
+struct top_hash_entry *originate_rt_lsa(struct ospf_area *oa,
+  struct proto_ospf *po);
 
 #endif /* _BIRD_OSPF_TOPOLOGY_H_ */