Skip to content

Commit 40451fd

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Pablo Neira Ayuso says: ==================== Netfilter updates for net-next The following patchset contains Netfilter updates for net-next. Basically, more incremental updates for br_netfilter from Florian Westphal, small nf_tables updates (including one fix for rb-tree locking) and small two-liner to add extra validation for the REJECT6 target. More specifically, they are: 1) Use the conntrack status flags from br_netfilter to know that DNAT is happening. Patch for Florian Westphal. 2) nf_bridge->physoutdev == NULL already indicates that the traffic is bridged, so let's get rid of the BRNF_BRIDGED flag. Also from Florian. 3) Another patch to prepare voidization of seq_printf/seq_puts/seq_putc, from Joe Perches. 4) Consolidation of nf_tables_newtable() error path. 5) Kill nf_bridge_pad used by br_netfilter from ip_fragment(), from Florian Westphal. 6) Access rb-tree root node inside the lock and remove unnecessary locking from the get path (we already hold nfnl_lock there), from Patrick McHardy. 7) You cannot use a NFT_SET_ELEM_INTERVAL_END when the set doesn't support interval, also from Patrick. 8) Enforce IP6T_F_PROTO from ip6t_REJECT to make sure the core is actually restricting matches to TCP. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 682f048 + e35158e commit 40451fd

File tree

11 files changed

+77
-68
lines changed

11 files changed

+77
-68
lines changed

include/linux/netfilter_bridge.h

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,10 @@ enum nf_br_hook_priorities {
1919

2020
#define BRNF_PKT_TYPE 0x01
2121
#define BRNF_BRIDGED_DNAT 0x02
22-
#define BRNF_BRIDGED 0x04
2322
#define BRNF_NF_BRIDGE_PREROUTING 0x08
2423
#define BRNF_8021Q 0x10
2524
#define BRNF_PPPoE 0x20
2625

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-
3926
static inline unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb)
4027
{
4128
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)
4532

4633
int br_handle_frame_finish(struct sk_buff *skb);
4734

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-
6335
static inline void br_drop_fake_rtable(struct sk_buff *skb)
6436
{
6537
struct dst_entry *dst = skb_dst(skb);
@@ -69,7 +41,6 @@ static inline void br_drop_fake_rtable(struct sk_buff *skb)
6941
}
7042

7143
#else
72-
#define nf_bridge_pad(skb) (0)
7344
#define br_drop_fake_rtable(skb) do { } while (0)
7445
#endif /* CONFIG_BRIDGE_NETFILTER */
7546

net/bridge/br_netfilter.c

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,16 @@
3737
#include <net/route.h>
3838
#include <net/netfilter/br_netfilter.h>
3939

40+
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
41+
#include <net/netfilter/nf_conntrack.h>
42+
#endif
43+
4044
#include <asm/uaccess.h>
4145
#include "br_private.h"
4246
#ifdef CONFIG_SYSCTL
4347
#include <linux/sysctl.h>
4448
#endif
4549

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-
5150
#ifdef CONFIG_SYSCTL
5251
static struct ctl_table_header *brnf_sysctl_header;
5352
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)
154153
return nf_bridge;
155154
}
156155

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+
157168
static inline void nf_bridge_push_encap_header(struct sk_buff *skb)
158169
{
159170
unsigned int len = nf_bridge_encap_header_len(skb);
@@ -322,6 +333,22 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
322333
return 0;
323334
}
324335

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+
325352
/* This requires some explaining. If DNAT has taken place,
326353
* we will need to fix up the destination Ethernet address.
327354
*
@@ -625,7 +652,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops,
625652
return NF_DROP;
626653
if (!setup_pre_routing(skb))
627654
return NF_DROP;
628-
store_orig_dstaddr(skb);
655+
629656
skb->protocol = htons(ETH_P_IP);
630657

631658
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,
721748
if (pf == NFPROTO_IPV4 && br_parse_ip_options(skb))
722749
return NF_DROP;
723750

724-
/* The physdev module checks on this */
725-
nf_bridge->mask |= BRNF_BRIDGED;
726751
nf_bridge->physoutdev = skb->dev;
727752
if (pf == NFPROTO_IPV4)
728753
skb->protocol = htons(ETH_P_IP);
@@ -842,7 +867,12 @@ static unsigned int br_nf_post_routing(const struct nf_hook_ops *ops,
842867
struct net_device *realoutdev = bridge_parent(skb->dev);
843868
u_int8_t pf;
844869

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)
846876
return NF_ACCEPT;
847877

