ipfw2 for IPV6

Vladimir Kotal vlada at devnull.cz
Wed Jan 19 05:12:43 PST 2005


More update on this one:

- I've added code which enables IPv6 forwarding functionality
  - this is confirmed to work with one_pass={0,1}
  - patch of ip6_forward.c (against 4.10 patch branch) included

Latest version of the IPFW2+IPv6+dummynet patch for 4.x is available at
  http://techie.devnull.cz/ipv6/ipfw2-ipv6-dummynet/


v.
-------------- next part --------------
diff -uNr --exclude-from=exclude src.orig/sys/netinet6/ip6_forward.c src/sys/netinet6/ip6_forward.c
--- sys/netinet6/ip6_forward.c	Fri Jan 24 06:11:35 2003
+++ sys/netinet6/ip6_forward.c	Wed Dec 22 17:55:54 2004
@@ -34,6 +34,7 @@
 #include "opt_inet.h"
 #include "opt_inet6.h"
 #include "opt_ipsec.h"
+#include "opt_ipfw.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -78,7 +79,12 @@
 #define	IPSEC
 #endif /* FAST_IPSEC */
 
+#ifdef IPFW2
+#include <netinet/ip_fw.h>
+#include <netinet/ip_dummynet.h>
+#else
 #include <netinet6/ip6_fw.h>
+#endif
 
 #include <net/net_osdep.h>
 
@@ -113,6 +119,16 @@
 #ifdef IPSEC
 	struct secpolicy *sp = NULL;
 #endif
+#ifdef IPFW2
+	struct ip_fw_args args;
+	int i;
+
+	args.eh = NULL;
+        args.oif = NULL;
+        args.rule = NULL;
+        args.divert_rule = 0;
+        args.next_hop = NULL;
+#endif
 
 #ifdef IPSEC
 	/*
@@ -455,20 +471,6 @@
 	}
 
 	/*
-	 * Check with the firewall...
-	 */
-	if (ip6_fw_enable && ip6_fw_chk_ptr) {
-		u_short port = 0;
-		/* If ipfw says divert, we have to just drop packet */
-		if ((*ip6_fw_chk_ptr)(&ip6, rt->rt_ifp, &port, &m)) {
-			m_freem(m);
-			goto freecopy;
-		}
-		if (!m)
-			goto freecopy;
-	}
-
-	/*
 	 * Fake scoped addresses. Note that even link-local source or
 	 * destinaion can appear, if the originating node just sends the
 	 * packet to us (without address resolution for the destination).
@@ -513,6 +515,61 @@
 	in6_clearscope(&ip6->ip6_src);
 	in6_clearscope(&ip6->ip6_dst);
 #endif
+
+	/*
+	 * Check with the firewall...
+	 * XXX not really sure if it belongs here, but we need origifp ptr
+	 */
+#ifdef IPFW2
+	if (fw_enable && IPFW_LOADED) {
+		args.m = m;
+		args.oif = rt->rt_ifp;
+		i = ip_fw_chk_ptr(&args);
+		m = args.m;
+
+		if ( (i & IP_FW_PORT_DENY_FLAG) || m == NULL) { /* drop */
+                        if (m)
+                                m_freem(m);	/* XXX error = EACCESS; */
+			goto freecopy;
+                }
+		ip6 = mtod(m, struct ip6_hdr *);   /* XXX check if necessary */
+#if 0
+		if (off == 0 && dst == old)             /* common case */
+			goto pass6;
+#endif
+		if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG) != 0) {
+                        args.dummypar.ro_or = ip6_forward_rt;
+                        args.dummypar.ifp_or = rt->rt_ifp;
+                        args.dummypar.origifp_or = origifp;
+                        args.dummypar.dst_or = *dst;
+#if 0
+                        args.dummypar.flags_or = flags;
+                        args.flags = flags;
+#endif
+                        error = ip_dn_io_ptr(m, i & 0xffff, DN_TO_IP6_OUT,
+                                &args);
+			/* packet was scheduled and it will be possibly 
+			  transferred by dummynet_io(), we need to free 
+			  copied mbuf and return 
+			*/
+                        goto freecopy;
+		}
+	}
+#else
+	if (ip6_fw_enable && ip6_fw_chk_ptr) {
+		u_short port = 0;
+		/* If ipfw says divert, we have to just drop packet */
+		if ((*ip6_fw_chk_ptr)(&ip6, rt->rt_ifp, &port, &m)) {
+			m_freem(m);
+			goto freecopy;
+		}
+		if (!m)
+			goto freecopy;
+	}
+#endif
+
+
+
 
 	/*
 	 * Check if we want to allow this packet to be processed.


More information about the freebsd-ipfw mailing list