Triggered updates should now actually work. Fixed metric=16 -> time it

out logic.
This commit is contained in:
Pavel Machek 1999-11-25 13:38:25 +00:00
parent 774f149959
commit 7e61cac325
3 changed files with 62 additions and 96 deletions

View file

@ -8,61 +8,6 @@ router id 62.168.0.1;
define xyzzy = 120+10; 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 filter testf
int j; int j;
{ {

View file

@ -8,15 +8,18 @@
FIXME: IpV6 support: packet size FIXME: IpV6 support: packet size
FIXME: IpV6 support: use right address for broadcasts FIXME: IpV6 support: use right address for broadcasts
FIXME: IpV6 support: receive "route using" blocks 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: fold rip_connection into rip_interface?
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).
We are not going to honour requests for sending part of We are not going to honour requests for sending part of
routing table. That would need to turn split horizont off, routing table. That would need to turn split horizont off,
etc. 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 #define LOCAL_DEBUG
@ -64,6 +67,46 @@ rip_tx_err( sock *s, int err )
log( L_ERR "Unexpected error at rip transmit: %m" ); 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 static void
rip_tx( sock *s ) rip_tx( sock *s )
{ {
@ -94,42 +137,11 @@ rip_tx( sock *s )
i = !!P_CF->authtype; i = !!P_CF->authtype;
FIB_ITERATE_START(&P->rtable, &c->iter, z) { FIB_ITERATE_START(&P->rtable, &c->iter, z) {
struct rip_entry *e = (struct rip_entry *) 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)) { if (i++ == ((P_CF->authtype == AT_MD5) ? PACKET_MD5_MAX : PACKET_MAX)) {
FIB_ITERATE_PUT(&c->iter, z); FIB_ITERATE_PUT(&c->iter, z);
goto break_loop; goto break_loop;
@ -143,6 +155,8 @@ rip_tx( sock *s )
rip_outgoing_authentication(p, (void *) &packet->block[0], packet, i); rip_outgoing_authentication(p, (void *) &packet->block[0], packet, i);
DBG( ", sending %d blocks, ", i ); DBG( ", sending %d blocks, ", i );
if (!i)
continue;
if (ipa_nonzero(c->daddr)) if (ipa_nonzero(c->daddr))
i = sk_send_to( s, sizeof( struct rip_packet_heading ) + i*sizeof( struct rip_block ), c->daddr, c->dport ); 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 ); if (i<0) rip_tx_err( s, i );
DBG( "blocked\n" ); DBG( "blocked\n" );
return;
} }
static void static void
@ -166,6 +182,7 @@ rip_sendto( struct proto *p, ip_addr daddr, int dport, struct rip_interface *rif
if (rif->busy) { if (rif->busy) {
log (L_WARN "Interface %s is much too slow, dropping request", iface->name); log (L_WARN "Interface %s is much too slow, dropping request", iface->name);
/* FIXME: memory leak */
return; return;
} }
rif->busy = c; rif->busy = c;
@ -424,6 +441,7 @@ rip_timer(timer *t)
DBG( "RIP: Broadcasting routing tables\n" ); DBG( "RIP: Broadcasting routing tables\n" );
{ {
struct rip_interface *rif; struct rip_interface *rif;
P->tx_count ++;
WALK_LIST( rif, P->interfaces ) { WALK_LIST( rif, P->interfaces ) {
struct iface *iface = rif->iface; struct iface *iface = rif->iface;
@ -432,6 +450,7 @@ rip_timer(timer *t)
if (rif->patt->mode & IM_QUIET) continue; if (rif->patt->mode & IM_QUIET) continue;
if (!(iface->flags & IF_UP)) continue; if (!(iface->flags & IF_UP)) continue;
rif->triggered = (P->tx_count % 6);
rip_sendto( p, IPA_NONE, 0, rif ); 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) if (old->u.rip.metric > new->u.rip.metric)
return 1; 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; 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 */ new->u.rip.lastmodX = now - P_CF->timeout_time; /* Check this: if new metric is 16, act as it was timed out */
} }

View file

@ -101,6 +101,7 @@ struct rip_interface {
sock *sock; sock *sock;
struct rip_connection *busy; struct rip_connection *busy;
struct rip_patt *patt; struct rip_patt *patt;
int triggered;
}; };
struct rip_patt { struct rip_patt {
@ -144,6 +145,7 @@ struct rip_proto {
list garbage; list garbage;
list interfaces; /* Interfaces we really know about */ list interfaces; /* Interfaces we really know about */
int magic; int magic;
int tx_count; /* Do one regular update once in a while */
}; };