aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-04-06 18:51:38 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2006-04-17 13:16:04 -0700
commitea0fcdd684262eed42bb40cceff450ef46a97306 (patch)
tree8ff3cfd6163979326e6735385b483c8a6380952c /net
parent8abb9bed57d5ee0f645eedb7208e8d53b2431b01 (diff)
[PATCH] NETFILTER: Fix fragmentation issues with bridge netfilter
[NETFILTER]: Fix fragmentation issues with bridge netfilter The conntrack code doesn't do re-fragmentation of defragmented packets anymore but relies on fragmentation in the IP layer. Purely bridged packets don't pass through the IP layer, so the bridge netfilter code needs to take care of fragmentation itself. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br_netfilter.c13
-rw-r--r--net/ipv4/ip_output.c6
2 files changed, 14 insertions, 5 deletions
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index e060aad8624..9e2737307b6 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -739,6 +739,15 @@ out:
return NF_STOLEN;
}
+static int br_nf_dev_queue_xmit(struct sk_buff *skb)
+{
+ if (skb->protocol == htons(ETH_P_IP) &&
+ skb->len > skb->dev->mtu &&
+ !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
+ return ip_fragment(skb, br_dev_queue_push_xmit);
+ else
+ return br_dev_queue_push_xmit(skb);
+}
/* PF_BRIDGE/POST_ROUTING ********************************************/
static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
@@ -798,7 +807,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
realoutdev = nf_bridge->netoutdev;
#endif
NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL, realoutdev,
- br_dev_queue_push_xmit);
+ br_nf_dev_queue_xmit);
return NF_STOLEN;
@@ -843,7 +852,7 @@ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb,
if ((out->hard_start_xmit == br_dev_xmit &&
okfn != br_nf_forward_finish &&
okfn != br_nf_local_out_finish &&
- okfn != br_dev_queue_push_xmit)
+ okfn != br_nf_dev_queue_xmit)
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
|| ((out->priv_flags & IFF_802_1Q_VLAN) &&
VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index f75ff1d9655..8dcba3887f0 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -86,8 +86,6 @@
int sysctl_ip_default_ttl = IPDEFTTL;
-static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*));
-
/* Generate a checksum for an outgoing IP datagram. */
__inline__ void ip_send_check(struct iphdr *iph)
{
@@ -421,7 +419,7 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
* single device frame, and queue such a frame for sending.
*/
-static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
+int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
{
struct iphdr *iph;
int raw = 0;
@@ -673,6 +671,8 @@ fail:
return err;
}
+EXPORT_SYMBOL(ip_fragment);
+
int
ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb)
{