Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 633c9a84 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso
Browse files

netfilter: nfnetlink: avoid recurrent netns lookups in call_batch



Pass the net pointer to the call_batch callback functions so we can skip
recurrent lookups.

Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
Tested-by: default avatarArturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
parent 639e077b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ struct nfnl_callback {
	int (*call_rcu)(struct sock *nl, struct sk_buff *skb, 
		    const struct nlmsghdr *nlh,
		    const struct nlattr * const cda[]);
	int (*call_batch)(struct sock *nl, struct sk_buff *skb,
	int (*call_batch)(struct net *net, struct sock *nl, struct sk_buff *skb,
			  const struct nlmsghdr *nlh,
			  const struct nlattr * const cda[]);
	const struct nla_policy *policy;	/* netlink attribute policy */
+45 −51
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ nf_tables_afinfo_lookup(struct net *net, int family, bool autoload)
}

static void nft_ctx_init(struct nft_ctx *ctx,
			 struct net *net,
			 const struct sk_buff *skb,
			 const struct nlmsghdr *nlh,
			 struct nft_af_info *afi,
@@ -96,7 +97,7 @@ static void nft_ctx_init(struct nft_ctx *ctx,
			 struct nft_chain *chain,
			 const struct nlattr * const *nla)
{
	ctx->net	= sock_net(skb->sk);
	ctx->net	= net;
	ctx->afi	= afi;
	ctx->table	= table;
	ctx->chain	= chain;
@@ -672,15 +673,14 @@ static int nf_tables_updtable(struct nft_ctx *ctx)
	return ret;
}

static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
			      const struct nlmsghdr *nlh,
static int nf_tables_newtable(struct net *net, struct sock *nlsk,
			      struct sk_buff *skb, const struct nlmsghdr *nlh,
			      const struct nlattr * const nla[])
{
	const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
	const struct nlattr *name;
	struct nft_af_info *afi;
	struct nft_table *table;
	struct net *net = sock_net(skb->sk);
	int family = nfmsg->nfgen_family;
	u32 flags = 0;
	struct nft_ctx ctx;
@@ -706,7 +706,7 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
		if (nlh->nlmsg_flags & NLM_F_REPLACE)
			return -EOPNOTSUPP;

		nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla);
		nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
		return nf_tables_updtable(&ctx);
	}

@@ -730,7 +730,7 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
	INIT_LIST_HEAD(&table->sets);
	table->flags = flags;

	nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla);
	nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
	err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE);
	if (err < 0)
		goto err3;
@@ -810,18 +810,17 @@ static int nft_flush(struct nft_ctx *ctx, int family)
	return err;
}

static int nf_tables_deltable(struct sock *nlsk, struct sk_buff *skb,
			      const struct nlmsghdr *nlh,
static int nf_tables_deltable(struct net *net, struct sock *nlsk,
			      struct sk_buff *skb, const struct nlmsghdr *nlh,
			      const struct nlattr * const nla[])
{
	const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
	struct nft_af_info *afi;
	struct nft_table *table;
	struct net *net = sock_net(skb->sk);
	int family = nfmsg->nfgen_family;
	struct nft_ctx ctx;

	nft_ctx_init(&ctx, skb, nlh, NULL, NULL, NULL, nla);
	nft_ctx_init(&ctx, net, skb, nlh, NULL, NULL, NULL, nla);
	if (family == AF_UNSPEC || nla[NFTA_TABLE_NAME] == NULL)
		return nft_flush(&ctx, family);

@@ -1221,8 +1220,8 @@ static void nf_tables_chain_destroy(struct nft_chain *chain)
	}
}

static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
			      const struct nlmsghdr *nlh,
static int nf_tables_newchain(struct net *net, struct sock *nlsk,
			      struct sk_buff *skb, const struct nlmsghdr *nlh,
			      const struct nlattr * const nla[])
{
	const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
@@ -1232,7 +1231,6 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
	struct nft_chain *chain;
	struct nft_base_chain *basechain = NULL;
	struct nlattr *ha[NFTA_HOOK_MAX + 1];
	struct net *net = sock_net(skb->sk);
	int family = nfmsg->nfgen_family;
	struct net_device *dev = NULL;
	u8 policy = NF_ACCEPT;
@@ -1313,7 +1311,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
				return PTR_ERR(stats);
		}

		nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);
		nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
		trans = nft_trans_alloc(&ctx, NFT_MSG_NEWCHAIN,
					sizeof(struct nft_trans_chain));
		if (trans == NULL) {
@@ -1461,7 +1459,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
	if (err < 0)
		goto err1;

	nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);
	nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
	err = nft_trans_chain_add(&ctx, NFT_MSG_NEWCHAIN);
	if (err < 0)
		goto err2;
@@ -1476,15 +1474,14 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
	return err;
}

static int nf_tables_delchain(struct sock *nlsk, struct sk_buff *skb,
			      const struct nlmsghdr *nlh,
static int nf_tables_delchain(struct net *net, struct sock *nlsk,
			      struct sk_buff *skb, const struct nlmsghdr *nlh,
			      const struct nlattr * const nla[])
{
	const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
	struct nft_af_info *afi;
	struct nft_table *table;
	struct nft_chain *chain;
	struct net *net = sock_net(skb->sk);
	int family = nfmsg->nfgen_family;
	struct nft_ctx ctx;

@@ -1506,7 +1503,7 @@ static int nf_tables_delchain(struct sock *nlsk, struct sk_buff *skb,
	if (chain->use > 0)
		return -EBUSY;

	nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);
	nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);

	return nft_delchain(&ctx);
}
@@ -2010,13 +2007,12 @@ static void nf_tables_rule_destroy(const struct nft_ctx *ctx,

static struct nft_expr_info *info;

static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
			     const struct nlmsghdr *nlh,
static int nf_tables_newrule(struct net *net, struct sock *nlsk,
			     struct sk_buff *skb, const struct nlmsghdr *nlh,
			     const struct nlattr * const nla[])
{
	const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
	struct nft_af_info *afi;
	struct net *net = sock_net(skb->sk);
	struct nft_table *table;
	struct nft_chain *chain;
	struct nft_rule *rule, *old_rule = NULL;
@@ -2075,7 +2071,7 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
			return PTR_ERR(old_rule);
	}

	nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);
	nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);

	n = 0;
	size = 0;
@@ -2176,13 +2172,12 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
	return err;
}

static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
			     const struct nlmsghdr *nlh,
