File:  [pfSense CVS Repository] / tools / patches / RELENG_7 / pfil.RELENG_7.diff
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Sat Oct 25 14:30:00 2008 UTC (15 months, 2 weeks ago) by ermal
Branches: MAIN
CVS tags: HEAD
Refactor pfil reorder patch to its own diff.

Index: sys/contrib/pf/net/pf_ioctl.c
===================================================================
RCS file: /home/ncvs/src/sys/contrib/pf/net/pf_ioctl.c,v
retrieving revision 1.28.2.5
diff -u -r1.28.2.5 pf_ioctl.c
--- sys/contrib/pf/net/pf_ioctl.c	24 Jul 2008 19:05:32 -0000	1.28.2.5
+++ sys/contrib/pf/net/pf_ioctl.c	25 Oct 2008 14:22:34 -0000
@@ -3761,8 +3761,10 @@
 	pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
 	if (pfh_inet == NULL)
 		return (ESRCH); /* XXX */
-	pfil_add_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet);
-	pfil_add_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet);
+	pfil_add_named_hook(pf_check_in, NULL, "pf", PFIL_IN | PFIL_WAITOK, 
+		pfh_inet);
+	pfil_add_named_hook(pf_check_out, NULL, "pf", PFIL_OUT | PFIL_WAITOK, 
+		pfh_inet);
 #ifdef INET6
 	pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
 	if (pfh_inet6 == NULL) {
@@ -3772,8 +3774,10 @@
 		    pfh_inet);
 		return (ESRCH); /* XXX */
 	}
-	pfil_add_hook(pf_check6_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet6);
-	pfil_add_hook(pf_check6_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet6);
+	pfil_add_named_hook(pf_check6_in, NULL, "pf", PFIL_IN | PFIL_WAITOK, 
+		pfh_inet6);
+	pfil_add_named_hook(pf_check6_out, NULL, "pf", PFIL_OUT | PFIL_WAITOK, 
+		pfh_inet6);
 #endif
 
 	pf_pfil_hooked = 1;
Index: sys/net/pfil.c
===================================================================
RCS file: /home/ncvs/src/sys/net/pfil.c,v
retrieving revision 1.14
diff -u -r1.14 pfil.c
--- sys/net/pfil.c	2 Feb 2006 03:13:15 -0000	1.14
+++ sys/net/pfil.c	25 Oct 2008 14:22:34 -0000
@@ -34,6 +34,7 @@
 #include <sys/errno.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
+#include <sys/sbuf.h>
 #include <sys/rwlock.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
