Commit 610a4314 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso
Browse files

netfilter: nf_nat_masquerade: unify ipv4/6 notifier registration



Only reason for having two different register functions was because of
ipt_MASQUERADE and ip6t_MASQUERADE being two different modules.

Previous patch merged those into xt_MASQUERADE, so we can merge this too.

Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent adf82acc
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -9,13 +9,11 @@ nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum,
		       const struct nf_nat_range2 *range,
		       const struct net_device *out);

int nf_nat_masquerade_ipv4_register_notifier(void);
void nf_nat_masquerade_ipv4_unregister_notifier(void);
int nf_nat_masquerade_inet_register_notifiers(void);
void nf_nat_masquerade_inet_unregister_notifiers(void);

unsigned int
nf_nat_masquerade_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range,
		       const struct net_device *out);
int nf_nat_masquerade_ipv6_register_notifier(void);
void nf_nat_masquerade_ipv6_unregister_notifier(void);

#endif /*_NF_NAT_MASQUERADE_H_ */
+37 −64
Original line number Diff line number Diff line
@@ -10,8 +10,7 @@
#include <net/netfilter/nf_nat_masquerade.h>

static DEFINE_MUTEX(masq_mutex);
static unsigned int masq_refcnt4 __read_mostly;
static unsigned int masq_refcnt6 __read_mostly;
static unsigned int masq_refcnt __read_mostly;

unsigned int
nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum,
@@ -136,56 +135,6 @@ static struct notifier_block masq_inet_notifier = {
	.notifier_call	= masq_inet_event,
};

int nf_nat_masquerade_ipv4_register_notifier(void)
{
	int ret = 0;

	mutex_lock(&masq_mutex);
	if (WARN_ON_ONCE(masq_refcnt4 == UINT_MAX)) {
		ret = -EOVERFLOW;
		goto out_unlock;
	}

	/* check if the notifier was already set */
	if (++masq_refcnt4 > 1)
		goto out_unlock;

	/* Register for device down reports */
	ret = register_netdevice_notifier(&masq_dev_notifier);
	if (ret)
		goto err_dec;
	/* Register IP address change reports */
	ret = register_inetaddr_notifier(&masq_inet_notifier);
	if (ret)
		goto err_unregister;

	mutex_unlock(&masq_mutex);
	return ret;

err_unregister:
	unregister_netdevice_notifier(&masq_dev_notifier);
err_dec:
	masq_refcnt4--;
out_unlock:
	mutex_unlock(&masq_mutex);
	return ret;
}
EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv4_register_notifier);

void nf_nat_masquerade_ipv4_unregister_notifier(void)
{
	mutex_lock(&masq_mutex);
	/* check if the notifier still has clients */
	if (--masq_refcnt4 > 0)
		goto out_unlock;

	unregister_netdevice_notifier(&masq_dev_notifier);
	unregister_inetaddr_notifier(&masq_inet_notifier);
out_unlock:
	mutex_unlock(&masq_mutex);
}
EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv4_unregister_notifier);

#if IS_ENABLED(CONFIG_IPV6)
static atomic_t v6_worker_count __read_mostly;

@@ -321,44 +270,68 @@ static struct notifier_block masq_inet6_notifier = {
	.notifier_call	= masq_inet6_event,
};

int nf_nat_masquerade_ipv6_register_notifier(void)
static int nf_nat_masquerade_ipv6_register_notifier(void)
{
	return register_inet6addr_notifier(&masq_inet6_notifier);
}
#else
static inline int nf_nat_masquerade_ipv6_register_notifier(void) { return 0; }
#endif

int nf_nat_masquerade_inet_register_notifiers(void)
{
	int ret = 0;

	mutex_lock(&masq_mutex);
	if (WARN_ON_ONCE(masq_refcnt6 == UINT_MAX)) {
	if (WARN_ON_ONCE(masq_refcnt == UINT_MAX)) {
		ret = -EOVERFLOW;
		goto out_unlock;
	}

	/* check if the notifier is already set */
	if (++masq_refcnt6 > 1)
	/* check if the notifier was already set */
	if (++masq_refcnt > 1)
		goto out_unlock;

	ret = register_inet6addr_notifier(&masq_inet6_notifier);
	/* Register for device down reports */
	ret = register_netdevice_notifier(&masq_dev_notifier);
	if (ret)
		goto err_dec;
	/* Register IP address change reports */
	ret = register_inetaddr_notifier(&masq_inet_notifier);
	if (ret)
		goto err_unregister;

	ret = nf_nat_masquerade_ipv6_register_notifier();
	if (ret)
		goto err_unreg_inet;

	mutex_unlock(&masq_mutex);
	return ret;
err_unreg_inet:
	unregister_inetaddr_notifier(&masq_inet_notifier);
err_unregister:
	unregister_netdevice_notifier(&masq_dev_notifier);
err_dec:
	masq_refcnt6--;
	masq_refcnt--;
out_unlock:
	mutex_unlock(&masq_mutex);
	return ret;
}
EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv6_register_notifier);
EXPORT_SYMBOL_GPL(nf_nat_masquerade_inet_register_notifiers);

