Index: sys/netinet6/ip6_id.c =================================================================== --- sys/netinet6/ip6_id.c +++ sys/netinet6/ip6_id.c @@ -89,9 +89,12 @@ #include #include #include +#include #include #include +#include + #include #include #include @@ -171,6 +174,25 @@ return (s); } +static inline uint32_t +arc4random_wrapper(void) +{ + /* + * Is it sane to generate potentially non-random IPv6 flowids if random + * isn't seeded yet, rather than blocking indefinitely? Or do IPv6 + * flowids really need to be unpredictable (and would prefer to block + * indefinitely until entropy is available)? + */ + + if (!is_random_seeded()) { + uint64_t cc; + + cc = get_cyclecount(); + return ((cc >> 32) ^ cc); + } + return (arc4random()); +} + /* * Initializes the seed and chooses a suitable generator. Also toggles * the msb flag. The msb flag is used to generate two distinct @@ -185,20 +207,20 @@ u_int32_t j, i; int noprime = 1; - p->ru_x = arc4random() % p->ru_m; + p->ru_x = arc4random_wrapper() % p->ru_m; /* (bits - 1) bits of random seed */ - p->ru_seed = arc4random() & (~0U >> (32 - p->ru_bits + 1)); - p->ru_seed2 = arc4random() & (~0U >> (32 - p->ru_bits + 1)); + p->ru_seed = arc4random_wrapper() & (~0U >> (32 - p->ru_bits + 1)); + p->ru_seed2 = arc4random_wrapper() & (~0U >> (32 - p->ru_bits + 1)); /* Determine the LCG we use */ - p->ru_b = (arc4random() & (~0U >> (32 - p->ru_bits))) | 1; + p->ru_b = (arc4random_wrapper() & (~0U >> (32 - p->ru_bits))) | 1; p->ru_a = pmod(p->ru_agen, - (arc4random() & (~0U >> (32 - p->ru_bits))) & (~1U), p->ru_m); + (arc4random_wrapper() & (~0U >> (32 - p->ru_bits))) & (~1U), p->ru_m); while (p->ru_b % 3 == 0) p->ru_b += 2; - j = arc4random() % p->ru_n; + j = arc4random_wrapper() % p->ru_n; /* * Do a fast gcd(j, RU_N - 1), so we can find a j with @@ -232,7 +254,7 @@ initid(p); /* Skip a random number of ids */ - n = arc4random() & 0x3; + n = arc4random_wrapper() & 0x3; if (p->ru_counter + n >= p->ru_max) initid(p);