@@ -74,7 +75,7 @@
 	KASSERT(ph->ph_nhooks >= 0, ("Pfil hook count dropped < 0"));
 	for (pfh = pfil_hook_get(dir, ph); pfh != NULL;
 	     pfh = TAILQ_NEXT(pfh, pfil_link)) {
-		if (pfh->pfil_func != NULL) {
+		if (!(pfh->pfil_flags & PFIL_DISABLED) && pfh->pfil_func != NULL) {
 			rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp, dir, inp);
 			if (rv != 0 || m == NULL)
 				break;
@@ -148,6 +149,140 @@
 	return (0);
 }
 
+static int
+pfil_sysctl_handler(SYSCTL_HANDLER_ARGS)
+{
+        struct pfil_head *ph;
+        struct packet_filter_hook *pfh, *pfhtmp;
+        struct sbuf *sb;
+        pfil_list_t npfl, *pfl;
+        char *new_order, *elm, *parse;
+        int i = 0, err = 0, hintlen, reqlen;
+
+        hintlen = 0;
+
+        ph = (struct pfil_head *)arg1;
+        if (ph == NULL || !PFIL_HOOKED(ph)) {
+                err = SYSCTL_OUT(req, "", 2);
+                return (err);
+        }
+
+        if (arg2 == PFIL_IN)
+                pfl = &ph->ph_in;
+        else
+                pfl = &ph->ph_out;
+
+        if (TAILQ_EMPTY(pfl)) {
+                err = SYSCTL_OUT(req, "", 2);
+                return (err);
+        }
+
+	/*
+	 * NOTE: This is needed to avoid witness(4) warnings.
+	 */
+	PFIL_RLOCK(ph);
+        TAILQ_FOREACH(pfh, pfl, pfil_link) {
+                if (pfh->pfil_name != NULL)
+                        hintlen = strlen(pfh->pfil_name);
+                else
+                        hintlen += 2;
+        }
+        PFIL_RUNLOCK(ph);
+
+        sb = sbuf_new(NULL, NULL, hintlen + 1, SBUF_AUTOEXTEND);
+        if (sb == NULL)
+                return (EINVAL);
+
+        PFIL_RLOCK(ph);
+        TAILQ_FOREACH(pfh, pfl, pfil_link) {
+                if (i > 0)
+                        sbuf_printf(sb, ", ");
+                if (pfh->pfil_name != NULL)
+                        sbuf_printf(sb, "%s%s", pfh->pfil_name,
+                                pfh->pfil_flags & PFIL_DISABLED ? "*" : "");
+                else
+                        sbuf_printf(sb, "%s%s", "NA",
+                                pfh->pfil_flags & PFIL_DISABLED ? "*" : "");
+                i++;
+        }
+        PFIL_RUNLOCK(ph);
+
+        sbuf_finish(sb);
+
+        /* hint for sensible write buffer sizes */
+        hintlen = sbuf_len(sb) + i * 2;
+        err = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
+        sbuf_delete(sb);
+
+        if (err || !req->newptr)
+                return (err);
+
+        if ((reqlen = req->newlen - req->newidx) > hintlen)
+                return (E2BIG);
+        new_order = malloc(reqlen + 1, M_TEMP, M_WAITOK|M_ZERO);
+
+        err = SYSCTL_IN(req, new_order, reqlen);
+        if (err)
+                goto error;
+        new_order[reqlen] = '\0'; /* Just in case */
+        parse = new_order;
+
+        TAILQ_INIT(&npfl);
+        PFIL_WLOCK(ph);
+        while ((elm = strsep(&parse, " \t,")) != NULL) {
+                if (*elm == '\0')
+                        continue;
+                TAILQ_FOREACH_SAFE(pfh, pfl, pfil_link, pfhtmp) {
+                        if (pfh->pfil_name != NULL) {
+                                if (!strcmp(pfh->pfil_name, elm)) {
+                                        TAILQ_REMOVE(pfl, pfh, pfil_link);
+                                        TAILQ_INSERT_TAIL(&npfl, pfh, pfil_link);
+					pfh->pfil_flags &= ~PFIL_DISABLED;
+                                        break;
+                                }
+                        } else {
+                                if (!strcmp(elm, "NA")) {
+                                        TAILQ_REMOVE(pfl, pfh, pfil_link);
+                                        TAILQ_INSERT_TAIL(&npfl, pfh, pfil_link);
+					pfh->pfil_flags &= ~PFIL_DISABLED;
+                                        break;
+                                }
+                        }
+                }
+        }
+
+	TAILQ_FOREACH_SAFE(pfh, pfl, pfil_link, pfhtmp) {
+                pfh->pfil_flags |= PFIL_DISABLED;
+		TAILQ_REMOVE(pfl, pfh, pfil_link);
+		TAILQ_INSERT_TAIL(&npfl, pfh, pfil_link);
+	}
+
+        TAILQ_CONCAT(pfl, &npfl, pfil_link);
+
+error:
+        PFIL_WUNLOCK(ph);
+        free(new_order, M_TEMP);
+        return (err);
+}
+
+void
+pfil_head_export_sysctl(struct pfil_head *ph, struct sysctl_oid_list *parent)
+{
+        struct sysctl_oid *root;
+
+        root = SYSCTL_ADD_NODE(&ph->ph_clist, parent, OID_AUTO, "pfil",
+            CTLFLAG_RW, 0, "pfil(9) management");
+        SYSCTL_ADD_PROC((void *)&ph->ph_clist, SYSCTL_CHILDREN(root), OID_AUTO,
+            "inbound", CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_SECURE3,
+            (void *)ph, PFIL_IN, pfil_sysctl_handler, "A",
+            "Inbound filter hooks");
+        SYSCTL_ADD_PROC((void *)&ph->ph_clist, SYSCTL_CHILDREN(root), OID_AUTO,
+            "outbound", CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_SECURE3,
+            (void *)ph, PFIL_OUT, pfil_sysctl_handler, "A",
+            "Outbound filter hooks");
+}
+
+
 /*
  * pfil_head_get() returns the pfil_head for a given key/dlt.
  */
@@ -177,6 +312,13 @@
 pfil_add_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *),
     void *arg, int flags, struct pfil_head *ph)
 {
+        return (pfil_add_named_hook(func, arg, NULL, flags, ph));
+}
+
+int
+pfil_add_named_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int,
+        struct inpcb *), void *arg, char *name, int flags, struct pfil_head *ph)
+{
 	struct packet_filter_hook *pfh1 = NULL;
 	struct packet_filter_hook *pfh2 = NULL;
 	int err;
@@ -206,6 +348,8 @@
 	if (flags & PFIL_IN) {
 		pfh1->pfil_func = func;
 		pfh1->pfil_arg = arg;
+		pfh1->pfil_name = name;
+		pfh1->pfil_flags &= ~PFIL_DISABLED;
 		err = pfil_list_add(&ph->ph_in, pfh1, flags & ~PFIL_OUT);
 		if (err)
 			goto done;
@@ -214,6 +358,8 @@
 	if (flags & PFIL_OUT) {
 		pfh2->pfil_func = func;
 		pfh2->pfil_arg = arg;
+                pfh2->pfil_name = name;
+                pfh2->pfil_flags &= ~PFIL_DISABLED;
 		err = pfil_list_add(&ph->ph_out, pfh2, flags & ~PFIL_IN);
 		if (err) {
 			if (flags & PFIL_IN)
Index: sys/net/pfil.h
===================================================================
RCS file: /home/ncvs/src/sys/net/pfil.h,v
retrieving revision 1.16
diff -u -r1.16 pfil.h
--- sys/net/pfil.h	8 Jun 2007 12:43:25 -0000	1.16
+++ sys/net/pfil.h	25 Oct 2008 14:22:34 -0000
@@ -38,6 +38,7 @@
 #include <sys/_mutex.h>
 #include <sys/lock.h>
 #include <sys/rwlock.h>
+#include <sys/sysctl.h>
 
 struct mbuf;
 struct ifnet;
@@ -52,8 +53,11 @@
 	int	(*pfil_func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *);
 	void	*pfil_arg;
 	int	pfil_flags;
+	char	*pfil_name;
 };
 
+#define PFIL_DISABLED   0x00000008
+
 #define PFIL_IN		0x00000001
 #define PFIL_OUT	0x00000002
 #define PFIL_WAITOK	0x00000004
@@ -70,6 +74,7 @@
 	int		ph_type;
 	int		ph_nhooks;
 	struct rwlock	ph_mtx;
+	struct sysctl_ctx_list ph_clist;
 	union {
 		u_long		phu_val;
 		void		*phu_ptr;
@@ -82,12 +87,16 @@
 int	pfil_run_hooks(struct pfil_head *, struct mbuf **, struct ifnet *,
 	    int, struct inpcb *inp);
 
+int     pfil_add_named_hook(int (*func)(void *, struct mbuf **,
+            struct ifnet *, int, struct inpcb *), void *, char *, int,
+            struct pfil_head *);
 int	pfil_add_hook(int (*func)(void *, struct mbuf **,
 	    struct ifnet *, int, struct inpcb *), void *, int, struct pfil_head *);
 int	pfil_remove_hook(int (*func)(void *, struct mbuf **,
 	    struct ifnet *, int, struct inpcb *), void *, int, struct pfil_head *);
 
 int	pfil_head_register(struct pfil_head *);
+void    pfil_head_export_sysctl(struct pfil_head *, struct sysctl_oid_list *);
 int	pfil_head_unregister(struct pfil_head *);
 
 struct pfil_head *pfil_head_get(int, u_long);
Index: sys/netinet/ip_fw_pfil.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_fw_pfil.c,v
retrieving revision 1.25.2.2
diff -u -r1.25.2.2 ip_fw_pfil.c
--- sys/netinet/ip_fw_pfil.c	25 Apr 2008 10:26:30 -0000	1.25.2.2
+++ sys/netinet/ip_fw_pfil.c	25 Oct 2008 14:22:35 -0000
@@ -430,8 +430,10 @@
 	if (pfh_inet == NULL)
 		return ENOENT;
 
-	pfil_add_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet);
-	pfil_add_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet);
+	pfil_add_named_hook(ipfw_check_in, NULL, "ipfw", PFIL_IN | PFIL_WAITOK, 
+		pfh_inet);
+	pfil_add_named_hook(ipfw_check_out, NULL, "ipfw", PFIL_OUT | PFIL_WAITOK, 
+		pfh_inet);
 
 	return 0;
 }
@@ -461,8 +463,10 @@
 	if (pfh_inet6 == NULL)
 		return ENOENT;
 
-	pfil_add_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet6);
-	pfil_add_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet6);
+	pfil_add_named_hook(ipfw_check_in, NULL, "ipfw", PFIL_IN | PFIL_WAITOK, 
+		pfh_inet6);
+	pfil_add_named_hook(ipfw_check_out, NULL, "ipfw", PFIL_OUT | PFIL_WAITOK, 
+		pfh_inet6);
 
 	return 0;
 }
