- status = queue_handler[pf].outfn(skb, info, queue_handler[pf].data);
- if (status < 0) {
- /* James M doesn't say fuck enough. */
- if (indev) dev_put(indev);
- if (outdev) dev_put(outdev);
-+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
-+ if (physindev) dev_put(physindev);
-+ if (physoutdev) dev_put(physoutdev);
-+#endif
- kfree(info);
- kfree_skb(skb);
- return;
-@@ -451,7 +473,8 @@
- int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
- struct net_device *indev,
- struct net_device *outdev,
-- int (*okfn)(struct sk_buff *))
-+ int (*okfn)(struct sk_buff *),
-+ int hook_thresh)
- {
- struct list_head *elem;
- unsigned int verdict;
-@@ -483,7 +506,7 @@
-
- elem = &nf_hooks[pf][hook];
- verdict = nf_iterate(&nf_hooks[pf][hook], &skb, hook, indev,
-- outdev, &elem, okfn);
-+ outdev, &elem, okfn, hook_thresh);
- if (verdict == NF_QUEUE) {
- NFDEBUG("nf_hook: Verdict = QUEUE.\n");
- nf_queue(skb, elem, pf, hook, indev, outdev, okfn);
-@@ -512,6 +535,14 @@
-
- /* We don't have BR_NETPROTO_LOCK here */
- br_read_lock_bh(BR_NETPROTO_LOCK);
-+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
-+ if (skb->nf_bridge) {
-+ if (skb->nf_bridge->physindev)
-+ dev_put(skb->nf_bridge->physindev);
-+ if (skb->nf_bridge->physoutdev)
-+ dev_put(skb->nf_bridge->physoutdev);
-+ }
-+#endif
- for (i = nf_hooks[info->pf][info->hook].next; i != elem; i = i->next) {
- if (i == &nf_hooks[info->pf][info->hook]) {
- /* The module which sent it to userspace is gone. */
-@@ -532,7 +563,7 @@
- verdict = nf_iterate(&nf_hooks[info->pf][info->hook],
- &skb, info->hook,
- info->indev, info->outdev, &elem,
-- info->okfn);
-+ info->okfn, INT_MIN);
- }
-
- switch (verdict) {
-diff -Nurb linux.stock/net/core/skbuff.c linux/net/core/skbuff.c
---- linux.stock/net/core/skbuff.c 2003-10-14 04:09:32.000000000 -0400
-+++ linux/net/core/skbuff.c 2004-07-10 23:46:39.000000000 -0400
-@@ -244,6 +244,9 @@
- #ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug = 0;
- #endif
-+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
-+ skb->nf_bridge = NULL;
-+#endif
- #endif
- #ifdef CONFIG_NET_SCHED
- skb->tc_index = 0;
-@@ -324,6 +327,9 @@
- }
- #ifdef CONFIG_NETFILTER
- nf_conntrack_put(skb->nfct);
-+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
-+ nf_bridge_put(skb->nf_bridge);
-+#endif
- #endif
- skb_headerinit(skb, NULL, 0); /* clean state */
- kfree_skbmem(skb);
-@@ -390,6 +396,9 @@
- #ifdef CONFIG_NETFILTER_DEBUG
- C(nf_debug);
- #endif
-+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
-+ C(nf_bridge);
-+#endif
- #endif /*CONFIG_NETFILTER*/
- #if defined(CONFIG_HIPPI)
- C(private);
-@@ -402,6 +411,9 @@
- skb->cloned = 1;
- #ifdef CONFIG_NETFILTER
- nf_conntrack_get(skb->nfct);
-+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
-+ nf_bridge_get(skb->nf_bridge);
-+#endif
- #endif
- return n;
- }
-@@ -436,6 +448,10 @@
- #ifdef CONFIG_NETFILTER_DEBUG
- new->nf_debug=old->nf_debug;
- #endif
-+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
-+ new->nf_bridge=old->nf_bridge;
-+ nf_bridge_get(new->nf_bridge);
-+#endif
- #endif
- #ifdef CONFIG_NET_SCHED
- new->tc_index = old->tc_index;
-@@ -722,8 +738,8 @@
- /* Set the tail pointer and length */
- skb_put(n,skb->len);
-
-- /* Copy the data only. */
-- if (skb_copy_bits(skb, 0, n->data, skb->len))
-+ /* Copy the linear data and header. */
-+ if (skb_copy_bits(skb, -newheadroom, n->head, newheadroom + skb->len))
- BUG();
-
- copy_skb_header(n, skb);
-diff -Nurb linux.stock/net/ipv4/ip_output.c linux/net/ipv4/ip_output.c
---- linux.stock/net/ipv4/ip_output.c 2003-10-14 04:09:33.000000000 -0400
-+++ linux/net/ipv4/ip_output.c 2004-07-10 23:46:39.000000000 -0400
-@@ -879,6 +879,10 @@
- /* Connection association is same as pre-frag packet */
- skb2->nfct = skb->nfct;
- nf_conntrack_get(skb2->nfct);
-+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
-+ skb2->nf_bridge = skb->nf_bridge;
-+ nf_bridge_get(skb2->nf_bridge);
-+#endif
- #ifdef CONFIG_NETFILTER_DEBUG
- skb2->nf_debug = skb->nf_debug;
- #endif
-diff -Nurb linux.stock/net/ipv4/netfilter/Config.in linux/net/ipv4/netfilter/Config.in
---- linux.stock/net/ipv4/netfilter/Config.in 2004-07-10 23:30:19.000000000 -0400
-+++ linux/net/ipv4/netfilter/Config.in 2004-07-10 23:46:39.000000000 -0400
-@@ -83,6 +83,9 @@
- dep_tristate ' String match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_STRING $CONFIG_IP_NF_IPTABLES
- dep_tristate ' Owner match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_OWNER $CONFIG_IP_NF_IPTABLES
- fi
-+ if [ "$CONFIG_BRIDGE" != "n" ]; then
-+ dep_tristate ' Physdev match support' CONFIG_IP_NF_MATCH_PHYSDEV $CONFIG_IP_NF_IPTABLES
-+ fi
- # The targets
- dep_tristate ' Packet filtering' CONFIG_IP_NF_FILTER $CONFIG_IP_NF_IPTABLES
- if [ "$CONFIG_IP_NF_FILTER" != "n" ]; then
-diff -Nurb linux.stock/net/ipv4/netfilter/Makefile linux/net/ipv4/netfilter/Makefile
---- linux.stock/net/ipv4/netfilter/Makefile 2004-07-10 23:30:19.000000000 -0400
-+++ linux/net/ipv4/netfilter/Makefile 2004-07-10 23:46:39.000000000 -0400
-@@ -149,6 +149,8 @@
- obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
- obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
-
-+obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o