]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Some lsack work. There is something very worng. :-( It locked my network.
authorOndrej Filip <feela@network.cz>
Tue, 18 Apr 2000 01:06:16 +0000 (01:06 +0000)
committerOndrej Filip <feela@network.cz>
Tue, 18 Apr 2000 01:06:16 +0000 (01:06 +0000)
proto/ospf/hello.c
proto/ospf/lsack.c
proto/ospf/lsack.h
proto/ospf/lsupd.c
proto/ospf/neighbor.c
proto/ospf/ospf.h
proto/ospf/packet.c
proto/ospf/packet.h

index 77d114c71202e3c6df12dfe4d8657306eb1a7afc..aea9c142aaa605a558d6cd80ecd479067695a1c1 100644 (file)
@@ -118,6 +118,13 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p,
     n->lsrr_timer->hook=lsrr_timer_hook;
     n->lsrr_timer->recurrent=ifa->rxmtint;
     DBG("%s: Installing lsrr timer.\n", p->name);
+    init_list(&n->ackl);
+    n->ackd_timer=tm_new(p->pool);
+    n->ackd_timer->data=n;
+    n->ackd_timer->randomize=0;
+    n->ackd_timer->hook=ackd_timer_hook;
+    n->ackd_timer->recurrent=ifa->rxmtint/2;   /* FIXME use some config? */
+    DBG("%s: Installing ackd timer.\n", p->name);
   }
   ospf_neigh_sm(n, INM_HELLOREC);
 
index c5f6bed01c161c9dd2c1759c276dff338fd9ef77..53346bc2794350c23ac2fc91ce327c3504e1c117 100644 (file)
 
 #include "ospf.h"
 
+/* Note, that h is in network endianity! */
 void
-ospf_lsack_tx(struct ospf_neighbor *n)
+ospf_lsack_direct_tx(struct ospf_neighbor *n,struct ospf_lsa_header *h)
 {
-  /* FIXME Go on! */
+  struct ospf_packet *op;
+  struct ospf_lsack_packet *pk;
+  sock *sk=n->ifa->ip_sk;
+  u16 len;
+
+  pk=(struct ospf_lsack_packet *)sk->tbuf;
+  op=(struct ospf_packet *)sk->tbuf;
+
+  fill_ospf_pkt_hdr(n->ifa, pk, LSUPD);
+
+  memcpy(pk+1,h,sizeof(struct ospf_lsa_header));
+  len=sizeof(struct ospf_lsack_packet)+sizeof(struct ospf_lsa_header);
+  op->length=htons(len);
+  ospf_pkt_finalize(n->ifa, op);
+  sk_send_to(sk,len, n->ip, OSPF_PROTO);
+}
+
+void
+ospf_lsa_delay(struct ospf_neighbor *n,struct ospf_lsa_header *h,
+  struct proto *p)
+{
+  struct lsah_n *no;
+
+  no=mb_alloc(p->pool,sizeof(struct lsah_n));
+  memcpy(&no->lsa,h,sizeof(struct ospf_lsa_header));
+  add_tail(&n->ackl, NODE no);
+
+}
+
+void
+ackd_timer_hook(timer *t)
+{
+  struct ospf_neighbor *n=t->data;
+  if(!EMPTY_LIST(n->ackl)) ospf_lsack_delay_tx(n);
+}
+
+void
+ospf_lsack_delay_tx(struct ospf_neighbor *n)
+{
+  struct ospf_packet *op;
+  struct ospf_lsack_packet *pk;
+  sock *sk;
+  u16 len,i=0;
+  struct ospf_lsa_header *h;
+  struct lsah_n *no;
+  struct ospf_iface *ifa=n->ifa;
+
+  if(ifa->type==OSPF_IT_BCAST)
+  {
+    sk=ifa->hello_sk;
+  }
+  else
+  {
+    sk=ifa->ip_sk;
+  }
+
+  pk=(struct ospf_lsack_packet *)sk->tbuf;
+  op=(struct ospf_packet *)sk->tbuf;
+
+  fill_ospf_pkt_hdr(n->ifa, pk, LSUPD);
+  h=(struct ospf_lsa_header *)(pk+1);
+
+  while(!EMPTY_LIST(n->ackl))
+  {
+    no=(struct lsah_n *)HEAD(n->ackl);
+    memcpy(h+i,&no->lsa, sizeof(struct ospf_lsa_header));
+    i++;
+    rem_node(NODE n);
+    if((i*sizeof(struct ospf_lsa_header)+sizeof(struct ospf_lsack_packet)-SIPH)>
+      n->ifa->iface->mtu)
+    {
+      if(!EMPTY_LIST(n->ackl))
+      {
+        len=sizeof(struct ospf_lsack_packet)+i*sizeof(struct ospf_lsa_header);
+       op->length=htons(len);
+       ospf_pkt_finalize(n->ifa, op);
+        if(ifa->type==OSPF_IT_BCAST)
+       {
+          if((ifa->state==OSPF_IS_DR)||(ifa->state==OSPF_IS_BACKUP))
+         {
+           sk_send_to(sk ,len, AllSPFRouters, OSPF_PROTO);
+         }
+         else
+         {
+           sk_send_to(sk ,len, AllDRouters, OSPF_PROTO);
+         }
+       }
+       else
+       {
+          sk_send_to_agt(sk, len, ifa, NEIGHBOR_EXCHANGE);
+       }
+
+       fill_ospf_pkt_hdr(n->ifa, pk, LSUPD);
+       h=(struct ospf_lsa_header *)(pk+1);
+       i=0;
+      }
+    }
+  }
+
+  len=sizeof(struct ospf_lsack_packet)+i*sizeof(struct ospf_lsa_header);
+  op->length=htons(len);
+  ospf_pkt_finalize(n->ifa, op);
+  if(ifa->type==OSPF_IT_BCAST)
+  {
+    if((ifa->state==OSPF_IS_DR)||(ifa->state==OSPF_IS_BACKUP))
+    {
+      sk_send_to(sk ,len, AllSPFRouters, OSPF_PROTO);
+    }
+    else
+    {
+      sk_send_to(sk ,len, AllDRouters, OSPF_PROTO);
+    }
+  }
+  else
+  {
+    sk_send_to_agt(sk, len, ifa, NEIGHBOR_EXCHANGE);
+  }
 }
 
