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

Commit 8b13eddf authored by Arturo Borrero's avatar Arturo Borrero Committed by Pablo Neira Ayuso
Browse files

netfilter: refactor NAT redirect IPv4 to use it from nf_tables



This patch refactors the IPv4 code so it can be usable both from xt and
nf_tables.

A similar patch follows-up to handle IPv6.

Signed-off-by: default avatarArturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent b8901ac3
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
#ifndef _NF_NAT_REDIRECT_IPV4_H_
#define _NF_NAT_REDIRECT_IPV4_H_

unsigned int
nf_nat_redirect_ipv4(struct sk_buff *skb,
		     const struct nf_nat_ipv4_multi_range_compat *mr,
		     unsigned int hooknum);

#endif /* _NF_NAT_REDIRECT_IPV4_H_ */
+6 −0
Original line number Original line Diff line number Diff line
@@ -104,6 +104,12 @@ config NF_NAT_MASQUERADE_IPV4
	  This is the kernel functionality to provide NAT in the masquerade
	  This is the kernel functionality to provide NAT in the masquerade
	  flavour (automatic source address selection).
	  flavour (automatic source address selection).


config NF_NAT_REDIRECT_IPV4
	tristate "IPv4 redirect support"
	help
	  This is the kernel functionality to provide NAT in the redirect
	  flavour (redirect packets to local machine).

config NFT_MASQ_IPV4
config NFT_MASQ_IPV4
	tristate "IPv4 masquerading support for nf_tables"
	tristate "IPv4 masquerading support for nf_tables"
	depends on NF_TABLES_IPV4
	depends on NF_TABLES_IPV4
+1 −0
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@ obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o
obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o
obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o
obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o
obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o
obj-$(CONFIG_NF_NAT_MASQUERADE_IPV4) += nf_nat_masquerade_ipv4.o
obj-$(CONFIG_NF_NAT_MASQUERADE_IPV4) += nf_nat_masquerade_ipv4.o
obj-$(CONFIG_NF_NAT_REDIRECT_IPV4) += nf_nat_redirect_ipv4.o


# NAT protocols (nf_nat)
# NAT protocols (nf_nat)
obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o
obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o
+82 −0
Original line number Original line Diff line number Diff line
/*
 * (C) 1999-2001 Paul `Rusty' Russell
 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
 * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Based on Rusty Russell's IPv4 REDIRECT target. Development of IPv6
 * NAT funded by Astaro.
 */

#include <linux/if.h>
#include <linux/inetdevice.h>
#include <linux/ip.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/netfilter.h>
#include <linux/types.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter/x_tables.h>
#include <net/addrconf.h>
#include <net/checksum.h>
#include <net/protocol.h>
#include <net/netfilter/nf_nat.h>
#include <net/netfilter/ipv4/nf_nat_redirect.h>

unsigned int
nf_nat_redirect_ipv4(struct sk_buff *skb,
		     const struct nf_nat_ipv4_multi_range_compat *mr,
		     unsigned int hooknum)
{
	struct nf_conn *ct;
	enum ip_conntrack_info ctinfo;
	__be32 newdst;
	struct nf_nat_range newrange;

	NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING ||
		     hooknum == NF_INET_LOCAL_OUT);

	ct = nf_ct_get(skb, &ctinfo);
	NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));

	/* Local packets: make them go to loopback */
	if (hooknum == NF_INET_LOCAL_OUT) {
		newdst = htonl(0x7F000001);
	} else {
		struct in_device *indev;
		struct in_ifaddr *ifa;

		newdst = 0;

		rcu_read_lock();
		indev = __in_dev_get_rcu(skb->dev);
		if (indev != NULL) {
			ifa = indev->ifa_list;
			newdst = ifa->ifa_local;
		}
		rcu_read_unlock();

		if (!newdst)
			return NF_DROP;
	}

	/* Transfer from original range. */
	memset(&newrange.min_addr, 0, sizeof(newrange.min_addr));
	memset(&newrange.max_addr, 0, sizeof(newrange.max_addr));
	newrange.flags	     = mr->range[0].flags | NF_NAT_RANGE_MAP_IPS;
	newrange.min_addr.ip = newdst;
	newrange.max_addr.ip = newdst;
	newrange.min_proto   = mr->range[0].min;
	newrange.max_proto   = mr->range[0].max;

	/* Hand modified range to generic setup. */
	return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
}
EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv4);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+1 −0
Original line number Original line Diff line number Diff line
@@ -835,6 +835,7 @@ config NETFILTER_XT_TARGET_RATEEST
config NETFILTER_XT_TARGET_REDIRECT
config NETFILTER_XT_TARGET_REDIRECT
	tristate "REDIRECT target support"
	tristate "REDIRECT target support"
	depends on NF_NAT
	depends on NF_NAT
	select NF_NAT_REDIRECT_IPV4
	---help---
	---help---
	REDIRECT is a special case of NAT: all incoming connections are
	REDIRECT is a special case of NAT: all incoming connections are
	mapped onto the incoming interface's address, causing the packets to
	mapped onto the incoming interface's address, causing the packets to
Loading