848878
if (!realoutdev)

net/ipv4/ip_output.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -636,10 +636,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
636636
left = skb->len - hlen; /* Space per frame */
637637
ptr = hlen; /* Where to start from */
638638

639-
/* for bridged IP traffic encapsulated inside f.e. a vlan header,
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));
639+
ll_rs = LL_RESERVED_SPACE(rt->dst.dev);
643640

644641
/*
645642
* Fragment the datagram.

net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,9 @@ static int exp_seq_show(struct seq_file *s, void *v)
300300
__nf_ct_l3proto_find(exp->tuple.src.l3num),
301301
__nf_ct_l4proto_find(exp->tuple.src.l3num,
302302
exp->tuple.dst.protonum));
303-
return seq_putc(s, '\n');
303+
seq_putc(s, '\n');
304+
305+
return 0;
304306
}
305307

306308
static const struct seq_operations exp_seq_ops = {

net/ipv6/netfilter/ip6t_REJECT.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ static int reject_tg6_check(const struct xt_tgchk_param *par)
8383
return -EINVAL;
8484
} else if (rejinfo->with == IP6T_TCP_RESET) {
8585
/* 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 ||
8788
(e->ipv6.invflags & XT_INV_PROTO)) {
8889
pr_info("TCP_RESET illegal for non-tcp\n");
8990
return -EINVAL;

net/netfilter/nf_conntrack_acct.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir)
4747
return 0;
4848

4949
counter = acct->counter;
50-
return seq_printf(s, "packets=%llu bytes=%llu ",
51-
(unsigned long long)atomic64_read(&counter[dir].packets),
52-
(unsigned long long)atomic64_read(&counter[dir].bytes));
50+
seq_printf(s, "packets=%llu bytes=%llu ",
51+
(unsigned long long)atomic64_read(&counter[dir].packets),
52+
(unsigned long long)atomic64_read(&counter[dir].bytes));
53+
54+
return 0;
5355
};
5456
EXPORT_SYMBOL_GPL(seq_print_acct);
5557

net/netfilter/nf_conntrack_expect.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,9 @@ static int exp_seq_show(struct seq_file *s, void *v)
561561
helper->expect_policy[expect->class].name);
562562
}
563563

564-
return seq_putc(s, '\n');
564+
seq_putc(s, '\n');
565+
566+
return 0;
565567
}
566568

567569
static const struct seq_operations exp_seq_ops = {

net/netfilter/nf_tables_api.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -687,11 +687,10 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
687687
if (!try_module_get(afi->owner))
688688
return -EAFNOSUPPORT;
689689

690+
err = -ENOMEM;
690691
table = kzalloc(sizeof(*table), GFP_KERNEL);
691-
if (table == NULL) {
692-
module_put(afi->owner);
693-
return -ENOMEM;
694-
}
692+
if (table == NULL)
693+
goto err1;
695694

696695
nla_strlcpy(table->name, name, NFT_TABLE_MAXNAMELEN);
697696
INIT_LIST_HEAD(&table->chains);
@@ -700,13 +699,16 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
700699

701700
nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla);
702701
err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE);
703-
if (err < 0) {
704-
kfree(table);
705-
module_put(afi->owner);
706-
return err;
707-
}
702+
if (err < 0)
703+
goto err2;
704+
708705
list_add_tail_rcu(&table->list, &afi->tables);
709706
return 0;
707+
err2:
708+
kfree(table);
709+
err1:
710+
module_put(afi->owner);
711+
return err;
710712
}
711713

712714
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,
31363138
elem.flags = ntohl(nla_get_be32(nla[NFTA_SET_ELEM_FLAGS]));
31373139
if (elem.flags & ~NFT_SET_ELEM_INTERVAL_END)
31383140
return -EINVAL;
3141+
if (!(set->flags & NFT_SET_INTERVAL) &&
3142+
elem.flags & NFT_SET_ELEM_INTERVAL_END)
3143+
return -EINVAL;
31393144
}
31403145

31413146
if (set->flags & NFT_SET_MAP) {

net/netfilter/nfnetlink_log.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -998,11 +998,13 @@ static int seq_show(struct seq_file *s, void *v)
998998
{
999999
const struct nfulnl_instance *inst = v;
10001000

1001-
return seq_printf(s, "%5d %6d %5d %1d %5d %6d %2d\n",
1002-
inst->group_num,
1003-
inst->peer_portid, inst->qlen,
1004-
inst->copy_mode, inst->copy_range,
1005-
inst->flushtimeout, atomic_read(&inst->use));
1001+
seq_printf(s, "%5d %6d %5d %1d %5d %6d %2d\n",
1002+
inst->group_num,
1003+
inst->peer_portid, inst->qlen,
1004+
inst->copy_mode, inst->copy_range,
1005+
inst->flushtimeout, atomic_read(&inst->use));
1006+
1007+
return 0;
10061008
}
10071009

10081010
static const struct seq_operations nful_seq_ops = {

net/netfilter/nft_rbtree.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,11 @@ static bool nft_rbtree_lookup(const struct nft_set *set,
3737
{
3838
const struct nft_rbtree *priv = nft_set_priv(set);
3939
const struct nft_rbtree_elem *rbe, *interval = NULL;
40-
const struct rb_node *parent = priv->root.rb_node;
40+
const struct rb_node *parent;
4141
int d;
4242

4343
spin_lock_bh(&nft_rbtree_lock);
44+
parent = priv->root.rb_node;
4445
while (parent != NULL) {
4546
rbe = rb_entry(parent, struct nft_rbtree_elem, node);
4647

@@ -158,7 +159,6 @@ static int nft_rbtree_get(const struct nft_set *set, struct nft_set_elem *elem)
158159
struct nft_rbtree_elem *rbe;
159160
int d;
160161

161-
spin_lock_bh(&nft_rbtree_lock);
162162
while (parent != NULL) {
163163
rbe = rb_entry(parent, struct nft_rbtree_elem, node);
164164

@@ -173,11 +173,9 @@ static int nft_rbtree_get(const struct nft_set *set, struct nft_set_elem *elem)
173173
!(rbe->flags & NFT_SET_ELEM_INTERVAL_END))
174174
nft_data_copy(&elem->data, rbe->data);
175175
elem->flags = rbe->flags;
176-
spin_unlock_bh(&nft_rbtree_lock);
177176
return 0;
178177
}
179178
}
180-
spin_unlock_bh(&nft_rbtree_lock);
181179
return -ENOENT;
182180
}
183181

net/netfilter/xt_physdev.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ physdev_mt(const struct sk_buff *skb, struct xt_action_param *par)
5656

5757
/* This only makes sense in the FORWARD and POSTROUTING chains */
5858
if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) &&
59-
(!!(nf_bridge->mask & BRNF_BRIDGED) ^
60-
!(info->invert & XT_PHYSDEV_OP_BRIDGED)))
59+
(!!nf_bridge->physoutdev ^ !(info->invert & XT_PHYSDEV_OP_BRIDGED)))
6160
return false;
6261

6362
if ((info->bitmask & XT_PHYSDEV_OP_ISIN &&

0 commit comments

Comments
 (0)