+
+
 void
 ospf_lsack_rx(struct ospf_lsack_packet *ps, struct proto *p,
   struct ospf_iface *ifa, u16 size)
@@ -60,10 +179,3 @@ ospf_lsack_rx(struct ospf_lsack_packet *ps, struct proto *p,
     ospf_hash_delete(n->lsrth,en);
   }  
 }
-
-void
-add_ack_list(struct ospf_neighbor *n,struct ospf_lsa_header *lsa)
-{
-  /* FIXME Go on */
-}
-
index 053e0b514f3f6653d027284aee34eb748ef59d08..5c4e5c4506e1e912bdf1799d0cbb7ff536720061 100644 (file)
@@ -9,10 +9,16 @@
 
 #ifndef _BIRD_OSPF_LSACK_H_
 #define _BIRD_OSPF_LSACK_H_
+struct lsah_n {
+  node n;
+  struct ospf_lsa_header lsa;
+};
 
-void ospf_lsack_tx(struct ospf_neighbor *n);
+void ospf_lsack_direct_tx(struct ospf_neighbor *n,struct ospf_lsa_header *h);
 void ospf_lsack_rx(struct ospf_lsack_packet *ps, struct proto *p,
   struct ospf_iface *ifa, u16 size);
-void add_ack_list(struct ospf_neighbor *n,struct ospf_lsa_header *lsa);
-
+void ackd_timer_hook(timer *t);
+void ospf_lsack_delay_tx(struct ospf_neighbor *n);
+void ospf_lsa_delay(struct ospf_neighbor *n,struct ospf_lsa_header *h,
+  struct proto *p);
 #endif /* _BIRD_OSPF_LSACK_H_ */