void nf_nat_masquerade_ipv6_unregister_notifier(void)
void nf_nat_masquerade_inet_unregister_notifiers(void)
{
	mutex_lock(&masq_mutex);
	/* check if the notifier still has clients */
	if (--masq_refcnt6 > 0)
	/* check if the notifiers still have clients */
	if (--masq_refcnt > 0)
		goto out_unlock;

	unregister_netdevice_notifier(&masq_dev_notifier);
	unregister_inetaddr_notifier(&masq_inet_notifier);
#if IS_ENABLED(CONFIG_IPV6)
	unregister_inet6addr_notifier(&masq_inet6_notifier);
#endif
out_unlock:
	mutex_unlock(&masq_mutex);
}
EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv6_unregister_notifier);
#endif
EXPORT_SYMBOL_GPL(nf_nat_masquerade_inet_unregister_notifiers);
+3 −13
Original line number Diff line number Diff line
@@ -195,22 +195,12 @@ static struct nft_expr_type nft_masq_ipv6_type __read_mostly = {

static int __init nft_masq_module_init_ipv6(void)
{
	int ret = nft_register_expr(&nft_masq_ipv6_type);

	if (ret)
		return ret;

	ret = nf_nat_masquerade_ipv6_register_notifier();
	if (ret < 0)
		nft_unregister_expr(&nft_masq_ipv6_type);

	return ret;
	return nft_register_expr(&nft_masq_ipv6_type);
}

static void nft_masq_module_exit_ipv6(void)
{
	nft_unregister_expr(&nft_masq_ipv6_type);
	nf_nat_masquerade_ipv6_unregister_notifier();
}
#else
static inline int nft_masq_module_init_ipv6(void) { return 0; }
@@ -293,7 +283,7 @@ static int __init nft_masq_module_init(void)
		return ret;
	}

	ret = nf_nat_masquerade_ipv4_register_notifier();
	ret = nf_nat_masquerade_inet_register_notifiers();
	if (ret < 0) {
		nft_masq_module_exit_ipv6();
		nft_masq_module_exit_inet();
@@ -309,7 +299,7 @@ static void __exit nft_masq_module_exit(void)
	nft_masq_module_exit_ipv6();
	nft_masq_module_exit_inet();
	nft_unregister_expr(&nft_masq_ipv4_type);
	nf_nat_masquerade_ipv4_unregister_notifier();
	nf_nat_masquerade_inet_unregister_notifiers();
}

module_init(nft_masq_module_init);
+2 −14
Original line number Diff line number Diff line
@@ -107,32 +107,20 @@ static int __init masquerade_tg_init(void)
	if (ret)
		return ret;

	ret = nf_nat_masquerade_ipv4_register_notifier();
	ret = nf_nat_masquerade_inet_register_notifiers();
	if (ret) {
		xt_unregister_targets(masquerade_tg_reg,
				      ARRAY_SIZE(masquerade_tg_reg));
		return ret;
	}

#if IS_ENABLED(CONFIG_IPV6)
	ret = nf_nat_masquerade_ipv6_register_notifier();
	if (ret) {
		xt_unregister_targets(masquerade_tg_reg,
				      ARRAY_SIZE(masquerade_tg_reg));
		nf_nat_masquerade_ipv4_unregister_notifier();
		return ret;
	}
#endif
	return ret;
}

static void __exit masquerade_tg_exit(void)
{
	xt_unregister_targets(masquerade_tg_reg, ARRAY_SIZE(masquerade_tg_reg));
	nf_nat_masquerade_ipv4_unregister_notifier();
#if IS_ENABLED(CONFIG_IPV6)
	nf_nat_masquerade_ipv6_unregister_notifier();
#endif
	nf_nat_masquerade_inet_unregister_notifiers();
}

module_init(masquerade_tg_init);