]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Triggered updates should now actually work. Fixed metric=16 -> time it
authorPavel Machek <pavel@ucw.cz>
Thu, 25 Nov 1999 13:38:25 +0000 (13:38 +0000)
committerPavel Machek <pavel@ucw.cz>
Thu, 25 Nov 1999 13:38:25 +0000 (13:38 +0000)
out logic.

bird.conf
proto/rip/rip.c
proto/rip/rip.h

index ec154759fa30a016a7b95ae6feec5342b0f6ac8a..f024c1649663256096c8069e5c9861ef132aec12 100644 (file)
--- a/bird.conf
+++ b/bird.conf
@@ -8,61 +8,6 @@ router id 62.168.0.1;
 
 define xyzzy = 120+10;
 
-function callme ( int arg1; int arg2 )
-int local1;
-int local2;
-int i;
-{
-       print "Function callme called arguments " arg1 " and " arg2;
-       i = arg2;
-
-       case arg1 {
-       2: print "dva"; print "jeste jednou dva";
-       3 .. 5: print "tri az pet";
-       else: print "neco jineho";
-       }       
-}
-
-function startup () 
-int i;
-prefix px;
-ip p;
-{ 
-       print "Testing filter language:";
-       i = 4; 
-       i = 1230 + i; 
-       i = ( i + 0 );
-       print "  arithmetics: 1234 = " i;
-       printn "  if statements ";
-       if i = 4 then { print "*** FAIL: if 0"; quitbird; } else printn ".";
-       if 1234 = i then printn "."; else { print "*** FAIL: if 1 else"; }
-       if 1 <= 1 then printn "."; else { print "*** FAIL: test 3"; }
-       if 1234 < 1234 then { print "*** FAIL: test 4"; quitbird; } else print "ok";
-       print "  data types; must be true: " 1.2.3.4 = 1.2.3.4 "," 1 ~ [1,2,3] "," 5 ~ [1..20] "," 2 ~ [ 1, 2, 3 ] "," 5 ~ [ 4 .. 7 ] "," 1.2.3.4 ~ [ 1.2.3.3..1.2.3.5 ] "," 1.2.3.4 ~ 1.2.3.4/8 "," 1.2.3.4/8 ~ 1.2.3.4/8 "," 1.2.3.4/8 ~ [ 1.2.3.4/8+ ] "," 1.2.3.4/16 ~ [ 1.2.3.4/8{ 15 , 16 } ] "," defined(1) "," defined(1.2.3.4);
-       print "  data types: must be false: " 1 ~ [ 2, 3, 4 ] "," 5 ~ [ 2, 3, 4, 7..11 ] "," 1.2.3.4 ~ [ 1.2.3.3, 1.2.3.5 ] "," (1,2) > (2,2) "," (1,1) > (1,1) "," 1.2.3.4/8 ~ [ 1.2.3.4/8- ] "," 1.2.3.4/17 ~ [ 1.2.3.4/8{ 15 , 16 } ];
-
-       px = 1.2.3.4/18;
-       print "Testing prefixes: 1.2.3.4/18 = " px;
-       p = 127.1.2.3;
-       print "Testing mask : 127.0.0.0 = " p.mask(8);
-       print "Testing pairs: (1,2) = " (1,2);
-       print "Set of enums: " RTSDUMMY;
-
-       print "What will this do? " [ 1, 2, 1, 1, 1, 3, 4, 1, 1, 1, 5 ];
-
-       print "Testing functions...";
-#      callme ( 1, 2 );
-       callme ( 2, 2 );
-       callme ( 2, 2 );
-       callme ( 3, 2 );
-       callme ( 4, 2 );
-       callme ( 7, 2 );
-
-       print "done";
-       quitbird;
-#      print "*** FAIL: this is unreachable"; 
-}
-
 filter testf 
 int j; 
 { 
index 2890f61e106616dc30845338fe139b2eb828d46b..1fdb179d3df22d2f0d7dc64152851cf7bf1e829e 100644 (file)
@@ -8,15 +8,18 @@
        FIXME: IpV6 support: packet size
        FIXME: IpV6 support: use right address for broadcasts
        FIXME: IpV6 support: receive "route using" blocks
-       FIXME: Do we send "triggered updates" correctly? No.
-       FIXME: When route's metric changes to 16, start garbage collection immediately? Do _not_ restart on new updates with metric == 16.
-       FIXME: When route's 60 seconds old and we get same metric, use that!
-       FIXME: Triggered updates. When triggered update was sent, don't send new one for something between 1 and 5 seconds (and send one after that).
+
+       FIXME: fold rip_connection into rip_interface?
 
        We are not going to honour requests for sending part of
        routing table. That would need to turn split horizont off,
        etc.  
+
+       Triggered updates. When triggered update was sent, don't send
+       new one for something between 1 and 5 seconds (and send one
+       after that), says RFC. We do something else: once in 5 second
+       we look for any changed routes and broadcast them.
+
  */
 
 #define LOCAL_DEBUG
@@ -64,6 +67,46 @@ rip_tx_err( sock *s, int err )
   log( L_ERR "Unexpected error at rip transmit: %m" );
 }
 
+static void
+rip_tx_prepare(struct proto *p, ip_addr daddr, struct rip_block *b, struct rip_entry *e )
+{
+  DBG( "." );
+  b->family  = htons( 2 ); /* AF_INET */
+  b->tag     = htons( e->tag );
+  b->network = e->n.prefix;
+#ifndef IPV6
+  b->netmask = ipa_mkmask( e->n.pxlen );
+  ipa_hton( b->netmask );
+  b->nexthop = IPA_NONE;       
+  {
+    /*
+     *  FIXME:  This DOESN'T work. The s->daddr will be typically
+     *  a broadcast or multicast address which will be of course
+     *  rejected by the neighbor cache. I've #ifdef'd out the whole
+     *  test to avoid dereferencing NULL pointer.  --mj
+     */
+#if 0
+    neighbor *n1, *n2;
+    n1 = neigh_find( p, &daddr, 0 );   /* FIXME, mj: this is neccessary for responses, still it is too complicated for common case */
+    n2 = neigh_find( p, &e->nexthop, 0 );
+    if (n1->iface == n2->iface)
+      b->nexthop = e->nexthop;
+    else
+#endif
+      b->nexthop = IPA_NONE;   
+  }
+  ipa_hton( b->nexthop );
+#else
+  b->pxlen = e->n.pxlen;
+#endif
+  b->metric  = htonl( e->metric );
+  if (ipa_equal(e->whotoldme, daddr)) {        /* FIXME: ouch, daddr is some kind of broadcast address. How am I expected to do split horizont?!?!? */
+    DBG( "(split horizont)" );
+    b->metric = P_CF->infinity;
+  }
+  ipa_hton( b->network );
+}
+
 static void
 rip_tx( sock *s )
 {
@@ -94,42 +137,11 @@ rip_tx( sock *s )
     i = !!P_CF->authtype;
     FIB_ITERATE_START(&P->rtable, &c->iter, z) {
       struct rip_entry *e = (struct rip_entry *) z;
-      DBG( "." );
-      packet->block[i].family  = htons( 2 ); /* AF_INET */
-      packet->block[i].tag     = htons( e->tag );
-      packet->block[i].network = e->n.prefix;
-#ifndef IPV6
-      packet->block[i].netmask = ipa_mkmask( e->n.pxlen );
-      ipa_hton( packet->block[i].netmask );
-      packet->block[i].nexthop = IPA_NONE;     
-      {
-       /*
-        *  FIXME:  This DOESN'T work. The s->daddr will be typically
-        *  a broadcast or multicast address which will be of course
-        *  rejected by the neighbor cache. I've #ifdef'd out the whole
-        *  test to avoid dereferencing NULL pointer.  --mj
-        */
-#if 0
-       neighbor *n1, *n2;
-       n1 = neigh_find( p, &s->daddr, 0 );     /* FIXME, mj: this is neccessary for responses, still it is too complicated for common case */
-       n2 = neigh_find( p, &e->nexthop, 0 );
-       if (n1->iface == n2->iface)
-         packet->block[i].nexthop = e->nexthop;
-       else
-#endif
-         packet->block[i].nexthop = IPA_NONE;  
-      }
-      ipa_hton( packet->block[i].nexthop );
-#else
-      packet->block[i].pxlen = e->n.pxlen;
-#endif
-      packet->block[i].metric  = htonl( e->metric );
-      if (ipa_equal(e->whotoldme, s->daddr)) {
-       DBG( "(split horizont)" );
-       packet->block[i].metric = P_CF->infinity;
-      }
-      ipa_hton( packet->block[i].network );
 
+      if (rif->triggered && (!(e->updated < now-5)))
+       continue;
+
+      rip_tx_prepare( p, s->daddr, packet->block + i, e );
       if (i++ == ((P_CF->authtype == AT_MD5) ? PACKET_MD5_MAX : PACKET_MAX)) {
        FIB_ITERATE_PUT(&c->iter, z);
        goto break_loop;
@@ -143,6 +155,8 @@ rip_tx( sock *s )
       rip_outgoing_authentication(p, (void *) &packet->block[0], packet, i);
 
     DBG( ", sending %d blocks, ", i );
+    if (!i)
+      continue;
 
     if (ipa_nonzero(c->daddr))
       i = sk_send_to( s, sizeof( struct rip_packet_heading ) + i*sizeof( struct rip_block ), c->daddr, c->dport );
@@ -155,6 +169,8 @@ rip_tx( sock *s )
   
   if (i<0) rip_tx_err( s, i );
   DBG( "blocked\n" );
+  return;
+
 }
 
 static void
@@ -166,6 +182,7 @@ rip_sendto( struct proto *p, ip_addr daddr, int dport, struct rip_interface *rif
 
   if (rif->busy) {
     log (L_WARN "Interface %s is much too slow, dropping request", iface->name);
+    /* FIXME: memory leak */
     return;
   }
   rif->busy = c;
@@ -424,6 +441,7 @@ rip_timer(timer *t)
   DBG( "RIP: Broadcasting routing tables\n" );
   {
     struct rip_interface *rif;
+    P->tx_count ++;
 
     WALK_LIST( rif, P->interfaces ) {
       struct iface *iface = rif->iface;
@@ -432,6 +450,7 @@ rip_timer(timer *t)
       if (rif->patt->mode & IM_QUIET) continue;
       if (!(iface->flags & IF_UP)) continue;
 
+      rif->triggered = (P->tx_count % 6);
       rip_sendto( p, IPA_NONE, 0, rif );
     }
   }
@@ -694,7 +713,7 @@ rip_rte_better(struct rte *new, struct rte *old)
   if (old->u.rip.metric > new->u.rip.metric)
     return 1;
 
-  if (new->u.rip.metric == 16) {
+  if ((old->u.rip.metric != 16) && (new->u.rip.metric == 16)) {
     struct proto *p = new->attrs->proto;
     new->u.rip.lastmodX = now - P_CF->timeout_time;    /* Check this: if new metric is 16, act as it was timed out */
   }
index 2f4d0372856fe2855f217c5569c3fbc4339be0d5..2b5a2d299da4c021051960b6d7fa84c37982a106 100644 (file)
@@ -101,6 +101,7 @@ struct rip_interface {
   sock *sock;
   struct rip_connection *busy;
   struct rip_patt *patt;  
+  int triggered;
 };
 
 struct rip_patt {
@@ -144,6 +145,7 @@ struct rip_proto {
   list garbage;
   list interfaces;     /* Interfaces we really know about */
   int magic;
+  int tx_count;                /* Do one regular update once in a while */
 };