Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 May 2005 16:34:23 +0200
From:      Max Laier <max@love2party.net>
To:        freebsd-ipfw@freebsd.org
Subject:   [PATCH] ipv4 only rules (test and feedback)
Message-ID:  <200505251634.34478.max@love2party.net>

next in thread | raw e-mail | index | archive | help
--nextPart3147247.EOBnkcBnR9
Content-Type: multipart/mixed;
  boundary="Boundary-01=_wzIlCq5E0qbcCzR"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

--Boundary-01=_wzIlCq5E0qbcCzR
Content-Type: text/plain;
  charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

All,

with the recent merge of IPv6 functionality into ipfw2, ip6fw is obsolete. =
 As=20
the latter is neither locked nor using the pfil_hooks API, it was decided=20
that it should be be removed.  Of course, this means that ipfw2 has to=20
provide all the functionality that ip6fw provided before.

In order to achieve this, there is one feature missing [for all I know, ple=
ase=20
scream now if you have anything else]: IPv4 only rules.  Previously, it was=
=20
possible to do:

  ipfw add 100 deny all from any to any

to block all IPv4 traffic.  With IPv6 incooperated into ipfw2 this does no=
=20
longer work as it will block IPv6 traffic as well.  With the patch attached=
=20
you can now do:
 =20
  ipfw add 100 deny ipv4 from any to any
or
  ipfw add 100 deny ipv6 from any to any

to block IPv4 or IPv6.

If you are running a IPv6/IPv4 host/gateway/firewall on current, please tes=
t=20
the patch and send you feedback.  Be sure to have kernel and userland in=20
sync!

=2D-=20
/"\  Best regards,                      | mlaier@freebsd.org
\ /  Max Laier                          | ICQ #67774661
 X   http://pf4freebsd.love2party.net/  | mlaier@EFnet
/ \  ASCII Ribbon Campaign              | Against HTML Mail and News

--Boundary-01=_wzIlCq5E0qbcCzR
Content-Type: text/x-diff;
  charset="us-ascii";
  name="ipv4-only.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="ipv4-only.patch"

Index: sbin/ipfw/ipfw2.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/store/mlaier/fcvs/src/sbin/ipfw/ipfw2.c,v
retrieving revision 1.74
diff -u -r1.74 ipfw2.c
=2D-- sbin/ipfw/ipfw2.c	21 May 2005 03:27:33 -0000	1.74
+++ sbin/ipfw/ipfw2.c	24 May 2005 19:19:30 -0000
@@ -275,6 +275,8 @@
 	TOK_EXT6HDR,
 	TOK_DSTIP6,
 	TOK_SRCIP6,
+
+	TOK_IPV4,
 };
=20
 struct _s_x dummynet_params[] =3D {
@@ -395,6 +397,8 @@
 	{ "flow-id",		TOK_FLOWID},
 	{ "ipv6",		TOK_IPV6},
 	{ "ip6",		TOK_IPV6},
+	{ "ipv4",		TOK_IPV4},
+	{ "ip4",		TOK_IPV4},
 	{ "dst-ipv6",		TOK_DSTIP6},
 	{ "dst-ip6",		TOK_DSTIP6},
 	{ "src-ipv6",		TOK_SRCIP6},
@@ -1260,6 +1264,7 @@
 #define	HAVE_DSTIP	0x0004
 #define	HAVE_MAC	0x0008
 #define	HAVE_MACTYPE	0x0010
+#define	HAVE_PROTO4	0x0040
 #define	HAVE_PROTO6	0x0080
 #define	HAVE_OPTIONS	0x8000
=20
@@ -1283,11 +1288,14 @@
 		return;
 	}
 	if ( !(*flags & HAVE_OPTIONS)) {
=2D		/* XXX BED: !(*flags & HAVE_PROTO) in patch */
=2D		if ( !(*flags & HAVE_PROTO6) && (want & HAVE_PROTO6))
=2D			printf(" ipv6");
 		if ( !(*flags & HAVE_PROTO) && (want & HAVE_PROTO))
=2D			printf(" ip");
+			if ( (*flags & HAVE_PROTO4))
+				printf(" ip4");
+			else if ( (*flags & HAVE_PROTO6))
+				printf(" ip6");
+			else
+				printf(" ip");
+
 		if ( !(*flags & HAVE_SRCIP) && (want & HAVE_SRCIP))
 			printf(" from any");
 		if ( !(*flags & HAVE_DSTIP) && (want & HAVE_DSTIP))
@@ -1468,9 +1476,23 @@
 	/*
 	 * then print the body.
 	 */
+        for (l =3D rule->act_ofs, cmd =3D rule->cmd ;
+			l > 0 ; l -=3D F_LEN(cmd) , cmd +=3D F_LEN(cmd)) {
+		if ((cmd->len & F_OR) || (cmd->len & F_NOT))
+			continue;
+		if (cmd->opcode =3D=3D O_IP4) {
+			flags |=3D HAVE_PROTO4;
+			break;
+		} else if (cmd->opcode =3D=3D O_IP6) {
+			flags |=3D HAVE_PROTO6;
+			break;
+		}		=09
+	}
 	if (rule->_pad & 1) {	/* empty rules before options */
=2D		if (!do_compact)
=2D			printf(" ip from any to any");
+		if (!do_compact) {
+			show_prerequisites(&flags, HAVE_PROTO, 0);
+			printf(" from any to any");
+		}
 		flags |=3D HAVE_IP | HAVE_OPTIONS;
 	}
=20
@@ -1611,6 +1633,12 @@
 			break;
=20
 		default: /*options ... */
+			if (!(cmd->len & (F_OR|F_NOT)))
+				if (((cmd->opcode =3D=3D O_IP6) &&
+				    (flags & HAVE_PROTO6)) ||
+				    ((cmd->opcode =3D=3D O_IP4) &&
+				    (flags & HAVE_PROTO4)))
+					break;
 			show_prerequisites(&flags, HAVE_IP | HAVE_OPTIONS, 0);
 			if ((cmd->len & F_OR) && !or_block)
 				printf(" {");
@@ -1810,10 +1838,14 @@
 			    }
 				break;
=20
=2D			case O_IP6:  =20
+			case O_IP6:
 				printf(" ipv6");
 				break;
=20
+			case O_IP4:
+				printf(" ipv4");
+				break;
+
 			case O_ICMP6TYPE:
 				print_icmp6types((ipfw_insn_u32 *)cmd);
 				break;
@@ -3506,13 +3538,18 @@
 	*proto =3D IPPROTO_IP;
=20
 	if (_substrcmp(av, "all") =3D=3D 0)
=2D		; /* same as "ip" */
=2D	else if ((*proto =3D atoi(av)) > 0)
+		; /* do not set O_IP4 nor O_IP6 */
+	else if (strcmp(av, "ipv4") =3D=3D 0 || strcmp(av, "ip4") =3D=3D 0)
+		/* explicit "just IPv4" rule */
+		fill_cmd(cmd, O_IP4, 0, 0);
+	else if (strcmp(av, "ipv6") =3D=3D 0 || strcmp(av, "ip6") =3D=3D 0) {
+		/* explicit "just IPv6" rule */
+		*proto =3D IPPROTO_IPV6;
+		fill_cmd(cmd, O_IP6, 0, 0);
+	} else if ((*proto =3D atoi(av)) > 0)
 		; /* all done! */
 	else if ((pe =3D getprotobyname(av)) !=3D NULL)
 		*proto =3D pe->p_proto;
=2D	else if (strcmp(av, "ipv6") =3D=3D 0 || strcmp(av, "ip6") =3D=3D 0)
=2D		*proto =3D IPPROTO_IPV6;
 	else
 		return NULL;
 	if (*proto !=3D IPPROTO_IP && *proto !=3D IPPROTO_IPV6)
@@ -4347,8 +4384,6 @@
 		case TOK_PROTO:
 			NEED1("missing protocol");
 			if (add_proto(cmd, *av, &proto)) {
=2D				if (proto =3D=3D IPPROTO_IPV6)
=2D					fill_cmd(cmd, O_IP6, 0, 0);
 				ac--; av++;
 			} else
 				errx(EX_DATAERR, "invalid protocol ``%s''",
@@ -4435,6 +4470,10 @@
 			fill_cmd(cmd, O_IP6, 0, 0);
 			break;
=20
+		case TOK_IPV4:
+			fill_cmd(cmd, O_IP4, 0, 0);
+			break;
+
 		case TOK_EXT6HDR:
 			fill_ext6hdr( cmd, *av );
 			ac--; av++;
Index: sys/netinet/ip_fw.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/store/mlaier/fcvs/src/sys/netinet/ip_fw.h,v
retrieving revision 1.99
diff -u -r1.99 ip_fw.h
=2D-- sys/netinet/ip_fw.h	4 May 2005 13:12:52 -0000	1.99
+++ sys/netinet/ip_fw.h	19 May 2005 00:30:39 -0000
@@ -153,6 +153,8 @@
 	O_NETGRAPH,		/* send to ng_ipfw		*/
 	O_NGTEE,		/* copy to ng_ipfw		*/
=20
+	O_IP4,
+
 	O_LAST_OPCODE		/* not an opcode!		*/
 };
=20
Index: sys/netinet/ip_fw2.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/store/mlaier/fcvs/src/sys/netinet/ip_fw2.c,v
retrieving revision 1.97
diff -u -r1.97 ip_fw2.c
=2D-- sys/netinet/ip_fw2.c	4 May 2005 13:12:52 -0000	1.97
+++ sys/netinet/ip_fw2.c	19 May 2005 00:32:55 -0000
@@ -1961,6 +1961,7 @@
 	int is_ipv6 =3D 0;
 	u_int16_t ext_hd =3D 0;	/* bits vector for extension header filtering */
 	/* end of ipv6 variables */
+	int is_ipv4 =3D 0;
=20
 	if (m->m_flags & M_SKIP_FIREWALL)
 		return (IP_FW_PASS);	/* accept */
@@ -2071,6 +2072,7 @@
 	} else if (pktlen >=3D sizeof(struct ip) &&
 	    (args->eh =3D=3D NULL || ntohs(args->eh->ether_type) =3D=3D ETHERTYPE=
_IP) &&
 	    mtod(m, struct ip *)->ip_v =3D=3D 4) {
+	    	is_ipv4 =3D 1;
 		ip =3D mtod(m, struct ip *);
 		hlen =3D ip->ip_hl << 2;
 		args->f_id.addr_type =3D 4;
@@ -2672,6 +2674,10 @@
 				break;
 #endif
=20
+			case O_IP4:
+				match =3D is_ipv4;
+				break;
+
 			/*
 			 * The second set of opcodes represents 'actions',
 			 * i.e. the terminal part of a rule once the packet
@@ -3317,6 +3323,7 @@
 		case O_IP6_DST_ME:
 		case O_EXT_HDR:
 		case O_IP6:
+		case O_IP4:
 			if (cmdlen !=3D F_INSN_SIZE(ipfw_insn))
 				goto bad_size;
 			break;

--Boundary-01=_wzIlCq5E0qbcCzR--

--nextPart3147247.EOBnkcBnR9
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (FreeBSD)

iD8DBQBClIz6XyyEoT62BG0RAinwAJ9nZ+7c4Qpfmm4v4yRdoftvOk6zzgCfTsFw
vDu6vg1BrhGhrnWO1uJxV3s=
=kNwn
-----END PGP SIGNATURE-----

--nextPart3147247.EOBnkcBnR9--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200505251634.34478.max>