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 && |
