@@ -543,6 +543,7 @@ int ip_fragment(struct sock *sk, struct sk_buff *skb,
if (skb_has_frag_list(skb)) {
struct sk_buff *frag, *frag2;
int first_len = skb_pagelen(skb);
+ bool is_df_skb;
if (first_len - hlen > mtu ||
((first_len - hlen) & 7) ||
@@ -579,6 +580,9 @@ int ip_fragment(struct sock *sk, struct sk_buff *skb,
skb->len = first_len;
iph->tot_len = htons(first_len);
iph->frag_off = htons(IP_MF);
+ is_df_skb = IPCB(skb)->flags & IPSKB_FRAG_PMTU;
+ if (is_df_skb)
+ iph->frag_off |= htons(IP_DF);
ip_send_check(iph);
for (;;) {
@@ -599,6 +603,8 @@ int ip_fragment(struct sock *sk, struct sk_buff *skb,
iph->frag_off = htons(offset>>3);
if (frag->next)
iph->frag_off |= htons(IP_MF);
+ if (is_df_skb)
+ iph->frag_off |= htons(IP_DF);
/* Ready, complete checksum */
ip_send_check(iph);
}
This extends the previous change to also set the DF bit in the fragment list skb, i.e. if the original fragments had DF set, then also set it when 'replaying' the fraglist skbs. Signed-off-by: Florian Westphal <fw@strlen.de> --- net/ipv4/ip_output.c | 6 ++++++ 1 file changed, 6 insertions(+)