|
@@ -14,6 +14,7 @@
|
|
|
#include <net/route.h>
|
|
|
#include <net/ip.h>
|
|
|
|
|
|
+#include <linux/netfilter_bridge.h>
|
|
|
#include <linux/netfilter_ipv4.h>
|
|
|
#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
|
|
|
|
|
@@ -34,6 +35,20 @@ static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+static enum ip_defrag_users nf_ct_defrag_user(unsigned int hooknum,
|
|
|
+ struct sk_buff *skb)
|
|
|
+{
|
|
|
+#ifdef CONFIG_BRIDGE_NETFILTER
|
|
|
+ if (skb->nf_bridge &&
|
|
|
+ skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
|
|
|
+ return IP_DEFRAG_CONNTRACK_BRIDGE_IN;
|
|
|
+#endif
|
|
|
+ if (hooknum == NF_INET_PRE_ROUTING)
|
|
|
+ return IP_DEFRAG_CONNTRACK_IN;
|
|
|
+ else
|
|
|
+ return IP_DEFRAG_CONNTRACK_OUT;
|
|
|
+}
|
|
|
+
|
|
|
static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
|
|
|
struct sk_buff *skb,
|
|
|
const struct net_device *in,
|
|
@@ -50,10 +65,8 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
|
|
|
#endif
|
|
|
/* Gather fragments. */
|
|
|
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
|
|
|
- if (nf_ct_ipv4_gather_frags(skb,
|
|
|
- hooknum == NF_INET_PRE_ROUTING ?
|
|
|
- IP_DEFRAG_CONNTRACK_IN :
|
|
|
- IP_DEFRAG_CONNTRACK_OUT))
|
|
|
+ enum ip_defrag_users user = nf_ct_defrag_user(hooknum, skb);
|
|
|
+ if (nf_ct_ipv4_gather_frags(skb, user))
|
|
|
return NF_STOLEN;
|
|
|
}
|
|
|
return NF_ACCEPT;
|