[PATCH nf-next 2/2] xt_nat: probe module for non-builtin L4 protocols

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



autoload nf_nat_proto_{dccp,sctp,udplite}.ko on invocation of checkentry()
callback, if rule matches DCCP, SCTP or UDPLITE protocols. This avoids
situations where, after a SNAT/DNAT rule with specified sport/dport is
created, no port translation is done unless the user manually loads
nf_nat_proto_{dccp,udplite,sctp}.ko with insmod/modprobe commands.

Suggested-by: Florian Westphal <fw@xxxxxxxxx>
Signed-off-by: Davide Caratti <dcaratti@xxxxxxxxxx>
---
 net/netfilter/xt_nat.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/net/netfilter/xt_nat.c b/net/netfilter/xt_nat.c
index bea7464..b78023d 100644
--- a/net/netfilter/xt_nat.c
+++ b/net/netfilter/xt_nat.c
@@ -13,6 +13,44 @@
 #include <linux/netfilter.h>
 #include <linux/netfilter/x_tables.h>
 #include <net/netfilter/nf_nat_core.h>
+#include <net/netfilter/nf_nat_l4proto.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+
+static void xt_nat_probe_proto(const struct xt_tgchk_param *par)
+{
+	const struct ip6t_ip6 *i6;
+	const struct ipt_ip *i;
+	u8 proto, l4proto;
+
+	switch (par->family) {
+	case NFPROTO_IPV4:
+		i = (const struct ipt_ip *)par->entryinfo;
+		if (i->invflags & IPT_INV_PROTO)
+			return;
+		proto = i->proto;
+		break;
+	case NFPROTO_IPV6:
+		i6 = (const struct ip6t_ip6 *)par->entryinfo;
+		if (i6->invflags & IP6T_INV_PROTO)
+			return;
+		proto = i6->proto;
+		break;
+	default:
+		return;
+	}
+
+	switch (proto) {
+	case IPPROTO_UDPLITE:
+	case IPPROTO_SCTP:
+	case IPPROTO_DCCP:
+		rcu_read_lock();
+		l4proto = __nf_nat_l4proto_find(par->family, proto)->l4proto;
+		rcu_read_unlock();
+		if (!l4proto)
+			request_module("nf-nat-l4-%u", proto);
+	}
+}
 
 static int xt_nat_checkentry_v0(const struct xt_tgchk_param *par)
 {
@@ -23,6 +61,13 @@ static int xt_nat_checkentry_v0(const struct xt_tgchk_param *par)
 			par->target->name);
 		return -EINVAL;
 	}
+	xt_nat_probe_proto(par);
+	return 0;
+}
+
+static int xt_nat_checkentry_v1(const struct xt_tgchk_param *par)
+{
+	xt_nat_probe_proto(par);
 	return 0;
 }
 
@@ -129,6 +174,7 @@ static struct xt_target xt_nat_target_reg[] __read_mostly = {
 	{
 		.name		= "SNAT",
 		.revision	= 1,
+		.checkentry     = xt_nat_checkentry_v1,
 		.target		= xt_snat_target_v1,
 		.targetsize	= sizeof(struct nf_nat_range),
 		.table		= "nat",
@@ -139,6 +185,7 @@ static struct xt_target xt_nat_target_reg[] __read_mostly = {
 	{
 		.name		= "DNAT",
 		.revision	= 1,
+		.checkentry     = xt_nat_checkentry_v1,
 		.target		= xt_dnat_target_v1,
 		.targetsize	= sizeof(struct nf_nat_range),
 		.table		= "nat",
-- 
2.5.5

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux