Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Mar 2008 00:05:36 +0100
From:      Max Laier <max@love2party.net>
To:        freebsd-hackers@freebsd.org
Subject:   Review please: pfil FIRST/LAST
Message-ID:  <200803160005.45827.max@love2party.net>

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

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

Hi,

attached is a small diff to allow pfil(9) consumers to force a sticky=20
position on the head/tail of the processing queue.  This can be used to=20
do traffic conditioning kind of tasks w/o disturbing the other filters. =20
I will need this to implement carp(4) ip based load balancing.  While=20
here I also removed a few paragraphs in BUGS which are no longer true=20
(since we are using rmlocks for pfil(9)).

I'd appreciate review of the logic in pfil_list_add - just to make sure I=20
didn't botch it.  Thanks.

=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=_AZF3H42vZy1W3mH
Content-Type: text/x-diff; charset="us-ascii"; name="pfil_FIRST_LAST.diff"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="pfil_FIRST_LAST.diff"

Index: sys/net/pfil.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: /home/ncvs/src/sys/net/pfil.c,v
retrieving revision 1.15
diff -u -r1.15 pfil.c
=2D-- sys/net/pfil.c	25 Nov 2007 12:41:47 -0000	1.15
+++ sys/net/pfil.c	15 Mar 2008 22:35:50 -0000
@@ -182,6 +182,9 @@
 	struct packet_filter_hook *pfh2 =3D NULL;
 	int err;
=20
+	if ((flags & (PFIL_FIRST|PFIL_LAST)) =3D=3D (PFIL_FIRST|PFIL_LAST))
+		return (EDOOFUS);
+
 	/* Get memory */
 	if (flags & PFIL_IN) {
 		pfh1 =3D (struct packet_filter_hook *)malloc(sizeof(*pfh1),=20
@@ -267,23 +270,50 @@
 static int
 pfil_list_add(pfil_list_t *list, struct packet_filter_hook *pfh1, int flag=
s)
 {
=2D	struct packet_filter_hook *pfh;
+	struct packet_filter_hook *pfh, *fh, *lh;
=20
 	/*
 	 * First make sure the hook is not already there.
 	 */
=2D	TAILQ_FOREACH(pfh, list, pfil_link)
+	fh =3D TAILQ_FIRST(list);
+	lh =3D NULL;
+	TAILQ_FOREACH(pfh, list, pfil_link) {
+		/* fh is the first hook not marked PFIL_FIRST */
+		if (pfh->pfil_flags & PFIL_FIRST)
+			fh =3D TAILQ_NEXT(pfh, pfil_link);
+		/* lh ist the last hook not marked PFIL_LAST */
+		if (!(pfh->pfil_flags & PFIL_LAST))
+			lh =3D pfh;
 		if (pfh->pfil_func =3D=3D pfh1->pfil_func &&
 		    pfh->pfil_arg =3D=3D pfh1->pfil_arg)
 			return EEXIST;
+	}
+
 	/*
 	 * insert the input list in reverse order of the output list
 	 * so that the same path is followed in or out of the kernel.
 	 */
=2D	if (flags & PFIL_IN)
+	if (flags & PFIL_FIRST) {
 		TAILQ_INSERT_HEAD(list, pfh1, pfil_link);
=2D	else
+	} else if (flags & PFIL_LAST) {
 		TAILQ_INSERT_TAIL(list, pfh1, pfil_link);
+	} else {
+		if (flags & PFIL_IN) {
+			if (fh)
+				TAILQ_INSERT_BEFORE(fh, pfh1, pfil_link);
+			else if (!TAILQ_EMPTY(list))
+				TAILQ_INSERT_TAIL(list, pfh1, pfil_link);
+			else
+				TAILQ_INSERT_HEAD(list, pfh1, pfil_link);
+		} else {
+			if (lh)
+				TAILQ_INSERT_AFTER(list, lh, pfh1, pfil_link);
+			else if (!TAILQ_EMPTY(list))
+				TAILQ_INSERT_HEAD(list, pfh1, pfil_link);
+			else
+				TAILQ_INSERT_TAIL(list, pfh1, pfil_link);
+		}
+	}
=20
 	return 0;
 }
Index: sys/net/pfil.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: /home/ncvs/src/sys/net/pfil.h,v
retrieving revision 1.17
diff -u -r1.17 pfil.h
=2D-- sys/net/pfil.h	25 Nov 2007 12:41:47 -0000	1.17
+++ sys/net/pfil.h	15 Mar 2008 22:34:44 -0000
@@ -54,10 +54,12 @@
 	int	pfil_flags;
 };
=20
=2D#define PFIL_IN		0x00000001
=2D#define PFIL_OUT	0x00000002
=2D#define PFIL_WAITOK	0x00000004
=2D#define PFIL_ALL	(PFIL_IN|PFIL_OUT)
+#define	PFIL_IN		(1<<0)
+#define	PFIL_OUT	(1<<2)
+#define	PFIL_WAITOK	(1<<3)
+#define	PFIL_ALL	(PFIL_IN|PFIL_OUT)
+#define	PFIL_FIRST	(1<<4)
+#define	PFIL_LAST	(1<<5)
=20
 typedef	TAILQ_HEAD(pfil_list, packet_filter_hook) pfil_list_t;
=20
Index: share/man/man9/pfil.9
=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: /home/ncvs/src/share/man/man9/pfil.9,v
retrieving revision 1.22
diff -u -r1.22 pfil.9
=2D-- share/man/man9/pfil.9	18 Sep 2006 15:24:20 -0000	1.22
+++ share/man/man9/pfil.9	15 Mar 2008 22:50:48 -0000
@@ -28,7 +28,7 @@
 .\"
 .\" $FreeBSD: src/share/man/man9/pfil.9,v 1.22 2006/09/18 15:24:20 ru Exp $
 .\"
=2D.Dd September 29, 2004
+.Dd March 15, 2008
 .Dt PFIL 9
 .Os
 .Sh NAME
@@ -115,6 +115,11 @@
 or
 .Dv PFIL_OUT )
 that the packet is traveling.
+.Dv PFIL_FIRST
+and
+.Dv PFIL_LAST
+can be used to force a sticky positioning of the hook in the front or the
+tail of the processing queue respectively.
 The filter may change which mbuf the
 .Vt "mbuf\ **"
 argument references.
@@ -134,15 +139,6 @@
 .Fn pfil_remove_hook
 functions
 return 0 if successful.
=2DIf called with flag
=2D.Dv PFIL_WAITOK ,
=2D.Fn pfil_remove_hook
=2Dis expected to always succeed.
=2D.Pp
=2DThe
=2D.Fn pfil_head_unregister
=2Dfunction
=2Dmight sleep!
 .Sh SEE ALSO
 .Xr bpf 4 ,
 .Xr if_bridge 4
@@ -203,14 +199,3 @@
 .Dv AF_INET6
 traffic according to its sysctl settings, but contrary to the above
 statements, the data is provided in host byte order.
=2D.Pp
=2DWhen a
=2D.Vt pfil_head
=2Dis being modified, no traffic is diverted
=2D(to avoid deadlock).
=2DThis means that traffic may be dropped unconditionally for a short period
=2Dof time.
=2D.Fn pfil_run_hooks
=2Dwill return
=2D.Er ENOBUFS
=2Dto indicate this.

--Boundary-01=_AZF3H42vZy1W3mH--

--nextPart3260259.LKNuToB0ym
Content-Type: application/pgp-signature; name=signature.asc 
Content-Description: This is a digitally signed message part.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.4 (FreeBSD)

iD8DBQBH3FZJXyyEoT62BG0RAulNAJ4nREpIJr8Ykor+QHlv1jmBSTN8EACfZDzr
1QWjz4gk8YD3PS0TJ6Rv6zw=
=RP4z
-----END PGP SIGNATURE-----

--nextPart3260259.LKNuToB0ym--



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