Skip to content

Commit

Permalink
Merge branch 'ipv4-less-uses-of-shared-ip-generator'
Browse files Browse the repository at this point in the history
Eric Dumazet says:

====================
ipv4: less uses of shared IP generator

From: Eric Dumazet <[email protected]>

We keep receiving research reports based on linux IPID generation.

Before breaking part of the Internet by switching to pure
random generator, this series reduces the need for the
shared IP generator for TCP sockets.
====================

Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
kuba-moo committed Jan 27, 2022
2 parents 153a0d1 + 23f5740 commit 3ede646
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 13 deletions.
21 changes: 10 additions & 11 deletions include/net/ip.h
Original file line number Diff line number Diff line change
Expand Up @@ -525,19 +525,18 @@ static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb,
{
struct iphdr *iph = ip_hdr(skb);

/* We had many attacks based on IPID, use the private
* generator as much as we can.
*/
if (sk && inet_sk(sk)->inet_daddr) {
iph->id = htons(inet_sk(sk)->inet_id);
inet_sk(sk)->inet_id += segs;
return;
}
if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) {
/* This is only to work around buggy Windows95/2000
* VJ compression implementations. If the ID field
* does not change, they drop every other packet in
* a TCP stream using header compression.
*/
if (sk && inet_sk(sk)->inet_daddr) {
iph->id = htons(inet_sk(sk)->inet_id);
inet_sk(sk)->inet_id += segs;
} else {
iph->id = 0;
}
iph->id = 0;
} else {
/* Unfortunately we need the big hammer to get a suitable IPID */
__ip_select_ident(net, iph, segs);
}
}
Expand Down
11 changes: 9 additions & 2 deletions net/ipv4/ip_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,19 @@ int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk,
iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr);
iph->saddr = saddr;
iph->protocol = sk->sk_protocol;
if (ip_dont_fragment(sk, &rt->dst)) {
/* Do not bother generating IPID for small packets (eg SYNACK) */
if (skb->len <= IPV4_MIN_MTU || ip_dont_fragment(sk, &rt->dst)) {
iph->frag_off = htons(IP_DF);
iph->id = 0;
} else {
iph->frag_off = 0;
__ip_select_ident(net, iph, 1);
/* TCP packets here are SYNACK with fat IPv4/TCP options.
* Avoid using the hashed IP ident generator.
*/
if (sk->sk_protocol == IPPROTO_TCP)
iph->id = (__force __be16)prandom_u32();
else
__ip_select_ident(net, iph, 1);
}

if (opt && opt->opt.optlen) {
Expand Down

0 comments on commit 3ede646

Please sign in to comment.