Skip to content

Commit 490ab08

Browse files
Pravin B Shelardavem330
authored andcommitted
IP_GRE: Fix IP-Identification.
GRE-GSO generates ip fragments with id 0,2,3,4... for every GSO packet, which is not correct. Following patch fixes it by setting ip-header id unique id of fragments are allowed. As Eric Dumazet suggested it is optimized by using inner ip-header whenever inner packet is ipv4. Signed-off-by: Pravin B Shelar <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2bedc2e commit 490ab08

File tree

3 files changed

+23
-3
lines changed

3 files changed

+23
-3
lines changed

include/net/ipip.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,21 @@ static inline void iptunnel_xmit(struct sk_buff *skb, struct net_device *dev)
7171
}
7272
}
7373

74+
static inline void tunnel_ip_select_ident(struct sk_buff *skb,
75+
const struct iphdr *old_iph,
76+
struct dst_entry *dst)
77+
{
78+
struct iphdr *iph = ip_hdr(skb);
79+
80+
if (iph->frag_off & htons(IP_DF))
81+
iph->id = 0;
82+
else {
83+
/* Use inner packet iph-id if possible. */
84+
if (skb->protocol == htons(ETH_P_IP) && old_iph->id)
85+
iph->id = old_iph->id;
86+
else
87+
__ip_select_ident(iph, dst,
88+
(skb_shinfo(skb)->gso_segs ?: 1) - 1);
89+
}
90+
}
7491
#endif

net/ipv4/af_inet.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,8 +1332,10 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
13321332
if (skb->next != NULL)
13331333
iph->frag_off |= htons(IP_MF);
13341334
offset += (skb->len - skb->mac_len - iph->ihl * 4);
1335-
} else
1336-
iph->id = htons(id++);
1335+
} else {
1336+
if (!(iph->frag_off & htons(IP_DF)))
1337+
iph->id = htons(id++);
1338+
}
13371339
iph->tot_len = htons(skb->len - skb->mac_len);
13381340
iph->check = 0;
13391341
iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);

net/ipv4/ip_gre.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,8 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
970970
iph->daddr = fl4.daddr;
971971
iph->saddr = fl4.saddr;
972972
iph->ttl = ttl;
973-
iph->id = 0;
973+
974+
tunnel_ip_select_ident(skb, old_iph, &rt->dst);
974975

975976
if (ttl == 0) {
976977
if (skb->protocol == htons(ETH_P_IP))

0 commit comments

Comments
 (0)