index 62b6f76a7c0ffc32860169c466399e2bc0516e59..23e7b1cb630af1b9606ed9b483ff982ec86a4b69 100644 (file)
@@ -122,12 +122,7 @@ flood_lsa(struct ospf_neighbor *n, struct ospf_lsa_header *hn,
 
       if(ifa->type==OSPF_IT_NBMA)
       {
-       struct ospf_neighbor *nnn;
-        WALK_LIST(NODE nnn,ifa->neigh_list)
-       {
-          if(nnn->state>NEIGHBOR_EXSTART)
-            sk_send_to(sk,len, nnn->ip, OSPF_PROTO);
-       }
+        sk_send_to_agt(sk ,len, ifa, NEIGHBOR_EXCHANGE);
       }
       else
       {
@@ -267,19 +262,19 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
     /* pg 143 (4) */
     if((lsatmp.age==LSA_MAXAGE)&&(lsadb==NULL))
     {
-      struct ospf_neighbor *n=NULL;
-      struct ospf_iface *ifa=NULL;
       int flag=0;
+      struct ospf_iface *ifatmp;
 
-      WALK_LIST(NODE ifa,po->iface_list)
-        WALK_LIST(NODE ntmp,ifa->neigh_list)
+      WALK_LIST(NODE ifatmp,po->iface_list)
+        WALK_LIST(NODE ntmp,ifatmp->neigh_list)
           if((ntmp->state==NEIGHBOR_EXCHANGE)&&
             (ntmp->state==NEIGHBOR_LOADING))
             flag=1;
 
       if(flag==0)
       {
-        add_ack_list(n,lsa);
+        ospf_lsack_direct_tx(n,lsa);
+
        continue;
       }
     }
@@ -317,7 +312,11 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
       lsadb=lsa_install_new(&lsatmp,body, oa);
       DBG("New LSA installed in DB\n");
 
-      /* FIXME 144 (5e) ack */
+      if(ifa->state==OSPF_IS_BACKUP)
+      {
+        if(ifa->drid==n->rid) ospf_lsa_delay(n, lsa, p);
+      }
+      else if(ifa->drid==n->rid) ospf_lsa_delay(n, lsa, p);
       /* FIXME 145 (5f) self originated? */
 
       continue;
@@ -330,13 +329,25 @@ ospf_lsupd_rx(struct ospf_lsupd_packet *ps, struct proto *p,
     {
        struct top_hash_entry *en;
        if((en=ospf_hash_find_header(n->lsrth,&lsadb->lsa))!=NULL)
+       {
          s_rem_node(SNODE en);
-        /* FIXME ack_lsa() */
+         if(ifa->state==OSPF_IS_BACKUP)
+         {
+           if(n->rid==ifa->drid) ospf_lsa_delay(n, lsa, p);
+         }
+       }
+       else
+       {
+         ospf_lsack_direct_tx(n,lsa);
+       }
        continue;
     }
 
     /* pg145 (8) */
-    if((lsadb->lsa.age==LSA_MAXAGE)&&(lsadb->lsa.sn==LSA_MAXSEQNO)) continue;
+    if((lsadb->lsa.age==LSA_MAXAGE)&&(lsadb->lsa.sn==LSA_MAXSEQNO))
+    {
+      continue;
+    }
 
     {
       list l;
index e57143e7a7c9f1951af9213b00c9f6e3ba589d93..f52ff67f86d20e8b87eeda712456e45b6d03c0dd 100644 (file)
@@ -215,6 +215,7 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event)
        s_init(&(n->lsrqi), &(n->lsrql));
        s_init(&(n->lsrti), &(n->lsrtl));
        tm_start(n->lsrr_timer,n->ifa->rxmtint);
+       tm_start(n->ackd_timer,n->ifa->rxmtint/2);
       }
       else die("NEGDONE and I'm not in EXSTART?\n");
       break;
index 6bcaef3c06b421107c9f8813c254fca96f269530..00397870eafffe5a7852489fffd748900567e689 100644 (file)
@@ -286,6 +286,8 @@ struct ospf_neighbor
   void *ldbdes;                /* Last database description packet */
   timer *rxmt_timer;   /* RXMT timer */
   timer *lsrr_timer;   /* Link state requiest retransmition timer */
+  list ackl;
+  timer *ackd_timer;   /* Delayed ack timer */
 };
 
 /* Definitions for interface state machine */
index cefc125e8bff76740236f4dee525511336168eca..b04fa9476cadc09a7b7117e956aea098633d65ee 100644 (file)
@@ -187,3 +187,12 @@ ospf_err_hook(sock *sk, int err)
   DBG("%s: Err_Hook called on interface %s\n", p->name,sk->iface->name);
 }
 
+void
+sk_send_to_agt(sock *sk, u16 len, struct ospf_iface *ifa, u8 state)
+{
+  struct ospf_neighbor *n;
+
+  WALK_LIST(NODE n,ifa->neigh_list)
+    if(n->state>=state)
+      sk_send_to(sk, len, n->ip, OSPF_PROTO);
+}                                                                       
index 1997c06d44cdeb01c0a3ce9da5f1ad6b80ddf77b..23999a23772dbe901a3a0b496c8021604c30b508 100644 (file)
@@ -16,5 +16,6 @@ void ospf_pkt_finalize(struct ospf_iface *ifa, struct ospf_packet *pkt);
 int  ospf_rx_hook(sock *sk, int size);
 void ospf_tx_hook(sock *sk);
 void ospf_err_hook(sock *sk, int err);
+void sk_send_to_agt(sock *sk, u16 len, struct ospf_iface *ifa, u8 state);
 
 #endif /* _BIRD_OSPF_PACKET_H_ */