Skip to content

Commit 2650be2

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: =================== Netfilter fixes for net The following patchset contains Netfilter fixes for net: 1) Allow conntrack entries with l3num == NFPROTO_IPV4 or == NFPROTO_IPV6 only via ctnetlink, from Will McVicker. 2) Batch notifications to userspace to improve netlink socket receive utilization. 3) Restore mark based dump filtering via ctnetlink, from Martin Willi. 4) nf_conncount_init() fails with -EPROTO with CONFIG_IPV6, from Eelco Chaudron. 5) Containers fail to match on meta skuid and skgid, use socket user_ns to retrieve meta skuid and skgid. =================== Signed-off-by: David S. Miller <[email protected]>
2 parents 843d926 + 0c92411 commit 2650be2

File tree

5 files changed

+67
-32
lines changed

5 files changed

+67
-32
lines changed

include/net/netns/nftables.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ struct netns_nftables {
88
struct list_head tables;
99
struct list_head commit_list;
1010
struct list_head module_list;
11+
struct list_head notify_list;
1112
struct mutex commit_mutex;
1213
unsigned int base_seq;
1314
u8 gencursor;

net/netfilter/nf_conntrack_netlink.c

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,6 @@ static int ctnetlink_done(struct netlink_callback *cb)
851851
}
852852

853853
struct ctnetlink_filter {
854-
u_int32_t cta_flags;
855854
u8 family;
856855

857856
u_int32_t orig_flags;
@@ -906,10 +905,6 @@ static int ctnetlink_parse_tuple_filter(const struct nlattr * const cda[],
906905
struct nf_conntrack_zone *zone,
907906
u_int32_t flags);
908907

909-
/* applied on filters */
910-
#define CTA_FILTER_F_CTA_MARK (1 << 0)
911-
#define CTA_FILTER_F_CTA_MARK_MASK (1 << 1)
912-
913908
static struct ctnetlink_filter *
914909
ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
915910
{
@@ -930,14 +925,10 @@ ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
930925
#ifdef CONFIG_NF_CONNTRACK_MARK
931926
if (cda[CTA_MARK]) {
932927
filter->mark.val = ntohl(nla_get_be32(cda[CTA_MARK]));
933-
filter->cta_flags |= CTA_FILTER_FLAG(CTA_MARK);
934-
935-
if (cda[CTA_MARK_MASK]) {
928+
if (cda[CTA_MARK_MASK])
936929
filter->mark.mask = ntohl(nla_get_be32(cda[CTA_MARK_MASK]));
937-
filter->cta_flags |= CTA_FILTER_FLAG(CTA_MARK_MASK);
938-
} else {
930+
else
939931
filter->mark.mask = 0xffffffff;
940-
}
941932
} else if (cda[CTA_MARK_MASK]) {
942933
err = -EINVAL;
943934
goto err_filter;
@@ -1117,11 +1108,7 @@ static int ctnetlink_filter_match(struct nf_conn *ct, void *data)
11171108
}
11181109

11191110
#ifdef CONFIG_NF_CONNTRACK_MARK
1120-
if ((filter->cta_flags & CTA_FILTER_FLAG(CTA_MARK_MASK)) &&
1121-
(ct->mark & filter->mark.mask) != filter->mark.val)
1122-
goto ignore_entry;
1123-
else if ((filter->cta_flags & CTA_FILTER_FLAG(CTA_MARK)) &&
1124-
ct->mark != filter->mark.val)
1111+
if ((ct->mark & filter->mark.mask) != filter->mark.val)
11251112
goto ignore_entry;
11261113
#endif
11271114

@@ -1404,7 +1391,8 @@ ctnetlink_parse_tuple_filter(const struct nlattr * const cda[],
14041391
if (err < 0)
14051392
return err;
14061393

1407-
1394+
if (l3num != NFPROTO_IPV4 && l3num != NFPROTO_IPV6)
1395+
return -EOPNOTSUPP;
14081396
tuple->src.l3num = l3num;
14091397

14101398
if (flags & CTA_FILTER_FLAG(CTA_IP_DST) ||

net/netfilter/nf_conntrack_proto.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ static int nf_ct_netns_inet_get(struct net *net)
565565
int err;
566566

567567
err = nf_ct_netns_do_get(net, NFPROTO_IPV4);
568+
#if IS_ENABLED(CONFIG_IPV6)
568569
if (err < 0)
569570
goto err1;
570571
err = nf_ct_netns_do_get(net, NFPROTO_IPV6);
@@ -575,6 +576,7 @@ static int nf_ct_netns_inet_get(struct net *net)
575576
err2:
576577
nf_ct_netns_put(net, NFPROTO_IPV4);
577578
err1:
579+
#endif
578580
return err;
579581
}
580582

net/netfilter/nf_tables_api.c

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,18 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
684684
return -1;
685685
}
686686

687+
struct nftnl_skb_parms {
688+
bool report;
689+
};
690+
#define NFT_CB(skb) (*(struct nftnl_skb_parms*)&((skb)->cb))
691+
692+
static void nft_notify_enqueue(struct sk_buff *skb, bool report,
693+
struct list_head *notify_list)
694+
{
695+
NFT_CB(skb).report = report;
696+
list_add_tail(&skb->list, notify_list);
697+
}
698+
687699
static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
688700
{
689701
struct sk_buff *skb;
@@ -715,8 +727,7 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
715727
goto err;
716728
}
717729

718-
nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
719-
ctx->report, GFP_KERNEL);
730+
nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
720731
return;
721732
err:
722733
nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
@@ -1468,8 +1479,7 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
14681479
goto err;
14691480
}
14701481

1471-
nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
1472-
ctx->report, GFP_KERNEL);
1482+
nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
14731483
return;
14741484
err:
14751485
nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
@@ -2807,8 +2817,7 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx,
28072817
goto err;
28082818
}
28092819

2810-
nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
2811-
ctx->report, GFP_KERNEL);
2820+
nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
28122821
return;
28132822
err:
28142823
nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
@@ -3837,8 +3846,7 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx,
38373846
goto err;
38383847
}
38393848

3840-
nfnetlink_send(skb, ctx->net, portid, NFNLGRP_NFTABLES, ctx->report,
3841-
gfp_flags);
3849+
nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
38423850
return;
38433851
err:
38443852
nfnetlink_set_err(ctx->net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
@@ -4959,8 +4967,7 @@ static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
49594967
goto err;
49604968
}
49614969

4962-
nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, ctx->report,
4963-
GFP_KERNEL);
4970+
nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
49644971
return;
49654972
err:
49664973
nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
@@ -6275,7 +6282,7 @@ void nft_obj_notify(struct net *net, const struct nft_table *table,
62756282
goto err;
62766283
}
62776284

6278-
nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report, gfp);
6285+
nft_notify_enqueue(skb, report, &net->nft.notify_list);
62796286
return;
62806287
err:
62816288
nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
@@ -7085,8 +7092,7 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx,
70857092
goto err;
70867093
}
70877094

7088-
nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
7089-
ctx->report, GFP_KERNEL);
7095+
nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
70907096
return;
70917097
err:
70927098
nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
@@ -7695,6 +7701,41 @@ static void nf_tables_commit_release(struct net *net)
76957701
mutex_unlock(&net->nft.commit_mutex);
76967702
}
76977703

7704+
static void nft_commit_notify(struct net *net, u32 portid)
7705+
{
7706+
struct sk_buff *batch_skb = NULL, *nskb, *skb;
7707+
unsigned char *data;
7708+
int len;
7709+
7710+
list_for_each_entry_safe(skb, nskb, &net->nft.notify_list, list) {
7711+
if (!batch_skb) {
7712+
new_batch:
7713+
batch_skb = skb;
7714+
len = NLMSG_GOODSIZE - skb->len;
7715+
list_del(&skb->list);
7716+
continue;
7717+
}
7718+
len -= skb->len;
7719+
if (len > 0 && NFT_CB(skb).report == NFT_CB(batch_skb).report) {
7720+
data = skb_put(batch_skb, skb->len);
7721+
memcpy(data, skb->data, skb->len);
7722+
list_del(&skb->list);
7723+
kfree_skb(skb);
7724+
continue;
7725+
}
7726+
nfnetlink_send(batch_skb, net, portid, NFNLGRP_NFTABLES,
7727+
NFT_CB(batch_skb).report, GFP_KERNEL);
7728+
goto new_batch;
7729+
}
7730+
7731+
if (batch_skb) {
7732+
nfnetlink_send(batch_skb, net, portid, NFNLGRP_NFTABLES,
7733+
NFT_CB(batch_skb).report, GFP_KERNEL);
7734+
}
7735+
7736+
WARN_ON_ONCE(!list_empty(&net->nft.notify_list));
7737+
}
7738+
76987739
static int nf_tables_commit(struct net *net, struct sk_buff *skb)
76997740
{
77007741
struct nft_trans *trans, *next;
@@ -7897,6 +7938,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
78977938
}
78987939
}
78997940

7941+
nft_commit_notify(net, NETLINK_CB(skb).portid);
79007942
nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
79017943
nf_tables_commit_release(net);
79027944

@@ -8721,6 +8763,7 @@ static int __net_init nf_tables_init_net(struct net *net)
87218763
INIT_LIST_HEAD(&net->nft.tables);
87228764
INIT_LIST_HEAD(&net->nft.commit_list);
87238765
INIT_LIST_HEAD(&net->nft.module_list);
8766+
INIT_LIST_HEAD(&net->nft.notify_list);
87248767
mutex_init(&net->nft.commit_mutex);
87258768
net->nft.base_seq = 1;
87268769
net->nft.validate_state = NFT_VALIDATE_SKIP;
@@ -8737,6 +8780,7 @@ static void __net_exit nf_tables_exit_net(struct net *net)
87378780
mutex_unlock(&net->nft.commit_mutex);
87388781
WARN_ON_ONCE(!list_empty(&net->nft.tables));
87398782
WARN_ON_ONCE(!list_empty(&net->nft.module_list));
8783+
WARN_ON_ONCE(!list_empty(&net->nft.notify_list));
87408784
}
87418785

87428786
static struct pernet_operations nf_tables_net_ops = {

net/netfilter/nft_meta.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,11 @@ nft_meta_get_eval_skugid(enum nft_meta_keys key,
147147

148148
switch (key) {
149149
case NFT_META_SKUID:
150-
*dest = from_kuid_munged(&init_user_ns,
150+
*dest = from_kuid_munged(sock_net(sk)->user_ns,
151151
sock->file->f_cred->fsuid);
152152
break;
153153
case NFT_META_SKGID:
154-
*dest = from_kgid_munged(&init_user_ns,
154+
*dest = from_kgid_munged(sock_net(sk)->user_ns,
155155
sock->file->f_cred->fsgid);
156156
break;
157157
default:

0 commit comments

Comments
 (0)