aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter_bridge.h1
-rw-r--r--net/bridge/br_netfilter.c9
-rw-r--r--net/netfilter/xt_physdev.c3
3 files changed, 7 insertions, 6 deletions
diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h
index de123d769ffc..ed0d3bf953c3 100644
--- a/include/linux/netfilter_bridge.h
+++ b/include/linux/netfilter_bridge.h
@@ -19,7 +19,6 @@ enum nf_br_hook_priorities {
19 19
20#define BRNF_PKT_TYPE 0x01 20#define BRNF_PKT_TYPE 0x01
21#define BRNF_BRIDGED_DNAT 0x02 21#define BRNF_BRIDGED_DNAT 0x02
22#define BRNF_BRIDGED 0x04
23#define BRNF_NF_BRIDGE_PREROUTING 0x08 22#define BRNF_NF_BRIDGE_PREROUTING 0x08
24#define BRNF_8021Q 0x10 23#define BRNF_8021Q 0x10
25#define BRNF_PPPoE 0x20 24#define BRNF_PPPoE 0x20
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 261fcd5a42d6..bd2d24d1ff21 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -736,8 +736,6 @@ static unsigned int br_nf_forward_ip(const struct nf_hook_ops *ops,
736 if (pf == NFPROTO_IPV4 && br_parse_ip_options(skb)) 736 if (pf == NFPROTO_IPV4 && br_parse_ip_options(skb))
737 return NF_DROP; 737 return NF_DROP;
738 738
739 /* The physdev module checks on this */
740 nf_bridge->mask |= BRNF_BRIDGED;
741 nf_bridge->physoutdev = skb->dev; 739 nf_bridge->physoutdev = skb->dev;
742 if (pf == NFPROTO_IPV4) 740 if (pf == NFPROTO_IPV4)
743 skb->protocol = htons(ETH_P_IP); 741 skb->protocol = htons(ETH_P_IP);
@@ -857,7 +855,12 @@ static unsigned int br_nf_post_routing(const struct nf_hook_ops *ops,
857 struct net_device *realoutdev = bridge_parent(skb->dev); 855 struct net_device *realoutdev = bridge_parent(skb->dev);
858 u_int8_t pf; 856 u_int8_t pf;
859 857
860 if (!nf_bridge || !(nf_bridge->mask & BRNF_BRIDGED)) 858 /* if nf_bridge is set, but ->physoutdev is NULL, this packet came in
859 * on a bridge, but was delivered locally and is now being routed:
860 *
861 * POST_ROUTING was already invoked from the ip stack.
862 */
863 if (!nf_bridge || !nf_bridge->physoutdev)
861 return NF_ACCEPT; 864 return NF_ACCEPT;
862 865
863 if (!realoutdev) 866 if (!realoutdev)
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c
index f440f57a452f..50a52043650f 100644
--- a/net/netfilter/xt_physdev.c
+++ b/net/netfilter/xt_physdev.c
@@ -56,8 +56,7 @@ physdev_mt(const struct sk_buff *skb, struct xt_action_param *par)
56 56
57 /* This only makes sense in the FORWARD and POSTROUTING chains */ 57 /* This only makes sense in the FORWARD and POSTROUTING chains */
58 if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) && 58 if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) &&
59 (!!(nf_bridge->mask & BRNF_BRIDGED) ^ 59 (!!nf_bridge->physoutdev ^ !(info->invert & XT_PHYSDEV_OP_BRIDGED)))
60 !(info->invert & XT_PHYSDEV_OP_BRIDGED)))
61 return false; 60 return false;
62 61
63 if ((info->bitmask & XT_PHYSDEV_OP_ISIN && 62 if ((info->bitmask & XT_PHYSDEV_OP_ISIN &&