aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter_bridge.h7
-rw-r--r--net/bridge/br_netfilter.c2
-rw-r--r--net/ipv4/ip_output.c4
3 files changed, 12 insertions, 1 deletions
diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h
index ea0e44b90432..0ddd161f3b06 100644
--- a/include/linux/netfilter_bridge.h
+++ b/include/linux/netfilter_bridge.h
@@ -68,6 +68,13 @@ static inline unsigned int nf_bridge_encap_header_len(const struct sk_buff *skb)
68 } 68 }
69} 69}
70 70
71static inline unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb)
72{
73 if (unlikely(skb->nf_bridge->mask & BRNF_PPPoE))
74 return PPPOE_SES_HLEN;
75 return 0;
76}
77
71extern int br_handle_frame_finish(struct sk_buff *skb); 78extern int br_handle_frame_finish(struct sk_buff *skb);
72/* Only used in br_device.c */ 79/* Only used in br_device.c */
73static inline int br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb) 80static inline int br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb)
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 6b80ebc37667..93f80fefa496 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -745,7 +745,7 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb,
745static int br_nf_dev_queue_xmit(struct sk_buff *skb) 745static int br_nf_dev_queue_xmit(struct sk_buff *skb)
746{ 746{
747 if (skb->nfct != NULL && skb->protocol == htons(ETH_P_IP) && 747 if (skb->nfct != NULL && skb->protocol == htons(ETH_P_IP) &&
748 skb->len > skb->dev->mtu && 748 skb->len + nf_bridge_mtu_reduction(skb) > skb->dev->mtu &&
749 !skb_is_gso(skb)) 749 !skb_is_gso(skb))
750 return ip_fragment(skb, br_dev_queue_push_xmit); 750 return ip_fragment(skb, br_dev_queue_push_xmit);
751 else 751 else
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index b0b2e3059f11..d979710684b2 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -469,6 +469,10 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
469 469
470 hlen = iph->ihl * 4; 470 hlen = iph->ihl * 4;
471 mtu = dst_mtu(&rt->u.dst) - hlen; /* Size of data space */ 471 mtu = dst_mtu(&rt->u.dst) - hlen; /* Size of data space */
472#ifdef CONFIG_BRIDGE_NETFILTER
473 if (skb->nf_bridge)
474 mtu -= nf_bridge_mtu_reduction(skb);
475#endif
472 IPCB(skb)->flags |= IPSKB_FRAG_COMPLETE; 476 IPCB(skb)->flags |= IPSKB_FRAG_COMPLETE;
473 477
474 /* When frag_list is given, use it. First, check its validity: 478 /* When frag_list is given, use it. First, check its validity: