|
@@ -449,6 +449,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
|
|
__be16 not_last_frag;
|
|
__be16 not_last_frag;
|
|
struct rtable *rt = skb_rtable(skb);
|
|
struct rtable *rt = skb_rtable(skb);
|
|
int err = 0;
|
|
int err = 0;
|
|
|
|
+ bool forwarding = IPCB(skb)->flags & IPSKB_FORWARDED;
|
|
|
|
|
|
dev = rt->dst.dev;
|
|
dev = rt->dst.dev;
|
|
|
|
|
|
@@ -458,12 +459,13 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
|
|
|
|
|
|
iph = ip_hdr(skb);
|
|
iph = ip_hdr(skb);
|
|
|
|
|
|
|
|
+ mtu = ip_dst_mtu_maybe_forward(&rt->dst, forwarding);
|
|
if (unlikely(((iph->frag_off & htons(IP_DF)) && !skb->local_df) ||
|
|
if (unlikely(((iph->frag_off & htons(IP_DF)) && !skb->local_df) ||
|
|
(IPCB(skb)->frag_max_size &&
|
|
(IPCB(skb)->frag_max_size &&
|
|
- IPCB(skb)->frag_max_size > dst_mtu(&rt->dst)))) {
|
|
|
|
|
|
+ IPCB(skb)->frag_max_size > mtu))) {
|
|
IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS);
|
|
IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS);
|
|
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
|
|
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
|
|
- htonl(ip_skb_dst_mtu(skb)));
|
|
|
|
|
|
+ htonl(mtu));
|
|
kfree_skb(skb);
|
|
kfree_skb(skb);
|
|
return -EMSGSIZE;
|
|
return -EMSGSIZE;
|
|
}
|
|
}
|
|
@@ -473,7 +475,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
|
|
*/
|
|
*/
|
|
|
|
|
|
hlen = iph->ihl * 4;
|
|
hlen = iph->ihl * 4;
|
|
- mtu = dst_mtu(&rt->dst) - hlen; /* Size of data space */
|
|
|
|
|
|
+ mtu = mtu - hlen; /* Size of data space */
|
|
#ifdef CONFIG_BRIDGE_NETFILTER
|
|
#ifdef CONFIG_BRIDGE_NETFILTER
|
|
if (skb->nf_bridge)
|
|
if (skb->nf_bridge)
|
|
mtu -= nf_bridge_mtu_reduction(skb);
|
|
mtu -= nf_bridge_mtu_reduction(skb);
|