libc: nmalloc - Add a per-thread magazine layer and a malloc slab magazine.
[dragonfly.git] / sys / net / pf / pf.c
CommitLineData
02742ec6
JS
1/* $FreeBSD: src/sys/contrib/pf/net/pf.c,v 1.19 2004/09/11 11:18:25 mlaier Exp $ */
2/* $OpenBSD: pf.c,v 1.433.2.2 2004/07/17 03:22:34 brad Exp $ */
3/* add $OpenBSD: pf.c,v 1.448 2004/05/11 07:34:11 dhartmei Exp $ */
3641b7ca 4/* $DragonFly: src/sys/net/pf/pf.c,v 1.20 2008/06/05 18:06:32 swildner Exp $ */
70224baa 5/* $OpenBSD: pf.c,v 1.527 2007/02/22 15:23:23 pyr Exp $ */
02742ec6
JS
6
7/*
8 * Copyright (c) 2004 The DragonFly Project. All rights reserved.
9 *
10 * Copyright (c) 2001 Daniel Hartmeier
11 * Copyright (c) 2002,2003 Henning Brauer
12 * All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * - Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials provided
23 * with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 *
38 * Effort sponsored in part by the Defense Advanced Research Projects
39 * Agency (DARPA) and Air Force Research Laboratory, Air Force
40 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
41 *
42 */
43
44#include "opt_inet.h"
45#include "opt_inet6.h"
46#include "use_pfsync.h"
47
48#include <sys/param.h>
49#include <sys/systm.h>
50#include <sys/malloc.h>
51#include <sys/mbuf.h>
52#include <sys/filio.h>
53#include <sys/socket.h>
54#include <sys/socketvar.h>
55#include <sys/kernel.h>
56#include <sys/time.h>
57#include <sys/sysctl.h>
58#include <sys/endian.h>
59#include <vm/vm_zone.h>
70224baa
JL
60#include <sys/proc.h>
61#include <sys/kthread.h>
02742ec6 62
cd8ab232
MD
63#include <sys/mplock2.h>
64
02742ec6
JS
65#include <machine/inttypes.h>
66
67#include <net/if.h>
68#include <net/if_types.h>
69#include <net/bpf.h>
4599cf19 70#include <net/netisr.h>
02742ec6
JS
71#include <net/route.h>
72
73#include <netinet/in.h>
74#include <netinet/in_var.h>
75#include <netinet/in_systm.h>
76#include <netinet/ip.h>
77#include <netinet/ip_var.h>
78#include <netinet/tcp.h>
79#include <netinet/tcp_seq.h>
80#include <netinet/udp.h>
81#include <netinet/ip_icmp.h>
82#include <netinet/in_pcb.h>
83#include <netinet/tcp_timer.h>
84#include <netinet/tcp_var.h>
85#include <netinet/udp_var.h>
86#include <netinet/icmp_var.h>
70224baa 87#include <netinet/if_ether.h>
02742ec6
JS
88
89#include <net/pf/pfvar.h>
90#include <net/pf/if_pflog.h>
91
92#if NPFSYNC > 0
93#include <net/pf/if_pfsync.h>
94#endif /* NPFSYNC > 0 */
95
96#ifdef INET6
97#include <netinet/ip6.h>
98#include <netinet/in_pcb.h>
99#include <netinet/icmp6.h>
100#include <netinet6/nd6.h>
101#include <netinet6/ip6_var.h>
102#include <netinet6/in6_pcb.h>
103#endif /* INET6 */
104
105#include <sys/in_cksum.h>
4599cf19 106#include <sys/ucred.h>
02742ec6
JS
107#include <machine/limits.h>
108#include <sys/msgport2.h>
4599cf19 109#include <net/netmsg2.h>
02742ec6
JS
110
111extern int ip_optcopy(struct ip *, struct ip *);
70224baa 112extern int debug_pfugidhack;
02742ec6 113
4b1cf444 114#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) kprintf x
02742ec6
JS
115
116/*
117 * Global variables
118 */
119
02742ec6
JS
120struct pf_altqqueue pf_altqs[2];
121struct pf_palist pf_pabuf;
122struct pf_altqqueue *pf_altqs_active;
123struct pf_altqqueue *pf_altqs_inactive;
124struct pf_status pf_status;
125
126u_int32_t ticket_altqs_active;
127u_int32_t ticket_altqs_inactive;
128int altqs_inactive_open;
129u_int32_t ticket_pabuf;
130
70224baa
JL
131struct pf_anchor_stackframe {
132 struct pf_ruleset *rs;
133 struct pf_rule *r;
134 struct pf_anchor_node *parent;
135 struct pf_anchor *child;
136} pf_anchor_stack[64];
02742ec6
JS
137
138vm_zone_t pf_src_tree_pl, pf_rule_pl;
139vm_zone_t pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
140
141void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t);
02742ec6 142
70224baa
JL
143void pf_init_threshold(struct pf_threshold *, u_int32_t,
144 u_int32_t);
145void pf_add_threshold(struct pf_threshold *);
146int pf_check_threshold(struct pf_threshold *);
147
02742ec6
JS
148void pf_change_ap(struct pf_addr *, u_int16_t *,
149 u_int16_t *, u_int16_t *, struct pf_addr *,
150 u_int16_t, u_int8_t, sa_family_t);
70224baa
JL
151int pf_modulate_sack(struct mbuf *, int, struct pf_pdesc *,
152 struct tcphdr *, struct pf_state_peer *);
02742ec6
JS
153#ifdef INET6
154void pf_change_a6(struct pf_addr *, u_int16_t *,
155 struct pf_addr *, u_int8_t);
156#endif /* INET6 */
157void pf_change_icmp(struct pf_addr *, u_int16_t *,
158 struct pf_addr *, struct pf_addr *, u_int16_t,
159 u_int16_t *, u_int16_t *, u_int16_t *,
160 u_int16_t *, u_int8_t, sa_family_t);
161void pf_send_tcp(const struct pf_rule *, sa_family_t,
162 const struct pf_addr *, const struct pf_addr *,
163 u_int16_t, u_int16_t, u_int32_t, u_int32_t,
70224baa
JL
164 u_int8_t, u_int16_t, u_int16_t, u_int8_t, int,
165 u_int16_t, struct ether_header *, struct ifnet *);
02742ec6
JS
166void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t,
167 sa_family_t, struct pf_rule *);
168struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
169 int, int, struct pfi_kif *,
170 struct pf_addr *, u_int16_t, struct pf_addr *,
171 u_int16_t, int);
172struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *,
173 int, int, struct pfi_kif *, struct pf_src_node **,
174 struct pf_addr *, u_int16_t,
175 struct pf_addr *, u_int16_t,
176 struct pf_addr *, u_int16_t *);
177int pf_test_tcp(struct pf_rule **, struct pf_state **,
178 int, struct pfi_kif *, struct mbuf *, int,
179 void *, struct pf_pdesc *, struct pf_rule **,
70224baa 180 struct pf_ruleset **, struct ifqueue *, struct inpcb *);
02742ec6
JS
181int pf_test_udp(struct pf_rule **, struct pf_state **,
182 int, struct pfi_kif *, struct mbuf *, int,
183 void *, struct pf_pdesc *, struct pf_rule **,
70224baa 184 struct pf_ruleset **, struct ifqueue *, struct inpcb *);
02742ec6
JS
185int pf_test_icmp(struct pf_rule **, struct pf_state **,
186 int, struct pfi_kif *, struct mbuf *, int,
187 void *, struct pf_pdesc *, struct pf_rule **,
70224baa 188 struct pf_ruleset **, struct ifqueue *);
02742ec6
JS
189int pf_test_other(struct pf_rule **, struct pf_state **,
190 int, struct pfi_kif *, struct mbuf *, int, void *,
191 struct pf_pdesc *, struct pf_rule **,
70224baa 192 struct pf_ruleset **, struct ifqueue *);
02742ec6
JS
193int pf_test_fragment(struct pf_rule **, int,
194 struct pfi_kif *, struct mbuf *, void *,
195 struct pf_pdesc *, struct pf_rule **,
196 struct pf_ruleset **);
197int pf_test_state_tcp(struct pf_state **, int,
198 struct pfi_kif *, struct mbuf *, int,
199 void *, struct pf_pdesc *, u_short *);
200int pf_test_state_udp(struct pf_state **, int,
201 struct pfi_kif *, struct mbuf *, int,
202 void *, struct pf_pdesc *);
203int pf_test_state_icmp(struct pf_state **, int,
204 struct pfi_kif *, struct mbuf *, int,
70224baa 205 void *, struct pf_pdesc *, u_short *);
02742ec6
JS
206int pf_test_state_other(struct pf_state **, int,
207 struct pfi_kif *, struct pf_pdesc *);
70224baa
JL
208int pf_match_tag(struct mbuf *, struct pf_rule *,
209 struct pf_mtag *, int *);
210int pf_step_out_of_anchor(int *, struct pf_ruleset **,
211 int, struct pf_rule **, struct pf_rule **,
212 int *);
02742ec6
JS
213void pf_hash(struct pf_addr *, struct pf_addr *,
214 struct pf_poolhashkey *, sa_family_t);
215int pf_map_addr(u_int8_t, struct pf_rule *,
216 struct pf_addr *, struct pf_addr *,
217 struct pf_addr *, struct pf_src_node **);
218int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *,
219 struct pf_addr *, struct pf_addr *, u_int16_t,
220 struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t,
221 struct pf_src_node **);
222void pf_route(struct mbuf **, struct pf_rule *, int,
70224baa
JL
223 struct ifnet *, struct pf_state *,
224 struct pf_pdesc *);
02742ec6 225void pf_route6(struct mbuf **, struct pf_rule *, int,
70224baa
JL
226 struct ifnet *, struct pf_state *,
227 struct pf_pdesc *);
02742ec6
JS
228u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t,
229 sa_family_t);
230u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t,
231 sa_family_t);
232u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t,
233 u_int16_t);
234void pf_set_rt_ifp(struct pf_state *,
235 struct pf_addr *);
236int pf_check_proto_cksum(struct mbuf *, int, int,
237 u_int8_t, sa_family_t);
238int pf_addr_wrap_neq(struct pf_addr_wrap *,
239 struct pf_addr_wrap *);
240struct pf_state *pf_find_state_recurse(struct pfi_kif *,
70224baa
JL
241 struct pf_state_cmp *, u_int8_t);
242int pf_src_connlimit(struct pf_state **);
243int pf_check_congestion(struct ifqueue *);
244
245extern int pf_end_threads;
246
247struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
248 { &pf_state_pl, PFSTATE_HIWAT },
249 { &pf_src_tree_pl, PFSNODE_HIWAT },
250 { &pf_frent_pl, PFFRAG_FRENT_HIWAT },
251 { &pfr_ktable_pl, PFR_KTABLE_HIWAT },
252 { &pfr_kentry_pl, PFR_KENTRY_HIWAT }
253};
02742ec6
JS
254
255#define STATE_LOOKUP() \
256 do { \
257 if (direction == PF_IN) \
70224baa 258 *state = pf_find_state_recurse( \
02742ec6
JS
259 kif, &key, PF_EXT_GWY); \
260 else \
261 *state = pf_find_state_recurse( \
262 kif, &key, PF_LAN_EXT); \
70224baa 263 if (*state == NULL || (*state)->timeout == PFTM_PURGE) \
02742ec6
JS
264 return (PF_DROP); \
265 if (direction == PF_OUT && \
266 (((*state)->rule.ptr->rt == PF_ROUTETO && \
267 (*state)->rule.ptr->direction == PF_OUT) || \
268 ((*state)->rule.ptr->rt == PF_REPLYTO && \
269 (*state)->rule.ptr->direction == PF_IN)) && \
270 (*state)->rt_kif != NULL && \
271 (*state)->rt_kif != kif) \
272 return (PF_PASS); \
273 } while (0)
274
275#define STATE_TRANSLATE(s) \
276 (s)->lan.addr.addr32[0] != (s)->gwy.addr.addr32[0] || \
277 ((s)->af == AF_INET6 && \
278 ((s)->lan.addr.addr32[1] != (s)->gwy.addr.addr32[1] || \
279 (s)->lan.addr.addr32[2] != (s)->gwy.addr.addr32[2] || \
280 (s)->lan.addr.addr32[3] != (s)->gwy.addr.addr32[3])) || \
281 (s)->lan.port != (s)->gwy.port
282
70224baa
JL
283#define BOUND_IFACE(r, k) \
284 ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all
285
286#define STATE_INC_COUNTERS(s) \
287 do { \
288 s->rule.ptr->states++; \
289 if (s->anchor.ptr != NULL) \
290 s->anchor.ptr->states++; \
291 if (s->nat_rule.ptr != NULL) \
292 s->nat_rule.ptr->states++; \
293 } while (0)
294
295#define STATE_DEC_COUNTERS(s) \
296 do { \
297 if (s->nat_rule.ptr != NULL) \
298 s->nat_rule.ptr->states--; \
299 if (s->anchor.ptr != NULL) \
300 s->anchor.ptr->states--; \
301 s->rule.ptr->states--; \
302 } while (0)
02742ec6 303
70224baa
JL
304static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
305static __inline int pf_state_compare_lan_ext(struct pf_state *,
02742ec6 306 struct pf_state *);
70224baa 307static __inline int pf_state_compare_ext_gwy(struct pf_state *,
02742ec6 308 struct pf_state *);
70224baa 309static __inline int pf_state_compare_id(struct pf_state *,
02742ec6
JS
310 struct pf_state *);
311
312struct pf_src_tree tree_src_tracking;
313
314struct pf_state_tree_id tree_id;
70224baa 315struct pf_state_queue state_list;
02742ec6
JS
316
317RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare);
318RB_GENERATE(pf_state_tree_lan_ext, pf_state,
319 u.s.entry_lan_ext, pf_state_compare_lan_ext);
320RB_GENERATE(pf_state_tree_ext_gwy, pf_state,
321 u.s.entry_ext_gwy, pf_state_compare_ext_gwy);
322RB_GENERATE(pf_state_tree_id, pf_state,
323 u.s.entry_id, pf_state_compare_id);
324
70224baa 325static __inline int
02742ec6
JS
326pf_src_compare(struct pf_src_node *a, struct pf_src_node *b)
327{
328 int diff;
329
330 if (a->rule.ptr > b->rule.ptr)
331 return (1);
332 if (a->rule.ptr < b->rule.ptr)
333 return (-1);
334 if ((diff = a->af - b->af) != 0)
335 return (diff);
336 switch (a->af) {
337#ifdef INET
338 case AF_INET:
339 if (a->addr.addr32[0] > b->addr.addr32[0])
340 return (1);
341 if (a->addr.addr32[0] < b->addr.addr32[0])
342 return (-1);
343 break;
344#endif /* INET */
345#ifdef INET6
346 case AF_INET6:
347 if (a->addr.addr32[3] > b->addr.addr32[3])
348 return (1);
349 if (a->addr.addr32[3] < b->addr.addr32[3])
350 return (-1);
351 if (a->addr.addr32[2] > b->addr.addr32[2])
352 return (1);
353 if (a->addr.addr32[2] < b->addr.addr32[2])
354 return (-1);
355 if (a->addr.addr32[1] > b->addr.addr32[1])
356 return (1);
357 if (a->addr.addr32[1] < b->addr.addr32[1])
358 return (-1);
359 if (a->addr.addr32[0] > b->addr.addr32[0])
360 return (1);
361 if (a->addr.addr32[0] < b->addr.addr32[0])
362 return (-1);
363 break;
364#endif /* INET6 */
365 }
366 return (0);
367}
368
a814431a 369u_int32_t
5950bf01
MD
370pf_state_hash(struct pf_state *s)
371{
a814431a 372 u_int32_t hv = (intptr_t)s / sizeof(*s);
5950bf01
MD
373
374 hv ^= crc32(&s->lan, sizeof(s->lan));
375 hv ^= crc32(&s->gwy, sizeof(s->gwy));
376 hv ^= crc32(&s->ext, sizeof(s->ext));
a814431a
MD
377 if (hv == 0) /* disallow 0 */
378 hv = 1;
5950bf01
MD
379 return(hv);
380}
381
70224baa 382static __inline int
02742ec6
JS
383pf_state_compare_lan_ext(struct pf_state *a, struct pf_state *b)
384{
385 int diff;
386
387 if ((diff = a->proto - b->proto) != 0)
388 return (diff);
389 if ((diff = a->af - b->af) != 0)
390 return (diff);
391 switch (a->af) {
392#ifdef INET
393 case AF_INET:
394 if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0])
395 return (1);
396 if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0])
397 return (-1);
398 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
399 return (1);
400 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
401 return (-1);
402 break;
403#endif /* INET */
404#ifdef INET6
405 case AF_INET6:
406 if (a->lan.addr.addr32[3] > b->lan.addr.addr32[3])
407 return (1);
408 if (a->lan.addr.addr32[3] < b->lan.addr.addr32[3])
409 return (-1);
410 if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3])
411 return (1);
412 if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3])
413 return (-1);
414 if (a->lan.addr.addr32[2] > b->lan.addr.addr32[2])
415 return (1);
416 if (a->lan.addr.addr32[2] < b->lan.addr.addr32[2])
417 return (-1);
418 if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2])
419 return (1);
420 if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2])
421 return (-1);
422 if (a->lan.addr.addr32[1] > b->lan.addr.addr32[1])
423 return (1);
424 if (a->lan.addr.addr32[1] < b->lan.addr.addr32[1])
425 return (-1);
426 if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1])
427 return (1);
428 if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1])
429 return (-1);
430 if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0])
431 return (1);
432 if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0])
433 return (-1);
434 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
435 return (1);
436 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
437 return (-1);
438 break;
439#endif /* INET6 */
440 }
441
442 if ((diff = a->lan.port - b->lan.port) != 0)
443 return (diff);
444 if ((diff = a->ext.port - b->ext.port) != 0)
445 return (diff);
446
447 return (0);
448}
449
70224baa 450static __inline int
02742ec6
JS
451pf_state_compare_ext_gwy(struct pf_state *a, struct pf_state *b)
452{
453 int diff;
454
455 if ((diff = a->proto - b->proto) != 0)
456 return (diff);
457 if ((diff = a->af - b->af) != 0)
458 return (diff);
459 switch (a->af) {
460#ifdef INET
461 case AF_INET:
462 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
463 return (1);
464 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
465 return (-1);
466 if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0])
467 return (1);
468 if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0])
469 return (-1);
470 break;
471#endif /* INET */
472#ifdef INET6
473 case AF_INET6:
474 if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3])
475 return (1);
476 if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3])
477 return (-1);
478 if (a->gwy.addr.addr32[3] > b->gwy.addr.addr32[3])
479 return (1);
480 if (a->gwy.addr.addr32[3] < b->gwy.addr.addr32[3])
481 return (-1);
482 if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2])
483 return (1);
484 if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2])
485 return (-1);
486 if (a->gwy.addr.addr32[2] > b->gwy.addr.addr32[2])
487 return (1);
488 if (a->gwy.addr.addr32[2] < b->gwy.addr.addr32[2])
489 return (-1);
490 if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1])
491 return (1);
492 if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1])
493 return (-1);
494 if (a->gwy.addr.addr32[1] > b->gwy.addr.addr32[1])
495 return (1);
496 if (a->gwy.addr.addr32[1] < b->gwy.addr.addr32[1])
497 return (-1);
498 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
499 return (1);
500 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
501 return (-1);
502 if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0])
503 return (1);
504 if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0])
505 return (-1);
506 break;
507#endif /* INET6 */
508 }
509
510 if ((diff = a->ext.port - b->ext.port) != 0)
511 return (diff);
512 if ((diff = a->gwy.port - b->gwy.port) != 0)
513 return (diff);
514
515 return (0);
516}
517
70224baa 518static __inline int
02742ec6
JS
519pf_state_compare_id(struct pf_state *a, struct pf_state *b)
520{
521 if (a->id > b->id)
522 return (1);
523 if (a->id < b->id)
524 return (-1);
525 if (a->creatorid > b->creatorid)
526 return (1);
527 if (a->creatorid < b->creatorid)
528 return (-1);
529
530 return (0);
531}
532
533#ifdef INET6
534void
535pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af)
536{
537 switch (af) {
538#ifdef INET
539 case AF_INET:
540 dst->addr32[0] = src->addr32[0];
541 break;
542#endif /* INET */
543 case AF_INET6:
544 dst->addr32[0] = src->addr32[0];
545 dst->addr32[1] = src->addr32[1];
546 dst->addr32[2] = src->addr32[2];
547 dst->addr32[3] = src->addr32[3];
548 break;
549 }
550}
70224baa 551#endif /* INET6 */
02742ec6
JS
552
553struct pf_state *
70224baa 554pf_find_state_byid(struct pf_state_cmp *key)
02742ec6
JS
555{
556 pf_status.fcounters[FCNT_STATE_SEARCH]++;
70224baa 557 return (RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state *)key));
02742ec6
JS
558}
559
560struct pf_state *
70224baa 561pf_find_state_recurse(struct pfi_kif *kif, struct pf_state_cmp *key, u_int8_t tree)
02742ec6
JS
562{
563 struct pf_state *s;
564
565 pf_status.fcounters[FCNT_STATE_SEARCH]++;
566
567 switch (tree) {
568 case PF_LAN_EXT:
70224baa
JL
569 if ((s = RB_FIND(pf_state_tree_lan_ext, &kif->pfik_lan_ext,
570 (struct pf_state *)key)) != NULL)
571 return (s);
572 if ((s = RB_FIND(pf_state_tree_lan_ext, &pfi_all->pfik_lan_ext,
573 (struct pf_state *)key)) != NULL)
574 return (s);
02742ec6
JS
575 return (NULL);
576 case PF_EXT_GWY:
70224baa
JL
577 if ((s = RB_FIND(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy,
578 (struct pf_state *)key)) != NULL)
579 return (s);
580 if ((s = RB_FIND(pf_state_tree_ext_gwy, &pfi_all->pfik_ext_gwy,
581 (struct pf_state *)key)) != NULL)
582 return (s);
02742ec6
JS
583 return (NULL);
584 default:
585 panic("pf_find_state_recurse");
586 }
587}
588
589struct pf_state *
70224baa 590pf_find_state_all(struct pf_state_cmp *key, u_int8_t tree, int *more)
02742ec6
JS
591{
592 struct pf_state *s, *ss = NULL;
593 struct pfi_kif *kif;
594
595 pf_status.fcounters[FCNT_STATE_SEARCH]++;
596
597 switch (tree) {
598 case PF_LAN_EXT:
599 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) {
600 s = RB_FIND(pf_state_tree_lan_ext,
70224baa 601 &kif->pfik_lan_ext, (struct pf_state *)key);
02742ec6
JS
602 if (s == NULL)
603 continue;
604 if (more == NULL)
605 return (s);
606 ss = s;
607 (*more)++;
608 }
609 return (ss);
610 case PF_EXT_GWY:
611 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) {
612 s = RB_FIND(pf_state_tree_ext_gwy,
70224baa 613 &kif->pfik_ext_gwy, (struct pf_state *)key);
02742ec6
JS
614 if (s == NULL)
615 continue;
616 if (more == NULL)
617 return (s);
618 ss = s;
619 (*more)++;
620 }
621 return (ss);
622 default:
623 panic("pf_find_state_all");
624 }
625}
626
70224baa
JL
627void
628pf_init_threshold(struct pf_threshold *threshold,
629 u_int32_t limit, u_int32_t seconds)
630{
631 threshold->limit = limit * PF_THRESHOLD_MULT;
632 threshold->seconds = seconds;
633 threshold->count = 0;
634 threshold->last = time_second;
635}
636
637void
638pf_add_threshold(struct pf_threshold *threshold)
639{
640 u_int32_t t = time_second, diff = t - threshold->last;
641
642 if (diff >= threshold->seconds)
643 threshold->count = 0;
644 else
645 threshold->count -= threshold->count * diff /
646 threshold->seconds;
647 threshold->count += PF_THRESHOLD_MULT;
648 threshold->last = t;
649}
650
651int
652pf_check_threshold(struct pf_threshold *threshold)
653{
654 return (threshold->count > threshold->limit);
655}
656
657int
658pf_src_connlimit(struct pf_state **state)
659{
660 struct pf_state *s;
661 int bad = 0;
662
663 (*state)->src_node->conn++;
664 (*state)->src.tcp_est = 1;
665 pf_add_threshold(&(*state)->src_node->conn_rate);
666
667 if ((*state)->rule.ptr->max_src_conn &&
668 (*state)->rule.ptr->max_src_conn <
669 (*state)->src_node->conn) {
670 pf_status.lcounters[LCNT_SRCCONN]++;
671 bad++;
672 }
673
674 if ((*state)->rule.ptr->max_src_conn_rate.limit &&
675 pf_check_threshold(&(*state)->src_node->conn_rate)) {
676 pf_status.lcounters[LCNT_SRCCONNRATE]++;
677 bad++;
678 }
679
680 if (!bad)
681 return (0);
682
683 if ((*state)->rule.ptr->overload_tbl) {
684 struct pfr_addr p;
685 u_int32_t killed = 0;
686
687 pf_status.lcounters[LCNT_OVERLOAD_TABLE]++;
688 if (pf_status.debug >= PF_DEBUG_MISC) {
689 kprintf("pf_src_connlimit: blocking address ");
690 pf_print_host(&(*state)->src_node->addr, 0,
691 (*state)->af);
692 }
693
694 bzero(&p, sizeof(p));
695 p.pfra_af = (*state)->af;
696 switch ((*state)->af) {
697#ifdef INET
698 case AF_INET:
699 p.pfra_net = 32;
700 p.pfra_ip4addr = (*state)->src_node->addr.v4;
701 break;
702#endif /* INET */
703#ifdef INET6
704 case AF_INET6:
705 p.pfra_net = 128;
706 p.pfra_ip6addr = (*state)->src_node->addr.v6;
707 break;
708#endif /* INET6 */
709 }
710
711 pfr_insert_kentry((*state)->rule.ptr->overload_tbl,
712 &p, time_second);
713
714 /* kill existing states if that's required. */
715 if ((*state)->rule.ptr->flush) {
716 pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
717
718 RB_FOREACH(s, pf_state_tree_id, &tree_id) {
719 /*
720 * Kill states from this source. (Only those
721 * from the same rule if PF_FLUSH_GLOBAL is not
722 * set)
723 */
724 if (s->af == (*state)->af &&
725 (((*state)->direction == PF_OUT &&
726 PF_AEQ(&(*state)->src_node->addr,
727 &s->lan.addr, s->af)) ||
728 ((*state)->direction == PF_IN &&
729 PF_AEQ(&(*state)->src_node->addr,
730 &s->ext.addr, s->af))) &&
731 ((*state)->rule.ptr->flush &
732 PF_FLUSH_GLOBAL ||
733 (*state)->rule.ptr == s->rule.ptr)) {
734 s->timeout = PFTM_PURGE;
735 s->src.state = s->dst.state =
736 TCPS_CLOSED;
737 killed++;
738 }
739 }
740 if (pf_status.debug >= PF_DEBUG_MISC)
741 kprintf(", %u states killed", killed);
742 }
743 if (pf_status.debug >= PF_DEBUG_MISC)
744 kprintf("\n");
745 }
746
747 /* kill this state */
748 (*state)->timeout = PFTM_PURGE;
749 (*state)->src.state = (*state)->dst.state = TCPS_CLOSED;
750 return (1);
751}
752
02742ec6
JS
753int
754pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
755 struct pf_addr *src, sa_family_t af)
756{
757 struct pf_src_node k;
758
759 if (*sn == NULL) {
760 k.af = af;
761 PF_ACPY(&k.addr, src, af);
762 if (rule->rule_flag & PFRULE_RULESRCTRACK ||
763 rule->rpool.opts & PF_POOL_STICKYADDR)
764 k.rule.ptr = rule;
765 else
766 k.rule.ptr = NULL;
767 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
768 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
769 }
770 if (*sn == NULL) {
771 if (!rule->max_src_nodes ||
772 rule->src_nodes < rule->max_src_nodes)
773 (*sn) = pool_get(&pf_src_tree_pl, PR_NOWAIT);
70224baa
JL
774 else
775 pf_status.lcounters[LCNT_SRCNODES]++;
02742ec6
JS
776 if ((*sn) == NULL)
777 return (-1);
778 bzero(*sn, sizeof(struct pf_src_node));
70224baa
JL
779
780 pf_init_threshold(&(*sn)->conn_rate,
781 rule->max_src_conn_rate.limit,
782 rule->max_src_conn_rate.seconds);
783
02742ec6
JS
784 (*sn)->af = af;
785 if (rule->rule_flag & PFRULE_RULESRCTRACK ||
786 rule->rpool.opts & PF_POOL_STICKYADDR)
787 (*sn)->rule.ptr = rule;
788 else
789 (*sn)->rule.ptr = NULL;
790 PF_ACPY(&(*sn)->addr, src, af);
791 if (RB_INSERT(pf_src_tree,
792 &tree_src_tracking, *sn) != NULL) {
793 if (pf_status.debug >= PF_DEBUG_MISC) {
4b1cf444 794 kprintf("pf: src_tree insert failed: ");
02742ec6 795 pf_print_host(&(*sn)->addr, 0, af);
4b1cf444 796 kprintf("\n");
02742ec6
JS
797 }
798 pool_put(&pf_src_tree_pl, *sn);
799 return (-1);
800 }
801 (*sn)->creation = time_second;
802 (*sn)->ruletype = rule->action;
803 if ((*sn)->rule.ptr != NULL)
804 (*sn)->rule.ptr->src_nodes++;
805 pf_status.scounters[SCNT_SRC_NODE_INSERT]++;
806 pf_status.src_nodes++;
807 } else {
808 if (rule->max_src_states &&
70224baa
JL
809 (*sn)->states >= rule->max_src_states) {
810 pf_status.lcounters[LCNT_SRCSTATES]++;
02742ec6 811 return (-1);
70224baa 812 }
02742ec6
JS
813 }
814 return (0);
815}
816
817int
818pf_insert_state(struct pfi_kif *kif, struct pf_state *state)
819{
820 /* Thou MUST NOT insert multiple duplicate keys */
821 state->u.s.kif = kif;
822 if (RB_INSERT(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state)) {
823 if (pf_status.debug >= PF_DEBUG_MISC) {
4b1cf444
SW
824 kprintf("pf: state insert failed: tree_lan_ext");
825 kprintf(" lan: ");
02742ec6
JS
826 pf_print_host(&state->lan.addr, state->lan.port,
827 state->af);
4b1cf444 828 kprintf(" gwy: ");
02742ec6
JS
829 pf_print_host(&state->gwy.addr, state->gwy.port,
830 state->af);
4b1cf444 831 kprintf(" ext: ");
02742ec6
JS
832 pf_print_host(&state->ext.addr, state->ext.port,
833 state->af);
834 if (state->sync_flags & PFSTATE_FROMSYNC)
4b1cf444
SW
835 kprintf(" (from sync)");
836 kprintf("\n");
02742ec6
JS
837 }
838 return (-1);
839 }
840
841 if (RB_INSERT(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state)) {
842 if (pf_status.debug >= PF_DEBUG_MISC) {
4b1cf444
SW
843 kprintf("pf: state insert failed: tree_ext_gwy");
844 kprintf(" lan: ");
02742ec6
JS
845 pf_print_host(&state->lan.addr, state->lan.port,
846 state->af);
4b1cf444 847 kprintf(" gwy: ");
02742ec6
JS
848 pf_print_host(&state->gwy.addr, state->gwy.port,
849 state->af);
4b1cf444 850 kprintf(" ext: ");
02742ec6
JS
851 pf_print_host(&state->ext.addr, state->ext.port,
852 state->af);
853 if (state->sync_flags & PFSTATE_FROMSYNC)
4b1cf444
SW
854 kprintf(" (from sync)");
855 kprintf("\n");
02742ec6
JS
856 }
857 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state);
858 return (-1);
859 }
860
861 if (state->id == 0 && state->creatorid == 0) {
862 state->id = htobe64(pf_status.stateid++);
863 state->creatorid = pf_status.hostid;
864 }
865 if (RB_INSERT(pf_state_tree_id, &tree_id, state) != NULL) {
866 if (pf_status.debug >= PF_DEBUG_MISC) {
4b1cf444 867 kprintf("pf: state insert failed: "
02742ec6
JS
868 "id: %016" PRIx64 " creatorid: %08" PRIx32,
869 be64toh(state->id), ntohl(state->creatorid));
870 if (state->sync_flags & PFSTATE_FROMSYNC)
4b1cf444
SW
871 kprintf(" (from sync)");
872 kprintf("\n");
02742ec6
JS
873 }
874 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state);
875 RB_REMOVE(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state);
876 return (-1);
877 }
70224baa 878 TAILQ_INSERT_TAIL(&state_list, state, u.s.entry_list);
02742ec6
JS
879 pf_status.fcounters[FCNT_STATE_INSERT]++;
880 pf_status.states++;
70224baa 881 pfi_kif_ref(kif, PFI_KIF_REF_STATE);
02742ec6
JS
882#if NPFSYNC
883 pfsync_insert_state(state);
884#endif
885 return (0);
886}
887
888void
70224baa 889pf_purge_thread(void *v)
02742ec6 890{
70224baa
JL
891 int nloops = 0;
892 int locked = 0;
893
cd8ab232 894 get_mplock();
70224baa
JL
895 for (;;) {
896 tsleep(pf_purge_thread, PWAIT, "pftm", 1 * hz);
897
898 lockmgr(&pf_consistency_lock, LK_EXCLUSIVE);
899
900 if (pf_end_threads) {
901 pf_purge_expired_states(pf_status.states, 1);
902 pf_purge_expired_fragments();
903 pf_purge_expired_src_nodes(1);
904 pf_end_threads++;
905
906 lockmgr(&pf_consistency_lock, LK_RELEASE);
907 wakeup(pf_purge_thread);
908 kthread_exit();
909 }
910 crit_enter();
911
912 /* process a fraction of the state table every second */
913 if(!pf_purge_expired_states(1 + (pf_status.states
914 / pf_default_rule.timeout[PFTM_INTERVAL]), 0)) {
02742ec6 915
70224baa
JL
916 pf_purge_expired_states(1 + (pf_status.states
917 / pf_default_rule.timeout[PFTM_INTERVAL]), 1);
918 }
02742ec6 919
70224baa
JL
920 /* purge other expired types every PFTM_INTERVAL seconds */
921 if (++nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) {
922 pf_purge_expired_fragments();
923 if (!pf_purge_expired_src_nodes(locked)) {
924 pf_purge_expired_src_nodes(1);
925 }
926 nloops = 0;
927 }
928 crit_exit();
929 lockmgr(&pf_consistency_lock, LK_RELEASE);
930 }
cd8ab232 931 rel_mplock();
02742ec6
JS
932}
933
934u_int32_t
935pf_state_expires(const struct pf_state *state)
936{
937 u_int32_t timeout;
938 u_int32_t start;
939 u_int32_t end;
940 u_int32_t states;
941
942 /* handle all PFTM_* > PFTM_MAX here */
943 if (state->timeout == PFTM_PURGE)
944 return (time_second);
945 if (state->timeout == PFTM_UNTIL_PACKET)
946 return (0);
70224baa
JL
947 KKASSERT(state->timeout != PFTM_UNLINKED);
948 KASSERT((state->timeout < PFTM_MAX),
949 ("pf_state_expires: timeout > PFTM_MAX"));
02742ec6
JS
950 timeout = state->rule.ptr->timeout[state->timeout];
951 if (!timeout)
952 timeout = pf_default_rule.timeout[state->timeout];
953 start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START];
954 if (start) {
955 end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END];
956 states = state->rule.ptr->states;
957 } else {
958 start = pf_default_rule.timeout[PFTM_ADAPTIVE_START];
959 end = pf_default_rule.timeout[PFTM_ADAPTIVE_END];
960 states = pf_status.states;
961 }
962 if (end && states > start && start < end) {
963 if (states < end)
964 return (state->expire + timeout * (end - states) /
965 (end - start));
966 else
967 return (time_second);
968 }
969 return (state->expire + timeout);
970}
971
70224baa
JL
972int
973pf_purge_expired_src_nodes(int waslocked)
02742ec6
JS
974{
975 struct pf_src_node *cur, *next;
70224baa 976 int locked = waslocked;
02742ec6
JS
977
978 for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) {
979 next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur);
980
981 if (cur->states <= 0 && cur->expire <= time_second) {
70224baa
JL
982 if (! locked) {
983 lockmgr(&pf_consistency_lock, LK_EXCLUSIVE);
984 next = RB_NEXT(pf_src_tree,
985 &tree_src_tracking, cur);
986 locked = 1;
987 }
02742ec6
JS
988 if (cur->rule.ptr != NULL) {
989 cur->rule.ptr->src_nodes--;
990 if (cur->rule.ptr->states <= 0 &&
991 cur->rule.ptr->max_src_nodes <= 0)
992 pf_rm_rule(NULL, cur->rule.ptr);
993 }
994 RB_REMOVE(pf_src_tree, &tree_src_tracking, cur);
995 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
996 pf_status.src_nodes--;
997 pool_put(&pf_src_tree_pl, cur);
998 }
999 }
70224baa
JL
1000
1001 if (locked && !waslocked)
1002 lockmgr(&pf_consistency_lock, LK_RELEASE);
1003 return(1);
02742ec6
JS
1004}
1005
1006void
1007pf_src_tree_remove_state(struct pf_state *s)
1008{
1009 u_int32_t timeout;
1010
1011 if (s->src_node != NULL) {
70224baa
JL
1012 if (s->proto == IPPROTO_TCP) {
1013 if (s->src.tcp_est)
1014 --s->src_node->conn;
1015 }
02742ec6
JS
1016 if (--s->src_node->states <= 0) {
1017 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
1018 if (!timeout)
1019 timeout =
1020 pf_default_rule.timeout[PFTM_SRC_NODE];
1021 s->src_node->expire = time_second + timeout;
1022 }
1023 }
1024 if (s->nat_src_node != s->src_node && s->nat_src_node != NULL) {
1025 if (--s->nat_src_node->states <= 0) {
1026 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
1027 if (!timeout)
1028 timeout =
1029 pf_default_rule.timeout[PFTM_SRC_NODE];
1030 s->nat_src_node->expire = time_second + timeout;
1031 }
1032 }
1033 s->src_node = s->nat_src_node = NULL;
1034}
1035
70224baa
JL
1036/* callers should be at crit_enter() */
1037void
1038pf_unlink_state(struct pf_state *cur)
02742ec6 1039{
70224baa
JL
1040 if (cur->src.state == PF_TCPS_PROXY_DST) {
1041 pf_send_tcp(cur->rule.ptr, cur->af,
1042 &cur->ext.addr, &cur->lan.addr,
1043 cur->ext.port, cur->lan.port,
1044 cur->src.seqhi, cur->src.seqlo + 1,
1045 TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL);
1046 }
1047 RB_REMOVE(pf_state_tree_ext_gwy,
1048 &cur->u.s.kif->pfik_ext_gwy, cur);
1049 RB_REMOVE(pf_state_tree_lan_ext,
1050 &cur->u.s.kif->pfik_lan_ext, cur);
1051 RB_REMOVE(pf_state_tree_id, &tree_id, cur);
02742ec6 1052#if NPFSYNC
70224baa 1053 if (cur->creatorid == pf_status.hostid)
f0ea6854 1054 pfsync_delete_state(cur);
02742ec6 1055#endif
70224baa
JL
1056 cur->timeout = PFTM_UNLINKED;
1057 pf_src_tree_remove_state(cur);
02742ec6
JS
1058}
1059
70224baa
JL
1060/* callers should be at crit_enter() and hold the
1061 * write_lock on pf_consistency_lock */
f0ea6854 1062void
70224baa 1063pf_free_state(struct pf_state *cur)
f0ea6854 1064{
70224baa
JL
1065#if NPFSYNC
1066 if (pfsyncif != NULL &&
1067 (pfsyncif->sc_bulk_send_next == cur ||
1068 pfsyncif->sc_bulk_terminator == cur))
1069 return;
1070#endif
1071 KKASSERT(cur->timeout == PFTM_UNLINKED);
1072 if (--cur->rule.ptr->states <= 0 &&
1073 cur->rule.ptr->src_nodes <= 0)
1074 pf_rm_rule(NULL, cur->rule.ptr);
1075 if (cur->nat_rule.ptr != NULL)
1076 if (--cur->nat_rule.ptr->states <= 0 &&
1077 cur->nat_rule.ptr->src_nodes <= 0)
1078 pf_rm_rule(NULL, cur->nat_rule.ptr);
1079 if (cur->anchor.ptr != NULL)
1080 if (--cur->anchor.ptr->states <= 0)
1081 pf_rm_rule(NULL, cur->anchor.ptr);
1082 pf_normalize_tcp_cleanup(cur);
1083 pfi_kif_unref(cur->u.s.kif, PFI_KIF_REF_STATE);
1084 TAILQ_REMOVE(&state_list, cur, u.s.entry_list);
1085 if (cur->tag)
1086 pf_tag_unref(cur->tag);
1087 pool_put(&pf_state_pl, cur);
1088 pf_status.fcounters[FCNT_STATE_REMOVALS]++;
1089 pf_status.states--;
f0ea6854
MD
1090}
1091
70224baa
JL
1092int
1093pf_purge_expired_states(u_int32_t maxcheck, int waslocked)
1094{
1095 static struct pf_state *cur = NULL;
1096 struct pf_state *next;
1097 int locked = waslocked;
1098
1099 while (maxcheck--) {
1100 /* wrap to start of list when we hit the end */
1101 if (cur == NULL) {
1102 cur = TAILQ_FIRST(&state_list);
1103 if (cur == NULL)
1104 break; /* list empty */
1105 }
1106
1107 /* get next state, as cur may get deleted */
1108 next = TAILQ_NEXT(cur, u.s.entry_list);
1109
1110 if (cur->timeout == PFTM_UNLINKED) {
1111 /* free unlinked state */
1112 if (! locked) {
1113 lockmgr(&pf_consistency_lock, LK_EXCLUSIVE);
1114 locked = 1;
1115 }
1116 pf_free_state(cur);
1117 } else if (pf_state_expires(cur) <= time_second) {
1118 /* unlink and free expired state */
1119 pf_unlink_state(cur);
1120 if (! locked) {
1121 if (!lockmgr(&pf_consistency_lock, LK_EXCLUSIVE))
1122 return (0);
1123 locked = 1;
1124 }
1125 pf_free_state(cur);
1126 }
1127 cur = next;
1128 }
1129
1130 if (locked)
1131 lockmgr(&pf_consistency_lock, LK_RELEASE);
1132 return (1);
1133}
f0ea6854 1134
02742ec6
JS
1135int
1136pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw)
1137{
1138 if (aw->type != PF_ADDR_TABLE)
1139 return (0);
1140 if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL)
1141 return (1);
1142 return (0);
1143}
1144
1145void
1146pf_tbladdr_remove(struct pf_addr_wrap *aw)
1147{
1148 if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL)
1149 return;
1150 pfr_detach_table(aw->p.tbl);
1151 aw->p.tbl = NULL;
1152}
1153
1154void
1155pf_tbladdr_copyout(struct pf_addr_wrap *aw)
1156{
1157 struct pfr_ktable *kt = aw->p.tbl;
1158
1159 if (aw->type != PF_ADDR_TABLE || kt == NULL)
1160 return;
1161 if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
1162 kt = kt->pfrkt_root;
1163 aw->p.tbl = NULL;
1164 aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
1165 kt->pfrkt_cnt : -1;
1166}
1167
1168void
1169pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af)
1170{
1171 switch (af) {
1172#ifdef INET
1173 case AF_INET: {
1174 u_int32_t a = ntohl(addr->addr32[0]);
4b1cf444 1175 kprintf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255,
02742ec6
JS
1176 (a>>8)&255, a&255);
1177 if (p) {
1178 p = ntohs(p);
4b1cf444 1179 kprintf(":%u", p);
02742ec6
JS
1180 }
1181 break;
1182 }
1183#endif /* INET */
1184#ifdef INET6
1185 case AF_INET6: {
1186 u_int16_t b;
1187 u_int8_t i, curstart = 255, curend = 0,
1188 maxstart = 0, maxend = 0;
1189 for (i = 0; i < 8; i++) {
1190 if (!addr->addr16[i]) {
1191 if (curstart == 255)
1192 curstart = i;
1193 else
1194 curend = i;
1195 } else {
1196 if (curstart) {
1197 if ((curend - curstart) >
1198 (maxend - maxstart)) {
1199 maxstart = curstart;
1200 maxend = curend;
1201 curstart = 255;
1202 }
1203 }
1204 }
1205 }
1206 for (i = 0; i < 8; i++) {
1207 if (i >= maxstart && i <= maxend) {
1208 if (maxend != 7) {
1209 if (i == maxstart)
4b1cf444 1210 kprintf(":");
02742ec6
JS
1211 } else {
1212 if (i == maxend)
4b1cf444 1213 kprintf(":");
02742ec6
JS
1214 }
1215 } else {
1216 b = ntohs(addr->addr16[i]);
4b1cf444 1217 kprintf("%x", b);
02742ec6 1218 if (i < 7)
4b1cf444 1219 kprintf(":");
02742ec6
JS
1220 }
1221 }
1222 if (p) {
1223 p = ntohs(p);
4b1cf444 1224 kprintf("[%u]", p);
02742ec6
JS
1225 }
1226 break;
1227 }
1228#endif /* INET6 */
1229 }
1230}
1231
1232void
1233pf_print_state(struct pf_state *s)
1234{
1235 switch (s->proto) {
1236 case IPPROTO_TCP:
4b1cf444 1237 kprintf("TCP ");
02742ec6
JS
1238 break;
1239 case IPPROTO_UDP:
4b1cf444 1240 kprintf("UDP ");
02742ec6
JS
1241 break;
1242 case IPPROTO_ICMP:
4b1cf444 1243 kprintf("ICMP ");
02742ec6
JS
1244 break;
1245 case IPPROTO_ICMPV6:
4b1cf444 1246 kprintf("ICMPV6 ");
02742ec6
JS
1247 break;
1248 default:
4b1cf444 1249 kprintf("%u ", s->proto);
02742ec6
JS
1250 break;
1251 }
1252 pf_print_host(&s->lan.addr, s->lan.port, s->af);
4b1cf444 1253 kprintf(" ");
02742ec6 1254 pf_print_host(&s->gwy.addr, s->gwy.port, s->af);
4b1cf444 1255 kprintf(" ");
02742ec6 1256 pf_print_host(&s->ext.addr, s->ext.port, s->af);
4b1cf444 1257 kprintf(" [lo=%u high=%u win=%u modulator=%u", s->src.seqlo,
02742ec6
JS
1258 s->src.seqhi, s->src.max_win, s->src.seqdiff);
1259 if (s->src.wscale && s->dst.wscale)
4b1cf444
SW
1260 kprintf(" wscale=%u", s->src.wscale & PF_WSCALE_MASK);
1261 kprintf("]");
1262 kprintf(" [lo=%u high=%u win=%u modulator=%u", s->dst.seqlo,
02742ec6
JS
1263 s->dst.seqhi, s->dst.max_win, s->dst.seqdiff);
1264 if (s->src.wscale && s->dst.wscale)
4b1cf444
SW
1265 kprintf(" wscale=%u", s->dst.wscale & PF_WSCALE_MASK);
1266 kprintf("]");
1267 kprintf(" %u:%u", s->src.state, s->dst.state);
02742ec6
JS
1268}
1269
1270void
1271pf_print_flags(u_int8_t f)
1272{
1273 if (f)
4b1cf444 1274 kprintf(" ");
02742ec6 1275 if (f & TH_FIN)
4b1cf444 1276 kprintf("F");
02742ec6 1277 if (f & TH_SYN)
4b1cf444 1278 kprintf("S");
02742ec6 1279 if (f & TH_RST)
4b1cf444 1280 kprintf("R");
02742ec6 1281 if (f & TH_PUSH)
4b1cf444 1282 kprintf("P");
02742ec6 1283 if (f & TH_ACK)
4b1cf444 1284 kprintf("A");
02742ec6 1285 if (f & TH_URG)
4b1cf444 1286 kprintf("U");
02742ec6 1287 if (f & TH_ECE)
4b1cf444 1288 kprintf("E");
02742ec6 1289 if (f & TH_CWR)
4b1cf444 1290 kprintf("W");
02742ec6
JS
1291}
1292
1293#define PF_SET_SKIP_STEPS(i) \
1294 do { \
1295 while (head[i] != cur) { \
1296 head[i]->skip[i].ptr = cur; \
1297 head[i] = TAILQ_NEXT(head[i], entries); \
1298 } \
1299 } while (0)
1300
1301void
1302pf_calc_skip_steps(struct pf_rulequeue *rules)
1303{
1304 struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT];
1305 int i;
1306
1307 cur = TAILQ_FIRST(rules);
1308 prev = cur;
1309 for (i = 0; i < PF_SKIP_COUNT; ++i)
1310 head[i] = cur;
1311 while (cur != NULL) {
1312
1313 if (cur->kif != prev->kif || cur->ifnot != prev->ifnot)
1314 PF_SET_SKIP_STEPS(PF_SKIP_IFP);
1315 if (cur->direction != prev->direction)
1316 PF_SET_SKIP_STEPS(PF_SKIP_DIR);
1317 if (cur->af != prev->af)
1318 PF_SET_SKIP_STEPS(PF_SKIP_AF);
1319 if (cur->proto != prev->proto)
1320 PF_SET_SKIP_STEPS(PF_SKIP_PROTO);
70224baa 1321 if (cur->src.neg != prev->src.neg ||
02742ec6
JS
1322 pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr))
1323 PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR);
1324 if (cur->src.port[0] != prev->src.port[0] ||
1325 cur->src.port[1] != prev->src.port[1] ||
1326 cur->src.port_op != prev->src.port_op)
1327 PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT);
70224baa 1328 if (cur->dst.neg != prev->dst.neg ||
02742ec6
JS
1329 pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr))
1330 PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR);
1331 if (cur->dst.port[0] != prev->dst.port[0] ||
1332 cur->dst.port[1] != prev->dst.port[1] ||
1333 cur->dst.port_op != prev->dst.port_op)
1334 PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT);
1335
1336 prev = cur;
1337 cur = TAILQ_NEXT(cur, entries);
1338 }
1339 for (i = 0; i < PF_SKIP_COUNT; ++i)
1340 PF_SET_SKIP_STEPS(i);
1341}
1342
1343int
1344pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2)
1345{
1346 if (aw1->type != aw2->type)
1347 return (1);
1348 switch (aw1->type) {
1349 case PF_ADDR_ADDRMASK:
1350 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0))
1351 return (1);
1352 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0))
1353 return (1);
1354 return (0);
1355 case PF_ADDR_DYNIFTL:
1356 return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt);
1357 case PF_ADDR_NOROUTE:
70224baa 1358 case PF_ADDR_URPFFAILED:
02742ec6
JS
1359 return (0);
1360 case PF_ADDR_TABLE:
1361 return (aw1->p.tbl != aw2->p.tbl);
70224baa
JL
1362 case PF_ADDR_RTLABEL:
1363 return (aw1->v.rtlabel != aw2->v.rtlabel);
02742ec6 1364 default:
4b1cf444 1365 kprintf("invalid address type: %d\n", aw1->type);
02742ec6
JS
1366 return (1);
1367 }
1368}
1369
02742ec6
JS
1370u_int16_t
1371pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp)
1372{
1373 u_int32_t l;
1374
1375 if (udp && !cksum)
1376 return (0x0000);
1377 l = cksum + old - new;
1378 l = (l >> 16) + (l & 65535);
1379 l = l & 65535;
1380 if (udp && !l)
1381 return (0xFFFF);
1382 return (l);
1383}
1384
1385void
1386pf_change_ap(struct pf_addr *a, u_int16_t *p, u_int16_t *ic, u_int16_t *pc,
1387 struct pf_addr *an, u_int16_t pn, u_int8_t u, sa_family_t af)
1388{
1389 struct pf_addr ao;
1390 u_int16_t po = *p;
1391
1392 PF_ACPY(&ao, a, af);
1393 PF_ACPY(a, an, af);
1394
1395 *p = pn;
1396
1397 switch (af) {
1398#ifdef INET
1399 case AF_INET:
1400 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
1401 ao.addr16[0], an->addr16[0], 0),
1402 ao.addr16[1], an->addr16[1], 0);
1403 *p = pn;
1404 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
1405 ao.addr16[0], an->addr16[0], u),
1406 ao.addr16[1], an->addr16[1], u),
1407 po, pn, u);
1408 break;
1409#endif /* INET */
1410#ifdef INET6
1411 case AF_INET6:
1412 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1413 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1414 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
1415 ao.addr16[0], an->addr16[0], u),
1416 ao.addr16[1], an->addr16[1], u),
1417 ao.addr16[2], an->addr16[2], u),
1418 ao.addr16[3], an->addr16[3], u),
1419 ao.addr16[4], an->addr16[4], u),
1420 ao.addr16[5], an->addr16[5], u),
1421 ao.addr16[6], an->addr16[6], u),
1422 ao.addr16[7], an->addr16[7], u),
1423 po, pn, u);
1424 break;
1425#endif /* INET6 */
1426 }
1427}
1428
1429
1430/* Changes a u_int32_t. Uses a void * so there are no align restrictions */
1431void
1432pf_change_a(void *a, u_int16_t *c, u_int32_t an, u_int8_t u)
1433{
1434 u_int32_t ao;
1435
1436 memcpy(&ao, a, sizeof(ao));
1437 memcpy(a, &an, sizeof(u_int32_t));
1438 *c = pf_cksum_fixup(pf_cksum_fixup(*c, ao / 65536, an / 65536, u),
1439 ao % 65536, an % 65536, u);
1440}
1441
1442#ifdef INET6
1443void
1444pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u)
1445{
1446 struct pf_addr ao;
1447
1448 PF_ACPY(&ao, a, AF_INET6);
1449 PF_ACPY(a, an, AF_INET6);
1450
1451 *c = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1452 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1453 pf_cksum_fixup(pf_cksum_fixup(*c,
1454 ao.addr16[0], an->addr16[0], u),
1455 ao.addr16[1], an->addr16[1], u),
1456 ao.addr16[2], an->addr16[2], u),
1457 ao.addr16[3], an->addr16[3], u),
1458 ao.addr16[4], an->addr16[4], u),
1459 ao.addr16[5], an->addr16[5], u),
1460 ao.addr16[6], an->addr16[6], u),
1461 ao.addr16[7], an->addr16[7], u);
1462}
1463#endif /* INET6 */
1464
1465void
1466pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa,
1467 struct pf_addr *na, u_int16_t np, u_int16_t *pc, u_int16_t *h2c,
1468 u_int16_t *ic, u_int16_t *hc, u_int8_t u, sa_family_t af)
1469{
1470 struct pf_addr oia, ooa;
1471
1472 PF_ACPY(&oia, ia, af);
1473 PF_ACPY(&ooa, oa, af);
1474
1475 /* Change inner protocol port, fix inner protocol checksum. */
1476 if (ip != NULL) {
1477 u_int16_t oip = *ip;
1478 u_int32_t opc = 0;
1479
1480 if (pc != NULL)
1481 opc = *pc;
1482 *ip = np;
1483 if (pc != NULL)
1484 *pc = pf_cksum_fixup(*pc, oip, *ip, u);
1485 *ic = pf_cksum_fixup(*ic, oip, *ip, 0);
1486 if (pc != NULL)
1487 *ic = pf_cksum_fixup(*ic, opc, *pc, 0);
1488 }
1489 /* Change inner ip address, fix inner ip and icmp checksums. */
1490 PF_ACPY(ia, na, af);
1491 switch (af) {
1492#ifdef INET
1493 case AF_INET: {
1494 u_int32_t oh2c = *h2c;
1495
1496 *h2c = pf_cksum_fixup(pf_cksum_fixup(*h2c,
1497 oia.addr16[0], ia->addr16[0], 0),
1498 oia.addr16[1], ia->addr16[1], 0);
1499 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
1500 oia.addr16[0], ia->addr16[0], 0),
1501 oia.addr16[1], ia->addr16[1], 0);
1502 *ic = pf_cksum_fixup(*ic, oh2c, *h2c, 0);
1503 break;
1504 }
1505#endif /* INET */
1506#ifdef INET6
1507 case AF_INET6:
1508 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1509 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1510 pf_cksum_fixup(pf_cksum_fixup(*ic,
1511 oia.addr16[0], ia->addr16[0], u),
1512 oia.addr16[1], ia->addr16[1], u),
1513 oia.addr16[2], ia->addr16[2], u),
1514 oia.addr16[3], ia->addr16[3], u),
1515 oia.addr16[4], ia->addr16[4], u),
1516 oia.addr16[5], ia->addr16[5], u),
1517 oia.addr16[6], ia->addr16[6], u),
1518 oia.addr16[7], ia->addr16[7], u);
1519 break;
1520#endif /* INET6 */
1521 }
1522 /* Change outer ip address, fix outer ip or icmpv6 checksum. */
1523 PF_ACPY(oa, na, af);
1524 switch (af) {
1525#ifdef INET
1526 case AF_INET:
1527 *hc = pf_cksum_fixup(pf_cksum_fixup(*hc,
1528 ooa.addr16[0], oa->addr16[0], 0),
1529 ooa.addr16[1], oa->addr16[1], 0);
1530 break;
1531#endif /* INET */
1532#ifdef INET6
1533 case AF_INET6:
1534 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1535 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1536 pf_cksum_fixup(pf_cksum_fixup(*ic,
1537 ooa.addr16[0], oa->addr16[0], u),
1538 ooa.addr16[1], oa->addr16[1], u),
1539 ooa.addr16[2], oa->addr16[2], u),
1540 ooa.addr16[3], oa->addr16[3], u),
1541 ooa.addr16[4], oa->addr16[4], u),
1542 ooa.addr16[5], oa->addr16[5], u),
1543 ooa.addr16[6], oa->addr16[6], u),
1544 ooa.addr16[7], oa->addr16[7], u);
1545 break;
1546#endif /* INET6 */
1547 }
1548}
1549
70224baa
JL
1550
1551/*
1552 * Need to modulate the sequence numbers in the TCP SACK option
1553 * (credits to Krzysztof Pfaff for report and patch)
1554 */
1555int
1556pf_modulate_sack(struct mbuf *m, int off, struct pf_pdesc *pd,
1557 struct tcphdr *th, struct pf_state_peer *dst)
1558{
1559 int hlen = (th->th_off << 2) - sizeof(*th), thoptlen = hlen;
1560 u_int8_t opts[TCP_MAXOLEN], *opt = opts;
1561 int copyback = 0, i, olen;
1562 struct raw_sackblock sack;
1563
1564#define TCPOLEN_SACKLEN (TCPOLEN_SACK + 2)
1565 if (hlen < TCPOLEN_SACKLEN ||
1566 !pf_pull_hdr(m, off + sizeof(*th), opts, hlen, NULL, NULL, pd->af))
1567 return 0;
1568
1569 while (hlen >= TCPOLEN_SACKLEN) {
1570 olen = opt[1];
1571 switch (*opt) {
1572 case TCPOPT_EOL: /* FALLTHROUGH */
1573 case TCPOPT_NOP:
1574 opt++;
1575 hlen--;
1576 break;
1577 case TCPOPT_SACK:
1578 if (olen > hlen)
1579 olen = hlen;
1580 if (olen >= TCPOLEN_SACKLEN) {
1581 for (i = 2; i + TCPOLEN_SACK <= olen;
1582 i += TCPOLEN_SACK) {
1583 memcpy(&sack, &opt[i], sizeof(sack));
1584 pf_change_a(&sack.rblk_start, &th->th_sum,
1585 htonl(ntohl(sack.rblk_start) -
1586 dst->seqdiff), 0);
1587 pf_change_a(&sack.rblk_end, &th->th_sum,
1588 htonl(ntohl(sack.rblk_end) -
1589 dst->seqdiff), 0);
1590 memcpy(&opt[i], &sack, sizeof(sack));
1591 }
1592 copyback = 1;
1593 }
1594 /* FALLTHROUGH */
1595 default:
1596 if (olen < 2)
1597 olen = 2;
1598 hlen -= olen;
1599 opt += olen;
1600 }
1601 }
1602
1603 if (copyback)
1604 m_copyback(m, off + sizeof(*th), thoptlen, opts);
1605 return (copyback);
1606}
1607
02742ec6
JS
1608void
1609pf_send_tcp(const struct pf_rule *r, sa_family_t af,
1610 const struct pf_addr *saddr, const struct pf_addr *daddr,
1611 u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
70224baa
JL
1612 u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag,
1613 u_int16_t rtag, struct ether_header *eh, struct ifnet *ifp)
02742ec6
JS
1614{
1615 struct mbuf *m;
1616 int len = 0, tlen;
1617#ifdef INET
1618 struct ip *h = NULL;
1619#endif /* INET */
1620#ifdef INET6
1621 struct ip6_hdr *h6 = NULL;
1622#endif /* INET6 */
1623 struct tcphdr *th = NULL;
70224baa
JL
1624 char *opt;
1625 struct pf_mtag *pf_mtag;
02742ec6
JS
1626
1627 /* maximum segment size tcp option */
1628 tlen = sizeof(struct tcphdr);
1629 if (mss)
1630 tlen += 4;
1631
1632 switch (af) {
1633#ifdef INET
1634 case AF_INET:
1635 len = sizeof(struct ip) + tlen;
1636 break;
1637#endif /* INET */
1638#ifdef INET6
1639 case AF_INET6:
1640 len = sizeof(struct ip6_hdr) + tlen;
1641 break;
1642#endif /* INET6 */
1643 }
1644
1645 /* create outgoing mbuf */
1646 m = m_gethdr(MB_DONTWAIT, MT_HEADER);
1647 if (m == NULL)
1648 return;
70224baa
JL
1649 if ((pf_mtag = pf_get_mtag(m)) == NULL) {
1650 m_freem(m);
1651 return;
1652 }
1653 if (tag)
1654 pf_mtag->flags |= PF_TAG_GENERATED;
1655
1656 pf_mtag->tag = rtag;
1657
1658 if (r != NULL && r->rtableid >= 0)
1659 pf_mtag->rtableid = r->rtableid;
1660
02742ec6
JS
1661#ifdef ALTQ
1662 if (r != NULL && r->qid) {
70224baa
JL
1663 pf_mtag->qid = r->qid;
1664 /* add hints for ecn */
1665 pf_mtag->af = af;
1666 pf_mtag->hdr = mtod(m, struct ip *);
02742ec6 1667 }
70224baa 1668#endif /* ALTQ */
02742ec6
JS
1669 m->m_data += max_linkhdr;
1670 m->m_pkthdr.len = m->m_len = len;
1671 m->m_pkthdr.rcvif = NULL;
1672 bzero(m->m_data, len);
1673 switch (af) {
1674#ifdef INET
1675 case AF_INET:
1676 h = mtod(m, struct ip *);
1677
1678 /* IP header fields included in the TCP checksum */
1679 h->ip_p = IPPROTO_TCP;
1680 h->ip_len = tlen;
1681 h->ip_src.s_addr = saddr->v4.s_addr;
1682 h->ip_dst.s_addr = daddr->v4.s_addr;
1683
1684 th = (struct tcphdr *)((caddr_t)h + sizeof(struct ip));
1685 break;
1686#endif /* INET */
1687#ifdef INET6
1688 case AF_INET6:
1689 h6 = mtod(m, struct ip6_hdr *);
1690
1691 /* IP header fields included in the TCP checksum */
1692 h6->ip6_nxt = IPPROTO_TCP;
1693 h6->ip6_plen = htons(tlen);
1694 memcpy(&h6->ip6_src, &saddr->v6, sizeof(struct in6_addr));
1695 memcpy(&h6->ip6_dst, &daddr->v6, sizeof(struct in6_addr));
1696
1697 th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr));
1698 break;
1699#endif /* INET6 */
1700 }
1701
1702 /* TCP header */
1703 th->th_sport = sport;
1704 th->th_dport = dport;
1705 th->th_seq = htonl(seq);
1706 th->th_ack = htonl(ack);
1707 th->th_off = tlen >> 2;
1708 th->th_flags = flags;
1709 th->th_win = htons(win);
1710
1711 if (mss) {
1712 opt = (char *)(th + 1);
1713 opt[0] = TCPOPT_MAXSEG;
1714 opt[1] = 4;
1715 mss = htons(mss);
1716 bcopy((caddr_t)&mss, (caddr_t)(opt + 2), 2);
1717 }
1718
1719 switch (af) {
1720#ifdef INET
1721 case AF_INET:
1722 /* TCP checksum */
1723 th->th_sum = in_cksum(m, len);
1724
1725 /* Finish the IP header */
1726 h->ip_v = 4;
1727 h->ip_hl = sizeof(*h) >> 2;
1728 h->ip_tos = IPTOS_LOWDELAY;
1729 h->ip_len = len;
1730 h->ip_off = path_mtu_discovery ? IP_DF : 0;
1731 h->ip_ttl = ttl ? ttl : ip_defttl;
1732 h->ip_sum = 0;
70224baa
JL
1733 if (eh == NULL) {
1734 ip_output(m, NULL, NULL, 0, NULL, NULL);
1735 } else {
1736 struct route ro;
1737 struct rtentry rt;
1738 struct ether_header *e = (void *)ro.ro_dst.sa_data;
1739
1740 if (ifp == NULL) {
1741 m_freem(m);
1742 return;
1743 }
1744 rt.rt_ifp = ifp;
1745 ro.ro_rt = &rt;
1746 ro.ro_dst.sa_len = sizeof(ro.ro_dst);
1747 ro.ro_dst.sa_family = pseudo_AF_HDRCMPLT;
1748 bcopy(eh->ether_dhost, e->ether_shost, ETHER_ADDR_LEN);
1749 bcopy(eh->ether_shost, e->ether_dhost, ETHER_ADDR_LEN);
1750 e->ether_type = eh->ether_type;
1751 /* XXX_IMPORT: later */
1752 ip_output(m, (void *)NULL, &ro, 0,
1753 (void *)NULL, (void *)NULL);
1754 }
02742ec6
JS
1755 break;
1756#endif /* INET */
1757#ifdef INET6
1758 case AF_INET6:
1759 /* TCP checksum */
1760 th->th_sum = in6_cksum(m, IPPROTO_TCP,
1761 sizeof(struct ip6_hdr), tlen);
1762
1763 h6->ip6_vfc |= IPV6_VERSION;
1764 h6->ip6_hlim = IPV6_DEFHLIM;
1765
1766 ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
1767 break;
1768#endif /* INET6 */
1769 }
1770}
1771
1772void
1773pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
1774 struct pf_rule *r)
1775{
70224baa 1776 struct pf_mtag *pf_mtag;
02742ec6
JS
1777 struct mbuf *m0;
1778
70224baa
JL
1779 m0 = m_copy(m, 0, M_COPYALL);
1780
1781 if ((pf_mtag = pf_get_mtag(m0)) == NULL)
02742ec6 1782 return;
70224baa
JL
1783 pf_mtag->flags |= PF_TAG_GENERATED;
1784
1785 if (r->rtableid >= 0)
1786 pf_mtag->rtableid = r->rtableid;
02742ec6
JS
1787
1788#ifdef ALTQ
1789 if (r->qid) {
70224baa
JL
1790 pf_mtag->qid = r->qid;
1791 /* add hints for ecn */
1792 pf_mtag->af = af;
1793 pf_mtag->hdr = mtod(m0, struct ip *);
02742ec6 1794 }
70224baa 1795#endif /* ALTQ */
02742ec6
JS
1796
1797 switch (af) {
1798#ifdef INET
1799 case AF_INET:
745a4a5d 1800 icmp_error(m0, type, code, 0, 0);
02742ec6
JS
1801 break;
1802#endif /* INET */
1803#ifdef INET6
1804 case AF_INET6:
1805 icmp6_error(m0, type, code, 0);
1806 break;
1807#endif /* INET6 */
1808 }
1809}
1810
1811/*
1812 * Return 1 if the addresses a and b match (with mask m), otherwise return 0.
1813 * If n is 0, they match if they are equal. If n is != 0, they match if they
1814 * are different.
1815 */
1816int
1817pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m,
1818 struct pf_addr *b, sa_family_t af)
1819{
1820 int match = 0;
1821
1822 switch (af) {
1823#ifdef INET
1824 case AF_INET:
1825 if ((a->addr32[0] & m->addr32[0]) ==
1826 (b->addr32[0] & m->addr32[0]))
1827 match++;
1828 break;
1829#endif /* INET */
1830#ifdef INET6
1831 case AF_INET6:
1832 if (((a->addr32[0] & m->addr32[0]) ==
1833 (b->addr32[0] & m->addr32[0])) &&
1834 ((a->addr32[1] & m->addr32[1]) ==
1835 (b->addr32[1] & m->addr32[1])) &&
1836 ((a->addr32[2] & m->addr32[2]) ==
1837 (b->addr32[2] & m->addr32[2])) &&
1838 ((a->addr32[3] & m->addr32[3]) ==
1839 (b->addr32[3] & m->addr32[3])))
1840 match++;
1841 break;
1842#endif /* INET6 */
1843 }
1844 if (match) {
1845 if (n)
1846 return (0);
1847 else
1848 return (1);
1849 } else {
1850 if (n)
1851 return (1);
1852 else
1853 return (0);
1854 }
1855}
1856
1857int
1858pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p)
1859{
1860 switch (op) {
1861 case PF_OP_IRG:
1862 return ((p > a1) && (p < a2));
1863 case PF_OP_XRG:
1864 return ((p < a1) || (p > a2));
1865 case PF_OP_RRG:
1866 return ((p >= a1) && (p <= a2));
1867 case PF_OP_EQ:
1868 return (p == a1);
1869 case PF_OP_NE:
1870 return (p != a1);
1871 case PF_OP_LT:
1872 return (p < a1);
1873 case PF_OP_LE:
1874 return (p <= a1);
1875 case PF_OP_GT:
1876 return (p > a1);
1877 case PF_OP_GE:
1878 return (p >= a1);
1879 }
1880 return (0); /* never reached */
1881}
1882
1883int
1884pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p)
1885{
1886 a1 = ntohs(a1);
1887 a2 = ntohs(a2);
1888 p = ntohs(p);
1889 return (pf_match(op, a1, a2, p));
1890}
1891
1892int
1893pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u)
1894{
1895 if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
1896 return (0);
1897 return (pf_match(op, a1, a2, u));
1898}
1899
1900int
1901pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g)
1902{
1903 if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
1904 return (0);
1905 return (pf_match(op, a1, a2, g));
1906}
1907
70224baa
JL
1908struct pf_mtag *
1909pf_find_mtag(struct mbuf *m)
02742ec6 1910{
70224baa
JL
1911 struct m_tag *mtag;
1912
1913 if ((mtag = m_tag_find(m, PF_MBUF_TAGGED, NULL)) == NULL)
1914 return (NULL);
1915
1916 return ((struct pf_mtag *)(mtag + 1));
1917}
1918
1919struct pf_mtag *
1920pf_get_mtag(struct mbuf *m)
1921{
1922 struct m_tag *mtag;
1923
1924 if ((mtag = m_tag_find(m, PF_MBUF_TAGGED, NULL)) == NULL) {
1925 mtag = m_tag_get(PF_MBUF_TAGGED, sizeof(struct pf_mtag),
1926 M_NOWAIT);
1927 if (mtag == NULL)
1928 return (NULL);
1929 bzero(mtag + 1, sizeof(struct pf_mtag));
1930 m_tag_prepend(m, mtag);
02742ec6
JS
1931 }
1932
70224baa
JL
1933 return ((struct pf_mtag *)(mtag + 1));
1934}
1935
1936int
1937pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_mtag *pf_mtag,
1938 int *tag)
1939{
1940 if (*tag == -1)
1941 *tag = pf_mtag->tag;
1942
02742ec6
JS
1943 return ((!r->match_tag_not && r->match_tag == *tag) ||
1944 (r->match_tag_not && r->match_tag != *tag));
1945}
1946
70224baa
JL
1947int
1948pf_tag_packet(struct mbuf *m, struct pf_mtag *pf_mtag, int tag, int rtableid)
02742ec6 1949{
70224baa
JL
1950 if (tag <= 0 && rtableid < 0)
1951 return (0);
1952
1953 if (pf_mtag == NULL)
1954 if ((pf_mtag = pf_get_mtag(m)) == NULL)
1955 return (1);
1956 if (tag > 0)
1957 pf_mtag->tag = tag;
1958 if (rtableid >= 0)
1959 pf_mtag->rtableid = rtableid;
02742ec6 1960
70224baa 1961 return (0);
02742ec6
JS
1962}
1963
70224baa
JL
1964static void
1965pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n,
1966 struct pf_rule **r, struct pf_rule **a, int *match)
1967{
1968 struct pf_anchor_stackframe *f;
1969
1970 (*r)->anchor->match = 0;
1971 if (match)
1972 *match = 0;
1973 if (*depth >= sizeof(pf_anchor_stack) /
1974 sizeof(pf_anchor_stack[0])) {
1975 kprintf("pf_step_into_anchor: stack overflow\n");
1976 *r = TAILQ_NEXT(*r, entries);
1977 return;
1978 } else if (*depth == 0 && a != NULL)
1979 *a = *r;
1980 f = pf_anchor_stack + (*depth)++;
1981 f->rs = *rs;
1982 f->r = *r;
1983 if ((*r)->anchor_wildcard) {
1984 f->parent = &(*r)->anchor->children;
1985 if ((f->child = RB_MIN(pf_anchor_node, f->parent)) ==
1986 NULL) {
1987 *r = NULL;
1988 return;
1989 }
1990 *rs = &f->child->ruleset;
1991 } else {
1992 f->parent = NULL;
1993 f->child = NULL;
1994 *rs = &(*r)->anchor->ruleset;
1995 }
1996 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
1997}
02742ec6 1998
70224baa
JL
1999int
2000pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n,
2001 struct pf_rule **r, struct pf_rule **a, int *match)
2002{
2003 struct pf_anchor_stackframe *f;
2004 int quick = 0;
2005
2006 do {
2007 if (*depth <= 0)
2008 break;
2009 f = pf_anchor_stack + *depth - 1;
2010 if (f->parent != NULL && f->child != NULL) {
2011 if (f->child->match ||
2012 (match != NULL && *match)) {
2013 f->r->anchor->match = 1;
2014 *match = 0;
2015 }
2016 f->child = RB_NEXT(pf_anchor_node, f->parent, f->child);
2017 if (f->child != NULL) {
2018 *rs = &f->child->ruleset;
2019 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
2020 if (*r == NULL)
2021 continue;
2022 else
2023 break;
2024 }
2025 }
2026 (*depth)--;
2027 if (*depth == 0 && a != NULL)
2028 *a = NULL;
2029 *rs = f->rs;
2030 if (f->r->anchor->match || (match != NULL && *match))
2031 quick = f->r->quick;
2032 *r = TAILQ_NEXT(f->r, entries);
2033 } while (*r == NULL);
2034
2035 return (quick);
2036}
02742ec6
JS
2037
2038#ifdef INET6
2039void
2040pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr,
2041 struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af)
2042{
2043 switch (af) {
2044#ifdef INET
2045 case AF_INET:
2046 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
2047 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
2048 break;
2049#endif /* INET */
2050 case AF_INET6:
2051 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
2052 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
2053 naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) |
2054 ((rmask->addr32[1] ^ 0xffffffff ) & saddr->addr32[1]);
2055 naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) |
2056 ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]);
2057 naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) |
2058 ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]);
2059 break;
2060 }
2061}
2062
2063void
2064pf_addr_inc(struct pf_addr *addr, sa_family_t af)
2065{
2066 switch (af) {
2067#ifdef INET
2068 case AF_INET:
2069 addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1);
2070 break;
2071#endif /* INET */
2072 case AF_INET6:
2073 if (addr->addr32[3] == 0xffffffff) {
2074 addr->addr32[3] = 0;
2075 if (addr->addr32[2] == 0xffffffff) {
2076 addr->addr32[2] = 0;
2077 if (addr->addr32[1] == 0xffffffff) {
2078 addr->addr32[1] = 0;
2079 addr->addr32[0] =
2080 htonl(ntohl(addr->addr32[0]) + 1);
2081 } else
2082 addr->addr32[1] =
2083 htonl(ntohl(addr->addr32[1]) + 1);
2084 } else
2085 addr->addr32[2] =
2086 htonl(ntohl(addr->addr32[2]) + 1);
2087 } else
2088 addr->addr32[3] =
2089 htonl(ntohl(addr->addr32[3]) + 1);
2090 break;
2091 }
2092}
2093#endif /* INET6 */
2094
2095#define mix(a,b,c) \
2096 do { \
2097 a -= b; a -= c; a ^= (c >> 13); \
2098 b -= c; b -= a; b ^= (a << 8); \
2099 c -= a; c -= b; c ^= (b >> 13); \
2100 a -= b; a -= c; a ^= (c >> 12); \
2101 b -= c; b -= a; b ^= (a << 16); \
2102 c -= a; c -= b; c ^= (b >> 5); \
2103 a -= b; a -= c; a ^= (c >> 3); \
2104 b -= c; b -= a; b ^= (a << 10); \
2105 c -= a; c -= b; c ^= (b >> 15); \
2106 } while (0)
2107
2108/*
2109 * hash function based on bridge_hash in if_bridge.c
2110 */
2111void
2112pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
2113 struct pf_poolhashkey *key, sa_family_t af)
2114{
2115 u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0];
2116
2117 switch (af) {
2118#ifdef INET
2119 case AF_INET:
2120 a += inaddr->addr32[0];
2121 b += key->key32[1];
2122 mix(a, b, c);
2123 hash->addr32[0] = c + key->key32[2];
2124 break;
2125#endif /* INET */
2126#ifdef INET6
2127 case AF_INET6:
2128 a += inaddr->addr32[0];
2129 b += inaddr->addr32[2];
2130 mix(a, b, c);
2131 hash->addr32[0] = c;
2132 a += inaddr->addr32[1];
2133 b += inaddr->addr32[3];
2134 c += key->key32[1];
2135 mix(a, b, c);
2136 hash->addr32[1] = c;
2137 a += inaddr->addr32[2];
2138 b += inaddr->addr32[1];
2139 c += key->key32[2];
2140 mix(a, b, c);
2141 hash->addr32[2] = c;
2142 a += inaddr->addr32[3];
2143 b += inaddr->addr32[0];
2144 c += key->key32[3];
2145 mix(a, b, c);
2146 hash->addr32[3] = c;
2147 break;
2148#endif /* INET6 */
2149 }
2150}
2151
2152int
2153pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
2154 struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn)
2155{
2156 unsigned char hash[16];
2157 struct pf_pool *rpool = &r->rpool;
2158 struct pf_addr *raddr = &rpool->cur->addr.v.a.addr;
2159 struct pf_addr *rmask = &rpool->cur->addr.v.a.mask;
2160 struct pf_pooladdr *acur = rpool->cur;
2161 struct pf_src_node k;
2162
2163 if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR &&
2164 (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
2165 k.af = af;
2166 PF_ACPY(&k.addr, saddr, af);
2167 if (r->rule_flag & PFRULE_RULESRCTRACK ||
2168 r->rpool.opts & PF_POOL_STICKYADDR)
2169 k.rule.ptr = r;
2170 else
2171 k.rule.ptr = NULL;
2172 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
2173 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
2174 if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) {
2175 PF_ACPY(naddr, &(*sn)->raddr, af);
2176 if (pf_status.debug >= PF_DEBUG_MISC) {
4b1cf444 2177 kprintf("pf_map_addr: src tracking maps ");
02742ec6 2178 pf_print_host(&k.addr, 0, af);
4b1cf444 2179 kprintf(" to ");
02742ec6 2180 pf_print_host(naddr, 0, af);
4b1cf444 2181 kprintf("\n");
02742ec6
JS
2182 }
2183 return (0);
2184 }
2185 }
2186
2187 if (rpool->cur->addr.type == PF_ADDR_NOROUTE)
2188 return (1);
2189 if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
70224baa
JL
2190 switch (af) {
2191#ifdef INET
2192 case AF_INET:
02742ec6
JS
2193 if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 &&
2194 (rpool->opts & PF_POOL_TYPEMASK) !=
2195 PF_POOL_ROUNDROBIN)
2196 return (1);
2197 raddr = &rpool->cur->addr.p.dyn->pfid_addr4;
2198 rmask = &rpool->cur->addr.p.dyn->pfid_mask4;
70224baa
JL
2199 break;
2200#endif /* INET */
2201#ifdef INET6
2202 case AF_INET6:
02742ec6
JS
2203 if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 &&
2204 (rpool->opts & PF_POOL_TYPEMASK) !=
2205 PF_POOL_ROUNDROBIN)
2206 return (1);
2207 raddr = &rpool->cur->addr.p.dyn->pfid_addr6;
2208 rmask = &rpool->cur->addr.p.dyn->pfid_mask6;
70224baa
JL
2209 break;
2210#endif /* INET6 */
02742ec6
JS
2211 }
2212 } else if (rpool->cur->addr.type == PF_ADDR_TABLE) {
2213 if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN)
2214 return (1); /* unsupported */
2215 } else {
2216 raddr = &rpool->cur->addr.v.a.addr;
2217 rmask = &rpool->cur->addr.v.a.mask;
2218 }
2219
2220 switch (rpool->opts & PF_POOL_TYPEMASK) {
2221 case PF_POOL_NONE:
2222 PF_ACPY(naddr, raddr, af);
2223 break;
2224 case PF_POOL_BITMASK:
2225 PF_POOLMASK(naddr, raddr, rmask, saddr, af);
2226 break;
2227 case PF_POOL_RANDOM:
2228 if (init_addr != NULL && PF_AZERO(init_addr, af)) {
2229 switch (af) {
2230#ifdef INET
2231 case AF_INET:
70224baa 2232 rpool->counter.addr32[0] = htonl(karc4random());
02742ec6
JS
2233 break;
2234#endif /* INET */
2235#ifdef INET6
2236 case AF_INET6:
2237 if (rmask->addr32[3] != 0xffffffff)
70224baa
JL
2238 rpool->counter.addr32[3] =
2239 htonl(karc4random());
02742ec6
JS
2240 else
2241 break;
2242 if (rmask->addr32[2] != 0xffffffff)
70224baa
JL
2243 rpool->counter.addr32[2] =
2244 htonl(karc4random());
02742ec6
JS
2245 else
2246 break;
2247 if (rmask->addr32[1] != 0xffffffff)
70224baa
JL
2248 rpool->counter.addr32[1] =
2249 htonl(karc4random());
02742ec6
JS
2250 else
2251 break;
2252 if (rmask->addr32[0] != 0xffffffff)
70224baa
JL
2253 rpool->counter.addr32[0] =
2254 htonl(karc4random());
02742ec6
JS
2255 break;
2256#endif /* INET6 */
2257 }
2258 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
2259 PF_ACPY(init_addr, naddr, af);
2260
2261 } else {
2262 PF_AINC(&rpool->counter, af);
2263 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
2264 }
2265 break;
2266 case PF_POOL_SRCHASH:
2267 pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
2268 PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af);
2269 break;
2270 case PF_POOL_ROUNDROBIN:
2271 if (rpool->cur->addr.type == PF_ADDR_TABLE) {
2272 if (!pfr_pool_get(rpool->cur->addr.p.tbl,
2273 &rpool->tblidx, &rpool->counter,
2274 &raddr, &rmask, af))
2275 goto get_addr;
2276 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
2277 if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
2278 &rpool->tblidx, &rpool->counter,
2279 &raddr, &rmask, af))
2280 goto get_addr;
2281 } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
2282 goto get_addr;
2283
2284 try_next:
2285 if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL)
2286 rpool->cur = TAILQ_FIRST(&rpool->list);
2287 if (rpool->cur->addr.type == PF_ADDR_TABLE) {
2288 rpool->tblidx = -1;
2289 if (pfr_pool_get(rpool->cur->addr.p.tbl,
2290 &rpool->tblidx, &rpool->counter,
2291 &raddr, &rmask, af)) {
2292 /* table contains no address of type 'af' */
2293 if (rpool->cur != acur)
2294 goto try_next;
2295 return (1);
2296 }
2297 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
2298 rpool->tblidx = -1;
2299 if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
2300 &rpool->tblidx, &rpool->counter,
2301 &raddr, &rmask, af)) {
2302 /* table contains no address of type 'af' */
2303 if (rpool->cur != acur)
2304 goto try_next;
2305 return (1);
2306 }
2307 } else {
2308 raddr = &rpool->cur->addr.v.a.addr;
2309 rmask = &rpool->cur->addr.v.a.mask;
2310 PF_ACPY(&rpool->counter, raddr, af);
2311 }
2312
2313 get_addr:
2314 PF_ACPY(naddr, &rpool->counter, af);
70224baa
JL
2315 if (init_addr != NULL && PF_AZERO(init_addr, af))
2316 PF_ACPY(init_addr, naddr, af);
02742ec6
JS
2317 PF_AINC(&rpool->counter, af);
2318 break;
2319 }
2320 if (*sn != NULL)
2321 PF_ACPY(&(*sn)->raddr, naddr, af);
2322
2323 if (pf_status.debug >= PF_DEBUG_MISC &&
2324 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
4b1cf444 2325 kprintf("pf_map_addr: selected address ");
02742ec6 2326 pf_print_host(naddr, 0, af);
4b1cf444 2327 kprintf("\n");
02742ec6
JS
2328 }
2329
2330 return (0);
2331}
2332
2333int
2334pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
2335 struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport,
2336 struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high,
2337 struct pf_src_node **sn)
2338{
70224baa 2339 struct pf_state_cmp key;
02742ec6
JS
2340 struct pf_addr init_addr;
2341 u_int16_t cut;
2342
2343 bzero(&init_addr, sizeof(init_addr));
2344 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
2345 return (1);
2346
70224baa
JL
2347 if (proto == IPPROTO_ICMP) {
2348 low = 1;
2349 high = 65535;
2350 }
2351
02742ec6
JS
2352 do {
2353 key.af = af;
2354 key.proto = proto;
2355 PF_ACPY(&key.ext.addr, daddr, key.af);
2356 PF_ACPY(&key.gwy.addr, naddr, key.af);
2357 key.ext.port = dport;
2358
2359 /*
2360 * port search; start random, step;
2361 * similar 2 portloop in in_pcbbind
2362 */
70224baa
JL
2363 if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP ||
2364 proto == IPPROTO_ICMP)) {
2365 key.gwy.port = dport;
02742ec6
JS
2366 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
2367 return (0);
2368 } else if (low == 0 && high == 0) {
2369 key.gwy.port = *nport;
2370 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
2371 return (0);
2372 } else if (low == high) {
2373 key.gwy.port = htons(low);
2374 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) {
2375 *nport = htons(low);
2376 return (0);
2377 }
2378 } else {
2379 u_int16_t tmp;
2380
2381 if (low > high) {
2382 tmp = low;
2383 low = high;
2384 high = tmp;
2385 }
2386 /* low < high */
70224baa 2387 cut = htonl(karc4random()) % (1 + high - low) + low;
02742ec6
JS
2388 /* low <= cut <= high */
2389 for (tmp = cut; tmp <= high; ++(tmp)) {
2390 key.gwy.port = htons(tmp);
2391 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) ==
2392 NULL) {
2393 *nport = htons(tmp);
2394 return (0);
2395 }
2396 }
2397 for (tmp = cut - 1; tmp >= low; --(tmp)) {
2398 key.gwy.port = htons(tmp);
2399 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) ==
2400 NULL) {
2401 *nport = htons(tmp);
2402 return (0);
2403 }
2404 }
2405 }
2406
2407 switch (r->rpool.opts & PF_POOL_TYPEMASK) {
2408 case PF_POOL_RANDOM:
2409 case PF_POOL_ROUNDROBIN:
2410 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
2411 return (1);
2412 break;
2413 case PF_POOL_NONE:
2414 case PF_POOL_SRCHASH:
2415 case PF_POOL_BITMASK:
2416 default:
2417 return (1);
2418 }
2419 } while (! PF_AEQ(&init_addr, naddr, af) );
2420
2421 return (1); /* none available */
2422}
2423
2424struct pf_rule *
2425pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
2426 int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport,
2427 struct pf_addr *daddr, u_int16_t dport, int rs_num)
2428{
70224baa 2429 struct pf_rule *r, *rm = NULL;
02742ec6 2430 struct pf_ruleset *ruleset = NULL;
70224baa
JL
2431 int tag = -1;
2432 int rtableid = -1;
2433 int asd = 0;
02742ec6
JS
2434
2435 r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr);
2436 while (r && rm == NULL) {
2437 struct pf_rule_addr *src = NULL, *dst = NULL;
2438 struct pf_addr_wrap *xdst = NULL;
2439
2440 if (r->action == PF_BINAT && direction == PF_IN) {
2441 src = &r->dst;
2442 if (r->rpool.cur != NULL)
2443 xdst = &r->rpool.cur->addr;
2444 } else {
2445 src = &r->src;
2446 dst = &r->dst;
2447 }
2448
2449 r->evaluations++;
70224baa 2450 if (pfi_kif_match(r->kif, kif) == r->ifnot)
02742ec6
JS
2451 r = r->skip[PF_SKIP_IFP].ptr;
2452 else if (r->direction && r->direction != direction)
2453 r = r->skip[PF_SKIP_DIR].ptr;
2454 else if (r->af && r->af != pd->af)
2455 r = r->skip[PF_SKIP_AF].ptr;
2456 else if (r->proto && r->proto != pd->proto)
2457 r = r->skip[PF_SKIP_PROTO].ptr;
70224baa
JL
2458 else if (PF_MISMATCHAW(&src->addr, saddr, pd->af,
2459 src->neg, kif))
02742ec6
JS
2460 r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR :
2461 PF_SKIP_DST_ADDR].ptr;
2462 else if (src->port_op && !pf_match_port(src->port_op,
2463 src->port[0], src->port[1], sport))
2464 r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT :
2465 PF_SKIP_DST_PORT].ptr;
2466 else if (dst != NULL &&
70224baa 2467 PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg, NULL))
02742ec6 2468 r = r->skip[PF_SKIP_DST_ADDR].ptr;
70224baa
JL
2469 else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af,
2470 0, NULL))
02742ec6
JS
2471 r = TAILQ_NEXT(r, entries);
2472 else if (dst != NULL && dst->port_op &&
2473 !pf_match_port(dst->port_op, dst->port[0],
2474 dst->port[1], dport))
2475 r = r->skip[PF_SKIP_DST_PORT].ptr;
70224baa
JL
2476 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
2477 r = TAILQ_NEXT(r, entries);
02742ec6
JS
2478 else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto !=
2479 IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m,
2480 off, pd->hdr.tcp), r->os_fingerprint)))
2481 r = TAILQ_NEXT(r, entries);
70224baa
JL
2482 else {
2483 if (r->tag)
2484 tag = r->tag;
2485 if (r->rtableid >= 0)
2486 rtableid = r->rtableid;
2487 if (r->anchor == NULL) {
02742ec6 2488 rm = r;
70224baa
JL
2489 } else
2490 pf_step_into_anchor(&asd, &ruleset, rs_num,
2491 &r, NULL, NULL);
2492 }
2493 if (r == NULL)
2494 pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r,
2495 NULL, NULL);
02742ec6 2496 }
70224baa
JL
2497 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid))
2498 return (NULL);
02742ec6
JS
2499 if (rm != NULL && (rm->action == PF_NONAT ||
2500 rm->action == PF_NORDR || rm->action == PF_NOBINAT))
2501 return (NULL);
2502 return (rm);
2503}
2504
2505struct pf_rule *
2506pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
2507 struct pfi_kif *kif, struct pf_src_node **sn,
2508 struct pf_addr *saddr, u_int16_t sport,
2509 struct pf_addr *daddr, u_int16_t dport,
2510 struct pf_addr *naddr, u_int16_t *nport)
2511{
2512 struct pf_rule *r = NULL;
2513
2514 if (direction == PF_OUT) {
2515 r = pf_match_translation(pd, m, off, direction, kif, saddr,
2516 sport, daddr, dport, PF_RULESET_BINAT);
2517 if (r == NULL)
2518 r = pf_match_translation(pd, m, off, direction, kif,
2519 saddr, sport, daddr, dport, PF_RULESET_NAT);
2520 } else {
2521 r = pf_match_translation(pd, m, off, direction, kif, saddr,
2522 sport, daddr, dport, PF_RULESET_RDR);
2523 if (r == NULL)
2524 r = pf_match_translation(pd, m, off, direction, kif,
2525 saddr, sport, daddr, dport, PF_RULESET_BINAT);
2526 }
2527
2528 if (r != NULL) {
2529 switch (r->action) {
2530 case PF_NONAT:
2531 case PF_NOBINAT:
2532 case PF_NORDR:
2533 return (NULL);
2534 case PF_NAT:
2535 if (pf_get_sport(pd->af, pd->proto, r, saddr,
2536 daddr, dport, naddr, nport, r->rpool.proxy_port[0],
2537 r->rpool.proxy_port[1], sn)) {
2538 DPFPRINTF(PF_DEBUG_MISC,
2539 ("pf: NAT proxy port allocation "
2540 "(%u-%u) failed\n",
2541 r->rpool.proxy_port[0],
2542 r->rpool.proxy_port[1]));
2543 return (NULL);
2544 }
2545 break;
2546 case PF_BINAT:
2547 switch (direction) {
2548 case PF_OUT:
2549 if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){
70224baa
JL
2550 switch (pd->af) {
2551#ifdef INET
2552 case AF_INET:
02742ec6
JS
2553 if (r->rpool.cur->addr.p.dyn->
2554 pfid_acnt4 < 1)
2555 return (NULL);
2556 PF_POOLMASK(naddr,
2557 &r->rpool.cur->addr.p.dyn->
2558 pfid_addr4,
2559 &r->rpool.cur->addr.p.dyn->
2560 pfid_mask4,
2561 saddr, AF_INET);
70224baa
JL
2562 break;
2563#endif /* INET */
2564#ifdef INET6
2565 case AF_INET6:
02742ec6
JS
2566 if (r->rpool.cur->addr.p.dyn->
2567 pfid_acnt6 < 1)
2568 return (NULL);
2569 PF_POOLMASK(naddr,
2570 &r->rpool.cur->addr.p.dyn->
2571 pfid_addr6,
2572 &r->rpool.cur->addr.p.dyn->
2573 pfid_mask6,
2574 saddr, AF_INET6);
70224baa
JL
2575 break;
2576#endif /* INET6 */
02742ec6
JS
2577 }
2578 } else
2579 PF_POOLMASK(naddr,
2580 &r->rpool.cur->addr.v.a.addr,
2581 &r->rpool.cur->addr.v.a.mask,
2582 saddr, pd->af);
2583 break;
2584 case PF_IN:
70224baa
JL
2585 if (r->src.addr.type == PF_ADDR_DYNIFTL) {
2586 switch (pd->af) {
2587#ifdef INET
2588 case AF_INET:
02742ec6
JS
2589 if (r->src.addr.p.dyn->
2590 pfid_acnt4 < 1)
2591 return (NULL);
2592 PF_POOLMASK(naddr,
2593 &r->src.addr.p.dyn->
2594 pfid_addr4,
2595 &r->src.addr.p.dyn->
2596 pfid_mask4,
2597 daddr, AF_INET);
70224baa
JL
2598 break;
2599#endif /* INET */
2600#ifdef INET6
2601 case AF_INET6:
02742ec6
JS
2602 if (r->src.addr.p.dyn->
2603 pfid_acnt6 < 1)
2604 return (NULL);
2605 PF_POOLMASK(naddr,
2606 &r->src.addr.p.dyn->
2607 pfid_addr6,
2608 &r->src.addr.p.dyn->
2609 pfid_mask6,
2610 daddr, AF_INET6);
70224baa
JL
2611 break;
2612#endif /* INET6 */
02742ec6
JS
2613 }
2614 } else
2615 PF_POOLMASK(naddr,
2616 &r->src.addr.v.a.addr,
2617 &r->src.addr.v.a.mask, daddr,
2618 pd->af);
2619 break;
2620 }
2621 break;
2622 case PF_RDR: {
70224baa 2623 if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn))
02742ec6 2624 return (NULL);
70224baa
JL
2625 if ((r->rpool.opts & PF_POOL_TYPEMASK) ==
2626 PF_POOL_BITMASK)
2627 PF_POOLMASK(naddr, naddr,
2628 &r->rpool.cur->addr.v.a.mask, daddr,
2629 pd->af);
02742ec6
JS
2630 if (r->rpool.proxy_port[1]) {
2631 u_int32_t tmp_nport;
2632
2633 tmp_nport = ((ntohs(dport) -
2634 ntohs(r->dst.port[0])) %
2635 (r->rpool.proxy_port[1] -
2636 r->rpool.proxy_port[0] + 1)) +
2637 r->rpool.proxy_port[0];
2638
2639 /* wrap around if necessary */
2640 if (tmp_nport > 65535)
2641 tmp_nport -= 65535;
2642 *nport = htons((u_int16_t)tmp_nport);
2643 } else if (r->rpool.proxy_port[0])
2644 *nport = htons(r->rpool.proxy_port[0]);
2645 break;
2646 }
2647 default:
2648 return (NULL);
2649 }
2650 }
2651
2652 return (r);
2653}
2654
2655#ifdef SMP
2656struct netmsg_hashlookup {
4599cf19 2657 struct netmsg nm_netmsg;
02742ec6
JS
2658 struct inpcb **nm_pinp;
2659 struct inpcbinfo *nm_pcbinfo;
2660 struct pf_addr *nm_saddr;
2661 struct pf_addr *nm_daddr;
2662 uint16_t nm_sport;
2663 uint16_t nm_dport;
2664 sa_family_t nm_af;
2665};
2666
4599cf19
MD
2667static void
2668in_pcblookup_hash_handler(struct netmsg *msg0)
02742ec6
JS
2669{
2670 struct netmsg_hashlookup *msg = (struct netmsg_hashlookup *)msg0;
2671
2672 if (msg->nm_af == AF_INET)
2673 *msg->nm_pinp = in_pcblookup_hash(msg->nm_pcbinfo,
2674 msg->nm_saddr->v4, msg->nm_sport, msg->nm_daddr->v4,
2675 msg->nm_dport, INPLOOKUP_WILDCARD, NULL);
2676#ifdef INET6
2677 else
2678 *msg->nm_pinp = in6_pcblookup_hash(msg->nm_pcbinfo,
2679 &msg->nm_saddr->v6, msg->nm_sport, &msg->nm_daddr->v6,
2680 msg->nm_dport, INPLOOKUP_WILDCARD, NULL);
2681#endif /* INET6 */
4599cf19 2682 lwkt_replymsg(&msg->nm_netmsg.nm_lmsg, 0);
02742ec6
JS
2683}
2684#endif /* SMP */
2685
2686int
70224baa 2687pf_socket_lookup(int direction, struct pf_pdesc *pd, struct inpcb *inp_arg)
02742ec6
JS
2688{
2689 struct pf_addr *saddr, *daddr;
2690 u_int16_t sport, dport;
2691 struct inpcbinfo *pi;
2692 struct inpcb *inp;
2693#ifdef SMP
2694 struct netmsg_hashlookup *msg = NULL;
2695#endif
2696 int pi_cpu = 0;
2697
70224baa
JL
2698 if (pd == NULL)
2699 return (-1);
2700 pd->lookup.uid = UID_MAX;
2701 pd->lookup.gid = GID_MAX;
2702 pd->lookup.pid = NO_PID;
02742ec6
JS
2703 if (direction == PF_IN) {
2704 saddr = pd->src;
2705 daddr = pd->dst;
2706 } else {
2707 saddr = pd->dst;
2708 daddr = pd->src;
2709 }
2710 switch (pd->proto) {
2711 case IPPROTO_TCP:
2712 sport = pd->hdr.tcp->th_sport;
2713 dport = pd->hdr.tcp->th_dport;
2714
2715 pi_cpu = tcp_addrcpu(saddr->v4.s_addr, sport, daddr->v4.s_addr, dport);
2716 pi = &tcbinfo[pi_cpu];
2717#ifdef SMP
2718 /*
2719 * Our netstack runs lockless on MP systems
2720 * (only for TCP connections at the moment).
2721 *
2722 * As we are not allowed to read another CPU's tcbinfo,
2723 * we have to ask that CPU via remote call to search the
2724 * table for us.
2725 *
2726 * Prepare a msg iff data belongs to another CPU.
2727 */
2728 if (pi_cpu != mycpu->gd_cpuid) {
efda3bd0 2729 msg = kmalloc(sizeof(*msg), M_LWKTMSG, M_INTWAIT);
48e7b118
MD
2730 netmsg_init(&msg->nm_netmsg, NULL, &netisr_afree_rport,
2731 0, in_pcblookup_hash_handler);
02742ec6
JS
2732 msg->nm_pinp = &inp;
2733 msg->nm_pcbinfo = pi;
2734 msg->nm_saddr = saddr;
2735 msg->nm_sport = sport;
2736 msg->nm_daddr = daddr;
2737 msg->nm_dport = dport;
2738 msg->nm_af = pd->af;
2739 }
2740#endif /* SMP */
2741 break;
2742 case IPPROTO_UDP:
2743 sport = pd->hdr.udp->uh_sport;
2744 dport = pd->hdr.udp->uh_dport;
2745 pi = &udbinfo;
2746 break;
2747 default:
2748 return (0);
2749 }
2750 if (direction != PF_IN) {
2751 u_int16_t p;
2752
2753 p = sport;
2754 sport = dport;
2755 dport = p;
2756 }
2757 switch (pd->af) {
2758#ifdef INET6
2759 case AF_INET6:
2760#ifdef SMP
2761 /*
2762 * Query other CPU, second part
2763 *
2764 * msg only gets initialized when:
2765 * 1) packet is TCP
2766 * 2) the info belongs to another CPU
2767 *
2768 * Use some switch/case magic to avoid code duplication.
2769 */
2770 if (msg == NULL)
2771#endif /* SMP */
2772 {
2773 inp = in6_pcblookup_hash(pi, &saddr->v6, sport,
2774 &daddr->v6, dport, INPLOOKUP_WILDCARD, NULL);
2775
2776 if (inp == NULL)
70224baa 2777 return (-1);
02742ec6
JS
2778 break;
2779 }
2780 /* FALLTHROUGH if SMP and on other CPU */
2781#endif /* INET6 */
2782 case AF_INET:
2783#ifdef SMP
2784 if (msg != NULL) {
4599cf19
MD
2785 lwkt_sendmsg(tcp_cport(pi_cpu),
2786 &msg->nm_netmsg.nm_lmsg);
02742ec6
JS
2787 } else
2788#endif /* SMP */
2789 {
2790 inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4,
2791 dport, INPLOOKUP_WILDCARD, NULL);
2792 }
2793 if (inp == NULL)
2794 return (0);
2795 break;
2796
2797 default:
70224baa 2798 return (-1);
02742ec6 2799 }
70224baa
JL
2800 pd->lookup.uid = inp->inp_socket->so_cred->cr_uid;
2801 pd->lookup.gid = inp->inp_socket->so_cred->cr_groups[0];
02742ec6
JS
2802 return (1);
2803}
2804
2805u_int8_t
2806pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
2807{
2808 int hlen;
2809 u_int8_t hdr[60];
2810 u_int8_t *opt, optlen;
2811 u_int8_t wscale = 0;
2812
2813 hlen = th_off << 2; /* hlen <= sizeof(hdr) */
2814 if (hlen <= sizeof(struct tcphdr))
2815 return (0);
2816 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
2817 return (0);
2818 opt = hdr + sizeof(struct tcphdr);
2819 hlen -= sizeof(struct tcphdr);
2820 while (hlen >= 3) {
2821 switch (*opt) {
2822 case TCPOPT_EOL:
2823 case TCPOPT_NOP:
2824 ++opt;
2825 --hlen;
2826 break;
2827 case TCPOPT_WINDOW:
2828 wscale = opt[2];
2829 if (wscale > TCP_MAX_WINSHIFT)
2830 wscale = TCP_MAX_WINSHIFT;
2831 wscale |= PF_WSCALE_FLAG;
2832 /* FALLTHROUGH */
2833 default:
2834 optlen = opt[1];
2835 if (optlen < 2)
2836 optlen = 2;
2837 hlen -= optlen;
2838 opt += optlen;
2839 break;
2840 }
2841 }
2842 return (wscale);
2843}
2844
2845u_int16_t
2846pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
2847{
2848 int hlen;
2849 u_int8_t hdr[60];
2850 u_int8_t *opt, optlen;
2851 u_int16_t mss = tcp_mssdflt;
2852
2853 hlen = th_off << 2; /* hlen <= sizeof(hdr) */
2854 if (hlen <= sizeof(struct tcphdr))
2855 return (0);
2856 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
2857 return (0);
2858 opt = hdr + sizeof(struct tcphdr);
2859 hlen -= sizeof(struct tcphdr);
2860 while (hlen >= TCPOLEN_MAXSEG) {
2861 switch (*opt) {
2862 case TCPOPT_EOL:
2863 case TCPOPT_NOP:
2864 ++opt;
2865 --hlen;
2866 break;
2867 case TCPOPT_MAXSEG:
2868 bcopy((caddr_t)(opt + 2), (caddr_t)&mss, 2);
70224baa 2869 NTOHS(mss);
02742ec6
JS
2870 /* FALLTHROUGH */
2871 default:
2872 optlen = opt[1];
2873 if (optlen < 2)
2874 optlen = 2;
2875 hlen -= optlen;
2876 opt += optlen;
2877 break;
2878 }
2879 }
2880 return (mss);
2881}
2882
2883u_int16_t
2884pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer)
2885{
2886#ifdef INET
2887 struct sockaddr_in *dst;
2888 struct route ro;
2889#endif /* INET */
2890#ifdef INET6
2891 struct sockaddr_in6 *dst6;
2892 struct route_in6 ro6;
2893#endif /* INET6 */
2894 struct rtentry *rt = NULL;
2895 int hlen = 0;
2896 u_int16_t mss = tcp_mssdflt;
2897
2898 switch (af) {
2899#ifdef INET
2900 case AF_INET:
2901 hlen = sizeof(struct ip);
2902 bzero(&ro, sizeof(ro));
2903 dst = (struct sockaddr_in *)&ro.ro_dst;
2904 dst->sin_family = AF_INET;
2905 dst->sin_len = sizeof(*dst);
2906 dst->sin_addr = addr->v4;
2907 rtalloc_ign(&ro, (RTF_CLONING | RTF_PRCLONING));
2908 rt = ro.ro_rt;
2909 break;
2910#endif /* INET */
2911#ifdef INET6
2912 case AF_INET6:
2913 hlen = sizeof(struct ip6_hdr);
2914 bzero(&ro6, sizeof(ro6));
2915 dst6 = (struct sockaddr_in6 *)&ro6.ro_dst;
2916 dst6->sin6_family = AF_INET6;
2917 dst6->sin6_len = sizeof(*dst6);
2918 dst6->sin6_addr = addr->v6;
2919 rtalloc_ign((struct route *)&ro6, (RTF_CLONING | RTF_PRCLONING));
2920 rt = ro6.ro_rt;
2921 break;
2922#endif /* INET6 */
2923 }
2924
2925 if (rt && rt->rt_ifp) {
2926 mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr);
2927 mss = max(tcp_mssdflt, mss);
2928 RTFREE(rt);
2929 }
2930 mss = min(mss, offer);
2931 mss = max(mss, 64); /* sanity - at least max opt space */
2932 return (mss);
2933}
2934
2935void
2936pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr)
2937{
2938 struct pf_rule *r = s->rule.ptr;
2939
2940 s->rt_kif = NULL;
2941 if (!r->rt || r->rt == PF_FASTROUTE)
2942 return;
2943 switch (s->af) {
2944#ifdef INET
2945 case AF_INET:
2946 pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL,
2947 &s->nat_src_node);
2948 s->rt_kif = r->rpool.cur->kif;
2949 break;
2950#endif /* INET */
2951#ifdef INET6
2952 case AF_INET6:
2953 pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL,
2954 &s->nat_src_node);
2955 s->rt_kif = r->rpool.cur->kif;
2956 break;
2957#endif /* INET6 */
2958 }
2959}
2960
2961int
2962pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
2963 struct pfi_kif *kif, struct mbuf *m, int off, void *h,
70224baa
JL
2964 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
2965 struct ifqueue *ifq, struct inpcb *inp)
02742ec6
JS
2966{
2967 struct pf_rule *nr = NULL;
2968 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
2969 struct tcphdr *th = pd->hdr.tcp;
2970 u_int16_t bport, nport = 0;
2971 sa_family_t af = pd->af;
02742ec6
JS
2972 struct pf_rule *r, *a = NULL;
2973 struct pf_ruleset *ruleset = NULL;
2974 struct pf_src_node *nsn = NULL;
2975 u_short reason;
2976 int rewrite = 0;
70224baa
JL
2977 int tag = -1, rtableid = -1;
2978 u_int16_t mss = tcp_mssdflt;
2979 int asd = 0;
2980 int match = 0;
2981
2982 if (pf_check_congestion(ifq)) {
2983 REASON_SET(&reason, PFRES_CONGEST);
2984 return (PF_DROP);
2985 }
2986
2987 if (inp != NULL)
2988 pd->lookup.done = pf_socket_lookup(direction, pd, inp);
2989 else if (debug_pfugidhack) {
2990 crit_exit();
2991 DPFPRINTF(PF_DEBUG_MISC, ("pf: unlocked lookup\n"));
2992 pd->lookup.done = pf_socket_lookup(direction, pd, inp);
2993 crit_enter();
2994 }
2995
02742ec6
JS
2996
2997 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
2998
2999 if (direction == PF_OUT) {
3000 bport = nport = th->th_sport;
3001 /* check outgoing packet for BINAT/NAT */
3002 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
3003 saddr, th->th_sport, daddr, th->th_dport,
3004 &pd->naddr, &nport)) != NULL) {
3005 PF_ACPY(&pd->baddr, saddr, af);
3006 pf_change_ap(saddr, &th->th_sport, pd->ip_sum,
3007 &th->th_sum, &pd->naddr, nport, 0, af);
3008 rewrite++;
3009 if (nr->natpass)
3010 r = NULL;
3011 pd->nat_rule = nr;
3012 }
3013 } else {
3014 bport = nport = th->th_dport;
3015 /* check incoming packet for BINAT/RDR */
3016 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
3017 saddr, th->th_sport, daddr, th->th_dport,
3018 &pd->naddr, &nport)) != NULL) {
3019 PF_ACPY(&pd->baddr, daddr, af);
3020 pf_change_ap(daddr, &th->th_dport, pd->ip_sum,
3021 &th->th_sum, &pd->naddr, nport, 0, af);
3022 rewrite++;
3023 if (nr->natpass)
3024 r = NULL;
3025 pd->nat_rule = nr;
3026 }
3027 }
3028
3029 while (r != NULL) {
3030 r->evaluations++;
70224baa 3031 if (pfi_kif_match(r->kif, kif) == r->ifnot)
02742ec6
JS
3032 r = r->skip[PF_SKIP_IFP].ptr;
3033 else if (r->direction && r->direction != direction)
3034 r = r->skip[PF_SKIP_DIR].ptr;
3035 else if (r->af && r->af != af)
3036 r = r->skip[PF_SKIP_AF].ptr;
3037 else if (r->proto && r->proto != IPPROTO_TCP)
3038 r = r->skip[PF_SKIP_PROTO].ptr;
70224baa
JL
3039 else if (PF_MISMATCHAW(&r->src.addr, saddr, af,
3040 r->src.neg, kif))
02742ec6
JS
3041 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3042 else if (r->src.port_op && !pf_match_port(r->src.port_op,
3043 r->src.port[0], r->src.port[1], th->th_sport))
3044 r = r->skip[PF_SKIP_SRC_PORT].ptr;
70224baa
JL
3045 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af,
3046 r->dst.neg, NULL))
02742ec6
JS
3047 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3048 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
3049 r->dst.port[0], r->dst.port[1], th->th_dport))
3050 r = r->skip[PF_SKIP_DST_PORT].ptr;
70224baa 3051 else if (r->tos && !(r->tos == pd->tos))
02742ec6
JS
3052 r = TAILQ_NEXT(r, entries);
3053 else if (r->rule_flag & PFRULE_FRAGMENT)
3054 r = TAILQ_NEXT(r, entries);
3055 else if ((r->flagset & th->th_flags) != r->flags)
3056 r = TAILQ_NEXT(r, entries);
70224baa
JL
3057 else if (r->uid.op && (pd->lookup.done || (pd->lookup.done =
3058 pf_socket_lookup(direction, pd, inp), 1)) &&
02742ec6 3059 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
70224baa 3060 pd->lookup.uid))
02742ec6 3061 r = TAILQ_NEXT(r, entries);
70224baa
JL
3062 else if (r->gid.op && (pd->lookup.done || (pd->lookup.done =
3063 pf_socket_lookup(direction, pd, inp), 1)) &&
02742ec6 3064 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
70224baa 3065 pd->lookup.gid))
02742ec6 3066 r = TAILQ_NEXT(r, entries);
75fda04a
MD
3067 else if (r->prob && r->prob <= karc4random())
3068 r = TAILQ_NEXT(r, entries);
70224baa 3069 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
02742ec6
JS
3070 r = TAILQ_NEXT(r, entries);
3071 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match(
3072 pf_osfp_fingerprint(pd, m, off, th), r->os_fingerprint))
3073 r = TAILQ_NEXT(r, entries);
3074 else {
3075 if (r->tag)
3076 tag = r->tag;
70224baa
JL
3077 if (r->rtableid >= 0)
3078 rtableid = r->rtableid;
02742ec6 3079 if (r->anchor == NULL) {
70224baa 3080 match = 1;
02742ec6
JS
3081 *rm = r;
3082 *am = a;
3083 *rsm = ruleset;
3084 if ((*rm)->quick)
3085 break;
3086 r = TAILQ_NEXT(r, entries);
3087 } else
70224baa
JL
3088 pf_step_into_anchor(&asd, &ruleset,
3089 PF_RULESET_FILTER, &r, &a, &match);
02742ec6 3090 }
70224baa
JL
3091 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
3092 PF_RULESET_FILTER, &r, &a, &match))
3093 break;
02742ec6
JS
3094 }
3095 r = *rm;
3096 a = *am;
3097 ruleset = *rsm;
3098
3099 REASON_SET(&reason, PFRES_MATCH);
3100
70224baa 3101 if (r->log || (nr != NULL && nr->natpass && nr->log)) {
02742ec6
JS
3102 if (rewrite)
3103 m_copyback(m, off, sizeof(*th), (caddr_t)th);
70224baa
JL
3104 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr,
3105 a, ruleset, pd);
02742ec6
JS
3106 }
3107
3108 if ((r->action == PF_DROP) &&
3109 ((r->rule_flag & PFRULE_RETURNRST) ||
3110 (r->rule_flag & PFRULE_RETURNICMP) ||
3111 (r->rule_flag & PFRULE_RETURN))) {
3112 /* undo NAT changes, if they have taken place */
3113 if (nr != NULL) {
3114 if (direction == PF_OUT) {
3115 pf_change_ap(saddr, &th->th_sport, pd->ip_sum,
3116 &th->th_sum, &pd->baddr, bport, 0, af);
3117 rewrite++;
3118 } else {
3119 pf_change_ap(daddr, &th->th_dport, pd->ip_sum,
3120 &th->th_sum, &pd->baddr, bport, 0, af);
3121 rewrite++;
3122 }
3123 }
3124 if (((r->rule_flag & PFRULE_RETURNRST) ||
3125 (r->rule_flag & PFRULE_RETURN)) &&
3126 !(th->th_flags & TH_RST)) {
3127 u_int32_t ack = ntohl(th->th_seq) + pd->p_len;
3128
3129 if (th->th_flags & TH_SYN)
3130 ack++;
3131 if (th->th_flags & TH_FIN)
3132 ack++;
3133 pf_send_tcp(r, af, pd->dst,
3134 pd->src, th->th_dport, th->th_sport,
3135 ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0,
70224baa 3136 r->return_ttl, 1, 0, pd->eh, kif->pfik_ifp);
02742ec6
JS
3137 } else if ((af == AF_INET) && r->return_icmp)
3138 pf_send_icmp(m, r->return_icmp >> 8,
3139 r->return_icmp & 255, af, r);
3140 else if ((af == AF_INET6) && r->return_icmp6)
3141 pf_send_icmp(m, r->return_icmp6 >> 8,
3142 r->return_icmp6 & 255, af, r);
3143 }
3144
70224baa 3145 if (r->action == PF_DROP) {
02742ec6 3146 return (PF_DROP);
70224baa 3147 }
02742ec6 3148
70224baa
JL
3149 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) {
3150 REASON_SET(&reason, PFRES_MEMORY);
3151 return (PF_DROP);
3152 }
02742ec6
JS
3153
3154 if (r->keep_state || nr != NULL ||
3155 (pd->flags & PFDESC_TCP_NORM)) {
3156 /* create new state */
3157 u_int16_t len;
3158 struct pf_state *s = NULL;
3159 struct pf_src_node *sn = NULL;
3160
3161 len = pd->tot_len - off - (th->th_off << 2);
3162
3163 /* check maximums */
70224baa
JL
3164 if (r->max_states && (r->states >= r->max_states)) {
3165 pf_status.lcounters[LCNT_STATES]++;
3166 REASON_SET(&reason, PFRES_MAXSTATES);
02742ec6 3167 goto cleanup;
70224baa
JL
3168 }
3169 /* src node for filter rule */
02742ec6
JS
3170 if ((r->rule_flag & PFRULE_SRCTRACK ||
3171 r->rpool.opts & PF_POOL_STICKYADDR) &&
70224baa
JL
3172 pf_insert_src_node(&sn, r, saddr, af) != 0) {
3173 REASON_SET(&reason, PFRES_SRCLIMIT);
02742ec6 3174 goto cleanup;
70224baa 3175 }
02742ec6
JS
3176 /* src node for translation rule */
3177 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
3178 ((direction == PF_OUT &&
3179 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
70224baa
JL
3180 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) {
3181 REASON_SET(&reason, PFRES_SRCLIMIT);
02742ec6 3182 goto cleanup;
70224baa 3183 }
02742ec6
JS
3184 s = pool_get(&pf_state_pl, PR_NOWAIT);
3185 if (s == NULL) {
70224baa 3186 REASON_SET(&reason, PFRES_MEMORY);
02742ec6
JS
3187cleanup:
3188 if (sn != NULL && sn->states == 0 && sn->expire == 0) {
3189 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
3190 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3191 pf_status.src_nodes--;
3192 pool_put(&pf_src_tree_pl, sn);
3193 }
3194 if (nsn != sn && nsn != NULL && nsn->states == 0 &&
3195 nsn->expire == 0) {
3196 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
3197 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3198 pf_status.src_nodes--;
3199 pool_put(&pf_src_tree_pl, nsn);
3200 }
02742ec6
JS
3201 return (PF_DROP);
3202 }
3203 bzero(s, sizeof(*s));
02742ec6
JS
3204 s->rule.ptr = r;
3205 s->nat_rule.ptr = nr;
02742ec6 3206 s->anchor.ptr = a;
70224baa 3207 STATE_INC_COUNTERS(s);
02742ec6 3208 s->allow_opts = r->allow_opts;
70224baa
JL
3209 s->log = r->log & PF_LOG_ALL;
3210 if (nr != NULL)
3211 s->log |= nr->log & PF_LOG_ALL;
02742ec6
JS
3212 s->proto = IPPROTO_TCP;
3213 s->direction = direction;
3214 s->af = af;
3215 if (direction == PF_OUT) {
3216 PF_ACPY(&s->gwy.addr, saddr, af);
3217 s->gwy.port = th->th_sport; /* sport */
3218 PF_ACPY(&s->ext.addr, daddr, af);
3219 s->ext.port = th->th_dport;
3220 if (nr != NULL) {
3221 PF_ACPY(&s->lan.addr, &pd->baddr, af);
3222 s->lan.port = bport;
3223 } else {
3224 PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
3225 s->lan.port = s->gwy.port;
3226 }
3227 } else {
3228 PF_ACPY(&s->lan.addr, daddr, af);
3229 s->lan.port = th->th_dport;
3230 PF_ACPY(&s->ext.addr, saddr, af);
3231 s->ext.port = th->th_sport;
3232 if (nr != NULL) {
3233 PF_ACPY(&s->gwy.addr, &pd->baddr, af);
3234 s->gwy.port = bport;
3235 } else {
3236 PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
3237 s->gwy.port = s->lan.port;
3238 }
3239 }
3240
a814431a 3241 s->hash = pf_state_hash(s);
02742ec6
JS
3242 s->src.seqlo = ntohl(th->th_seq);
3243 s->src.seqhi = s->src.seqlo + len + 1;
a814431a
MD
3244 s->pickup_mode = r->pickup_mode;
3245
02742ec6
JS
3246 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
3247 r->keep_state == PF_STATE_MODULATE) {
3248 /* Generate sequence number modulator */
70224baa
JL
3249 while ((s->src.seqdiff =
3250 pf_new_isn(s) - s->src.seqlo) == 0)
02742ec6
JS
3251 ;
3252 pf_change_a(&th->th_seq, &th->th_sum,
3253 htonl(s->src.seqlo + s->src.seqdiff), 0);
3254 rewrite = 1;
3255 } else
3256 s->src.seqdiff = 0;
3257 if (th->th_flags & TH_SYN) {
3258 s->src.seqhi++;
3259 s->src.wscale = pf_get_wscale(m, off, th->th_off, af);
a814431a
MD
3260 s->sync_flags |= PFSTATE_GOT_SYN1;
3261 }
3262 s->src.max_win = MAX(ntohs(th->th_win), 1);
3263 if (s->src.wscale & PF_WSCALE_MASK) {
02742ec6 3264 /* Remove scale factor from initial window */
9aa13ad5 3265 u_int win = s->src.max_win;
02742ec6
JS
3266 win += 1 << (s->src.wscale & PF_WSCALE_MASK);
3267 s->src.max_win = (win - 1) >>
3268 (s->src.wscale & PF_WSCALE_MASK);
3269 }
3270 if (th->th_flags & TH_FIN)
3271 s->src.seqhi++;
3272 s->dst.seqhi = 1;
3273 s->dst.max_win = 1;
3274 s->src.state = TCPS_SYN_SENT;
3275 s->dst.state = TCPS_CLOSED;
3276 s->creation = time_second;
3277 s->expire = time_second;
3278 s->timeout = PFTM_TCP_FIRST_PACKET;
3279 pf_set_rt_ifp(s, saddr);
3280 if (sn != NULL) {
3281 s->src_node = sn;
3282 s->src_node->states++;
3283 }
3284 if (nsn != NULL) {
3285 PF_ACPY(&nsn->raddr, &pd->naddr, af);
3286 s->nat_src_node = nsn;
3287 s->nat_src_node->states++;
3288 }
3289 if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m,
3290 off, pd, th, &s->src, &s->dst)) {
3291 REASON_SET(&reason, PFRES_MEMORY);
3292 pf_src_tree_remove_state(s);
70224baa 3293 STATE_DEC_COUNTERS(s);
02742ec6
JS
3294 pool_put(&pf_state_pl, s);
3295 return (PF_DROP);
3296 }
3297 if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub &&
70224baa
JL
3298 pf_normalize_tcp_stateful(m, off, pd, &reason, th, s,
3299 &s->src, &s->dst, &rewrite)) {
3300 /* This really shouldn't happen!!! */
3301 DPFPRINTF(PF_DEBUG_URGENT,
3302 ("pf_normalize_tcp_stateful failed on first pkt"));
02742ec6
JS
3303 pf_normalize_tcp_cleanup(s);
3304 pf_src_tree_remove_state(s);
70224baa 3305 STATE_DEC_COUNTERS(s);
02742ec6
JS
3306 pool_put(&pf_state_pl, s);
3307 return (PF_DROP);
3308 }
3309 if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
3310 pf_normalize_tcp_cleanup(s);
70224baa 3311 REASON_SET(&reason, PFRES_STATEINS);
02742ec6 3312 pf_src_tree_remove_state(s);
70224baa 3313 STATE_DEC_COUNTERS(s);
02742ec6
JS
3314 pool_put(&pf_state_pl, s);
3315 return (PF_DROP);
3316 } else
3317 *sm = s;
70224baa
JL
3318 if (tag > 0) {
3319 pf_tag_ref(tag);
3320 s->tag = tag;
3321 }
02742ec6
JS
3322 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
3323 r->keep_state == PF_STATE_SYNPROXY) {
3324 s->src.state = PF_TCPS_PROXY_SRC;
3325 if (nr != NULL) {
3326 if (direction == PF_OUT) {
3327 pf_change_ap(saddr, &th->th_sport,
3328 pd->ip_sum, &th->th_sum, &pd->baddr,
3329 bport, 0, af);
3330 } else {
3331 pf_change_ap(daddr, &th->th_dport,
3332 pd->ip_sum, &th->th_sum, &pd->baddr,
3333 bport, 0, af);
3334 }
3335 }
70224baa 3336 s->src.seqhi = htonl(karc4random());
02742ec6
JS
3337 /* Find mss option */
3338 mss = pf_get_mss(m, off, th->th_off, af);
3339 mss = pf_calc_mss(saddr, af, mss);
3340 mss = pf_calc_mss(daddr, af, mss);
3341 s->src.mss = mss;
3342 pf_send_tcp(r, af, daddr, saddr, th->th_dport,
3343 th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1,
70224baa
JL
3344 TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, NULL, NULL);
3345 REASON_SET(&reason, PFRES_SYNPROXY);
02742ec6
JS
3346 return (PF_SYNPROXY_DROP);
3347 }
3348 }
3349
3350 /* copy back packet headers if we performed NAT operations */
3351 if (rewrite)
3352 m_copyback(m, off, sizeof(*th), (caddr_t)th);
3353
3354 return (PF_PASS);
3355}
3356
3357int
3358pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction,
3359 struct pfi_kif *kif, struct mbuf *m, int off, void *h,
70224baa
JL
3360 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
3361 struct ifqueue *ifq, struct inpcb *inp)
02742ec6
JS
3362{
3363 struct pf_rule *nr = NULL;
3364 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
3365 struct udphdr *uh = pd->hdr.udp;
3366 u_int16_t bport, nport = 0;
3367 sa_family_t af = pd->af;
02742ec6
JS
3368 struct pf_rule *r, *a = NULL;
3369 struct pf_ruleset *ruleset = NULL;
3370 struct pf_src_node *nsn = NULL;
3371 u_short reason;
3372 int rewrite = 0;
70224baa
JL
3373 int tag = -1, rtableid = -1;
3374 int asd = 0;
3375 int match = 0;
3376
3377 if (pf_check_congestion(ifq)) {
3378 REASON_SET(&reason, PFRES_CONGEST);
3379 return (PF_DROP);
3380 }
3381
3382 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
02742ec6
JS
3383
3384 if (direction == PF_OUT) {
3385 bport = nport = uh->uh_sport;
3386 /* check outgoing packet for BINAT/NAT */
3387 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
3388 saddr, uh->uh_sport, daddr, uh->uh_dport,
3389 &pd->naddr, &nport)) != NULL) {
3390 PF_ACPY(&pd->baddr, saddr, af);
3391 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum,
3392 &uh->uh_sum, &pd->naddr, nport, 1, af);
3393 rewrite++;
3394 if (nr->natpass)
3395 r = NULL;
3396 pd->nat_rule = nr;
3397 }
3398 } else {
3399 bport = nport = uh->uh_dport;
3400 /* check incoming packet for BINAT/RDR */
3401 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
3402 saddr, uh->uh_sport, daddr, uh->uh_dport, &pd->naddr,
3403 &nport)) != NULL) {
3404 PF_ACPY(&pd->baddr, daddr, af);
3405 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum,
3406 &uh->uh_sum, &pd->naddr, nport, 1, af);
3407 rewrite++;
3408 if (nr->natpass)
3409 r = NULL;
3410 pd->nat_rule = nr;
3411 }
3412 }
3413
3414 while (r != NULL) {
3415 r->evaluations++;
70224baa 3416 if (pfi_kif_match(r->kif, kif) == r->ifnot)
02742ec6
JS
3417 r = r->skip[PF_SKIP_IFP].ptr;
3418 else if (r->direction && r->direction != direction)
3419 r = r->skip[PF_SKIP_DIR].ptr;
3420 else if (r->af && r->af != af)
3421 r = r->skip[PF_SKIP_AF].ptr;
3422 else if (r->proto && r->proto != IPPROTO_UDP)
3423 r = r->skip[PF_SKIP_PROTO].ptr;
70224baa
JL
3424 else if (PF_MISMATCHAW(&r->src.addr, saddr, af,
3425 r->src.neg, kif))
02742ec6
JS
3426 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3427 else if (r->src.port_op && !pf_match_port(r->src.port_op,
3428 r->src.port[0], r->src.port[1], uh->uh_sport))
3429 r = r->skip[PF_SKIP_SRC_PORT].ptr;
70224baa
JL
3430 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af,
3431 r->dst.neg, NULL))
02742ec6
JS
3432 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3433 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
3434 r->dst.port[0], r->dst.port[1], uh->uh_dport))
3435 r = r->skip[PF_SKIP_DST_PORT].ptr;
70224baa 3436 else if (r->tos && !(r->tos == pd->tos))
02742ec6
JS
3437 r = TAILQ_NEXT(r, entries);
3438 else if (r->rule_flag & PFRULE_FRAGMENT)
3439 r = TAILQ_NEXT(r, entries);
70224baa
JL
3440 else if (r->uid.op && (pd->lookup.done || (pd->lookup.done =
3441 pf_socket_lookup(direction, pd, inp), 1)) &&
02742ec6 3442 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
70224baa 3443 pd->lookup.uid))
02742ec6 3444 r = TAILQ_NEXT(r, entries);
70224baa
JL
3445 else if (r->gid.op && (pd->lookup.done || (pd->lookup.done =
3446 pf_socket_lookup(direction, pd, inp), 1)) &&
02742ec6 3447 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
70224baa 3448 pd->lookup.gid))
02742ec6 3449 r = TAILQ_NEXT(r, entries);
75fda04a
MD
3450 else if (r->prob && r->prob <= karc4random())
3451 r = TAILQ_NEXT(r, entries);
70224baa 3452 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
02742ec6
JS
3453 r = TAILQ_NEXT(r, entries);
3454 else if (r->os_fingerprint != PF_OSFP_ANY)
3455 r = TAILQ_NEXT(r, entries);
3456 else {
3457 if (r->tag)
3458 tag = r->tag;
70224baa
JL
3459 if (r->rtableid >= 0)
3460 rtableid = r->rtableid;
02742ec6 3461 if (r->anchor == NULL) {
70224baa 3462 match = 1;
02742ec6
JS
3463 *rm = r;
3464 *am = a;
3465 *rsm = ruleset;
3466 if ((*rm)->quick)
3467 break;
3468 r = TAILQ_NEXT(r, entries);
3469 } else
70224baa
JL
3470 pf_step_into_anchor(&asd, &ruleset,
3471 PF_RULESET_FILTER, &r, &a, &match);
02742ec6 3472 }
70224baa
JL
3473 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
3474 PF_RULESET_FILTER, &r, &a, &match))
3475 break;
02742ec6
JS
3476 }
3477 r = *rm;
3478 a = *am;
3479 ruleset = *rsm;
3480
3481 REASON_SET(&reason, PFRES_MATCH);
3482
70224baa 3483 if (r->log || (nr != NULL && nr->natpass && nr->log)) {
02742ec6
JS
3484 if (rewrite)
3485 m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
70224baa
JL
3486 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr,
3487 a, ruleset, pd);
02742ec6
JS
3488 }
3489
3490 if ((r->action == PF_DROP) &&
3491 ((r->rule_flag & PFRULE_RETURNICMP) ||
3492 (r->rule_flag & PFRULE_RETURN))) {
3493 /* undo NAT changes, if they have taken place */
3494 if (nr != NULL) {
3495 if (direction == PF_OUT) {
3496 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum,
3497 &uh->uh_sum, &pd->baddr, bport, 1, af);
3498 rewrite++;
3499 } else {
3500 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum,
3501 &uh->uh_sum, &pd->baddr, bport, 1, af);
3502 rewrite++;
3503 }
3504 }
3505 if ((af == AF_INET) && r->return_icmp)
3506 pf_send_icmp(m, r->return_icmp >> 8,
3507 r->return_icmp & 255, af, r);
3508 else if ((af == AF_INET6) && r->return_icmp6)
3509 pf_send_icmp(m, r->return_icmp6 >> 8,
3510 r->return_icmp6 & 255, af, r);
3511 }
3512
3513 if (r->action == PF_DROP)
3514 return (PF_DROP);
3515
70224baa
JL
3516 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) {
3517 REASON_SET(&reason, PFRES_MEMORY);
3518 return (PF_DROP);
3519 }
02742ec6
JS
3520
3521 if (r->keep_state || nr != NULL) {
3522 /* create new state */
3523 struct pf_state *s = NULL;
3524 struct pf_src_node *sn = NULL;
3525
3526 /* check maximums */
70224baa
JL
3527 if (r->max_states && (r->states >= r->max_states)) {
3528 pf_status.lcounters[LCNT_STATES]++;
3529 REASON_SET(&reason, PFRES_MAXSTATES);
02742ec6 3530 goto cleanup;
70224baa
JL
3531 }
3532 /* src node for filter rule */
02742ec6
JS
3533 if ((r->rule_flag & PFRULE_SRCTRACK ||
3534 r->rpool.opts & PF_POOL_STICKYADDR) &&
70224baa
JL
3535 pf_insert_src_node(&sn, r, saddr, af) != 0) {
3536 REASON_SET(&reason, PFRES_SRCLIMIT);
02742ec6 3537 goto cleanup;
70224baa 3538 }
02742ec6
JS
3539 /* src node for translation rule */
3540 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
3541 ((direction == PF_OUT &&
3542 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
70224baa
JL
3543 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) {
3544 REASON_SET(&reason, PFRES_SRCLIMIT);
02742ec6 3545 goto cleanup;
70224baa 3546 }
02742ec6
JS
3547 s = pool_get(&pf_state_pl, PR_NOWAIT);
3548 if (s == NULL) {
70224baa 3549 REASON_SET(&reason, PFRES_MEMORY);
02742ec6
JS
3550cleanup:
3551 if (sn != NULL && sn->states == 0 && sn->expire == 0) {
3552 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
3553 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3554 pf_status.src_nodes--;
3555 pool_put(&pf_src_tree_pl, sn);
3556 }
3557 if (nsn != sn && nsn != NULL && nsn->states == 0 &&
3558 nsn->expire == 0) {
3559 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
3560 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3561 pf_status.src_nodes--;
3562 pool_put(&pf_src_tree_pl, nsn);
3563 }
02742ec6
JS
3564 return (PF_DROP);
3565 }
3566 bzero(s, sizeof(*s));
02742ec6
JS
3567 s->rule.ptr = r;
3568 s->nat_rule.ptr = nr;
02742ec6 3569 s->anchor.ptr = a;
70224baa 3570 STATE_INC_COUNTERS(s);
02742ec6 3571 s->allow_opts = r->allow_opts;
70224baa
JL
3572 s->log = r->log & PF_LOG_ALL;
3573 if (nr != NULL)
3574 s->log |= nr->log & PF_LOG_ALL;
02742ec6
JS
3575 s->proto = IPPROTO_UDP;
3576 s->direction = direction;
3577 s->af = af;
3578 if (direction == PF_OUT) {
3579 PF_ACPY(&s->gwy.addr, saddr, af);
3580 s->gwy.port = uh->uh_sport;
3581 PF_ACPY(&s->ext.addr, daddr, af);
3582 s->ext.port = uh->uh_dport;
3583 if (nr != NULL) {
3584 PF_ACPY(&s->lan.addr, &pd->baddr, af);
3585 s->lan.port = bport;
3586 } else {
3587 PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
3588 s->lan.port = s->gwy.port;
3589 }
3590 } else {
3591 PF_ACPY(&s->lan.addr, daddr, af);
3592 s->lan.port = uh->uh_dport;
3593 PF_ACPY(&s->ext.addr, saddr, af);
3594 s->ext.port = uh->uh_sport;
3595 if (nr != NULL) {
3596 PF_ACPY(&s->gwy.addr, &pd->baddr, af);
3597 s->gwy.port = bport;
3598 } else {
3599 PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
3600 s->gwy.port = s->lan.port;
3601 }
3602 }
a814431a 3603 s->hash = pf_state_hash(s);
02742ec6
JS
3604 s->src.state = PFUDPS_SINGLE;
3605 s->dst.state = PFUDPS_NO_TRAFFIC;
3606 s->creation = time_second;
3607 s->expire = time_second;
3608 s->timeout = PFTM_UDP_FIRST_PACKET;
3609 pf_set_rt_ifp(s, saddr);
3610 if (sn != NULL) {
3611 s->src_node = sn;
3612 s->src_node->states++;
3613 }
3614 if (nsn != NULL) {
3615 PF_ACPY(&nsn->raddr, &pd->naddr, af);
3616 s->nat_src_node = nsn;
3617 s->nat_src_node->states++;
3618 }
3619 if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
70224baa 3620 REASON_SET(&reason, PFRES_STATEINS);
02742ec6 3621 pf_src_tree_remove_state(s);
70224baa 3622 STATE_DEC_COUNTERS(s);
02742ec6
JS
3623 pool_put(&pf_state_pl, s);
3624 return (PF_DROP);
3625 } else
3626 *sm = s;
70224baa
JL
3627 if (tag > 0) {
3628 pf_tag_ref(tag);
3629 s->tag = tag;
3630 }
02742ec6
JS
3631 }
3632
3633 /* copy back packet headers if we performed NAT operations */
3634 if (rewrite)
3635 m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
3636
3637 return (PF_PASS);
3638}
3639
3640int
3641pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
3642 struct pfi_kif *kif, struct mbuf *m, int off, void *h,
70224baa
JL
3643 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
3644 struct ifqueue *ifq)
02742ec6
JS
3645{
3646 struct pf_rule *nr = NULL;
3647 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
3648 struct pf_rule *r, *a = NULL;
3649 struct pf_ruleset *ruleset = NULL;
3650 struct pf_src_node *nsn = NULL;
3651 u_short reason;
70224baa 3652 u_int16_t icmpid = 0, bport, nport = 0;
02742ec6
JS
3653 sa_family_t af = pd->af;
3654 u_int8_t icmptype = 0, icmpcode = 0;
3655 int state_icmp = 0;
70224baa 3656 int tag = -1, rtableid = -1;
02742ec6
JS
3657#ifdef INET6
3658 int rewrite = 0;
3659#endif /* INET6 */
70224baa
JL
3660 int asd = 0;
3661 int match = 0;
3662
3663 if (pf_check_congestion(ifq)) {
3664 REASON_SET(&reason, PFRES_CONGEST);
3665 return (PF_DROP);
3666 }
02742ec6
JS
3667
3668 switch (pd->proto) {
3669#ifdef INET
3670 case IPPROTO_ICMP:
3671 icmptype = pd->hdr.icmp->icmp_type;
3672 icmpcode = pd->hdr.icmp->icmp_code;
3673 icmpid = pd->hdr.icmp->icmp_id;
3674
3675 if (icmptype == ICMP_UNREACH ||
3676 icmptype == ICMP_SOURCEQUENCH ||
3677 icmptype == ICMP_REDIRECT ||
3678 icmptype == ICMP_TIMXCEED ||
3679 icmptype == ICMP_PARAMPROB)
3680 state_icmp++;
3681 break;
3682#endif /* INET */
3683#ifdef INET6
3684 case IPPROTO_ICMPV6:
3685 icmptype = pd->hdr.icmp6->icmp6_type;
3686 icmpcode = pd->hdr.icmp6->icmp6_code;
3687 icmpid = pd->hdr.icmp6->icmp6_id;
3688
3689 if (icmptype == ICMP6_DST_UNREACH ||
3690 icmptype == ICMP6_PACKET_TOO_BIG ||
3691 icmptype == ICMP6_TIME_EXCEEDED ||
3692 icmptype == ICMP6_PARAM_PROB)
3693 state_icmp++;
3694 break;
3695#endif /* INET6 */
3696 }
3697
3698 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
3699
3700 if (direction == PF_OUT) {
70224baa 3701 bport = nport = icmpid;
02742ec6
JS
3702 /* check outgoing packet for BINAT/NAT */
3703 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
70224baa
JL
3704 saddr, icmpid, daddr, icmpid, &pd->naddr, &nport)) !=
3705 NULL) {
02742ec6
JS
3706 PF_ACPY(&pd->baddr, saddr, af);
3707 switch (af) {
3708#ifdef INET
3709 case AF_INET:
3710 pf_change_a(&saddr->v4.s_addr, pd->ip_sum,
3711 pd->naddr.v4.s_addr, 0);
70224baa
JL
3712 pd->hdr.icmp->icmp_cksum = pf_cksum_fixup(
3713 pd->hdr.icmp->icmp_cksum, icmpid, nport, 0);
3714 pd->hdr.icmp->icmp_id = nport;
3715 m_copyback(m, off, ICMP_MINLEN, (caddr_t)pd->hdr.icmp);
02742ec6
JS
3716 break;
3717#endif /* INET */
3718#ifdef INET6
3719 case AF_INET6:
3720 pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum,
3721 &pd->naddr, 0);
3722 rewrite++;
3723 break;
3724#endif /* INET6 */
3725 }
3726 if (nr->natpass)
3727 r = NULL;
3728 pd->nat_rule = nr;
3729 }
3730 } else {
70224baa 3731 bport = nport = icmpid;
02742ec6
JS
3732 /* check incoming packet for BINAT/RDR */
3733 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
70224baa
JL
3734 saddr, icmpid, daddr, icmpid, &pd->naddr, &nport)) !=
3735 NULL) {
02742ec6
JS
3736 PF_ACPY(&pd->baddr, daddr, af);
3737 switch (af) {
3738#ifdef INET
3739 case AF_INET:
3740 pf_change_a(&daddr->v4.s_addr,
3741 pd->ip_sum, pd->naddr.v4.s_addr, 0);
3742 break;
3743#endif /* INET */
3744#ifdef INET6
3745 case AF_INET6:
3746 pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum,
3747 &pd->naddr, 0);
3748 rewrite++;
3749 break;
3750#endif /* INET6 */
3751 }
3752 if (nr->natpass)
3753 r = NULL;
3754 pd->nat_rule = nr;
3755 }
3756 }
3757
3758 while (r != NULL) {
3759 r->evaluations++;
70224baa 3760 if (pfi_kif_match(r->kif, kif) == r->ifnot)
02742ec6
JS
3761 r = r->skip[PF_SKIP_IFP].ptr;
3762 else if (r->direction && r->direction != direction)
3763 r = r->skip[PF_SKIP_DIR].ptr;
3764 else if (r->af && r->af != af)
3765 r = r->skip[PF_SKIP_AF].ptr;
3766 else if (r->proto && r->proto != pd->proto)
3767 r = r->skip[PF_SKIP_PROTO].ptr;
70224baa
JL
3768 else if (PF_MISMATCHAW(&r->src.addr, saddr, af,
3769 r->src.neg, kif))
02742ec6 3770 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
70224baa
JL
3771 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af,
3772 r->dst.neg, NULL))
02742ec6
JS
3773 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3774 else if (r->type && r->type != icmptype + 1)
3775 r = TAILQ_NEXT(r, entries);
3776 else if (r->code && r->code != icmpcode + 1)
3777 r = TAILQ_NEXT(r, entries);
70224baa 3778 else if (r->tos && !(r->tos == pd->tos))
02742ec6
JS
3779 r = TAILQ_NEXT(r, entries);
3780 else if (r->rule_flag & PFRULE_FRAGMENT)
3781 r = TAILQ_NEXT(r, entries);
75fda04a
MD
3782 else if (r->prob && r->prob <= karc4random())
3783 r = TAILQ_NEXT(r, entries);
70224baa 3784 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
02742ec6
JS
3785 r = TAILQ_NEXT(r, entries);
3786 else if (r->os_fingerprint != PF_OSFP_ANY)
3787 r = TAILQ_NEXT(r, entries);
3788 else {
3789 if (r->tag)
3790 tag = r->tag;
70224baa
JL
3791 if (r->rtableid >= 0)
3792 rtableid = r->rtableid;
02742ec6 3793 if (r->anchor == NULL) {
70224baa 3794 match = 1;
02742ec6
JS
3795 *rm = r;
3796 *am = a;
3797 *rsm = ruleset;
3798 if ((*rm)->quick)
3799 break;
3800 r = TAILQ_NEXT(r, entries);
3801 } else
70224baa
JL
3802 pf_step_into_anchor(&asd, &ruleset,
3803 PF_RULESET_FILTER, &r, &a, &match);
02742ec6 3804 }
70224baa
JL
3805 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
3806 PF_RULESET_FILTER, &r, &a, &match))
3807 break;
02742ec6
JS
3808 }
3809 r = *rm;
3810 a = *am;
3811 ruleset = *rsm;
3812
3813 REASON_SET(&reason, PFRES_MATCH);
3814
70224baa 3815 if (r->log || (nr != NULL && nr->natpass && nr->log)) {
02742ec6
JS
3816#ifdef INET6
3817 if (rewrite)
3818 m_copyback(m, off, sizeof(struct icmp6_hdr),
3819 (caddr_t)pd->hdr.icmp6);
3820#endif /* INET6 */
70224baa
JL
3821 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr,
3822 a, ruleset, pd);
02742ec6
JS
3823 }
3824
3825 if (r->action != PF_PASS)
3826 return (PF_DROP);
3827
70224baa
JL
3828 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) {
3829 REASON_SET(&reason, PFRES_MEMORY);
3830 return (PF_DROP);
3831 }
02742ec6
JS
3832
3833 if (!state_icmp && (r->keep_state || nr != NULL)) {
3834 /* create new state */
3835 struct pf_state *s = NULL;
3836 struct pf_src_node *sn = NULL;
3837
3838 /* check maximums */
70224baa
JL
3839 if (r->max_states && (r->states >= r->max_states)) {
3840 pf_status.lcounters[LCNT_STATES]++;
3841 REASON_SET(&reason, PFRES_MAXSTATES);
02742ec6 3842 goto cleanup;
70224baa
JL
3843 }
3844 /* src node for filter rule */
02742ec6
JS
3845 if ((r->rule_flag & PFRULE_SRCTRACK ||
3846 r->rpool.opts & PF_POOL_STICKYADDR) &&
70224baa
JL
3847 pf_insert_src_node(&sn, r, saddr, af) != 0) {
3848 REASON_SET(&reason, PFRES_SRCLIMIT);
02742ec6 3849 goto cleanup;
70224baa 3850 }
02742ec6
JS
3851 /* src node for translation rule */
3852 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
3853 ((direction == PF_OUT &&
3854 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
70224baa
JL
3855 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) {
3856 REASON_SET(&reason, PFRES_SRCLIMIT);
02742ec6 3857 goto cleanup;
70224baa 3858 }
02742ec6
JS
3859 s = pool_get(&pf_state_pl, PR_NOWAIT);
3860 if (s == NULL) {
70224baa 3861 REASON_SET(&reason, PFRES_MEMORY);
02742ec6
JS
3862cleanup:
3863 if (sn != NULL && sn->states == 0 && sn->expire == 0) {
3864 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
3865 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3866 pf_status.src_nodes--;
3867 pool_put(&pf_src_tree_pl, sn);
3868 }
3869 if (nsn != sn && nsn != NULL && nsn->states == 0 &&
3870 nsn->expire == 0) {
3871 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
3872 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3873 pf_status.src_nodes--;
3874 pool_put(&pf_src_tree_pl, nsn);
3875 }
02742ec6
JS
3876 return (PF_DROP);
3877 }
3878 bzero(s, sizeof(*s));
02742ec6
JS
3879 s->rule.ptr = r;
3880 s->nat_rule.ptr = nr;
02742ec6 3881 s->anchor.ptr = a;
70224baa 3882 STATE_INC_COUNTERS(s);
02742ec6 3883 s->allow_opts = r->allow_opts;
70224baa
JL
3884 s->log = r->log & PF_LOG_ALL;
3885 if (nr != NULL)
3886 s->log |= nr->log & PF_LOG_ALL;
02742ec6
JS
3887 s->proto = pd->proto;
3888 s->direction = direction;
3889 s->af = af;
3890 if (direction == PF_OUT) {
3891 PF_ACPY(&s->gwy.addr, saddr, af);
70224baa 3892 s->gwy.port = nport;
02742ec6 3893 PF_ACPY(&s->ext.addr, daddr, af);
70224baa
JL
3894 s->ext.port = 0;
3895 if (nr != NULL) {
02742ec6 3896 PF_ACPY(&s->lan.addr, &pd->baddr, af);
70224baa
JL
3897 s->lan.port = bport;
3898 } else {
02742ec6 3899 PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
70224baa
JL
3900 s->lan.port = s->gwy.port;
3901 }
02742ec6
JS
3902 } else {
3903 PF_ACPY(&s->lan.addr, daddr, af);
70224baa 3904 s->lan.port = nport;
02742ec6 3905 PF_ACPY(&s->ext.addr, saddr, af);
70224baa
JL
3906 s->ext.port = 0;
3907 if (nr != NULL) {
02742ec6 3908 PF_ACPY(&s->gwy.addr, &pd->baddr, af);
70224baa
JL
3909 s->gwy.port = bport;
3910 } else {
02742ec6 3911 PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
70224baa
JL
3912 s->gwy.port = s->lan.port;
3913 }
02742ec6 3914 }
a814431a 3915 s->hash = pf_state_hash(s);
02742ec6
JS
3916 s->creation = time_second;
3917 s->expire = time_second;
3918 s->timeout = PFTM_ICMP_FIRST_PACKET;
3919 pf_set_rt_ifp(s, saddr);
3920 if (sn != NULL) {
3921 s->src_node = sn;
3922 s->src_node->states++;
3923 }
3924 if (nsn != NULL) {
3925 PF_ACPY(&nsn->raddr, &pd->naddr, af);
3926 s->nat_src_node = nsn;
3927 s->nat_src_node->states++;
3928 }
3929 if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
70224baa 3930 REASON_SET(&reason, PFRES_STATEINS);
02742ec6 3931 pf_src_tree_remove_state(s);
70224baa 3932 STATE_DEC_COUNTERS(s);
02742ec6
JS
3933 pool_put(&pf_state_pl, s);
3934 return (PF_DROP);
3935 } else
3936 *sm = s;
70224baa
JL