Projet

Général

Profil

Télécharger (10,6 ko) Statistiques
| Branche: | Révision:

univnautes-tools / patches / stable / 10 / pfil.RELENG_10.diff @ 4ab3b90b

1
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
2
index ea22d33..5e2499d 100644
3
--- a/sys/net/if_ethersubr.c
4
+++ b/sys/net/if_ethersubr.c
5
@@ -108,6 +108,8 @@ CTASSERT(sizeof (struct ether_addr) == ETHER_ADDR_LEN);
6
 
7
 VNET_DEFINE(struct pfil_head, link_pfil_hook);	/* Packet filter hooks */
8
 
9
+SYSCTL_DECL(_net_link);
10
+
11
 /* netgraph node hooks for ng_ether(4) */
12
 void	(*ng_ether_input_p)(struct ifnet *ifp, struct mbuf **mp);
13
 void	(*ng_ether_input_orphan_p)(struct ifnet *ifp, struct mbuf *m);
14
@@ -685,6 +687,9 @@ vnet_ether_init(__unused void *arg)
15
 	if ((i = pfil_head_register(&V_link_pfil_hook)) != 0)
16
 		printf("%s: WARNING: unable to register pfil link hook, "
17
 			"error %d\n", __func__, i);
18
+	else
19
+                pfil_head_export_sysctl(&V_link_pfil_hook,
20
+                        SYSCTL_STATIC_CHILDREN(_net_link));
21
 }
22
 VNET_SYSINIT(vnet_ether_init, SI_SUB_PROTO_IF, SI_ORDER_ANY,
23
     vnet_ether_init, NULL);
24
@@ -972,7 +977,6 @@ ether_reassign(struct ifnet *ifp, struct vnet *new_vnet, char *unused __unused)
25
 }
26
 #endif
27
 
28
-SYSCTL_DECL(_net_link);
29
 SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet");
30
 
31
 #if 0
32
diff --git a/sys/net/pfil.c b/sys/net/pfil.c
33
index 44373ee..5d5d346 100644
34
--- a/sys/net/pfil.c
35
+++ b/sys/net/pfil.c
36
@@ -34,6 +34,7 @@
37
 #include <sys/errno.h>
38
 #include <sys/lock.h>
39
 #include <sys/malloc.h>
40
+#include <sys/sbuf.h>
41
 #include <sys/rmlock.h>
42
 #include <sys/socket.h>
43
 #include <sys/socketvar.h>
44
@@ -78,7 +79,7 @@ pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp,
45
 	KASSERT(ph->ph_nhooks >= 0, ("Pfil hook count dropped < 0"));
46
 	for (pfh = pfil_chain_get(dir, ph); pfh != NULL;
47
 	     pfh = TAILQ_NEXT(pfh, pfil_chain)) {
48
-		if (pfh->pfil_func != NULL) {
49
+		if (!(pfh->pfil_flags & PFIL_DISABLED) && pfh->pfil_func != NULL) {
50
 			rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp, dir,
51
 			    inp);
52
 			if (rv != 0 || m == NULL)
53
@@ -211,6 +212,140 @@ pfil_head_unregister(struct pfil_head *ph)
54
 	return (0);
55
 }
56
 
57
+static int
58
+pfil_sysctl_handler(SYSCTL_HANDLER_ARGS)
59
+{
60
+	struct rm_priotracker rmpt;
61
+	struct pfil_head *ph;
62
+	struct packet_filter_hook *pfh, *pfhtmp;
63
+	struct sbuf *sb;
64
+	pfil_chain_t npfl, *pfl;
65
+	char *new_order, *elm, *parse;
66
+	int i = 0, err = 0, hintlen, reqlen;
67
+
68
+	hintlen = 0;
69
+
70
+	ph = (struct pfil_head *)arg1;
71
+	if (ph == NULL || !PFIL_HOOKED(ph)) {
72
+		err = SYSCTL_OUT(req, "", 2);
73
+		return (err);
74
+	}
75
+
76
+	if (arg2 == PFIL_IN)
77
+		pfl = &ph->ph_in;
78
+	else
79
+		pfl = &ph->ph_out;
80
+
81
+	if (TAILQ_EMPTY(pfl)) {
82
+		err = SYSCTL_OUT(req, "", 2);
83
+		return (err);
84
+	}
85
+
86
+	/*
87
+	 * NOTE: This is needed to avoid witness(4) warnings.
88
+	 */
89
+	PFIL_RLOCK(ph, &rmpt);
90
+	TAILQ_FOREACH(pfh, pfl, pfil_chain) {
91
+		if (pfh->pfil_name != NULL)
92
+			hintlen = strlen(pfh->pfil_name);
93
+		else
94
+			hintlen += 2;
95
+	}
96
+	PFIL_RUNLOCK(ph, &rmpt);
97
+
98
+	sb = sbuf_new(NULL, NULL, hintlen + 1, SBUF_AUTOEXTEND);
99
+	if (sb == NULL)
100
+		return (EINVAL);
101
+
102
+	PFIL_RLOCK(ph, &rmpt);
103
+	TAILQ_FOREACH(pfh, pfl, pfil_chain) {
104
+		if (i > 0)
105
+			sbuf_printf(sb, ", ");
106
+		if (pfh->pfil_name != NULL)
107
+			sbuf_printf(sb, "%s%s", pfh->pfil_name,
108
+					pfh->pfil_flags & PFIL_DISABLED ? "*" : "");
109
+		else
110
+			sbuf_printf(sb, "%s%s", "NA",
111
+					pfh->pfil_flags & PFIL_DISABLED ? "*" : "");
112
+		i++;
113
+	}
114
+	PFIL_RUNLOCK(ph, &rmpt);
115
+
116
+	sbuf_finish(sb);
117
+
118
+	/* hint for sensible write buffer sizes */
119
+	hintlen = sbuf_len(sb) + i * 2;
120
+	err = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
121
+	sbuf_delete(sb);
122
+
123
+	if (err || !req->newptr)
124
+		return (err);
125
+
126
+	if ((reqlen = req->newlen - req->newidx) > hintlen)
127
+		return (E2BIG);
128
+	new_order = malloc(reqlen + 1, M_TEMP, M_WAITOK|M_ZERO);
129
+
130
+	err = SYSCTL_IN(req, new_order, reqlen);
131
+	if (err)
132
+		goto error;
133
+	new_order[reqlen] = '\0'; /* Just in case */
134
+	parse = new_order;
135
+
136
+	TAILQ_INIT(&npfl);
137
+	PFIL_WLOCK(ph);
138
+	while ((elm = strsep(&parse, " \t,")) != NULL) {
139
+		if (*elm == '\0')
140
+			continue;
141
+		TAILQ_FOREACH_SAFE(pfh, pfl, pfil_chain, pfhtmp) {
142
+			if (pfh->pfil_name != NULL) {
143
+				if (!strcmp(pfh->pfil_name, elm)) {
144
+					TAILQ_REMOVE(pfl, pfh, pfil_chain);
145
+					TAILQ_INSERT_TAIL(&npfl, pfh, pfil_chain);
146
+					pfh->pfil_flags &= ~PFIL_DISABLED;
147
+					break;
148
+				}
149
+			} else {
150
+				if (!strcmp(elm, "NA")) {
151
+					TAILQ_REMOVE(pfl, pfh, pfil_chain);
152
+					TAILQ_INSERT_TAIL(&npfl, pfh, pfil_chain);
153
+					pfh->pfil_flags &= ~PFIL_DISABLED;
154
+					break;
155
+				}
156
+			}
157
+		}
158
+	}
159
+
160
+	TAILQ_FOREACH_SAFE(pfh, pfl, pfil_chain, pfhtmp) {
161
+		pfh->pfil_flags |= PFIL_DISABLED;
162
+		TAILQ_REMOVE(pfl, pfh, pfil_chain);
163
+		TAILQ_INSERT_TAIL(&npfl, pfh, pfil_chain);
164
+	}
165
+
166
+	TAILQ_CONCAT(pfl, &npfl, pfil_chain);
167
+
168
+error:
169
+	PFIL_WUNLOCK(ph);
170
+	free(new_order, M_TEMP);
171
+	return (err);
172
+}
173
+
174
+void
175
+pfil_head_export_sysctl(struct pfil_head *ph, struct sysctl_oid_list *parent)
176
+{
177
+	struct sysctl_oid *root;
178
+
179
+	root = SYSCTL_ADD_NODE(&ph->ph_clist, parent, OID_AUTO, "pfil",
180
+	    CTLFLAG_RW, 0, "pfil(9) management");
181
+	SYSCTL_ADD_PROC((void *)&ph->ph_clist, SYSCTL_CHILDREN(root), OID_AUTO,
182
+	    "inbound", CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_SECURE3,
183
+	    (void *)ph, PFIL_IN, pfil_sysctl_handler, "A",
184
+	    "Inbound filter hooks");
185
+	SYSCTL_ADD_PROC((void *)&ph->ph_clist, SYSCTL_CHILDREN(root), OID_AUTO,
186
+	    "outbound", CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_SECURE3,
187
+	    (void *)ph, PFIL_OUT, pfil_sysctl_handler, "A",
188
+	    "Outbound filter hooks");
189
+}
190
+
191
 /*
192
  * pfil_head_get() returns the pfil_head for a given key/dlt.
193
  */
194
@@ -238,6 +373,12 @@ pfil_head_get(int type, u_long val)
195
 int
196
 pfil_add_hook(pfil_func_t func, void *arg, int flags, struct pfil_head *ph)
197
 {
198
+	return (pfil_add_named_hook(func, arg, NULL, flags, ph));
199
+}
200
+
201
+int
202
+pfil_add_named_hook(pfil_func_t func, void *arg, char *name, int flags, struct pfil_head *ph)
203
+{
204
 	struct packet_filter_hook *pfh1 = NULL;
205
 	struct packet_filter_hook *pfh2 = NULL;
206
 	int err;
207
@@ -262,6 +403,8 @@ pfil_add_hook(pfil_func_t func, void *arg, int flags, struct pfil_head *ph)
208
 	if (flags & PFIL_IN) {
209
 		pfh1->pfil_func = func;
210
 		pfh1->pfil_arg = arg;
211
+		pfh1->pfil_name = name;
212
+		pfh1->pfil_flags &= ~PFIL_DISABLED;
213
 		err = pfil_chain_add(&ph->ph_in, pfh1, flags & ~PFIL_OUT);
214
 		if (err)
215
 			goto locked_error;
216
@@ -270,6 +413,8 @@ pfil_add_hook(pfil_func_t func, void *arg, int flags, struct pfil_head *ph)
217
 	if (flags & PFIL_OUT) {
218
 		pfh2->pfil_func = func;
219
 		pfh2->pfil_arg = arg;
220
+		pfh2->pfil_name = name;
221
+		pfh2->pfil_flags &= ~PFIL_DISABLED;
222
 		err = pfil_chain_add(&ph->ph_out, pfh2, flags & ~PFIL_IN);
223
 		if (err) {
224
 			if (flags & PFIL_IN)
225
diff --git a/sys/net/pfil.h b/sys/net/pfil.h
226
index c9a1b65..ff260ce 100644
227
--- a/sys/net/pfil.h
228
+++ b/sys/net/pfil.h
229
@@ -38,6 +38,7 @@
230
 #include <sys/_mutex.h>
231
 #include <sys/lock.h>
232
 #include <sys/rmlock.h>
233
+#include <sys/sysctl.h>
234
 
235
 struct mbuf;
236
 struct ifnet;
237
@@ -55,11 +56,14 @@ struct packet_filter_hook {
238
 	TAILQ_ENTRY(packet_filter_hook) pfil_chain;
239
 	pfil_func_t	 pfil_func;
240
 	void		*pfil_arg;
241
+	int		 pfil_flags;
242
+	char		*pfil_name;
243
 };
244
 
245
 #define PFIL_IN		0x00000001
246
 #define PFIL_OUT	0x00000002
247
 #define PFIL_WAITOK	0x00000004
248
+#define PFIL_DISABLED	0x00000008
249
 #define PFIL_ALL	(PFIL_IN|PFIL_OUT)
250
 
251
 typedef	TAILQ_HEAD(pfil_chain, packet_filter_hook) pfil_chain_t;
252
@@ -85,6 +89,7 @@ struct pfil_head {
253
 	struct rmlock	 ph_lock;	/* Private lock storage */
254
 	int		 flags;
255
 #endif
256
+	struct sysctl_ctx_list ph_clist;
257
 	union {
258
 		u_long	 phu_val;
259
 		void	*phu_ptr;
260
@@ -96,7 +101,9 @@ struct pfil_head {
261
 
262
 /* Public functions for pfil hook management by packet filters. */
263
 struct pfil_head *pfil_head_get(int, u_long);
264
+void	pfil_head_export_sysctl(struct pfil_head *, struct sysctl_oid_list *);
265
 int	pfil_add_hook(pfil_func_t, void *, int, struct pfil_head *);
266
+int	pfil_add_named_hook(pfil_func_t, void *, char *, int, struct pfil_head *);
267
 int	pfil_remove_hook(pfil_func_t, void *, int, struct pfil_head *);
268
 #define	PFIL_HOOKED(p) ((p)->ph_nhooks > 0)
269
 
270
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
271
index 49281d5..010f0e3 100644
272
--- a/sys/netinet/ip_input.c
273
+++ b/sys/netinet/ip_input.c
274
@@ -297,6 +297,9 @@ ip_init(void)
275
 	if ((i = pfil_head_register(&V_inet_pfil_hook)) != 0)
276
 		printf("%s: WARNING: unable to register pfil hook, "
277
 			"error %d\n", __func__, i);
278
+	else
279
+		pfil_head_export_sysctl(&V_inet_pfil_hook,
280
+			SYSCTL_STATIC_CHILDREN(_net_inet_ip));
281
 
282
 	/* Skip initialization of globals for non-default instances. */
283
 	if (!IS_DEFAULT_VNET(curvnet))
284
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
285
index 12249db..b43e4c7 100644
286
--- a/sys/netinet6/ip6_input.c
287
+++ b/sys/netinet6/ip6_input.c
288
@@ -136,6 +136,7 @@ static struct netisr_handler ip6_nh = {
289
 VNET_DECLARE(struct callout, in6_tmpaddrtimer_ch);
290
 #define	V_in6_tmpaddrtimer_ch		VNET(in6_tmpaddrtimer_ch)
291
 
292
+SYSCTL_DECL(_net_inet6_ip6);
293
 VNET_DEFINE(struct pfil_head, inet6_pfil_hook);
294
 
295
 VNET_PCPUSTAT_DEFINE(struct ip6stat, ip6stat);
296
@@ -182,6 +183,9 @@ ip6_init(void)
297
 	if ((i = pfil_head_register(&V_inet6_pfil_hook)) != 0)
298
 		printf("%s: WARNING: unable to register pfil hook, "
299
 			"error %d\n", __func__, i);
300
+	else
301
+		pfil_head_export_sysctl(&V_inet6_pfil_hook,
302
+			SYSCTL_STATIC_CHILDREN(_net_inet6_ip6));
303
 
304
 	scope6_init();
305
 	addrsel_policy_init();
306
diff --git a/sys/netpfil/ipfw/ip_fw_pfil.c b/sys/netpfil/ipfw/ip_fw_pfil.c
307
index 79973b1..6d29e29 100644
308
--- a/sys/netpfil/ipfw/ip_fw_pfil.c
309
+++ b/sys/netpfil/ipfw/ip_fw_pfil.c
310
@@ -499,7 +499,11 @@ ipfw_hook(int onoff, int pf)
311
 
312
 	hook_func = (pf == AF_LINK) ? ipfw_check_frame : ipfw_check_packet;
313
 
314
-	(void) (onoff ? pfil_add_hook : pfil_remove_hook)
315
+	if (onoff)
316
+	(void) pfil_add_named_hook
317
+		(hook_func, NULL, "ipfw", PFIL_IN | PFIL_OUT | PFIL_WAITOK, pfh);
318
+	else
319
+	(void) pfil_remove_hook
320
 	    (hook_func, NULL, PFIL_IN | PFIL_OUT | PFIL_WAITOK, pfh);
321
 
322
 	return 0;
323
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
324
index aa42040..1c9ef89 100644
325
--- a/sys/netpfil/pf/pf_ioctl.c
326
+++ b/sys/netpfil/pf/pf_ioctl.c
327
@@ -3605,8 +3605,8 @@ hook_pf(void)
328
 	pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
329
 	if (pfh_inet == NULL)
330
 		return (ESRCH); /* XXX */
331
-	pfil_add_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet);
332
-	pfil_add_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet);
333
+	pfil_add_named_hook(pf_check_in, NULL, "pf", PFIL_IN | PFIL_WAITOK, pfh_inet);
334
+	pfil_add_named_hook(pf_check_out, NULL, "pf", PFIL_OUT | PFIL_WAITOK, pfh_inet);
335
 #endif
336
 #ifdef INET6
337
 	pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
338
@@ -3619,8 +3619,10 @@ hook_pf(void)
339
 #endif
340
 		return (ESRCH); /* XXX */
341
 	}
342
-	pfil_add_hook(pf_check6_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet6);
343
-	pfil_add_hook(pf_check6_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet6);
344
+	pfil_add_named_hook(pf_check6_in, NULL, "pf", PFIL_IN | PFIL_WAITOK,
345
+		pfh_inet6);
346
+	pfil_add_named_hook(pf_check6_out, NULL, "pf", PFIL_OUT | PFIL_WAITOK,
347
+		pfh_inet6);
348
 #endif
349
 
350
 	V_pf_pfil_hooked = 1;
(54-54/67)