static int nf_tables_delrule(struct net *net, struct sock *nlsk,
			     struct sk_buff *skb, const struct nlmsghdr *nlh,
			     const struct nlattr * const nla[])
{
	const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
	struct nft_af_info *afi;
	struct net *net = sock_net(skb->sk);
	struct nft_table *table;
	struct nft_chain *chain = NULL;
	struct nft_rule *rule;
@@ -2205,7 +2200,7 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
			return PTR_ERR(chain);
	}

	nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);
	nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);

	if (chain) {
		if (nla[NFTA_RULE_HANDLE]) {
@@ -2344,12 +2339,11 @@ static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {
	[NFTA_SET_DESC_SIZE]		= { .type = NLA_U32 },
};

static int nft_ctx_init_from_setattr(struct nft_ctx *ctx,
static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net,
				     const struct sk_buff *skb,
				     const struct nlmsghdr *nlh,
				     const struct nlattr * const nla[])
{
	struct net *net = sock_net(skb->sk);
	const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
	struct nft_af_info *afi = NULL;
	struct nft_table *table = NULL;
@@ -2371,7 +2365,7 @@ static int nft_ctx_init_from_setattr(struct nft_ctx *ctx,
			return -ENOENT;
	}

	nft_ctx_init(ctx, skb, nlh, afi, table, NULL, nla);
	nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
	return 0;
}

@@ -2623,6 +2617,7 @@ static int nf_tables_getset(struct sock *nlsk, struct sk_buff *skb,
			    const struct nlmsghdr *nlh,
			    const struct nlattr * const nla[])
{
	struct net *net = sock_net(skb->sk);
	const struct nft_set *set;
	struct nft_ctx ctx;
	struct sk_buff *skb2;
@@ -2630,7 +2625,7 @@ static int nf_tables_getset(struct sock *nlsk, struct sk_buff *skb,
	int err;

	/* Verify existence before starting dump */
	err = nft_ctx_init_from_setattr(&ctx, skb, nlh, nla);
	err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla);
	if (err < 0)
		return err;

@@ -2693,14 +2688,13 @@ static int nf_tables_set_desc_parse(const struct nft_ctx *ctx,
	return 0;
}

static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
			    const struct nlmsghdr *nlh,
static int nf_tables_newset(struct net *net, struct sock *nlsk,
			    struct sk_buff *skb, const struct nlmsghdr *nlh,
			    const struct nlattr * const nla[])
{
	const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
	const struct nft_set_ops *ops;
	struct nft_af_info *afi;
	struct net *net = sock_net(skb->sk);
	struct nft_table *table;
	struct nft_set *set;
	struct nft_ctx ctx;
@@ -2798,7 +2792,7 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
	if (IS_ERR(table))
		return PTR_ERR(table);

	nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla);
	nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);

	set = nf_tables_set_lookup(table, nla[NFTA_SET_NAME]);
	if (IS_ERR(set)) {
@@ -2882,8 +2876,8 @@ static void nf_tables_set_destroy(const struct nft_ctx *ctx, struct nft_set *set
	nft_set_destroy(set);
}

static int nf_tables_delset(struct sock *nlsk, struct sk_buff *skb,
			    const struct nlmsghdr *nlh,
static int nf_tables_delset(struct net *net, struct sock *nlsk,
			    struct sk_buff *skb, const struct nlmsghdr *nlh,
			    const struct nlattr * const nla[])
{
	const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
@@ -2896,7 +2890,7 @@ static int nf_tables_delset(struct sock *nlsk, struct sk_buff *skb,
	if (nla[NFTA_SET_TABLE] == NULL)
		return -EINVAL;

	err = nft_ctx_init_from_setattr(&ctx, skb, nlh, nla);
	err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla);
	if (err < 0)
		return err;

@@ -3024,7 +3018,7 @@ static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX +
	[NFTA_SET_ELEM_LIST_SET_ID]	= { .type = NLA_U32 },
};

static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx,
static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
				      const struct sk_buff *skb,
				      const struct nlmsghdr *nlh,
				      const struct nlattr * const nla[],
@@ -3033,7 +3027,6 @@ static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx,
	const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
	struct nft_af_info *afi;
	struct nft_table *table;
	struct net *net = sock_net(skb->sk);

	afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false);
	if (IS_ERR(afi))
@@ -3045,7 +3038,7 @@ static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx,
	if (!trans && (table->flags & NFT_TABLE_INACTIVE))
		return -ENOENT;

	nft_ctx_init(ctx, skb, nlh, afi, table, NULL, nla);
	nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
	return 0;
}

@@ -3135,6 +3128,7 @@ static int nf_tables_dump_setelem(const struct nft_ctx *ctx,

static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct net *net = sock_net(skb->sk);
	const struct nft_set *set;
	struct nft_set_dump_args args;
	struct nft_ctx ctx;
@@ -3150,8 +3144,8 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
	if (err < 0)
		return err;

	err = nft_ctx_init_from_elemattr(&ctx, cb->skb, cb->nlh, (void *)nla,
					 false);
	err = nft_ctx_init_from_elemattr(&ctx, net, cb->skb, cb->nlh,
					 (void *)nla, false);
	if (err < 0)
		return err;

@@ -3212,11 +3206,12 @@ static int nf_tables_getsetelem(struct sock *nlsk, struct sk_buff *skb,
				const struct nlmsghdr *nlh,
				const struct nlattr * const nla[])
{
	struct net *net = sock_net(skb->sk);
	const struct nft_set *set;
	struct nft_ctx ctx;
	int err;

	err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla, false);
	err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, false);
	if (err < 0)
		return err;

@@ -3528,11 +3523,10 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
	return err;
}

static int nf_tables_newsetelem(struct sock *nlsk, struct sk_buff *skb,
				const struct nlmsghdr *nlh,
static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
				struct sk_buff *skb, const struct nlmsghdr *nlh,
				const struct nlattr * const nla[])
{
	struct net *net = sock_net(skb->sk);
	const struct nlattr *attr;
	struct nft_set *set;
	struct nft_ctx ctx;
@@ -3541,7 +3535,7 @@ static int nf_tables_newsetelem(struct sock *nlsk, struct sk_buff *skb,
	if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
		return -EINVAL;

	err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla, true);
	err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, true);
	if (err < 0)
		return err;

@@ -3623,8 +3617,8 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
	return err;
}

static int nf_tables_delsetelem(struct sock *nlsk, struct sk_buff *skb,
				const struct nlmsghdr *nlh,
static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
				struct sk_buff *skb, const struct nlmsghdr *nlh,
				const struct nlattr * const nla[])
{
	const struct nlattr *attr;
@@ -3635,7 +3629,7 @@ static int nf_tables_delsetelem(struct sock *nlsk, struct sk_buff *skb,
	if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
		return -EINVAL;

	err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla, false);
	err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, false);
	if (err < 0)
		return err;

+1 −1
Original line number Diff line number Diff line
@@ -381,7 +381,7 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh,
				goto ack;

			if (nc->call_batch) {
				err = nc->call_batch(net->nfnl, skb, nlh,
				err = nc->call_batch(net, net->nfnl, skb, nlh,
						     (const struct nlattr **)cda);
			}