aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ipip.h17
-rw-r--r--net/ipv4/af_inet.c6
-rw-r--r--net/ipv4/ip_gre.c3
3 files changed, 23 insertions, 3 deletions
diff --git a/include/net/ipip.h b/include/net/ipip.h
index 21947cf4fa46..fd19625ff99d 100644
--- a/include/net/ipip.h
+++ b/include/net/ipip.h
@@ -71,4 +71,21 @@ static inline void iptunnel_xmit(struct sk_buff *skb, struct net_device *dev)
71 } 71 }
72} 72}
73 73
74static 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}
74#endif 91#endif
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 15847e19b7dd..68f6a94f7661 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1332,8 +1332,10 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
1332 if (skb->next != NULL) 1332 if (skb->next != NULL)
1333 iph->frag_off |= htons(IP_MF); 1333 iph->frag_off |= htons(IP_MF);
1334 offset += (skb->len - skb->mac_len - iph->ihl * 4); 1334 offset += (skb->len - skb->mac_len - iph->ihl * 4);
1335 } else 1335 } else {
1336 iph->id = htons(id++); 1336 if (!(iph->frag_off & htons(IP_DF)))
1337 iph->id = htons(id++);
1338 }
1337 iph->tot_len = htons(skb->len - skb->mac_len); 1339 iph->tot_len = htons(skb->len - skb->mac_len);
1338 iph->check = 0; 1340 iph->check = 0;
1339 iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl); 1341 iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 5ef4da780ac1..b8bada00d516 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -970,7 +970,8 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
970 iph->daddr = fl4.daddr; 970 iph->daddr = fl4.daddr;
971 iph->saddr = fl4.saddr; 971 iph->saddr = fl4.saddr;
972 iph->ttl = ttl; 972 iph->ttl = ttl;
973 iph->id = 0; 973
974 tunnel_ip_select_ident(skb, old_iph, &rt->dst);
974 975
975 if (ttl == 0) { 976 if (ttl == 0) {
976 if (skb->protocol == htons(ETH_P_IP)) 977 if (skb->protocol == htons(ETH_P_IP))