diff options
-rw-r--r-- | include/linux/netfilter_bridge.h | 29 | ||||
-rw-r--r-- | net/bridge/br_netfilter.c | 48 | ||||
-rw-r--r-- | net/ipv4/ip_output.c | 5 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | 4 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_REJECT.c | 3 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_acct.c | 8 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_expect.c | 4 | ||||
-rw-r--r-- | net/netfilter/nf_tables_api.c | 23 | ||||
-rw-r--r-- | net/netfilter/nfnetlink_log.c | 12 | ||||
-rw-r--r-- | net/netfilter/nft_rbtree.c | 6 | ||||
-rw-r--r-- | net/netfilter/xt_physdev.c | 3 |
11 files changed, 77 insertions, 68 deletions
diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h index bb39113ea596..2734977199ca 100644 --- a/include/linux/netfilter_bridge.h +++ b/include/linux/netfilter_bridge.h | |||
@@ -19,23 +19,10 @@ 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 |
26 | 25 | ||
27 | static inline unsigned int nf_bridge_encap_header_len(const struct sk_buff *skb) | ||
28 | { | ||
29 | switch (skb->protocol) { | ||
30 | case __cpu_to_be16(ETH_P_8021Q): | ||
31 | return VLAN_HLEN; | ||
32 | case __cpu_to_be16(ETH_P_PPP_SES): | ||
33 | return PPPOE_SES_HLEN; | ||
34 | default: | ||
35 | return 0; | ||
36 | } | ||
37 | } | ||
38 | |||
39 | static inline unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb) | 26 | static inline unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb) |
40 | { | 27 | { |
41 | if (unlikely(skb->nf_bridge->mask & BRNF_PPPoE)) | 28 | if (unlikely(skb->nf_bridge->mask & BRNF_PPPoE)) |
@@ -45,21 +32,6 @@ static inline unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb) | |||
45 | 32 | ||
46 | int br_handle_frame_finish(struct sk_buff *skb); | 33 | int br_handle_frame_finish(struct sk_buff *skb); |
47 | 34 | ||
48 | /* This is called by the IP fragmenting code and it ensures there is | ||
49 | * enough room for the encapsulating header (if there is one). */ | ||
50 | static inline unsigned int nf_bridge_pad(const struct sk_buff *skb) | ||
51 | { | ||
52 | if (skb->nf_bridge) | ||
53 | return nf_bridge_encap_header_len(skb); | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | struct bridge_skb_cb { | ||
58 | union { | ||
59 | __be32 ipv4; | ||
60 | } daddr; | ||
61 | }; | ||
62 | |||
63 | static inline void br_drop_fake_rtable(struct sk_buff *skb) | 35 | static inline void br_drop_fake_rtable(struct sk_buff *skb) |
64 | { | 36 | { |
65 | struct dst_entry *dst = skb_dst(skb); | 37 | struct dst_entry *dst = skb_dst(skb); |
@@ -69,7 +41,6 @@ static inline void br_drop_fake_rtable(struct sk_buff *skb) | |||
69 | } | 41 | } |
70 | 42 | ||
71 | #else | 43 | #else |
72 | #define nf_bridge_pad(skb) (0) | ||
73 | #define br_drop_fake_rtable(skb) do { } while (0) | 44 | #define br_drop_fake_rtable(skb) do { } while (0) |
74 | #endif /* CONFIG_BRIDGE_NETFILTER */ | 45 | #endif /* CONFIG_BRIDGE_NETFILTER */ |
75 | 46 | ||
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index b260a97275db..f3884a1b942f 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -37,17 +37,16 @@ | |||
37 | #include <net/route.h> | 37 | #include <net/route.h> |
38 | #include <net/netfilter/br_netfilter.h> | 38 | #include <net/netfilter/br_netfilter.h> |
39 | 39 | ||
40 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) | ||
41 | #include <net/netfilter/nf_conntrack.h> | ||
42 | #endif | ||
43 | |||
40 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
41 | #include "br_private.h" | 45 | #include "br_private.h" |
42 | #ifdef CONFIG_SYSCTL | 46 | #ifdef CONFIG_SYSCTL |
43 | #include <linux/sysctl.h> | 47 | #include <linux/sysctl.h> |
44 | #endif | 48 | #endif |
45 | 49 | ||
46 | #define skb_origaddr(skb) (((struct bridge_skb_cb *) \ | ||
47 | (skb->nf_bridge->data))->daddr.ipv4) | ||
48 | #define store_orig_dstaddr(skb) (skb_origaddr(skb) = ip_hdr(skb)->daddr) | ||
49 | #define dnat_took_place(skb) (skb_origaddr(skb) != ip_hdr(skb)->daddr) | ||
50 | |||
51 | #ifdef CONFIG_SYSCTL | 50 | #ifdef CONFIG_SYSCTL |
52 | static struct ctl_table_header *brnf_sysctl_header; | 51 | static struct ctl_table_header *brnf_sysctl_header; |
53 | static int brnf_call_iptables __read_mostly = 1; | 52 | static int brnf_call_iptables __read_mostly = 1; |
@@ -154,6 +153,18 @@ static inline struct nf_bridge_info *nf_bridge_unshare(struct sk_buff *skb) | |||
154 | return nf_bridge; | 153 | return nf_bridge; |
155 | } | 154 | } |
156 | 155 | ||
156 | static unsigned int nf_bridge_encap_header_len(const struct sk_buff *skb) | ||
157 | { | ||
158 | switch (skb->protocol) { | ||
159 | case __cpu_to_be16(ETH_P_8021Q): | ||
160 | return VLAN_HLEN; | ||
161 | case __cpu_to_be16(ETH_P_PPP_SES): | ||
162 | return PPPOE_SES_HLEN; | ||
163 | default: | ||
164 | return 0; | ||
165 | } | ||
166 | } | ||
167 | |||
157 | static inline void nf_bridge_push_encap_header(struct sk_buff *skb) | 168 | static inline void nf_bridge_push_encap_header(struct sk_buff *skb) |
158 | { | 169 | { |
159 | unsigned int len = nf_bridge_encap_header_len(skb); | 170 | unsigned int len = nf_bridge_encap_header_len(skb); |
@@ -322,6 +333,22 @@ free_skb: | |||
322 | return 0; | 333 | return 0; |
323 | } | 334 | } |
324 | 335 | ||
336 | static bool dnat_took_place(const struct sk_buff *skb) | ||
337 | { | ||
338 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) | ||
339 | enum ip_conntrack_info ctinfo; | ||
340 | struct nf_conn *ct; | ||
341 | |||
342 | ct = nf_ct_get(skb, &ctinfo); | ||
343 | if (!ct || nf_ct_is_untracked(ct)) | ||
344 | return false; | ||
345 | |||
346 | return test_bit(IPS_DST_NAT_BIT, &ct->status); | ||
347 | #else | ||
348 | return false; | ||
349 | #endif | ||
350 | } | ||
351 | |||
325 | /* This requires some explaining. If DNAT has taken place, | 352 | /* This requires some explaining. If DNAT has taken place, |
326 | * we will need to fix up the destination Ethernet address. | 353 | * we will need to fix up the destination Ethernet address. |
327 | * | 354 | * |
@@ -625,7 +652,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops, | |||
625 | return NF_DROP; | 652 | return NF_DROP; |
626 | if (!setup_pre_routing(skb)) | 653 | if (!setup_pre_routing(skb)) |
627 | return NF_DROP; | 654 | return NF_DROP; |
628 | store_orig_dstaddr(skb); | 655 | |
629 | skb->protocol = htons(ETH_P_IP); | 656 | skb->protocol = htons(ETH_P_IP); |
630 | 657 | ||
631 | NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL, | 658 | NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL, |
@@ -721,8 +748,6 @@ static unsigned int br_nf_forward_ip(const struct nf_hook_ops *ops, | |||
721 | if (pf == NFPROTO_IPV4 && br_parse_ip_options(skb)) | 748 | if (pf == NFPROTO_IPV4 && br_parse_ip_options(skb)) |
722 | return NF_DROP; | 749 | return NF_DROP; |
723 | 750 | ||
724 | /* The physdev module checks on this */ | ||
725 | nf_bridge->mask |= BRNF_BRIDGED; | ||
726 | nf_bridge->physoutdev = skb->dev; | 751 | nf_bridge->physoutdev = skb->dev; |
727 | if (pf == NFPROTO_IPV4) | 752 | if (pf == NFPROTO_IPV4) |
728 | skb->protocol = htons(ETH_P_IP); | 753 | skb->protocol = htons(ETH_P_IP); |
@@ -842,7 +867,12 @@ static unsigned int br_nf_post_routing(const struct nf_hook_ops *ops, | |||
842 | struct net_device *realoutdev = bridge_parent(skb->dev); | 867 | struct net_device *realoutdev = bridge_parent(skb->dev); |
843 | u_int8_t pf; | 868 | u_int8_t pf; |
844 | 869 | ||
845 | if (!nf_bridge || !(nf_bridge->mask & BRNF_BRIDGED)) | 870 | /* if nf_bridge is set, but ->physoutdev is NULL, this packet came in |
871 | * on a bridge, but was delivered locally and is now being routed: | ||
872 | * | ||
873 | * POST_ROUTING was already invoked from the ip stack. | ||
874 | */ | ||
875 | if (!nf_bridge || !nf_bridge->physoutdev) | ||
846 | return NF_ACCEPT; | 876 | return NF_ACCEPT; |
847 | 877 | ||
848 | if (!realoutdev) | 878 | if (!realoutdev) |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index a7aea2048a0d..90b49e88e84a 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -636,10 +636,7 @@ slow_path: | |||
636 | left = skb->len - hlen; /* Space per frame */ | 636 | left = skb->len - hlen; /* Space per frame */ |
637 | ptr = hlen; /* Where to start from */ | 637 | ptr = hlen; /* Where to start from */ |
638 | 638 | ||
639 | /* for bridged IP traffic encapsulated inside f.e. a vlan header, | 639 | ll_rs = LL_RESERVED_SPACE(rt->dst.dev); |
640 | * we need to make room for the encapsulating header | ||
641 | */ | ||
642 | ll_rs = LL_RESERVED_SPACE_EXTRA(rt->dst.dev, nf_bridge_pad(skb)); | ||
643 | 640 | ||
644 | /* | 641 | /* |
645 | * Fragment the datagram. | 642 | * Fragment the datagram. |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c index a460a87e14f8..f0dfe92a00d6 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | |||
@@ -300,7 +300,9 @@ static int exp_seq_show(struct seq_file *s, void *v) | |||
300 | __nf_ct_l3proto_find(exp->tuple.src.l3num), | 300 | __nf_ct_l3proto_find(exp->tuple.src.l3num), |
301 | __nf_ct_l4proto_find(exp->tuple.src.l3num, | 301 | __nf_ct_l4proto_find(exp->tuple.src.l3num, |
302 | exp->tuple.dst.protonum)); | 302 | exp->tuple.dst.protonum)); |
303 | return seq_putc(s, '\n'); | 303 | seq_putc(s, '\n'); |
304 | |||
305 | return 0; | ||
304 | } | 306 | } |
305 | 307 | ||
306 | static const struct seq_operations exp_seq_ops = { | 308 | static const struct seq_operations exp_seq_ops = { |
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 544b0a9da1b5..12331efd49cf 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c | |||
@@ -83,7 +83,8 @@ static int reject_tg6_check(const struct xt_tgchk_param *par) | |||
83 | return -EINVAL; | 83 | return -EINVAL; |
84 | } else if (rejinfo->with == IP6T_TCP_RESET) { | 84 | } else if (rejinfo->with == IP6T_TCP_RESET) { |
85 | /* Must specify that it's a TCP packet */ | 85 | /* Must specify that it's a TCP packet */ |
86 | if (e->ipv6.proto != IPPROTO_TCP || | 86 | if (!(e->ipv6.flags & IP6T_F_PROTO) || |
87 | e->ipv6.proto != IPPROTO_TCP || | ||
87 | (e->ipv6.invflags & XT_INV_PROTO)) { | 88 | (e->ipv6.invflags & XT_INV_PROTO)) { |
88 | pr_info("TCP_RESET illegal for non-tcp\n"); | 89 | pr_info("TCP_RESET illegal for non-tcp\n"); |
89 | return -EINVAL; | 90 | return -EINVAL; |
diff --git a/net/netfilter/nf_conntrack_acct.c b/net/netfilter/nf_conntrack_acct.c index a4b5e2a435ac..45da11afa785 100644 --- a/net/netfilter/nf_conntrack_acct.c +++ b/net/netfilter/nf_conntrack_acct.c | |||
@@ -47,9 +47,11 @@ seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir) | |||
47 | return 0; | 47 | return 0; |
48 | 48 | ||
49 | counter = acct->counter; | 49 | counter = acct->counter; |
50 | return seq_printf(s, "packets=%llu bytes=%llu ", | 50 | seq_printf(s, "packets=%llu bytes=%llu ", |
51 | (unsigned long long)atomic64_read(&counter[dir].packets), | 51 | (unsigned long long)atomic64_read(&counter[dir].packets), |
52 | (unsigned long long)atomic64_read(&counter[dir].bytes)); | 52 | (unsigned long long)atomic64_read(&counter[dir].bytes)); |
53 | |||
54 | return 0; | ||
53 | }; | 55 | }; |
54 | EXPORT_SYMBOL_GPL(seq_print_acct); | 56 | EXPORT_SYMBOL_GPL(seq_print_acct); |
55 | 57 | ||
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index 91a1837acd0e..7a17070c5dab 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c | |||
@@ -561,7 +561,9 @@ static int exp_seq_show(struct seq_file *s, void *v) | |||
561 | helper->expect_policy[expect->class].name); | 561 | helper->expect_policy[expect->class].name); |
562 | } | 562 | } |
563 | 563 | ||
564 | return seq_putc(s, '\n'); | 564 | seq_putc(s, '\n'); |
565 | |||
566 | return 0; | ||
565 | } | 567 | } |
566 | 568 | ||
567 | static const struct seq_operations exp_seq_ops = { | 569 | static const struct seq_operations exp_seq_ops = { |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index ea51833c8f5a..f7e3371ce856 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
@@ -687,11 +687,10 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb, | |||
687 | if (!try_module_get(afi->owner)) | 687 | if (!try_module_get(afi->owner)) |
688 | return -EAFNOSUPPORT; | 688 | return -EAFNOSUPPORT; |
689 | 689 | ||
690 | err = -ENOMEM; | ||
690 | table = kzalloc(sizeof(*table), GFP_KERNEL); | 691 | table = kzalloc(sizeof(*table), GFP_KERNEL); |
691 | if (table == NULL) { | 692 | if (table == NULL) |
692 | module_put(afi->owner); | 693 | goto err1; |
693 | return -ENOMEM; | ||
694 | } | ||
695 | 694 | ||
696 | nla_strlcpy(table->name, name, NFT_TABLE_MAXNAMELEN); | 695 | nla_strlcpy(table->name, name, NFT_TABLE_MAXNAMELEN); |
697 | INIT_LIST_HEAD(&table->chains); | 696 | INIT_LIST_HEAD(&table->chains); |
@@ -700,13 +699,16 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb, | |||
700 | 699 | ||
701 | nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla); | 700 | nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla); |
702 | err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE); | 701 | err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE); |
703 | if (err < 0) { | 702 | if (err < 0) |
704 | kfree(table); | 703 | goto err2; |
705 | module_put(afi->owner); | 704 | |
706 | return err; | ||
707 | } | ||
708 | list_add_tail_rcu(&table->list, &afi->tables); | 705 | list_add_tail_rcu(&table->list, &afi->tables); |
709 | return 0; | 706 | return 0; |
707 | err2: | ||
708 | kfree(table); | ||
709 | err1: | ||
710 | module_put(afi->owner); | ||
711 | return err; | ||
710 | } | 712 | } |
711 | 713 | ||
712 | static int nft_flush_table(struct nft_ctx *ctx) | 714 | static int nft_flush_table(struct nft_ctx *ctx) |
@@ -3136,6 +3138,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, | |||
3136 | elem.flags = ntohl(nla_get_be32(nla[NFTA_SET_ELEM_FLAGS])); | 3138 | elem.flags = ntohl(nla_get_be32(nla[NFTA_SET_ELEM_FLAGS])); |
3137 | if (elem.flags & ~NFT_SET_ELEM_INTERVAL_END) | 3139 | if (elem.flags & ~NFT_SET_ELEM_INTERVAL_END) |
3138 | return -EINVAL; | 3140 | return -EINVAL; |
3141 | if (!(set->flags & NFT_SET_INTERVAL) && | ||
3142 | elem.flags & NFT_SET_ELEM_INTERVAL_END) | ||
3143 | return -EINVAL; | ||
3139 | } | 3144 | } |
3140 | 3145 | ||
3141 | if (set->flags & NFT_SET_MAP) { | 3146 | if (set->flags & NFT_SET_MAP) { |
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 61d04bf9be2b..957b83a0223b 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -998,11 +998,13 @@ static int seq_show(struct seq_file *s, void *v) | |||
998 | { | 998 | { |
999 | const struct nfulnl_instance *inst = v; | 999 | const struct nfulnl_instance *inst = v; |
1000 | 1000 | ||
1001 | return seq_printf(s, "%5d %6d %5d %1d %5d %6d %2d\n", | 1001 | seq_printf(s, "%5d %6d %5d %1d %5d %6d %2d\n", |
1002 | inst->group_num, | 1002 | inst->group_num, |
1003 | inst->peer_portid, inst->qlen, | 1003 | inst->peer_portid, inst->qlen, |
1004 | inst->copy_mode, inst->copy_range, | 1004 | inst->copy_mode, inst->copy_range, |
1005 | inst->flushtimeout, atomic_read(&inst->use)); | 1005 | inst->flushtimeout, atomic_read(&inst->use)); |
1006 | |||
1007 | return 0; | ||
1006 | } | 1008 | } |
1007 | 1009 | ||
1008 | static const struct seq_operations nful_seq_ops = { | 1010 | static const struct seq_operations nful_seq_ops = { |
diff --git a/net/netfilter/nft_rbtree.c b/net/netfilter/nft_rbtree.c index 46214f245665..2c75361077f7 100644 --- a/net/netfilter/nft_rbtree.c +++ b/net/netfilter/nft_rbtree.c | |||
@@ -37,10 +37,11 @@ static bool nft_rbtree_lookup(const struct nft_set *set, | |||
37 | { | 37 | { |
38 | const struct nft_rbtree *priv = nft_set_priv(set); | 38 | const struct nft_rbtree *priv = nft_set_priv(set); |
39 | const struct nft_rbtree_elem *rbe, *interval = NULL; | 39 | const struct nft_rbtree_elem *rbe, *interval = NULL; |
40 | const struct rb_node *parent = priv->root.rb_node; | 40 | const struct rb_node *parent; |
41 | int d; | 41 | int d; |
42 | 42 | ||
43 | spin_lock_bh(&nft_rbtree_lock); | 43 | spin_lock_bh(&nft_rbtree_lock); |
44 | parent = priv->root.rb_node; | ||
44 | while (parent != NULL) { | 45 | while (parent != NULL) { |
45 | rbe = rb_entry(parent, struct nft_rbtree_elem, node); | 46 | rbe = rb_entry(parent, struct nft_rbtree_elem, node); |
46 | 47 | ||
@@ -158,7 +159,6 @@ static int nft_rbtree_get(const struct nft_set *set, struct nft_set_elem *elem) | |||
158 | struct nft_rbtree_elem *rbe; | 159 | struct nft_rbtree_elem *rbe; |
159 | int d; | 160 | int d; |
160 | 161 | ||
161 | spin_lock_bh(&nft_rbtree_lock); | ||
162 | while (parent != NULL) { | 162 | while (parent != NULL) { |
163 | rbe = rb_entry(parent, struct nft_rbtree_elem, node); | 163 | rbe = rb_entry(parent, struct nft_rbtree_elem, node); |
164 | 164 | ||
@@ -173,11 +173,9 @@ static int nft_rbtree_get(const struct nft_set *set, struct nft_set_elem *elem) | |||
173 | !(rbe->flags & NFT_SET_ELEM_INTERVAL_END)) | 173 | !(rbe->flags & NFT_SET_ELEM_INTERVAL_END)) |
174 | nft_data_copy(&elem->data, rbe->data); | 174 | nft_data_copy(&elem->data, rbe->data); |
175 | elem->flags = rbe->flags; | 175 | elem->flags = rbe->flags; |
176 | spin_unlock_bh(&nft_rbtree_lock); | ||
177 | return 0; | 176 | return 0; |
178 | } | 177 | } |
179 | } | 178 | } |
180 | spin_unlock_bh(&nft_rbtree_lock); | ||
181 | return -ENOENT; | 179 | return -ENOENT; |
182 | } | 180 | } |
183 | 181 | ||
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 && |