diff options
| -rw-r--r-- | include/linux/netfilter_bridge.h | 7 | ||||
| -rw-r--r-- | net/bridge/br_netfilter.c | 2 | ||||
| -rw-r--r-- | net/ipv4/ip_output.c | 4 |
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 | ||
| 71 | static 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 | |||
| 71 | extern int br_handle_frame_finish(struct sk_buff *skb); | 78 | extern int br_handle_frame_finish(struct sk_buff *skb); |
| 72 | /* Only used in br_device.c */ | 79 | /* Only used in br_device.c */ |
| 73 | static inline int br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb) | 80 | static 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, | |||
| 745 | static int br_nf_dev_queue_xmit(struct sk_buff *skb) | 745 | static 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: |
