Projet

Général

Profil

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

univnautes-tools / patches / stable / 10 / pf_match.diff @ 2e75006f

1
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
2
index ce64898..bc9a8f7 100644
3
--- a/sbin/pfctl/parse.y
4
+++ b/sbin/pfctl/parse.y
5
@@ -446,7 +446,7 @@ int	parseport(char *, struct range *r, int);
6
 
7
 %}
8
 
9
-%token	PASS BLOCK SCRUB RETURN IN OS OUT LOG QUICK ON FROM TO FLAGS
10
+%token	PASS BLOCK MATCH SCRUB RETURN IN OS OUT LOG QUICK ON FROM TO FLAGS
11
 %token	RETURNRST RETURNICMP RETURNICMP6 PROTO INET INET6 ALL ANY ICMPTYPE
12
 %token	ICMP6TYPE CODE KEEP MODULATE STATE PORT RDR NAT BINAT ARROW NODF
13
 %token	MINTTL ERROR ALLOWOPTS FASTROUTE FILENAME ROUTETO DUPTO REPLYTO NO LABEL SCHEDULE
14
@@ -2565,6 +2565,7 @@ probability	: STRING				{
15
 
16
 
17
 action		: PASS			{ $$.b1 = PF_PASS; $$.b2 = $$.w = 0; }
18
+		| MATCH			{ $$.b1 = PF_MATCH; $$.b2 = $$.w = 0; }
19
 		| BLOCK blockspec	{ $$ = $2; $$.b1 = PF_DROP; }
20
 		;
21
 
22
@@ -5485,6 +5486,7 @@ lookup(char *s)
23
 		{ "load",		LOAD},
24
 		{ "log",		LOG},
25
 		{ "loginterface",	LOGINTERFACE},
26
+		{ "match",		MATCH},
27
 		{ "max",		MAXIMUM},
28
 		{ "max-mss",		MAXMSS},
29
 		{ "max-src-conn",	MAXSRCCONN},
30
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
31
index 8f23a7b..afc2b82 100644
32
--- a/sbin/pfctl/pfctl_parser.c
33
+++ b/sbin/pfctl/pfctl_parser.c
34
@@ -692,7 +692,9 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose, int numeric)
35
 
36
 	if (verbose)
37
 		printf("@%d ", r->nr);
38
-	if (r->action > PF_NORDR)
39
+	if (r->action == PF_MATCH)
40
+		printf("match");
41
+	else if (r->action > PF_NORDR)
42
 		printf("action(%d)", r->action);
43
 	else if (anchor_call[0]) {
44
 		if (anchor_call[0] == '_') {
45
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
46
index e77d02e..6061763 100644
47
--- a/sys/net/pfvar.h
48
+++ b/sys/net/pfvar.h
49
@@ -465,6 +465,13 @@ struct pf_osfp_ioctl {
50
 	int			fp_getnum;	/* DIOCOSFPGET number */
51
 };
52
 
53
+struct pf_rule_actions {
54
+	u_int16_t	qid;
55
+	u_int16_t	pqid;
56
+	u_int32_t	pdnpipe;
57
+	u_int32_t	dnpipe;
58
+	u_int8_t	flags;
59
+};
60
 
61
 union pf_rule_ptr {
62
 	struct pf_rule		*ptr;
63
@@ -521,8 +528,8 @@ struct pf_rule {
64
 		u_int32_t		limit;
65
 		u_int32_t		seconds;
66
 	}			 max_src_conn_rate;
67
-	u_int32_t		 qid;
68
-	u_int32_t		 pqid;
69
+	u_int16_t		 qid;
70
+	u_int16_t		 pqid;
71
 	u_int32_t                dnpipe;
72
         u_int32_t                pdnpipe;
73
 #define	PFRULE_DN_IS_PIPE	0x00000010
74
@@ -766,6 +773,10 @@ struct pf_state {
75
 	u_int32_t		 creation;
76
 	u_int32_t	 	 expire;
77
 	u_int32_t		 pfsync_time;
78
+	u_int16_t		 qid;
79
+	u_int16_t		 pqid;
80
+	u_int32_t		 pdnpipe;
81
+	u_int32_t		 dnpipe;
82
 	u_int16_t		 tag;
83
 	u_int8_t		 log;
84
 	u_int8_t		 state_flags;
85
@@ -1137,6 +1148,7 @@ struct pf_pdesc {
86
 	u_int16_t *sport;
87
 	u_int16_t *dport;
88
 	struct pf_mtag	*pf_mtag;
89
+	struct pf_rule_actions   act;
90
 
91
 	u_int32_t	 p_len;		/* total length of payload */
92
 
93
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
94
index 29c219e..f383822 100644
95
--- a/sys/netpfil/pf/pf.c
96
+++ b/sys/netpfil/pf/pf.c
97
@@ -229,6 +229,8 @@ static int		 pf_state_key_attach(struct pf_state_key *,
98
 static void		 pf_state_key_detach(struct pf_state *, int);
99
 static int		 pf_state_key_ctor(void *, int, void *, int);
100
 static u_int32_t	 pf_tcp_iss(struct pf_pdesc *);
101
+void			 pf_rule_to_actions(struct pf_rule *,
102
+			    struct pf_rule_actions *);
103
 static int		 pf_test_rule(struct pf_rule **, struct pf_state **,
104
 			    int, struct pfi_kif *, struct mbuf *, int,
105
 			    struct pf_pdesc *, struct pf_rule **,
106
@@ -2892,6 +2894,21 @@ pf_addr_inc(struct pf_addr *addr, sa_family_t af)
107
 }
108
 #endif /* INET6 */
109
 
110
+void
111
+pf_rule_to_actions(struct pf_rule *r, struct pf_rule_actions *a)
112
+{
113
+	if (r->qid)
114
+		a->qid = r->qid;
115
+	if (r->pqid)
116
+		a->pqid = r->pqid;
117
+	if (r->pdnpipe)
118
+		a->pdnpipe = r->pdnpipe;
119
+	if (r->dnpipe)
120
+		a->dnpipe = r->dnpipe;
121
+	if (r->free_flags & PFRULE_DN_IS_PIPE)
122
+		a->flags |= PFRULE_DN_IS_PIPE;
123
+}
124
+
125
 int
126
 pf_socket_lookup(int direction, struct pf_pdesc *pd, struct mbuf *m)
127
 {
128
@@ -3442,10 +3459,20 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
129
 			if (r->rtableid >= 0)
130
 				rtableid = r->rtableid;
131
 			if (r->anchor == NULL) {
132
-				match = 1;
133
-				*rm = r;
134
-				*am = a;
135
-				*rsm = ruleset;
136
+				if (r->action == PF_MATCH) {
137
+					r->packets[direction == PF_OUT]++;
138
+					r->bytes[direction == PF_OUT] += pd->tot_len;
139
+					pf_rule_to_actions(r, &pd->act);
140
+					if (r->log)
141
+						PFLOG_PACKET(kif, m, af,
142
+						    direction, PFRES_MATCH, r,
143
+						    a, ruleset, pd, 1);
144
+				} else {
145
+					match = 1;
146
+					*rm = r;
147
+					*am = a;
148
+					*rsm = ruleset;
149
+				}
150
 				if ((*rm)->quick)
151
 					break;
152
 				r = TAILQ_NEXT(r, entries);
153
@@ -3464,6 +3491,9 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
154
 
155
 	REASON_SET(&reason, PFRES_MATCH);
156
 
157
+	/* apply actions for last matching pass/block rule */
158
+	pf_rule_to_actions(r, &pd->act);
159
+
160
 	if (r->log || (nr != NULL && nr->log)) {
161
 		if (rewrite)
162
 			m_copyback(m, off, hdrlen, pd->hdr.any);
163
@@ -3637,6 +3667,11 @@ pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
164
 		s->state_flags |= PFSTATE_SLOPPY;
165
 	s->log = r->log & PF_LOG_ALL;
166
 	s->sync_state = PFSYNC_S_NONE;
167
+	s->qid = pd->act.qid;
168
+	s->pqid = pd->act.pqid;
169
+	s->pdnpipe = pd->act.pdnpipe;
170
+	s->dnpipe = pd->act.dnpipe;
171
+	s->state_flags |= pd->act.flags;
172
 	if (nr != NULL)
173
 		s->log |= nr->log & PF_LOG_ALL;
174
 	switch (pd->proto) {
175
@@ -3873,10 +3908,20 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
176
 			r = TAILQ_NEXT(r, entries);
177
 		else {
178
 			if (r->anchor == NULL) {
179
-				match = 1;
180
-				*rm = r;
181
-				*am = a;
182
-				*rsm = ruleset;
183
+				if (r->action == PF_MATCH) {
184
+                                        r->packets[direction == PF_OUT]++;
185
+                                        r->bytes[direction == PF_OUT] += pd->tot_len;
186
+                                        pf_rule_to_actions(r, &pd->act);
187
+                                        if (r->log)
188
+                                                PFLOG_PACKET(kif, m, af,
189
+                                                    direction, PFRES_MATCH, r,
190
+                                                    a, ruleset, pd, 1);
191
+                                } else {
192
+					match = 1;
193
+					*rm = r;
194
+					*am = a;
195
+					*rsm = ruleset;
196
+				}
197
 				if ((*rm)->quick)
198
 					break;
199
 				r = TAILQ_NEXT(r, entries);
200
@@ -3895,6 +3940,9 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
201
 
202
 	REASON_SET(&reason, PFRES_MATCH);
203
 
204
+	/* apply actions for last matching pass/block rule */
205
+        pf_rule_to_actions(r, &pd->act);
206
+
207
 	if (r->log)
208
 		PFLOG_PACKET(kif, m, af, direction, reason, r, a, ruleset, pd,
209
 		    1);
210
@@ -6158,34 +6206,46 @@ done:
211
 		M_SETFIB(m, r->rtableid);
212
 
213
 #ifdef ALTQ
214
-	if (action == PF_PASS && r->qid) {
215
-		if (pd.pf_mtag == NULL &&
216
-		    ((pd.pf_mtag = pf_get_mtag(m)) == NULL)) {
217
-			action = PF_DROP;
218
-			REASON_SET(&reason, PFRES_MEMORY);
219
-		}
220
+	if (s && s->qid) {
221
+		pd.act.pqid = s->pqid;
222
+		pd.act.qid = s->qid;
223
+	} else if (r->qid) {
224
+		pd.act.pqid = r->pqid;
225
+		pd.act.qid = r->qid;
226
+	}
227
+	if (action == PF_PASS && pd.act.qid) {
228
 		if (s)
229
 			pd.pf_mtag->qid_hash = pf_state_hash(s);
230
 		if (pqid || (pd.tos & IPTOS_LOWDELAY))
231
-			pd.pf_mtag->qid = r->pqid;
232
+			pd.pf_mtag->qid = pd.act.pqid;
233
 		else
234
-			pd.pf_mtag->qid = r->qid;
235
+			pd.pf_mtag->qid = pd.act.qid;
236
 		/* add hints for ecn */
237
 		pd.pf_mtag->hdr = h;
238
-
239
 	}
240
 #endif /* ALTQ */
241
 
242
-	if (r->dnpipe && ip_dn_io_ptr != NULL && loopedfrom != 1) {
243
-		if (dir != r->direction && r->pdnpipe) {
244
-			dnflow.rule.info = r->pdnpipe;
245
+	if (s && (s->dnpipe || s->pdnpipe)) {
246
+		pd.act.dnpipe = s->dnpipe;
247
+		pd.act.pdnpipe = s->pdnpipe;
248
+		pd.act.flags = s->state_flags;
249
+	} else if (r->dnpipe || r->pdnpipe) {
250
+		pd.act.dnpipe = r->dnpipe;
251
+		pd.act.dnpipe = r->pdnpipe;
252
+		pd.act.flags = r->free_flags;
253
+	}
254
+
255
+	if (pd.act.dnpipe && ip_dn_io_ptr != NULL && loopedfrom != 1) {
256
+		if (dir != r->direction && pd.act.pdnpipe) {
257
+			dnflow.rule.info = pd.act.pdnpipe;
258
 		} else if (dir == r->direction) {
259
-			dnflow.rule.info = r->dnpipe;
260
+			dnflow.rule.info = pd.act.dnpipe;
261
 		} else
262
 			goto continueprocessing;
263
 
264
-		if (r->free_flags & PFRULE_DN_IS_PIPE)
265
+		if (pd.act.flags & PFRULE_DN_IS_PIPE)
266
 			dnflow.rule.info |= IPFW_IS_PIPE;
267
+
268
 		dnflow.f_id.addr_type = 4; /* IPv4 type */
269
 		dnflow.f_id.proto = pd.proto;
270
 		if (dir == PF_OUT && s != NULL && s->nat_rule.ptr != NULL &&
271
@@ -6647,33 +6707,45 @@ done:
272
 		M_SETFIB(m, r->rtableid);
273
 
274
 #ifdef ALTQ
275
-	if (action == PF_PASS && r->qid) {
276
-		if (pd.pf_mtag == NULL &&
277
-		    ((pd.pf_mtag = pf_get_mtag(m)) == NULL)) {
278
-			action = PF_DROP;
279
-			REASON_SET(&reason, PFRES_MEMORY);
280
-		}
281
+	if (s && s->qid) {
282
+                pd.act.pqid = s->pqid;
283
+                pd.act.qid = s->qid;
284
+        } else if (r->qid) {
285
+                pd.act.pqid = r->pqid;
286
+                pd.act.qid = r->qid;
287
+        }
288
+	if (action == PF_PASS && pd.act.qid) {
289
 		if (s)
290
 			pd.pf_mtag->qid_hash = pf_state_hash(s);
291
 		if (pd.tos & IPTOS_LOWDELAY)
292
-			pd.pf_mtag->qid = r->pqid;
293
+			pd.pf_mtag->qid = pd.act.pqid;
294
 		else
295
-			pd.pf_mtag->qid = r->qid;
296
+			pd.pf_mtag->qid = pd.act.qid;
297
 		/* add hints for ecn */
298
 		pd.pf_mtag->hdr = h;
299
 	}
300
 #endif /* ALTQ */
301
 
302
-	if (r->dnpipe && ip_dn_io_ptr != NULL && loopedfrom != 1) {
303
-		if (dir != r->direction && r->pdnpipe) {
304
-			dnflow.rule.info = r->pdnpipe;
305
-		} else if (dir == r->direction) {
306
-			dnflow.rule.info = r->dnpipe;
307
+	if (s && (s->dnpipe || s->pdnpipe)) {
308
+                pd.act.dnpipe = s->dnpipe;
309
+                pd.act.pdnpipe = s->pdnpipe;
310
+                pd.act.flags = s->state_flags;
311
+        } else if (r->dnpipe || r->pdnpipe) {
312
+                pd.act.dnpipe = r->dnpipe;
313
+                pd.act.dnpipe = r->pdnpipe;
314
+                pd.act.flags = r->free_flags;
315
+        }
316
+	if ((pd.act.dnpipe || pd.act.pdnpipe) && ip_dn_io_ptr != NULL && loopedfrom != 1) {
317
+		if (dir != r->direction && pd.act.pdnpipe) {
318
+			dnflow.rule.info = pd.act.pdnpipe;
319
+		} else if (dir == r->direction && pd.act.dnpipe) {
320
+			dnflow.rule.info = pd.act.dnpipe;
321
 		} else
322
 			goto continueprocessing6;
323
 
324
-		if (r->free_flags & PFRULE_DN_IS_PIPE)
325
+		if (pd.act.flags & PFRULE_DN_IS_PIPE)
326
 			dnflow.rule.info |= IPFW_IS_PIPE;
327
+
328
 		dnflow.f_id.addr_type = 6; /* IPv4 type */
329
 		dnflow.f_id.proto = pd.proto;
330
 		dnflow.f_id.src_ip = 0;
331
diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h
332
index 7d692d4..f25adde 100644
333
--- a/sys/netpfil/pf/pf.h
334
+++ b/sys/netpfil/pf/pf.h
335
@@ -45,7 +45,8 @@
336
 
337
 enum	{ PF_INOUT, PF_IN, PF_OUT };
338
 enum	{ PF_PASS, PF_DROP, PF_SCRUB, PF_NOSCRUB, PF_NAT, PF_NONAT,
339
-	  PF_BINAT, PF_NOBINAT, PF_RDR, PF_NORDR, PF_SYNPROXY_DROP, PF_DEFER };
340
+	  PF_BINAT, PF_NOBINAT, PF_RDR, PF_NORDR, PF_SYNPROXY_DROP, PF_DEFER,
341
+	  PF_MATCH };
342
 enum	{ PF_RULESET_SCRUB, PF_RULESET_FILTER, PF_RULESET_NAT,
343
 	  PF_RULESET_BINAT, PF_RULESET_RDR, PF_RULESET_MAX };
344
 enum	{ PF_OP_NONE, PF_OP_IRG, PF_OP_EQ, PF_OP_NE, PF_OP_LT,
345
diff --git a/sys/netpfil/pf/pf_ruleset.c b/sys/netpfil/pf/pf_ruleset.c
346
index 384e42b..2274359 100644
347
--- a/sys/netpfil/pf/pf_ruleset.c
348
+++ b/sys/netpfil/pf/pf_ruleset.c
349
@@ -120,6 +120,7 @@ pf_get_ruleset_number(u_int8_t action)
350
 		return (PF_RULESET_SCRUB);
351
 		break;
352
 	case PF_PASS:
353
+	case PF_MATCH:
354
 	case PF_DROP:
355
 		return (PF_RULESET_FILTER);
356
 		break;
(43-43/64)