Index: sys/netinet/ip_input.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.332.2.4
diff -u -r1.332.2.4 ip_input.c
--- sys/netinet/ip_input.c	24 Jul 2008 01:13:22 -0000	1.332.2.4
+++ sys/netinet/ip_input.c	25 Oct 2008 14:22:36 -0000
@@ -244,6 +244,9 @@
 	if ((i = pfil_head_register(&inet_pfil_hook)) != 0)
 		printf("%s: WARNING: unable to register pfil hook, "
 			"error %d\n", __func__, i);
+	else
+		pfil_head_export_sysctl(&inet_pfil_hook,
+			SYSCTL_STATIC_CHILDREN(_net_inet_ip));
 
 	/* Initialize IP reassembly queue. */
 	IPQ_LOCK_INIT();
Index: sys/netinet6/ip6_input.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.95.2.4
diff -u -r1.95.2.4 ip6_input.c
--- sys/netinet6/ip6_input.c	1 Sep 2008 19:23:04 -0000	1.95.2.4
+++ sys/netinet6/ip6_input.c	25 Oct 2008 14:22:38 -0000
@@ -126,6 +126,7 @@
 
 int ip6_ours_check_algorithm;
 
+SYSCTL_DECL(_net_inet6_ip6);
 struct pfil_head inet6_pfil_hook;
 
 struct ip6stat ip6stat;
@@ -177,6 +178,9 @@
 	if ((i = pfil_head_register(&inet6_pfil_hook)) != 0)
 		printf("%s: WARNING: unable to register pfil hook, "
 			"error %d\n", __func__, i);
+	else
+		pfil_head_export_sysctl(&inet6_pfil_hook,
+			SYSCTL_STATIC_CHILDREN(_net_inet6_ip6));
 
 	ip6intrq.ifq_maxlen = ip6qmaxlen;
 	mtx_init(&ip6intrq.ifq_mtx, "ip6_inq", NULL, MTX_DEF);

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>