diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 7cdcbed3e5cb..24cbabc24582 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -207,7 +207,7 @@ struct rtable; * @inet_saddr - Sending source * @uc_ttl - Unicast TTL * @inet_sport - Source port - * @inet_id - ID counter for DF pkts + * @inet_id - ID counter for non atomic pkts * @tos - TOS * @mc_ttl - Multicasting TTL * @uc_index - Unicast outgoing device index diff --git a/include/net/ip.h b/include/net/ip.h index 6a3e8271a73b..604018cbf0f4 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -584,6 +584,13 @@ static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb, { struct iphdr *iph = ip_hdr(skb); + /* RFC 6864: the IPv4 ID of atomic datagrams has no meaning. + * DF packets without ignore_df can not be fragmented. + */ + if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) { + iph->id = 0; + return; + } /* We had many attacks based on IPID, use the private * generator as much as we can. */ @@ -603,12 +610,8 @@ static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb, iph->id = htons(val); return; } - if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) { - iph->id = 0; - } else { - /* Unfortunately we need the big hammer to get a suitable IPID */ - __ip_select_ident(net, iph, segs); - } + /* Unfortunately we need the big hammer to get a suitable IPID */ + __ip_select_ident(net, iph, segs); } static inline void ip_select_ident(struct net *net, struct sk_buff *skb,