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

Commit 99633ab2 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso
Browse files

netfilter: nf_tables: complete net namespace support



Register family per netnamespace to ensure that sets are
only visible in its approapriate namespace.

Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent eb31628e
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
#include <net/netns/conntrack.h>
#endif
#include <net/netns/nftables.h>
#include <net/netns/xfrm.h>

struct user_namespace;
@@ -101,6 +102,9 @@ struct net {
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
	struct netns_ct		ct;
#endif
#if defined(CONFIG_NF_TABLES) || defined(CONFIG_NF_TABLES_MODULE)
	struct netns_nftables	nft;
#endif
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
	struct netns_nf_frag	nf_frag;
#endif
+3 −1
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ static inline void nft_data_debug(const struct nft_data *data)
/**
 *	struct nft_ctx - nf_tables rule/set context
 *
 *	@net: net namespace
 * 	@skb: netlink skb
 * 	@nlh: netlink message header
 * 	@afi: address family info
@@ -76,6 +77,7 @@ static inline void nft_data_debug(const struct nft_data *data)
 *	@nla: netlink attributes
 */
struct nft_ctx {
	struct net			*net;
	const struct sk_buff		*skb;
	const struct nlmsghdr		*nlh;
	const struct nft_af_info	*afi;
@@ -462,7 +464,7 @@ struct nft_af_info {
	nf_hookfn			*hooks[NF_MAX_HOOKS];
};

extern int nft_register_afinfo(struct nft_af_info *);
extern int nft_register_afinfo(struct net *, struct nft_af_info *);
extern void nft_unregister_afinfo(struct nft_af_info *);

struct nf_chain_type {
+15 −0
Original line number Diff line number Diff line
#ifndef _NETNS_NFTABLES_H_
#define _NETNS_NFTABLES_H_

#include <linux/list.h>

struct nft_af_info;

struct netns_nftables {
	struct list_head	af_info;
	struct nft_af_info	*ipv4;
	struct nft_af_info	*ipv6;
	struct nft_af_info	*bridge;
};

#endif
+30 −2
Original line number Diff line number Diff line
@@ -19,14 +19,42 @@ static struct nft_af_info nft_af_bridge __read_mostly = {
	.owner		= THIS_MODULE,
};

static int nf_tables_bridge_init_net(struct net *net)
{
	net->nft.bridge = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL);
	if (net->nft.bridge == NULL)
		return -ENOMEM;

	memcpy(net->nft.bridge, &nft_af_bridge, sizeof(nft_af_bridge));

	if (nft_register_afinfo(net, net->nft.bridge) < 0)
		goto err;

	return 0;
err:
	kfree(net->nft.bridge);
	return -ENOMEM;
}

static void nf_tables_bridge_exit_net(struct net *net)
{
	nft_unregister_afinfo(net->nft.bridge);
	kfree(net->nft.bridge);
}

static struct pernet_operations nf_tables_bridge_net_ops = {
	.init	= nf_tables_bridge_init_net,
	.exit	= nf_tables_bridge_exit_net,
};

static int __init nf_tables_bridge_init(void)
{
	return nft_register_afinfo(&nft_af_bridge);
	return register_pernet_subsys(&nf_tables_bridge_net_ops);
}

static void __exit nf_tables_bridge_exit(void)
{
	nft_unregister_afinfo(&nft_af_bridge);
	return unregister_pernet_subsys(&nf_tables_bridge_net_ops);
}

module_init(nf_tables_bridge_init);
+30 −2
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/ip.h>
#include <linux/netfilter_ipv4.h>
#include <net/netfilter/nf_tables.h>
#include <net/net_namespace.h>
#include <net/ip.h>
#include <net/net_namespace.h>
#include <net/netfilter/nf_tables_ipv4.h>
@@ -47,6 +48,33 @@ static struct nft_af_info nft_af_ipv4 __read_mostly = {
	},
};

static int nf_tables_ipv4_init_net(struct net *net)
{
	net->nft.ipv4 = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL);
	if (net->nft.ipv4 == NULL)
		return -ENOMEM;

	memcpy(net->nft.ipv4, &nft_af_ipv4, sizeof(nft_af_ipv4));

	if (nft_register_afinfo(net, net->nft.ipv4) < 0)
		goto err;

	return 0;
err:
	kfree(net->nft.ipv4);
	return -ENOMEM;
}

static void nf_tables_ipv4_exit_net(struct net *net)
{
	nft_unregister_afinfo(net->nft.ipv4);
	kfree(net->nft.ipv4);
}

static struct pernet_operations nf_tables_ipv4_net_ops = {
	.init	= nf_tables_ipv4_init_net,
	.exit	= nf_tables_ipv4_exit_net,
};

static unsigned int
nft_do_chain_ipv4(const struct nf_hook_ops *ops,
@@ -83,12 +111,12 @@ static struct nf_chain_type filter_ipv4 = {
static int __init nf_tables_ipv4_init(void)
{
	nft_register_chain_type(&filter_ipv4);
	return nft_register_afinfo(&nft_af_ipv4);
	return register_pernet_subsys(&nf_tables_ipv4_net_ops);
}

static void __exit nf_tables_ipv4_exit(void)
{
	nft_unregister_afinfo(&nft_af_ipv4);
	unregister_pernet_subsys(&nf_tables_ipv4_net_ops);
	nft_unregister_chain_type(&filter_ipv4);
}

Loading