diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2011-07-22 00:25:58 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-07-22 00:25:58 -0400 |
commit | 87c48fa3b4630905f98268dde838ee43626a060c (patch) | |
tree | 1374b52ed0514682f836cfa0a6a683eb549c9613 /net/ipv4 | |
parent | 21efcfa0ff27776902a8a15e810147be4d937d69 (diff) |
ipv6: make fragment identifications less predictable
IPv6 fragment identification generation is way beyond what we use for
IPv4 : It uses a single generator. Its not scalable and allows DOS
attacks.
Now inetpeer is IPv6 aware, we can use it to provide a more secure and
scalable frag ident generator (per destination, instead of system wide)
This patch :
1) defines a new secure_ipv6_id() helper
2) extends inet_getid() to provide 32bit results
3) extends ipv6_select_ident() with a new dest parameter
Reported-by: Fernando Gont <fernando@gont.com.ar>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/inetpeer.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 90c5f0d1bcf3..e38213817d0a 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
@@ -391,7 +391,7 @@ static int inet_peer_gc(struct inet_peer_base *base, | |||
391 | return cnt; | 391 | return cnt; |
392 | } | 392 | } |
393 | 393 | ||
394 | struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create) | 394 | struct inet_peer *inet_getpeer(const struct inetpeer_addr *daddr, int create) |
395 | { | 395 | { |
396 | struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr; | 396 | struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr; |
397 | struct inet_peer_base *base = family_to_base(daddr->family); | 397 | struct inet_peer_base *base = family_to_base(daddr->family); |
@@ -436,7 +436,10 @@ relookup: | |||
436 | p->daddr = *daddr; | 436 | p->daddr = *daddr; |
437 | atomic_set(&p->refcnt, 1); | 437 | atomic_set(&p->refcnt, 1); |
438 | atomic_set(&p->rid, 0); | 438 | atomic_set(&p->rid, 0); |
439 | atomic_set(&p->ip_id_count, secure_ip_id(daddr->addr.a4)); | 439 | atomic_set(&p->ip_id_count, |
440 | (daddr->family == AF_INET) ? | ||
441 | secure_ip_id(daddr->addr.a4) : | ||
442 | secure_ipv6_id(daddr->addr.a6)); | ||
440 | p->tcp_ts_stamp = 0; | 443 | p->tcp_ts_stamp = 0; |
441 | p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; | 444 | p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; |
442 | p->rate_tokens = 0; | 445 | p->rate_tokens = 0; |