--- 2.6/drivers/char/random.c 2004-10-02 19:30:18.583688301 +0200 +++ build-2.6/drivers/char/random.c 2004-10-02 19:09:54.288451293 +0200 @@ -2184,7 +2184,7 @@ #undef K3 /* This should not be decreased so low that ISNs wrap too fast. */ -#define REKEY_INTERVAL 300 +#define REKEY_INTERVAL (300*HZ) /* * Bit layout of the tcp sequence numbers (before adding current time): * bit 24-31: increased after every key exchange @@ -2210,49 +2210,55 @@ #define HASH_MASK ( (1<rekey_time = tv.tv_sec; - memcpy(keyptr->secret, tmp.secret, sizeof(keyptr->secret)); + get_random_bytes(keyptr->secret, sizeof(keyptr->secret)); keyptr->count = (ip_cnt&COUNT_MASK)<rekey_time || (time - keyptr->rekey_time) > REKEY_INTERVAL) { - schedule_work(&rekey_work); - } + smp_rmb(); return keyptr; } +static __init int seqgen_init(void) +{ + rekey_seq_generator(NULL); + return 0; +} +late_initcall(seqgen_init); + #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) __u32 secure_tcpv6_sequence_number(__u32 *saddr, __u32 *daddr, __u16 sport, __u16 dport) @@ -2260,14 +2266,12 @@ struct timeval tv; __u32 seq; __u32 hash[12]; - struct keydata *keyptr; + struct keydata *keyptr = get_keyptr(); /* The procedure is the same as for IPv4, but addresses are longer. * Thus we must use twothirdsMD4Transform. */ - do_gettimeofday(&tv); /* We need the usecs below... */ - keyptr = check_and_rekey(tv.tv_sec); memcpy(hash, saddr, 16); hash[4]=(sport << 16) + dport; @@ -2275,6 +2279,8 @@ seq = twothirdsMD4Transform(daddr, hash) & HASH_MASK; seq += keyptr->count; + + do_gettimeofday(&tv); seq += tv.tv_usec + tv.tv_sec*1000000; return seq; @@ -2288,13 +2294,7 @@ struct timeval tv; __u32 seq; __u32 hash[4]; - struct keydata *keyptr; - - /* - * Pick a random secret every REKEY_INTERVAL seconds. - */ - do_gettimeofday(&tv); /* We need the usecs below... */ - keyptr = check_and_rekey(tv.tv_sec); + struct keydata *keyptr = get_keyptr(); /* * Pick a unique starting offset for each TCP connection endpoints @@ -2317,6 +2317,7 @@ * That's funny, Linux has one built in! Use it! * (Networks are faster now - should this be increased?) */ + do_gettimeofday(&tv); seq += tv.tv_usec + tv.tv_sec*1000000; #if 0 printk("init_seq(%lx, %lx, %d, %d) = %d\n", @@ -2335,7 +2336,7 @@ struct keydata *keyptr; __u32 hash[4]; - keyptr = check_and_rekey(get_seconds()); + keyptr = get_keyptr(); /* * Pick a unique starting offset for each IP destination.