[PATCH] DHCPv6 connection tracker helper

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

 



Adds a connection tracker helper for DHCPv6, which relies on UDP
multicast solicitations to discover DHCPv6 servers.

This allows DHCPv6 to work through ip6tables rulesets where
non-related traffic is dropped (e.g., default fedora iptables).
https://bugzilla.redhat.com/show_bug.cgi?id=656334

Signed-off-by: Darren Willis <djw@xxxxxxxxxx>

diff -rupN linux-orig/net/ipv6/netfilter/Kconfig
linux-dhcpv6/net/ipv6/netfilter/Kconfig
--- linux-orig/net/ipv6/netfilter/Kconfig	2011-10-24 07:10:05.000000000 +0000
+++ linux-dhcpv6/net/ipv6/netfilter/Kconfig	2012-02-10 02:05:54.000000000 +0000
@@ -25,6 +25,22 @@ config NF_CONNTRACK_IPV6

 	  To compile it as a module, choose M here.  If unsure, say N.

+if NF_CONNTRACK_IPV6
+
+config NF_CONNTRACK_DHCPV6
+       tristate "DHCPv6 connection tracking support"
+       depends on NF_CONNTRACK_IPV6
+       default m
+       help
+         DHCPv6 is an autoconfiguration protocol for IPv6 that makes use of
+	 IPv6's mulitcast addresses to solicit configuration providers. This
+	 module makes it possible for connection tracker to track replies to
+	 these multicast solicitations, allowing DHCPv6 to function correctly.
+
+	 To compile it as a module, choose M here. If unsure, say N.
+
+endif # NF_CONNTRACK_IPV6
+
 config IP6_NF_QUEUE
 	tristate "IP6 Userspace queueing via NETLINK (OBSOLETE)"
 	depends on INET && IPV6 && NETFILTER
diff -rupN linux-orig/net/ipv6/netfilter/Makefile
linux-dhcpv6/net/ipv6/netfilter/Makefile
--- linux-orig/net/ipv6/netfilter/Makefile	2011-10-24 07:10:05.000000000 +0000
+++ linux-dhcpv6/net/ipv6/netfilter/Makefile	2012-02-09 07:54:18.000000000 +0000
@@ -16,6 +16,9 @@ nf_conntrack_ipv6-y  :=  nf_conntrack_l3
 # l3 independent conntrack
 obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_defrag_ipv6.o

+# IPv6-only connection tracker protocol.
+obj-$(CONFIG_NF_CONNTRACK_DHCPV6) += nf_conntrack_dhcpv6.o
+
 # defrag
 nf_defrag_ipv6-y := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o
 obj-$(CONFIG_NF_DEFRAG_IPV6) += nf_defrag_ipv6.o
diff -rupN linux-orig/net/ipv6/netfilter/nf_conntrack_dhcpv6.c
linux-dhcpv6/net/ipv6/netfilter/nf_conntrack_dhcpv6.c
--- linux-orig/net/ipv6/netfilter/nf_conntrack_dhcpv6.c	1970-01-01
00:00:00.000000000 +0000
+++ linux-dhcpv6/net/ipv6/netfilter/nf_conntrack_dhcpv6.c	2012-02-09
07:54:32.000000000 +0000
@@ -0,0 +1,94 @@
+/*
+ *      DHCPv6 multicast connection tracking helper.
+ *
+ *      (c) 2012 Google Inc.
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/ip.h>
+#include <net/addrconf.h>
+#include <linux/skbuff.h>
+#include <linux/ipv6.h>
+
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_expect.h>
+#include <net/netfilter/nf_conntrack_helper.h>
+
+#define DHCPV6_SERVER_PORT 547
+
+MODULE_AUTHOR("Darren Willis <djw@xxxxxxxxxx>");
+MODULE_DESCRIPTION("DHCPv6 multicast connection tracking helper");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipv6_conntrack_dhcpv6");
+MODULE_ALIAS_NFCT_HELPER("dhcpv6");
+
+static unsigned int timeout __read_mostly = 120;
+module_param(timeout, uint, S_IRUSR);
+MODULE_PARM_DESC(timeout, "timeout for DHCPv6 replies in seconds");
+
+static int dhcpv6_help(struct sk_buff *skb,
+		       unsigned int protoff,
+		       struct nf_conn *ct,
+		       enum ip_conntrack_info ctinfo)
+{
+	struct nf_conntrack_expect *exp;
+	struct iphdr *iph = ip_hdr(skb);
+	if (iph->version == 6) {
+		struct ipv6hdr *ip6h = ipv6_hdr(skb);
+		if (skb->sk == NULL)
+			goto out;
+		if (ipv6_addr_is_multicast(&ip6h->daddr)) {
+			exp = nf_ct_expect_alloc(ct);
+			if (exp == NULL)
+				goto out;
+			exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+			exp->tuple.src.u.udp.port = htons(DHCPV6_SERVER_PORT);
+			exp->mask.src.u.udp.port = htons(0xFFFF);
+			exp->mask.src.u.all = 0x0;
+
+			exp->expectfn = NULL;
+			exp->flags = NF_CT_EXPECT_PERMANENT;
+			exp->class = NF_CT_EXPECT_CLASS_DEFAULT;
+			exp->helper = NULL;
+
+			nf_ct_expect_related(exp);
+			nf_ct_expect_put(exp);
+
+			nf_ct_refresh(ct, skb, timeout * HZ);
+		}
+	}
+	out:
+		return NF_ACCEPT;
+}
+
+static struct nf_conntrack_expect_policy exp_policy = {
+	.max_expected   = 1,
+};
+
+static struct nf_conntrack_helper helper __read_mostly = {
+	.name                   = "dhcpv6",
+	.tuple.src.l3num        = AF_INET6,
+	.tuple.src.u.udp.port   = htons(DHCPV6_SERVER_PORT),
+	.tuple.dst.protonum     = IPPROTO_UDP,
+	.me                     = THIS_MODULE,
+	.help                   = dhcpv6_help,
+	.expect_policy          = &exp_policy,
+};
+
+static int __init nf_conntrack_dhcpv6_init(void)
+{
+	exp_policy.timeout = timeout;
+	return nf_conntrack_helper_register(&helper);
+}
+
+static void __exit nf_conntrack_dhcpv6_fini(void)
+{
+	nf_conntrack_helper_unregister(&helper);
+}
+
+module_init(nf_conntrack_dhcpv6_init);
+module_exit(nf_conntrack_dhcpv6_fini);
--
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