Deleted Added
full compact
pf_ioctl.c (141584) pf_ioctl.c (145836)
1/* $FreeBSD: head/sys/contrib/pf/net/pf_ioctl.c 141584 2005-02-09 19:29:13Z mlaier $ */
2/* $OpenBSD: pf_ioctl.c,v 1.112.2.2 2004/07/24 18:28:12 brad Exp $ */
3/* add $OpenBSD: pf_ioctl.c,v 1.118 2004/05/03 07:51:59 kjc Exp $ */
1/* $FreeBSD: head/sys/contrib/pf/net/pf_ioctl.c 145836 2005-05-03 16:43:32Z mlaier $ */
2/* $OpenBSD: pf_ioctl.c,v 1.139 2005/03/03 07:13:39 dhartmei Exp $ */
4
5/*
6 * Copyright (c) 2001 Daniel Hartmeier
7 * Copyright (c) 2002,2003 Henning Brauer
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions

--- 98 unchanged lines hidden (view full) ---

110#endif /* __FreeBSD__ */
111
112#ifdef __FreeBSD__
113void init_zone_var(void);
114void cleanup_pf_zone(void);
115int pfattach(void);
116#else
117void pfattach(int);
3
4/*
5 * Copyright (c) 2001 Daniel Hartmeier
6 * Copyright (c) 2002,2003 Henning Brauer
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions

--- 98 unchanged lines hidden (view full) ---

109#endif /* __FreeBSD__ */
110
111#ifdef __FreeBSD__
112void init_zone_var(void);
113void cleanup_pf_zone(void);
114int pfattach(void);
115#else
116void pfattach(int);
118int pfopen(struct cdev *, int, int, struct proc *);
119int pfclose(struct cdev *, int, int, struct proc *);
117int pfopen(dev_t, int, int, struct proc *);
118int pfclose(dev_t, int, int, struct proc *);
120#endif
119#endif
121struct pf_pool *pf_get_pool(char *, char *, u_int32_t,
122 u_int8_t, u_int32_t, u_int8_t, u_int8_t, u_int8_t);
120struct pf_pool *pf_get_pool(char *, u_int32_t, u_int8_t, u_int32_t,
121 u_int8_t, u_int8_t, u_int8_t);
123int pf_get_ruleset_number(u_int8_t);
124void pf_init_ruleset(struct pf_ruleset *);
122int pf_get_ruleset_number(u_int8_t);
123void pf_init_ruleset(struct pf_ruleset *);
124int pf_anchor_setup(struct pf_rule *,
125 const struct pf_ruleset *, const char *);
126int pf_anchor_copyout(const struct pf_ruleset *,
127 const struct pf_rule *, struct pfioc_rule *);
128void pf_anchor_remove(struct pf_rule *);
129
125void pf_mv_pool(struct pf_palist *, struct pf_palist *);
126void pf_empty_pool(struct pf_palist *);
127#ifdef __FreeBSD__
128int pfioctl(struct cdev *, u_long, caddr_t, int, struct thread *);
129#else
130int pfioctl(struct cdev *, u_long, caddr_t, int, struct proc *);
131#endif
132#ifdef ALTQ
133int pf_begin_altq(u_int32_t *);
134int pf_rollback_altq(u_int32_t);
135int pf_commit_altq(u_int32_t);
136int pf_enable_altq(struct pf_altq *);
137int pf_disable_altq(struct pf_altq *);
138#endif /* ALTQ */
130void pf_mv_pool(struct pf_palist *, struct pf_palist *);
131void pf_empty_pool(struct pf_palist *);
132#ifdef __FreeBSD__
133int pfioctl(struct cdev *, u_long, caddr_t, int, struct thread *);
134#else
135int pfioctl(struct cdev *, u_long, caddr_t, int, struct proc *);
136#endif
137#ifdef ALTQ
138int pf_begin_altq(u_int32_t *);
139int pf_rollback_altq(u_int32_t);
140int pf_commit_altq(u_int32_t);
141int pf_enable_altq(struct pf_altq *);
142int pf_disable_altq(struct pf_altq *);
143#endif /* ALTQ */
139int pf_begin_rules(u_int32_t *, int, char *, char *);
140int pf_rollback_rules(u_int32_t, int, char *, char *);
141int pf_commit_rules(u_int32_t, int, char *, char *);
144int pf_begin_rules(u_int32_t *, int, const char *);
145int pf_rollback_rules(u_int32_t, int, char *);
146int pf_commit_rules(u_int32_t, int, char *);
142
143#ifdef __FreeBSD__
144extern struct callout pf_expire_to;
145#else
146extern struct timeout pf_expire_to;
147#endif
148
149struct pf_rule pf_default_rule;

--- 6 unchanged lines hidden (view full) ---

156 pf_qids = TAILQ_HEAD_INITIALIZER(pf_qids);
157
158#if (PF_QNAME_SIZE != PF_TAG_NAME_SIZE)
159#error PF_QNAME_SIZE must be equal to PF_TAG_NAME_SIZE
160#endif
161static u_int16_t tagname2tag(struct pf_tags *, char *);
162static void tag2tagname(struct pf_tags *, u_int16_t, char *);
163static void tag_unref(struct pf_tags *, u_int16_t);
147
148#ifdef __FreeBSD__
149extern struct callout pf_expire_to;
150#else
151extern struct timeout pf_expire_to;
152#endif
153
154struct pf_rule pf_default_rule;

--- 6 unchanged lines hidden (view full) ---

161 pf_qids = TAILQ_HEAD_INITIALIZER(pf_qids);
162
163#if (PF_QNAME_SIZE != PF_TAG_NAME_SIZE)
164#error PF_QNAME_SIZE must be equal to PF_TAG_NAME_SIZE
165#endif
166static u_int16_t tagname2tag(struct pf_tags *, char *);
167static void tag2tagname(struct pf_tags *, u_int16_t, char *);
168static void tag_unref(struct pf_tags *, u_int16_t);
169int pf_rtlabel_add(struct pf_addr_wrap *);
170void pf_rtlabel_remove(struct pf_addr_wrap *);
171void pf_rtlabel_copyout(struct pf_addr_wrap *);
164
165#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
166
167
168#ifdef __FreeBSD__
169static struct cdev *pf_dev;
170
171/*

--- 84 unchanged lines hidden (view full) ---

256 do {
257 UMA_CREATE(pf_src_tree_pl,struct pf_src_node, "pfsrctrpl");
258 UMA_CREATE(pf_rule_pl, struct pf_rule, "pfrulepl");
259 UMA_CREATE(pf_state_pl, struct pf_state, "pfstatepl");
260 UMA_CREATE(pf_altq_pl, struct pf_altq, "pfaltqpl");
261 UMA_CREATE(pf_pooladdr_pl, struct pf_pooladdr, "pfpooladdrpl");
262 UMA_CREATE(pfr_ktable_pl, struct pfr_ktable, "pfrktable");
263 UMA_CREATE(pfr_kentry_pl, struct pfr_kentry, "pfrkentry");
172
173#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
174
175
176#ifdef __FreeBSD__
177static struct cdev *pf_dev;
178
179/*

--- 84 unchanged lines hidden (view full) ---

264 do {
265 UMA_CREATE(pf_src_tree_pl,struct pf_src_node, "pfsrctrpl");
266 UMA_CREATE(pf_rule_pl, struct pf_rule, "pfrulepl");
267 UMA_CREATE(pf_state_pl, struct pf_state, "pfstatepl");
268 UMA_CREATE(pf_altq_pl, struct pf_altq, "pfaltqpl");
269 UMA_CREATE(pf_pooladdr_pl, struct pf_pooladdr, "pfpooladdrpl");
270 UMA_CREATE(pfr_ktable_pl, struct pfr_ktable, "pfrktable");
271 UMA_CREATE(pfr_kentry_pl, struct pfr_kentry, "pfrkentry");
272 UMA_CREATE(pfr_kentry_pl2, struct pfr_kentry, "pfrkentry2");
264 UMA_CREATE(pf_frent_pl, struct pf_frent, "pffrent");
265 UMA_CREATE(pf_frag_pl, struct pf_fragment, "pffrag");
266 UMA_CREATE(pf_cache_pl, struct pf_fragment, "pffrcache");
267 UMA_CREATE(pf_cent_pl, struct pf_frcache, "pffrcent");
268 UMA_CREATE(pf_state_scrub_pl, struct pf_state_scrub,
269 "pfstatescrub");
270 UMA_CREATE(pfi_addr_pl, struct pfi_dynaddr, "pfiaddrpl");
271 error = 0;

--- 7 unchanged lines hidden (view full) ---

279 if ( (error = pf_osfp_initialize()) ) {
280 cleanup_pf_zone();
281 pf_osfp_cleanup();
282 return (error);
283 }
284
285 pf_pool_limits[PF_LIMIT_STATES].pp = pf_state_pl;
286 pf_pool_limits[PF_LIMIT_STATES].limit = PFSTATE_HIWAT;
273 UMA_CREATE(pf_frent_pl, struct pf_frent, "pffrent");
274 UMA_CREATE(pf_frag_pl, struct pf_fragment, "pffrag");
275 UMA_CREATE(pf_cache_pl, struct pf_fragment, "pffrcache");
276 UMA_CREATE(pf_cent_pl, struct pf_frcache, "pffrcent");
277 UMA_CREATE(pf_state_scrub_pl, struct pf_state_scrub,
278 "pfstatescrub");
279 UMA_CREATE(pfi_addr_pl, struct pfi_dynaddr, "pfiaddrpl");
280 error = 0;

--- 7 unchanged lines hidden (view full) ---

288 if ( (error = pf_osfp_initialize()) ) {
289 cleanup_pf_zone();
290 pf_osfp_cleanup();
291 return (error);
292 }
293
294 pf_pool_limits[PF_LIMIT_STATES].pp = pf_state_pl;
295 pf_pool_limits[PF_LIMIT_STATES].limit = PFSTATE_HIWAT;
296 pf_pool_limits[PF_LIMIT_SRC_NODES].pp = pf_src_tree_pl;
297 pf_pool_limits[PF_LIMIT_SRC_NODES].limit = PFSNODE_HIWAT;
287 pf_pool_limits[PF_LIMIT_FRAGS].pp = pf_frent_pl;
288 pf_pool_limits[PF_LIMIT_FRAGS].limit = PFFRAG_FRENT_HIWAT;
289 uma_zone_set_max(pf_pool_limits[PF_LIMIT_STATES].pp,
290 pf_pool_limits[PF_LIMIT_STATES].limit);
291
292 RB_INIT(&tree_src_tracking);
298 pf_pool_limits[PF_LIMIT_FRAGS].pp = pf_frent_pl;
299 pf_pool_limits[PF_LIMIT_FRAGS].limit = PFFRAG_FRENT_HIWAT;
300 uma_zone_set_max(pf_pool_limits[PF_LIMIT_STATES].pp,
301 pf_pool_limits[PF_LIMIT_STATES].limit);
302
303 RB_INIT(&tree_src_tracking);
293 TAILQ_INIT(&pf_anchors);
304 RB_INIT(&pf_anchors);
294 pf_init_ruleset(&pf_main_ruleset);
295 TAILQ_INIT(&pf_altqs[0]);
296 TAILQ_INIT(&pf_altqs[1]);
297 TAILQ_INIT(&pf_pabuf);
298 pf_altqs_active = &pf_altqs[0];
299 pf_altqs_inactive = &pf_altqs[1];
300 TAILQ_INIT(&state_updates);
301
302 /* default rule should never be garbage collected */
303 pf_default_rule.entries.tqe_prev = &pf_default_rule.entries.tqe_next;
304 pf_default_rule.action = PF_PASS;
305 pf_default_rule.nr = -1;
306
307 /* initialize default timeouts */
305 pf_init_ruleset(&pf_main_ruleset);
306 TAILQ_INIT(&pf_altqs[0]);
307 TAILQ_INIT(&pf_altqs[1]);
308 TAILQ_INIT(&pf_pabuf);
309 pf_altqs_active = &pf_altqs[0];
310 pf_altqs_inactive = &pf_altqs[1];
311 TAILQ_INIT(&state_updates);
312
313 /* default rule should never be garbage collected */
314 pf_default_rule.entries.tqe_prev = &pf_default_rule.entries.tqe_next;
315 pf_default_rule.action = PF_PASS;
316 pf_default_rule.nr = -1;
317
318 /* initialize default timeouts */
308 my_timeout[PFTM_TCP_FIRST_PACKET] = 120; /* First TCP packet */
309 my_timeout[PFTM_TCP_OPENING] = 30; /* No response yet */
310 my_timeout[PFTM_TCP_ESTABLISHED] = 24*60*60; /* Established */
311 my_timeout[PFTM_TCP_CLOSING] = 15 * 60; /* Half closed */
312 my_timeout[PFTM_TCP_FIN_WAIT] = 45; /* Got both FINs */
313 my_timeout[PFTM_TCP_CLOSED] = 90; /* Got a RST */
314 my_timeout[PFTM_UDP_FIRST_PACKET] = 60; /* First UDP packet */
315 my_timeout[PFTM_UDP_SINGLE] = 30; /* Unidirectional */
316 my_timeout[PFTM_UDP_MULTIPLE] = 60; /* Bidirectional */
317 my_timeout[PFTM_ICMP_FIRST_PACKET] = 20; /* First ICMP packet */
318 my_timeout[PFTM_ICMP_ERROR_REPLY] = 10; /* Got error response */
319 my_timeout[PFTM_OTHER_FIRST_PACKET] = 60; /* First packet */
320 my_timeout[PFTM_OTHER_SINGLE] = 30; /* Unidirectional */
321 my_timeout[PFTM_OTHER_MULTIPLE] = 60; /* Bidirectional */
322 my_timeout[PFTM_FRAG] = 30; /* Fragment expire */
323 my_timeout[PFTM_INTERVAL] = 10; /* Expire interval */
319 my_timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
320 my_timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
321 my_timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
322 my_timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL;
323 my_timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL;
324 my_timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL;
325 my_timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL;
326 my_timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL;
327 my_timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL;
328 my_timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL;
329 my_timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL;
330 my_timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL;
331 my_timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL;
332 my_timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL;
333 my_timeout[PFTM_FRAG] = PFTM_FRAG_VAL;
334 my_timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL;
335 my_timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL;
336 my_timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL;
324
325 /*
326 * XXX
327 * The 2nd arg. 0 to callout_init(9) shoule be set to CALLOUT_MPSAFE
328 * if Gaint lock is removed from the network stack.
329 */
330 callout_init(&pf_expire_to, 0);
331 callout_reset(&pf_expire_to, my_timeout[PFTM_INTERVAL] * hz,
332 pf_purge_timeout, &pf_expire_to);
333
334 pf_normalize_init();
337
338 /*
339 * XXX
340 * The 2nd arg. 0 to callout_init(9) shoule be set to CALLOUT_MPSAFE
341 * if Gaint lock is removed from the network stack.
342 */
343 callout_init(&pf_expire_to, 0);
344 callout_reset(&pf_expire_to, my_timeout[PFTM_INTERVAL] * hz,
345 pf_purge_timeout, &pf_expire_to);
346
347 pf_normalize_init();
335 pf_status.debug = PF_DEBUG_URGENT;
348 bzero(&pf_status, sizeof(pf_status));
336 pf_pfil_hooked = 0;
337
338 /* XXX do our best to avoid a conflict */
339 pf_status.hostid = arc4random();
340
341 return (error);
342}
343#else /* !__FreeBSD__ */

--- 4 unchanged lines hidden (view full) ---

348
349 pool_init(&pf_rule_pl, sizeof(struct pf_rule), 0, 0, 0, "pfrulepl",
350 &pool_allocator_nointr);
351 pool_init(&pf_src_tree_pl, sizeof(struct pf_src_node), 0, 0, 0,
352 "pfsrctrpl", NULL);
353 pool_init(&pf_state_pl, sizeof(struct pf_state), 0, 0, 0, "pfstatepl",
354 NULL);
355 pool_init(&pf_altq_pl, sizeof(struct pf_altq), 0, 0, 0, "pfaltqpl",
349 pf_pfil_hooked = 0;
350
351 /* XXX do our best to avoid a conflict */
352 pf_status.hostid = arc4random();
353
354 return (error);
355}
356#else /* !__FreeBSD__ */

--- 4 unchanged lines hidden (view full) ---

361
362 pool_init(&pf_rule_pl, sizeof(struct pf_rule), 0, 0, 0, "pfrulepl",
363 &pool_allocator_nointr);
364 pool_init(&pf_src_tree_pl, sizeof(struct pf_src_node), 0, 0, 0,
365 "pfsrctrpl", NULL);
366 pool_init(&pf_state_pl, sizeof(struct pf_state), 0, 0, 0, "pfstatepl",
367 NULL);
368 pool_init(&pf_altq_pl, sizeof(struct pf_altq), 0, 0, 0, "pfaltqpl",
356 NULL);
369 &pool_allocator_nointr);
357 pool_init(&pf_pooladdr_pl, sizeof(struct pf_pooladdr), 0, 0, 0,
370 pool_init(&pf_pooladdr_pl, sizeof(struct pf_pooladdr), 0, 0, 0,
358 "pfpooladdrpl", NULL);
371 "pfpooladdrpl", &pool_allocator_nointr);
359 pfr_initialize();
360 pfi_initialize();
361 pf_osfp_initialize();
362
363 pool_sethardlimit(pf_pool_limits[PF_LIMIT_STATES].pp,
364 pf_pool_limits[PF_LIMIT_STATES].limit, NULL, 0);
365
366 RB_INIT(&tree_src_tracking);
372 pfr_initialize();
373 pfi_initialize();
374 pf_osfp_initialize();
375
376 pool_sethardlimit(pf_pool_limits[PF_LIMIT_STATES].pp,
377 pf_pool_limits[PF_LIMIT_STATES].limit, NULL, 0);
378
379 RB_INIT(&tree_src_tracking);
367 TAILQ_INIT(&pf_anchors);
380 RB_INIT(&pf_anchors);
368 pf_init_ruleset(&pf_main_ruleset);
369 TAILQ_INIT(&pf_altqs[0]);
370 TAILQ_INIT(&pf_altqs[1]);
371 TAILQ_INIT(&pf_pabuf);
372 pf_altqs_active = &pf_altqs[0];
373 pf_altqs_inactive = &pf_altqs[1];
374 TAILQ_INIT(&state_updates);
375
376 /* default rule should never be garbage collected */
377 pf_default_rule.entries.tqe_prev = &pf_default_rule.entries.tqe_next;
378 pf_default_rule.action = PF_PASS;
379 pf_default_rule.nr = -1;
380
381 /* initialize default timeouts */
381 pf_init_ruleset(&pf_main_ruleset);
382 TAILQ_INIT(&pf_altqs[0]);
383 TAILQ_INIT(&pf_altqs[1]);
384 TAILQ_INIT(&pf_pabuf);
385 pf_altqs_active = &pf_altqs[0];
386 pf_altqs_inactive = &pf_altqs[1];
387 TAILQ_INIT(&state_updates);
388
389 /* default rule should never be garbage collected */
390 pf_default_rule.entries.tqe_prev = &pf_default_rule.entries.tqe_next;
391 pf_default_rule.action = PF_PASS;
392 pf_default_rule.nr = -1;
393
394 /* initialize default timeouts */
382 timeout[PFTM_TCP_FIRST_PACKET] = 120; /* First TCP packet */
383 timeout[PFTM_TCP_OPENING] = 30; /* No response yet */
384 timeout[PFTM_TCP_ESTABLISHED] = 24*60*60; /* Established */
385 timeout[PFTM_TCP_CLOSING] = 15 * 60; /* Half closed */
386 timeout[PFTM_TCP_FIN_WAIT] = 45; /* Got both FINs */
387 timeout[PFTM_TCP_CLOSED] = 90; /* Got a RST */
388 timeout[PFTM_UDP_FIRST_PACKET] = 60; /* First UDP packet */
389 timeout[PFTM_UDP_SINGLE] = 30; /* Unidirectional */
390 timeout[PFTM_UDP_MULTIPLE] = 60; /* Bidirectional */
391 timeout[PFTM_ICMP_FIRST_PACKET] = 20; /* First ICMP packet */
392 timeout[PFTM_ICMP_ERROR_REPLY] = 10; /* Got error response */
393 timeout[PFTM_OTHER_FIRST_PACKET] = 60; /* First packet */
394 timeout[PFTM_OTHER_SINGLE] = 30; /* Unidirectional */
395 timeout[PFTM_OTHER_MULTIPLE] = 60; /* Bidirectional */
396 timeout[PFTM_FRAG] = 30; /* Fragment expire */
397 timeout[PFTM_INTERVAL] = 10; /* Expire interval */
398 timeout[PFTM_SRC_NODE] = 0; /* Source tracking */
395 timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
396 timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
397 timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
398 timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL;
399 timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL;
400 timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL;
401 timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL;
402 timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL;
403 timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL;
404 timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL;
405 timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL;
406 timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL;
407 timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL;
408 timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL;
409 timeout[PFTM_FRAG] = PFTM_FRAG_VAL;
410 timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL;
411 timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL;
412 timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL;
399
400 timeout_set(&pf_expire_to, pf_purge_timeout, &pf_expire_to);
401 timeout_add(&pf_expire_to, timeout[PFTM_INTERVAL] * hz);
402
403 pf_normalize_init();
404 bzero(&pf_status, sizeof(pf_status));
405 pf_status.debug = PF_DEBUG_URGENT;
406

--- 14 unchanged lines hidden (view full) ---

421{
422 if (minor(dev) >= 1)
423 return (ENXIO);
424 return (0);
425}
426#endif /* __FreeBSD__ */
427
428struct pf_pool *
413
414 timeout_set(&pf_expire_to, pf_purge_timeout, &pf_expire_to);
415 timeout_add(&pf_expire_to, timeout[PFTM_INTERVAL] * hz);
416
417 pf_normalize_init();
418 bzero(&pf_status, sizeof(pf_status));
419 pf_status.debug = PF_DEBUG_URGENT;
420

--- 14 unchanged lines hidden (view full) ---

435{
436 if (minor(dev) >= 1)
437 return (ENXIO);
438 return (0);
439}
440#endif /* __FreeBSD__ */
441
442struct pf_pool *
429pf_get_pool(char *anchorname, char *rulesetname, u_int32_t ticket,
430 u_int8_t rule_action, u_int32_t rule_number, u_int8_t r_last,
431 u_int8_t active, u_int8_t check_ticket)
443pf_get_pool(char *anchor, u_int32_t ticket, u_int8_t rule_action,
444 u_int32_t rule_number, u_int8_t r_last, u_int8_t active,
445 u_int8_t check_ticket)
432{
433 struct pf_ruleset *ruleset;
434 struct pf_rule *rule;
435 int rs_num;
436
446{
447 struct pf_ruleset *ruleset;
448 struct pf_rule *rule;
449 int rs_num;
450
437 ruleset = pf_find_ruleset(anchorname, rulesetname);
451 ruleset = pf_find_ruleset(anchor);
438 if (ruleset == NULL)
439 return (NULL);
440 rs_num = pf_get_ruleset_number(rule_action);
441 if (rs_num >= PF_RULESET_MAX)
442 return (NULL);
443 if (active) {
444 if (check_ticket && ticket !=
445 ruleset->rules[rs_num].active.ticket)

--- 23 unchanged lines hidden (view full) ---

469 return (&rule->rpool);
470}
471
472int
473pf_get_ruleset_number(u_int8_t action)
474{
475 switch (action) {
476 case PF_SCRUB:
452 if (ruleset == NULL)
453 return (NULL);
454 rs_num = pf_get_ruleset_number(rule_action);
455 if (rs_num >= PF_RULESET_MAX)
456 return (NULL);
457 if (active) {
458 if (check_ticket && ticket !=
459 ruleset->rules[rs_num].active.ticket)

--- 23 unchanged lines hidden (view full) ---

483 return (&rule->rpool);
484}
485
486int
487pf_get_ruleset_number(u_int8_t action)
488{
489 switch (action) {
490 case PF_SCRUB:
491 case PF_NOSCRUB:
477 return (PF_RULESET_SCRUB);
478 break;
479 case PF_PASS:
480 case PF_DROP:
481 return (PF_RULESET_FILTER);
482 break;
483 case PF_NAT:
484 case PF_NONAT:

--- 23 unchanged lines hidden (view full) ---

508 TAILQ_INIT(&ruleset->rules[i].queues[0]);
509 TAILQ_INIT(&ruleset->rules[i].queues[1]);
510 ruleset->rules[i].active.ptr = &ruleset->rules[i].queues[0];
511 ruleset->rules[i].inactive.ptr = &ruleset->rules[i].queues[1];
512 }
513}
514
515struct pf_anchor *
492 return (PF_RULESET_SCRUB);
493 break;
494 case PF_PASS:
495 case PF_DROP:
496 return (PF_RULESET_FILTER);
497 break;
498 case PF_NAT:
499 case PF_NONAT:

--- 23 unchanged lines hidden (view full) ---

523 TAILQ_INIT(&ruleset->rules[i].queues[0]);
524 TAILQ_INIT(&ruleset->rules[i].queues[1]);
525 ruleset->rules[i].active.ptr = &ruleset->rules[i].queues[0];
526 ruleset->rules[i].inactive.ptr = &ruleset->rules[i].queues[1];
527 }
528}
529
530struct pf_anchor *
516pf_find_anchor(const char *anchorname)
531pf_find_anchor(const char *path)
517{
532{
518 struct pf_anchor *anchor;
519 int n = -1;
533 static struct pf_anchor key;
520
534
521 anchor = TAILQ_FIRST(&pf_anchors);
522 while (anchor != NULL && (n = strcmp(anchor->name, anchorname)) < 0)
523 anchor = TAILQ_NEXT(anchor, entries);
524 if (n == 0)
525 return (anchor);
526 else
527 return (NULL);
535 memset(&key, 0, sizeof(key));
536 strlcpy(key.path, path, sizeof(key.path));
537 return (RB_FIND(pf_anchor_global, &pf_anchors, &key));
528}
529
530struct pf_ruleset *
538}
539
540struct pf_ruleset *
531pf_find_ruleset(char *anchorname, char *rulesetname)
541pf_find_ruleset(const char *path)
532{
533 struct pf_anchor *anchor;
542{
543 struct pf_anchor *anchor;
534 struct pf_ruleset *ruleset;
535
544
536 if (!anchorname[0] && !rulesetname[0])
545 while (*path == '/')
546 path++;
547 if (!*path)
537 return (&pf_main_ruleset);
548 return (&pf_main_ruleset);
538 if (!anchorname[0] || !rulesetname[0])
539 return (NULL);
540 anchorname[PF_ANCHOR_NAME_SIZE-1] = 0;
541 rulesetname[PF_RULESET_NAME_SIZE-1] = 0;
542 anchor = pf_find_anchor(anchorname);
549 anchor = pf_find_anchor(path);
543 if (anchor == NULL)
544 return (NULL);
550 if (anchor == NULL)
551 return (NULL);
545 ruleset = TAILQ_FIRST(&anchor->rulesets);
546 while (ruleset != NULL && strcmp(ruleset->name, rulesetname) < 0)
547 ruleset = TAILQ_NEXT(ruleset, entries);
548 if (ruleset != NULL && !strcmp(ruleset->name, rulesetname))
549 return (ruleset);
550 else
552 else
551 return (NULL);
553 return (&anchor->ruleset);
552}
553
554struct pf_ruleset *
554}
555
556struct pf_ruleset *
555pf_find_or_create_ruleset(char anchorname[PF_ANCHOR_NAME_SIZE],
556 char rulesetname[PF_RULESET_NAME_SIZE])
557pf_find_or_create_ruleset(const char *path)
557{
558{
558 struct pf_anchor *anchor, *a;
559 struct pf_ruleset *ruleset, *r;
559 static char p[MAXPATHLEN];
560 char *q = NULL, *r; /* make the compiler happy */
561 struct pf_ruleset *ruleset;
562 struct pf_anchor *anchor = NULL, *dup, *parent = NULL;
560
563
561 if (!anchorname[0] && !rulesetname[0])
562 return (&pf_main_ruleset);
563 if (!anchorname[0] || !rulesetname[0])
564 while (*path == '/')
565 path++;
566 ruleset = pf_find_ruleset(path);
567 if (ruleset != NULL)
568 return (ruleset);
569 strlcpy(p, path, sizeof(p));
570#ifdef __FreeBSD__
571 while (parent == NULL && (q = rindex(p, '/')) != NULL) {
572#else
573 while (parent == NULL && (q = strrchr(p, '/')) != NULL) {
574#endif
575 *q = 0;
576 if ((ruleset = pf_find_ruleset(p)) != NULL) {
577 parent = ruleset->anchor;
578 break;
579 }
580 }
581 if (q == NULL)
582 q = p;
583 else
584 q++;
585 strlcpy(p, path, sizeof(p));
586 if (!*q)
564 return (NULL);
587 return (NULL);
565 anchorname[PF_ANCHOR_NAME_SIZE-1] = 0;
566 rulesetname[PF_RULESET_NAME_SIZE-1] = 0;
567 a = TAILQ_FIRST(&pf_anchors);
568 while (a != NULL && strcmp(a->name, anchorname) < 0)
569 a = TAILQ_NEXT(a, entries);
570 if (a != NULL && !strcmp(a->name, anchorname))
571 anchor = a;
572 else {
573 anchor = (struct pf_anchor *)malloc(sizeof(struct pf_anchor),
574 M_TEMP, M_NOWAIT);
588#ifdef __FreeBSD__
589 while ((r = index(q, '/')) != NULL || *q) {
590#else
591 while ((r = strchr(q, '/')) != NULL || *q) {
592#endif
593 if (r != NULL)
594 *r = 0;
595 if (!*q || strlen(q) >= PF_ANCHOR_NAME_SIZE ||
596 (parent != NULL && strlen(parent->path) >=
597 MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 1))
598 return (NULL);
599 anchor = (struct pf_anchor *)malloc(sizeof(*anchor), M_TEMP,
600 M_NOWAIT);
575 if (anchor == NULL)
576 return (NULL);
601 if (anchor == NULL)
602 return (NULL);
577 memset(anchor, 0, sizeof(struct pf_anchor));
578 bcopy(anchorname, anchor->name, sizeof(anchor->name));
579 TAILQ_INIT(&anchor->rulesets);
580 if (a != NULL)
581 TAILQ_INSERT_BEFORE(a, anchor, entries);
582 else
583 TAILQ_INSERT_TAIL(&pf_anchors, anchor, entries);
584 }
585 r = TAILQ_FIRST(&anchor->rulesets);
586 while (r != NULL && strcmp(r->name, rulesetname) < 0)
587 r = TAILQ_NEXT(r, entries);
588 if (r != NULL && !strcmp(r->name, rulesetname))
589 return (r);
590 ruleset = (struct pf_ruleset *)malloc(sizeof(struct pf_ruleset),
591 M_TEMP, M_NOWAIT);
592 if (ruleset != NULL) {
593 pf_init_ruleset(ruleset);
594 bcopy(rulesetname, ruleset->name, sizeof(ruleset->name));
595 ruleset->anchor = anchor;
603 memset(anchor, 0, sizeof(*anchor));
604 RB_INIT(&anchor->children);
605 strlcpy(anchor->name, q, sizeof(anchor->name));
606 if (parent != NULL) {
607 strlcpy(anchor->path, parent->path,
608 sizeof(anchor->path));
609 strlcat(anchor->path, "/", sizeof(anchor->path));
610 }
611 strlcat(anchor->path, anchor->name, sizeof(anchor->path));
612 if ((dup = RB_INSERT(pf_anchor_global, &pf_anchors, anchor)) !=
613 NULL) {
614 printf("pf_find_or_create_ruleset: RB_INSERT1 "
615 "'%s' '%s' collides with '%s' '%s'\n",
616 anchor->path, anchor->name, dup->path, dup->name);
617 free(anchor, M_TEMP);
618 return (NULL);
619 }
620 if (parent != NULL) {
621 anchor->parent = parent;
622 if ((dup = RB_INSERT(pf_anchor_node, &parent->children,
623 anchor)) != NULL) {
624 printf("pf_find_or_create_ruleset: "
625 "RB_INSERT2 '%s' '%s' collides with "
626 "'%s' '%s'\n", anchor->path, anchor->name,
627 dup->path, dup->name);
628 RB_REMOVE(pf_anchor_global, &pf_anchors,
629 anchor);
630 free(anchor, M_TEMP);
631 return (NULL);
632 }
633 }
634 pf_init_ruleset(&anchor->ruleset);
635 anchor->ruleset.anchor = anchor;
636 parent = anchor;
596 if (r != NULL)
637 if (r != NULL)
597 TAILQ_INSERT_BEFORE(r, ruleset, entries);
638 q = r + 1;
598 else
639 else
599 TAILQ_INSERT_TAIL(&anchor->rulesets, ruleset, entries);
640 *q = 0;
600 }
641 }
601 return (ruleset);
642 return (&anchor->ruleset);
602}
603
604void
605pf_remove_if_empty_ruleset(struct pf_ruleset *ruleset)
606{
643}
644
645void
646pf_remove_if_empty_ruleset(struct pf_ruleset *ruleset)
647{
607 struct pf_anchor *anchor;
648 struct pf_anchor *parent;
608 int i;
609
649 int i;
650
610 if (ruleset == NULL || ruleset->anchor == NULL || ruleset->tables > 0 ||
611 ruleset->topen)
612 return;
613 for (i = 0; i < PF_RULESET_MAX; ++i)
614 if (!TAILQ_EMPTY(ruleset->rules[i].active.ptr) ||
615 !TAILQ_EMPTY(ruleset->rules[i].inactive.ptr) ||
616 ruleset->rules[i].inactive.open)
651 while (ruleset != NULL) {
652 if (ruleset == &pf_main_ruleset || ruleset->anchor == NULL ||
653 !RB_EMPTY(&ruleset->anchor->children) ||
654 ruleset->anchor->refcnt > 0 || ruleset->tables > 0 ||
655 ruleset->topen)
617 return;
656 return;
657 for (i = 0; i < PF_RULESET_MAX; ++i)
658 if (!TAILQ_EMPTY(ruleset->rules[i].active.ptr) ||
659 !TAILQ_EMPTY(ruleset->rules[i].inactive.ptr) ||
660 ruleset->rules[i].inactive.open)
661 return;
662 RB_REMOVE(pf_anchor_global, &pf_anchors, ruleset->anchor);
663 if ((parent = ruleset->anchor->parent) != NULL)
664 RB_REMOVE(pf_anchor_node, &parent->children,
665 ruleset->anchor);
666 free(ruleset->anchor, M_TEMP);
667 if (parent == NULL)
668 return;
669 ruleset = &parent->ruleset;
670 }
671}
618
672
619 anchor = ruleset->anchor;
620 TAILQ_REMOVE(&anchor->rulesets, ruleset, entries);
621 free(ruleset, M_TEMP);
673int
674pf_anchor_setup(struct pf_rule *r, const struct pf_ruleset *s,
675 const char *name)
676{
677 static char *p, path[MAXPATHLEN];
678 struct pf_ruleset *ruleset;
622
679
623 if (TAILQ_EMPTY(&anchor->rulesets)) {
624 TAILQ_REMOVE(&pf_anchors, anchor, entries);
625 free(anchor, M_TEMP);
626 pf_update_anchor_rules();
680 r->anchor = NULL;
681 r->anchor_relative = 0;
682 r->anchor_wildcard = 0;
683 if (!name[0])
684 return (0);
685 if (name[0] == '/')
686 strlcpy(path, name + 1, sizeof(path));
687 else {
688 /* relative path */
689 r->anchor_relative = 1;
690 if (s->anchor == NULL || !s->anchor->path[0])
691 path[0] = 0;
692 else
693 strlcpy(path, s->anchor->path, sizeof(path));
694 while (name[0] == '.' && name[1] == '.' && name[2] == '/') {
695 if (!path[0]) {
696 printf("pf_anchor_setup: .. beyond root\n");
697 return (1);
698 }
699#ifdef __FreeBSD__
700 if ((p = rindex(path, '/')) != NULL)
701#else
702 if ((p = strrchr(path, '/')) != NULL)
703#endif
704 *p = 0;
705 else
706 path[0] = 0;
707 r->anchor_relative++;
708 name += 3;
709 }
710 if (path[0])
711 strlcat(path, "/", sizeof(path));
712 strlcat(path, name, sizeof(path));
627 }
713 }
714#ifdef __FreeBSD__
715 if ((p = rindex(path, '/')) != NULL && !strcmp(p, "/*")) {
716#else
717 if ((p = strrchr(path, '/')) != NULL && !strcmp(p, "/*")) {
718#endif
719 r->anchor_wildcard = 1;
720 *p = 0;
721 }
722 ruleset = pf_find_or_create_ruleset(path);
723 if (ruleset == NULL || ruleset->anchor == NULL) {
724 printf("pf_anchor_setup: ruleset\n");
725 return (1);
726 }
727 r->anchor = ruleset->anchor;
728 r->anchor->refcnt++;
729 return (0);
628}
629
730}
731
732int
733pf_anchor_copyout(const struct pf_ruleset *rs, const struct pf_rule *r,
734 struct pfioc_rule *pr)
735{
736 pr->anchor_call[0] = 0;
737 if (r->anchor == NULL)
738 return (0);
739 if (!r->anchor_relative) {
740 strlcpy(pr->anchor_call, "/", sizeof(pr->anchor_call));
741 strlcat(pr->anchor_call, r->anchor->path,
742 sizeof(pr->anchor_call));
743 } else {
744 char a[MAXPATHLEN], b[MAXPATHLEN], *p;
745 int i;
746
747 if (rs->anchor == NULL)
748 a[0] = 0;
749 else
750 strlcpy(a, rs->anchor->path, sizeof(a));
751 strlcpy(b, r->anchor->path, sizeof(b));
752 for (i = 1; i < r->anchor_relative; ++i) {
753#ifdef __FreeBSD__
754 if ((p = rindex(a, '/')) == NULL)
755#else
756 if ((p = strrchr(a, '/')) == NULL)
757#endif
758 p = a;
759 *p = 0;
760 strlcat(pr->anchor_call, "../",
761 sizeof(pr->anchor_call));
762 }
763 if (strncmp(a, b, strlen(a))) {
764 printf("pf_anchor_copyout: '%s' '%s'\n", a, b);
765 return (1);
766 }
767 if (strlen(b) > strlen(a))
768 strlcat(pr->anchor_call, b + (a[0] ? strlen(a) + 1 : 0),
769 sizeof(pr->anchor_call));
770 }
771 if (r->anchor_wildcard)
772 strlcat(pr->anchor_call, pr->anchor_call[0] ? "/*" : "*",
773 sizeof(pr->anchor_call));
774 return (0);
775}
776
630void
777void
778pf_anchor_remove(struct pf_rule *r)
779{
780 if (r->anchor == NULL)
781 return;
782 if (r->anchor->refcnt <= 0) {
783 printf("pf_anchor_remove: broken refcount");
784 r->anchor = NULL;
785 return;
786 }
787 if (!--r->anchor->refcnt)
788 pf_remove_if_empty_ruleset(&r->anchor->ruleset);
789 r->anchor = NULL;
790}
791
792void
631pf_mv_pool(struct pf_palist *poola, struct pf_palist *poolb)
632{
633 struct pf_pooladdr *mv_pool_pa;
634
635 while ((mv_pool_pa = TAILQ_FIRST(poola)) != NULL) {
636 TAILQ_REMOVE(poola, mv_pool_pa, entries);
637 TAILQ_INSERT_TAIL(poolb, mv_pool_pa, entries);
638 }

--- 20 unchanged lines hidden (view full) ---

659 if (rule->states <= 0) {
660 /*
661 * XXX - we need to remove the table *before* detaching
662 * the rule to make sure the table code does not delete
663 * the anchor under our feet.
664 */
665 pf_tbladdr_remove(&rule->src.addr);
666 pf_tbladdr_remove(&rule->dst.addr);
793pf_mv_pool(struct pf_palist *poola, struct pf_palist *poolb)
794{
795 struct pf_pooladdr *mv_pool_pa;
796
797 while ((mv_pool_pa = TAILQ_FIRST(poola)) != NULL) {
798 TAILQ_REMOVE(poola, mv_pool_pa, entries);
799 TAILQ_INSERT_TAIL(poolb, mv_pool_pa, entries);
800 }

--- 20 unchanged lines hidden (view full) ---

821 if (rule->states <= 0) {
822 /*
823 * XXX - we need to remove the table *before* detaching
824 * the rule to make sure the table code does not delete
825 * the anchor under our feet.
826 */
827 pf_tbladdr_remove(&rule->src.addr);
828 pf_tbladdr_remove(&rule->dst.addr);
829 if (rule->overload_tbl)
830 pfr_detach_table(rule->overload_tbl);
667 }
668 TAILQ_REMOVE(rulequeue, rule, entries);
669 rule->entries.tqe_prev = NULL;
670 rule->nr = -1;
671 }
672
673 if (rule->states > 0 || rule->src_nodes > 0 ||
674 rule->entries.tqe_prev != NULL)
675 return;
676 pf_tag_unref(rule->tag);
677 pf_tag_unref(rule->match_tag);
678#ifdef ALTQ
679 if (rule->pqid != rule->qid)
680 pf_qid_unref(rule->pqid);
681 pf_qid_unref(rule->qid);
682#endif
831 }
832 TAILQ_REMOVE(rulequeue, rule, entries);
833 rule->entries.tqe_prev = NULL;
834 rule->nr = -1;
835 }
836
837 if (rule->states > 0 || rule->src_nodes > 0 ||
838 rule->entries.tqe_prev != NULL)
839 return;
840 pf_tag_unref(rule->tag);
841 pf_tag_unref(rule->match_tag);
842#ifdef ALTQ
843 if (rule->pqid != rule->qid)
844 pf_qid_unref(rule->pqid);
845 pf_qid_unref(rule->qid);
846#endif
847 pf_rtlabel_remove(&rule->src.addr);
848 pf_rtlabel_remove(&rule->dst.addr);
683 pfi_dynaddr_remove(&rule->src.addr);
684 pfi_dynaddr_remove(&rule->dst.addr);
685 if (rulequeue == NULL) {
686 pf_tbladdr_remove(&rule->src.addr);
687 pf_tbladdr_remove(&rule->dst.addr);
849 pfi_dynaddr_remove(&rule->src.addr);
850 pfi_dynaddr_remove(&rule->dst.addr);
851 if (rulequeue == NULL) {
852 pf_tbladdr_remove(&rule->src.addr);
853 pf_tbladdr_remove(&rule->dst.addr);
854 if (rule->overload_tbl)
855 pfr_detach_table(rule->overload_tbl);
688 }
689 pfi_detach_rule(rule->kif);
856 }
857 pfi_detach_rule(rule->kif);
858 pf_anchor_remove(rule);
690 pf_empty_pool(&rule->rpool.list);
691 pool_put(&pf_rule_pl, rule);
692}
693
694static u_int16_t
695tagname2tag(struct pf_tags *head, char *tagname)
696{
697 struct pf_tagname *tag, *p = NULL;

--- 78 unchanged lines hidden (view full) ---

776
777void
778pf_tag2tagname(u_int16_t tagid, char *p)
779{
780 return (tag2tagname(&pf_tags, tagid, p));
781}
782
783void
859 pf_empty_pool(&rule->rpool.list);
860 pool_put(&pf_rule_pl, rule);
861}
862
863static u_int16_t
864tagname2tag(struct pf_tags *head, char *tagname)
865{
866 struct pf_tagname *tag, *p = NULL;

--- 78 unchanged lines hidden (view full) ---

945
946void
947pf_tag2tagname(u_int16_t tagid, char *p)
948{
949 return (tag2tagname(&pf_tags, tagid, p));
950}
951
952void
953pf_tag_ref(u_int16_t tag)
954{
955 struct pf_tagname *t;
956
957 TAILQ_FOREACH(t, &pf_tags, entries)
958 if (t->tag == tag)
959 break;
960 if (t != NULL)
961 t->ref++;
962}
963
964void
784pf_tag_unref(u_int16_t tag)
785{
786 return (tag_unref(&pf_tags, tag));
787}
788
965pf_tag_unref(u_int16_t tag)
966{
967 return (tag_unref(&pf_tags, tag));
968}
969
970int
971pf_rtlabel_add(struct pf_addr_wrap *a)
972{
973#ifdef __FreeBSD__
974 /* XXX_IMPORT: later */
975 return (0);
976#else
977 if (a->type == PF_ADDR_RTLABEL &&
978 (a->v.rtlabel = rtlabel_name2id(a->v.rtlabelname)) == 0)
979 return (-1);
980 return (0);
981#endif
982}
983
984void
985pf_rtlabel_remove(struct pf_addr_wrap *a)
986{
987#ifdef __FreeBSD__
988 /* XXX_IMPORT: later */
989#else
990 if (a->type == PF_ADDR_RTLABEL)
991 rtlabel_unref(a->v.rtlabel);
992#endif
993}
994
995void
996pf_rtlabel_copyout(struct pf_addr_wrap *a)
997{
998#ifdef __FreeBSD__
999 /* XXX_IMPORT: later */
1000 if (a->type == PF_ADDR_RTLABEL && a->v.rtlabel)
1001 strlcpy(a->v.rtlabelname, "?", sizeof(a->v.rtlabelname));
1002#else
1003 const char *name;
1004
1005 if (a->type == PF_ADDR_RTLABEL && a->v.rtlabel) {
1006 if ((name = rtlabel_id2name(a->v.rtlabel)) == NULL)
1007 strlcpy(a->v.rtlabelname, "?",
1008 sizeof(a->v.rtlabelname));
1009 else
1010 strlcpy(a->v.rtlabelname, name,
1011 sizeof(a->v.rtlabelname));
1012 }
1013#endif
1014}
1015
789#ifdef ALTQ
790u_int32_t
791pf_qname2qid(char *qname)
792{
793 return ((u_int32_t)tagname2tag(&pf_qids, qname));
794}
795
796void

--- 126 unchanged lines hidden (view full) ---

923 tb.depth = altq->tbrsize;
924 s = splimp();
925#ifdef __FreeBSD__
926 PF_UNLOCK();
927#endif
928 error = tbr_set(&ifp->if_snd, &tb);
929#ifdef __FreeBSD__
930 PF_LOCK();
1016#ifdef ALTQ
1017u_int32_t
1018pf_qname2qid(char *qname)
1019{
1020 return ((u_int32_t)tagname2tag(&pf_qids, qname));
1021}
1022
1023void

--- 126 unchanged lines hidden (view full) ---

1150 tb.depth = altq->tbrsize;
1151 s = splimp();
1152#ifdef __FreeBSD__
1153 PF_UNLOCK();
1154#endif
1155 error = tbr_set(&ifp->if_snd, &tb);
1156#ifdef __FreeBSD__
1157 PF_LOCK();
931#endif
1158#endif
932 splx(s);
933 }
934
935 return (error);
936}
937
938int
939pf_disable_altq(struct pf_altq *altq)

--- 28 unchanged lines hidden (view full) ---

968 splx(s);
969 }
970
971 return (error);
972}
973#endif /* ALTQ */
974
975int
1159 splx(s);
1160 }
1161
1162 return (error);
1163}
1164
1165int
1166pf_disable_altq(struct pf_altq *altq)

--- 28 unchanged lines hidden (view full) ---

1195 splx(s);
1196 }
1197
1198 return (error);
1199}
1200#endif /* ALTQ */
1201
1202int
976pf_begin_rules(u_int32_t *ticket, int rs_num, char *anchor, char *ruleset)
1203pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor)
977{
978 struct pf_ruleset *rs;
979 struct pf_rule *rule;
980
981 if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
982 return (EINVAL);
1204{
1205 struct pf_ruleset *rs;
1206 struct pf_rule *rule;
1207
1208 if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
1209 return (EINVAL);
983 rs = pf_find_or_create_ruleset(anchor, ruleset);
1210 rs = pf_find_or_create_ruleset(anchor);
984 if (rs == NULL)
985 return (EINVAL);
986 while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL)
987 pf_rm_rule(rs->rules[rs_num].inactive.ptr, rule);
988 *ticket = ++rs->rules[rs_num].inactive.ticket;
989 rs->rules[rs_num].inactive.open = 1;
990 return (0);
991}
992
993int
1211 if (rs == NULL)
1212 return (EINVAL);
1213 while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL)
1214 pf_rm_rule(rs->rules[rs_num].inactive.ptr, rule);
1215 *ticket = ++rs->rules[rs_num].inactive.ticket;
1216 rs->rules[rs_num].inactive.open = 1;
1217 return (0);
1218}
1219
1220int
994pf_rollback_rules(u_int32_t ticket, int rs_num, char *anchor, char *ruleset)
1221pf_rollback_rules(u_int32_t ticket, int rs_num, char *anchor)
995{
996 struct pf_ruleset *rs;
997 struct pf_rule *rule;
998
999 if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
1000 return (EINVAL);
1222{
1223 struct pf_ruleset *rs;
1224 struct pf_rule *rule;
1225
1226 if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
1227 return (EINVAL);
1001 rs = pf_find_ruleset(anchor, ruleset);
1228 rs = pf_find_ruleset(anchor);
1002 if (rs == NULL || !rs->rules[rs_num].inactive.open ||
1003 rs->rules[rs_num].inactive.ticket != ticket)
1004 return (0);
1005 while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL)
1006 pf_rm_rule(rs->rules[rs_num].inactive.ptr, rule);
1007 rs->rules[rs_num].inactive.open = 0;
1008 return (0);
1009}
1010
1011int
1229 if (rs == NULL || !rs->rules[rs_num].inactive.open ||
1230 rs->rules[rs_num].inactive.ticket != ticket)
1231 return (0);
1232 while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL)
1233 pf_rm_rule(rs->rules[rs_num].inactive.ptr, rule);
1234 rs->rules[rs_num].inactive.open = 0;
1235 return (0);
1236}
1237
1238int
1012pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor, char *ruleset)
1239pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
1013{
1014 struct pf_ruleset *rs;
1015 struct pf_rule *rule;
1016 struct pf_rulequeue *old_rules;
1017 int s;
1018
1019 if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
1020 return (EINVAL);
1240{
1241 struct pf_ruleset *rs;
1242 struct pf_rule *rule;
1243 struct pf_rulequeue *old_rules;
1244 int s;
1245
1246 if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
1247 return (EINVAL);
1021 rs = pf_find_ruleset(anchor, ruleset);
1248 rs = pf_find_ruleset(anchor);
1022 if (rs == NULL || !rs->rules[rs_num].inactive.open ||
1023 ticket != rs->rules[rs_num].inactive.ticket)
1024 return (EBUSY);
1025
1026 /* Swap rules, keep the old. */
1027 s = splsoftnet();
1028 old_rules = rs->rules[rs_num].active.ptr;
1029 rs->rules[rs_num].active.ptr =
1030 rs->rules[rs_num].inactive.ptr;
1031 rs->rules[rs_num].inactive.ptr = old_rules;
1032 rs->rules[rs_num].active.ticket =
1033 rs->rules[rs_num].inactive.ticket;
1034 pf_calc_skip_steps(rs->rules[rs_num].active.ptr);
1035
1036 /* Purge the old rule list. */
1037 while ((rule = TAILQ_FIRST(old_rules)) != NULL)
1038 pf_rm_rule(old_rules, rule);
1039 rs->rules[rs_num].inactive.open = 0;
1040 pf_remove_if_empty_ruleset(rs);
1249 if (rs == NULL || !rs->rules[rs_num].inactive.open ||
1250 ticket != rs->rules[rs_num].inactive.ticket)
1251 return (EBUSY);
1252
1253 /* Swap rules, keep the old. */
1254 s = splsoftnet();
1255 old_rules = rs->rules[rs_num].active.ptr;
1256 rs->rules[rs_num].active.ptr =
1257 rs->rules[rs_num].inactive.ptr;
1258 rs->rules[rs_num].inactive.ptr = old_rules;
1259 rs->rules[rs_num].active.ticket =
1260 rs->rules[rs_num].inactive.ticket;
1261 pf_calc_skip_steps(rs->rules[rs_num].active.ptr);
1262
1263 /* Purge the old rule list. */
1264 while ((rule = TAILQ_FIRST(old_rules)) != NULL)
1265 pf_rm_rule(old_rules, rule);
1266 rs->rules[rs_num].inactive.open = 0;
1267 pf_remove_if_empty_ruleset(rs);
1041 pf_update_anchor_rules();
1042 splx(s);
1043 return (0);
1044}
1045
1046#ifdef __FreeBSD__
1047int
1048pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
1049#else
1050int
1051pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
1052#endif
1053{
1054 struct pf_pooladdr *pa = NULL;
1055 struct pf_pool *pool = NULL;
1268 splx(s);
1269 return (0);
1270}
1271
1272#ifdef __FreeBSD__
1273int
1274pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
1275#else
1276int
1277pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
1278#endif
1279{
1280 struct pf_pooladdr *pa = NULL;
1281 struct pf_pool *pool = NULL;
1282#ifndef __FreeBSD__
1056 int s;
1283 int s;
1284#endif
1057 int error = 0;
1058
1059 /* XXX keep in sync with switch() below */
1060#ifdef __FreeBSD__
1061 if (securelevel_gt(td->td_ucred, 2))
1062#else
1063 if (securelevel > 1)
1064#endif

--- 10 unchanged lines hidden (view full) ---

1075 case DIOCSETDEBUG:
1076 case DIOCGETSTATES:
1077 case DIOCGETTIMEOUT:
1078 case DIOCCLRRULECTRS:
1079 case DIOCGETLIMIT:
1080 case DIOCGETALTQS:
1081 case DIOCGETALTQ:
1082 case DIOCGETQSTATS:
1285 int error = 0;
1286
1287 /* XXX keep in sync with switch() below */
1288#ifdef __FreeBSD__
1289 if (securelevel_gt(td->td_ucred, 2))
1290#else
1291 if (securelevel > 1)
1292#endif

--- 10 unchanged lines hidden (view full) ---

1303 case DIOCSETDEBUG:
1304 case DIOCGETSTATES:
1305 case DIOCGETTIMEOUT:
1306 case DIOCCLRRULECTRS:
1307 case DIOCGETLIMIT:
1308 case DIOCGETALTQS:
1309 case DIOCGETALTQ:
1310 case DIOCGETQSTATS:
1083 case DIOCGETANCHORS:
1084 case DIOCGETANCHOR:
1085 case DIOCGETRULESETS:
1086 case DIOCGETRULESET:
1087 case DIOCRGETTABLES:
1088 case DIOCRGETTSTATS:
1089 case DIOCRCLRTSTATS:
1090 case DIOCRCLRADDRS:
1091 case DIOCRADDADDRS:
1092 case DIOCRDELADDRS:

--- 5 unchanged lines hidden (view full) ---

1098 case DIOCOSFPGET:
1099 case DIOCGETSRCNODES:
1100 case DIOCCLRSRCNODES:
1101 case DIOCIGETIFACES:
1102 case DIOCICLRISTATS:
1103#ifdef __FreeBSD__
1104 case DIOCGIFSPEED:
1105#endif
1311 case DIOCGETRULESETS:
1312 case DIOCGETRULESET:
1313 case DIOCRGETTABLES:
1314 case DIOCRGETTSTATS:
1315 case DIOCRCLRTSTATS:
1316 case DIOCRCLRADDRS:
1317 case DIOCRADDADDRS:
1318 case DIOCRDELADDRS:

--- 5 unchanged lines hidden (view full) ---

1324 case DIOCOSFPGET:
1325 case DIOCGETSRCNODES:
1326 case DIOCCLRSRCNODES:
1327 case DIOCIGETIFACES:
1328 case DIOCICLRISTATS:
1329#ifdef __FreeBSD__
1330 case DIOCGIFSPEED:
1331#endif
1332 case DIOCSETIFFLAG:
1333 case DIOCCLRIFFLAG:
1106 break;
1107 case DIOCRCLRTABLES:
1108 case DIOCRADDTABLES:
1109 case DIOCRDELTABLES:
1110 case DIOCRSETTFLAGS:
1111 if (((struct pfioc_table *)addr)->pfrio_flags &
1112 PFR_FLAG_DUMMY)
1113 break; /* dummy operation ok */

--- 11 unchanged lines hidden (view full) ---

1125 case DIOCGETSTATE:
1126 case DIOCGETSTATUS:
1127 case DIOCGETSTATES:
1128 case DIOCGETTIMEOUT:
1129 case DIOCGETLIMIT:
1130 case DIOCGETALTQS:
1131 case DIOCGETALTQ:
1132 case DIOCGETQSTATS:
1334 break;
1335 case DIOCRCLRTABLES:
1336 case DIOCRADDTABLES:
1337 case DIOCRDELTABLES:
1338 case DIOCRSETTFLAGS:
1339 if (((struct pfioc_table *)addr)->pfrio_flags &
1340 PFR_FLAG_DUMMY)
1341 break; /* dummy operation ok */

--- 11 unchanged lines hidden (view full) ---

1353 case DIOCGETSTATE:
1354 case DIOCGETSTATUS:
1355 case DIOCGETSTATES:
1356 case DIOCGETTIMEOUT:
1357 case DIOCGETLIMIT:
1358 case DIOCGETALTQS:
1359 case DIOCGETALTQ:
1360 case DIOCGETQSTATS:
1133 case DIOCGETANCHORS:
1134 case DIOCGETANCHOR:
1135 case DIOCGETRULESETS:
1136 case DIOCGETRULESET:
1137 case DIOCRGETTABLES:
1138 case DIOCRGETTSTATS:
1139 case DIOCRGETADDRS:
1140 case DIOCRGETASTATS:
1141 case DIOCRTSTADDRS:
1142 case DIOCOSFPGET:

--- 17 unchanged lines hidden (view full) ---

1160 break; /* dummy operation ok */
1161 return (EACCES);
1162 default:
1163 return (EACCES);
1164 }
1165
1166#ifdef __FreeBSD__
1167 PF_LOCK();
1361 case DIOCGETRULESETS:
1362 case DIOCGETRULESET:
1363 case DIOCRGETTABLES:
1364 case DIOCRGETTSTATS:
1365 case DIOCRGETADDRS:
1366 case DIOCRGETASTATS:
1367 case DIOCRTSTADDRS:
1368 case DIOCOSFPGET:

--- 17 unchanged lines hidden (view full) ---

1386 break; /* dummy operation ok */
1387 return (EACCES);
1388 default:
1389 return (EACCES);
1390 }
1391
1392#ifdef __FreeBSD__
1393 PF_LOCK();
1394#else
1395 s = splsoftnet();
1168#endif
1396#endif
1169
1170 switch (cmd) {
1171
1172 case DIOCSTART:
1173 if (pf_status.running)
1174 error = EEXIST;
1175 else {
1176#ifdef __FreeBSD__
1177 PF_UNLOCK();
1178 error = hook_pf();
1179 PF_LOCK();
1180 if (error) {
1181 DPFPRINTF(PF_DEBUG_MISC,
1182 ("pf: pfil registeration fail\n"));
1183 break;
1184 }
1185#endif
1186 pf_status.running = 1;
1397 switch (cmd) {
1398
1399 case DIOCSTART:
1400 if (pf_status.running)
1401 error = EEXIST;
1402 else {
1403#ifdef __FreeBSD__
1404 PF_UNLOCK();
1405 error = hook_pf();
1406 PF_LOCK();
1407 if (error) {
1408 DPFPRINTF(PF_DEBUG_MISC,
1409 ("pf: pfil registeration fail\n"));
1410 break;
1411 }
1412#endif
1413 pf_status.running = 1;
1187#ifdef __FreeBSD__
1188 pf_status.since = time_second;
1414 pf_status.since = time_second;
1189#else
1190 pf_status.since = time.tv_sec;
1191#endif
1192 if (pf_status.stateid == 0) {
1415 if (pf_status.stateid == 0) {
1193#ifdef __FreeBSD__
1194 pf_status.stateid = time_second;
1416 pf_status.stateid = time_second;
1195#else
1196 pf_status.stateid = time.tv_sec;
1197#endif
1198 pf_status.stateid = pf_status.stateid << 32;
1199 }
1200 DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n"));
1201 }
1202 break;
1203
1204 case DIOCSTOP:
1205 if (!pf_status.running)

--- 4 unchanged lines hidden (view full) ---

1210 PF_UNLOCK();
1211 error = dehook_pf();
1212 PF_LOCK();
1213 if (error) {
1214 pf_status.running = 1;
1215 DPFPRINTF(PF_DEBUG_MISC,
1216 ("pf: pfil unregisteration failed\n"));
1217 }
1417 pf_status.stateid = pf_status.stateid << 32;
1418 }
1419 DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n"));
1420 }
1421 break;
1422
1423 case DIOCSTOP:
1424 if (!pf_status.running)

--- 4 unchanged lines hidden (view full) ---

1429 PF_UNLOCK();
1430 error = dehook_pf();
1431 PF_LOCK();
1432 if (error) {
1433 pf_status.running = 1;
1434 DPFPRINTF(PF_DEBUG_MISC,
1435 ("pf: pfil unregisteration failed\n"));
1436 }
1218 pf_status.since = time_second;
1219#else
1220 pf_status.since = time.tv_sec;
1221#endif
1437#endif
1438 pf_status.since = time_second;
1222 DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n"));
1223 }
1224 break;
1225
1439 DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n"));
1440 }
1441 break;
1442
1226 case DIOCBEGINRULES: {
1227 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
1228
1229 error = pf_begin_rules(&pr->ticket, pf_get_ruleset_number(
1230 pr->rule.action), pr->anchor, pr->ruleset);
1231 break;
1232 }
1233
1234 case DIOCADDRULE: {
1235 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
1236 struct pf_ruleset *ruleset;
1237 struct pf_rule *rule, *tail;
1238 struct pf_pooladdr *pa;
1239 int rs_num;
1240
1443 case DIOCADDRULE: {
1444 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
1445 struct pf_ruleset *ruleset;
1446 struct pf_rule *rule, *tail;
1447 struct pf_pooladdr *pa;
1448 int rs_num;
1449
1241 ruleset = pf_find_ruleset(pr->anchor, pr->ruleset);
1450 pr->anchor[sizeof(pr->anchor) - 1] = 0;
1451 ruleset = pf_find_ruleset(pr->anchor);
1242 if (ruleset == NULL) {
1243 error = EINVAL;
1244 break;
1245 }
1246 rs_num = pf_get_ruleset_number(pr->rule.action);
1247 if (rs_num >= PF_RULESET_MAX) {
1248 error = EINVAL;
1249 break;
1250 }
1452 if (ruleset == NULL) {
1453 error = EINVAL;
1454 break;
1455 }
1456 rs_num = pf_get_ruleset_number(pr->rule.action);
1457 if (rs_num >= PF_RULESET_MAX) {
1458 error = EINVAL;
1459 break;
1460 }
1251 if (pr->rule.anchorname[0] && ruleset != &pf_main_ruleset) {
1252 error = EINVAL;
1253 break;
1254 }
1255 if (pr->rule.return_icmp >> 8 > ICMP_MAXTYPE) {
1256 error = EINVAL;
1257 break;
1258 }
1259 if (pr->ticket != ruleset->rules[rs_num].inactive.ticket) {
1461 if (pr->rule.return_icmp >> 8 > ICMP_MAXTYPE) {
1462 error = EINVAL;
1463 break;
1464 }
1465 if (pr->ticket != ruleset->rules[rs_num].inactive.ticket) {
1466 printf("ticket: %d != [%d]%d\n", pr->ticket,
1467 rs_num, ruleset->rules[rs_num].inactive.ticket);
1260 error = EBUSY;
1261 break;
1262 }
1263 if (pr->pool_ticket != ticket_pabuf) {
1468 error = EBUSY;
1469 break;
1470 }
1471 if (pr->pool_ticket != ticket_pabuf) {
1472 printf("pool_ticket: %d != %d\n", pr->pool_ticket,
1473 ticket_pabuf);
1264 error = EBUSY;
1265 break;
1266 }
1267 rule = pool_get(&pf_rule_pl, PR_NOWAIT);
1268 if (rule == NULL) {
1269 error = ENOMEM;
1270 break;
1271 }

--- 51 unchanged lines hidden (view full) ---

1323 if ((rule->tag = pf_tagname2tag(rule->tagname)) == 0)
1324 error = EBUSY;
1325 if (rule->match_tagname[0])
1326 if ((rule->match_tag =
1327 pf_tagname2tag(rule->match_tagname)) == 0)
1328 error = EBUSY;
1329 if (rule->rt && !rule->direction)
1330 error = EINVAL;
1474 error = EBUSY;
1475 break;
1476 }
1477 rule = pool_get(&pf_rule_pl, PR_NOWAIT);
1478 if (rule == NULL) {
1479 error = ENOMEM;
1480 break;
1481 }

--- 51 unchanged lines hidden (view full) ---

1533 if ((rule->tag = pf_tagname2tag(rule->tagname)) == 0)
1534 error = EBUSY;
1535 if (rule->match_tagname[0])
1536 if ((rule->match_tag =
1537 pf_tagname2tag(rule->match_tagname)) == 0)
1538 error = EBUSY;
1539 if (rule->rt && !rule->direction)
1540 error = EINVAL;
1541 if (pf_rtlabel_add(&rule->src.addr) ||
1542 pf_rtlabel_add(&rule->dst.addr))
1543 error = EBUSY;
1331 if (pfi_dynaddr_setup(&rule->src.addr, rule->af))
1332 error = EINVAL;
1333 if (pfi_dynaddr_setup(&rule->dst.addr, rule->af))
1334 error = EINVAL;
1335 if (pf_tbladdr_setup(ruleset, &rule->src.addr))
1336 error = EINVAL;
1337 if (pf_tbladdr_setup(ruleset, &rule->dst.addr))
1338 error = EINVAL;
1544 if (pfi_dynaddr_setup(&rule->src.addr, rule->af))
1545 error = EINVAL;
1546 if (pfi_dynaddr_setup(&rule->dst.addr, rule->af))
1547 error = EINVAL;
1548 if (pf_tbladdr_setup(ruleset, &rule->src.addr))
1549 error = EINVAL;
1550 if (pf_tbladdr_setup(ruleset, &rule->dst.addr))
1551 error = EINVAL;
1552 if (pf_anchor_setup(rule, ruleset, pr->anchor_call))
1553 error = EINVAL;
1339 TAILQ_FOREACH(pa, &pf_pabuf, entries)
1340 if (pf_tbladdr_setup(ruleset, &pa->addr))
1341 error = EINVAL;
1342
1554 TAILQ_FOREACH(pa, &pf_pabuf, entries)
1555 if (pf_tbladdr_setup(ruleset, &pa->addr))
1556 error = EINVAL;
1557
1558 if (rule->overload_tblname[0]) {
1559 if ((rule->overload_tbl = pfr_attach_table(ruleset,
1560 rule->overload_tblname)) == NULL)
1561 error = EINVAL;
1562 else
1563 rule->overload_tbl->pfrkt_flags |=
1564 PFR_TFLAG_ACTIVE;
1565 }
1566
1343 pf_mv_pool(&pf_pabuf, &rule->rpool.list);
1344 if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) ||
1567 pf_mv_pool(&pf_pabuf, &rule->rpool.list);
1568 if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) ||
1345 (rule->action == PF_BINAT)) && !rule->anchorname[0]) ||
1569 (rule->action == PF_BINAT)) && rule->anchor == NULL) ||
1346 (rule->rt > PF_FASTROUTE)) &&
1347 (TAILQ_FIRST(&rule->rpool.list) == NULL))
1348 error = EINVAL;
1349
1350 if (error) {
1351 pf_rm_rule(NULL, rule);
1352 break;
1353 }
1354 rule->rpool.cur = TAILQ_FIRST(&rule->rpool.list);
1355 rule->evaluations = rule->packets = rule->bytes = 0;
1356 TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr,
1357 rule, entries);
1358 break;
1359 }
1360
1570 (rule->rt > PF_FASTROUTE)) &&
1571 (TAILQ_FIRST(&rule->rpool.list) == NULL))
1572 error = EINVAL;
1573
1574 if (error) {
1575 pf_rm_rule(NULL, rule);
1576 break;
1577 }
1578 rule->rpool.cur = TAILQ_FIRST(&rule->rpool.list);
1579 rule->evaluations = rule->packets = rule->bytes = 0;
1580 TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr,
1581 rule, entries);
1582 break;
1583 }
1584
1361 case DIOCCOMMITRULES: {
1362 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
1363
1364 error = pf_commit_rules(pr->ticket, pf_get_ruleset_number(
1365 pr->rule.action), pr->anchor, pr->ruleset);
1366 break;
1367 }
1368
1369 case DIOCGETRULES: {
1370 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
1371 struct pf_ruleset *ruleset;
1372 struct pf_rule *tail;
1373 int rs_num;
1374
1585 case DIOCGETRULES: {
1586 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
1587 struct pf_ruleset *ruleset;
1588 struct pf_rule *tail;
1589 int rs_num;
1590
1375 ruleset = pf_find_ruleset(pr->anchor, pr->ruleset);
1591 pr->anchor[sizeof(pr->anchor) - 1] = 0;
1592 ruleset = pf_find_ruleset(pr->anchor);
1376 if (ruleset == NULL) {
1377 error = EINVAL;
1378 break;
1379 }
1380 rs_num = pf_get_ruleset_number(pr->rule.action);
1381 if (rs_num >= PF_RULESET_MAX) {
1382 error = EINVAL;
1383 break;
1384 }
1593 if (ruleset == NULL) {
1594 error = EINVAL;
1595 break;
1596 }
1597 rs_num = pf_get_ruleset_number(pr->rule.action);
1598 if (rs_num >= PF_RULESET_MAX) {
1599 error = EINVAL;
1600 break;
1601 }
1385 s = splsoftnet();
1386 tail = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
1387 pf_rulequeue);
1388 if (tail)
1389 pr->nr = tail->nr + 1;
1390 else
1391 pr->nr = 0;
1392 pr->ticket = ruleset->rules[rs_num].active.ticket;
1602 tail = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
1603 pf_rulequeue);
1604 if (tail)
1605 pr->nr = tail->nr + 1;
1606 else
1607 pr->nr = 0;
1608 pr->ticket = ruleset->rules[rs_num].active.ticket;
1393 splx(s);
1394 break;
1395 }
1396
1397 case DIOCGETRULE: {
1398 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
1399 struct pf_ruleset *ruleset;
1400 struct pf_rule *rule;
1401 int rs_num, i;
1402
1609 break;
1610 }
1611
1612 case DIOCGETRULE: {
1613 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
1614 struct pf_ruleset *ruleset;
1615 struct pf_rule *rule;
1616 int rs_num, i;
1617
1403 ruleset = pf_find_ruleset(pr->anchor, pr->ruleset);
1618 pr->anchor[sizeof(pr->anchor) - 1] = 0;
1619 ruleset = pf_find_ruleset(pr->anchor);
1404 if (ruleset == NULL) {
1405 error = EINVAL;
1406 break;
1407 }
1408 rs_num = pf_get_ruleset_number(pr->rule.action);
1409 if (rs_num >= PF_RULESET_MAX) {
1410 error = EINVAL;
1411 break;
1412 }
1413 if (pr->ticket != ruleset->rules[rs_num].active.ticket) {
1414 error = EBUSY;
1415 break;
1416 }
1620 if (ruleset == NULL) {
1621 error = EINVAL;
1622 break;
1623 }
1624 rs_num = pf_get_ruleset_number(pr->rule.action);
1625 if (rs_num >= PF_RULESET_MAX) {
1626 error = EINVAL;
1627 break;
1628 }
1629 if (pr->ticket != ruleset->rules[rs_num].active.ticket) {
1630 error = EBUSY;
1631 break;
1632 }
1417 s = splsoftnet();
1418 rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
1419 while ((rule != NULL) && (rule->nr != pr->nr))
1420 rule = TAILQ_NEXT(rule, entries);
1421 if (rule == NULL) {
1422 error = EBUSY;
1633 rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
1634 while ((rule != NULL) && (rule->nr != pr->nr))
1635 rule = TAILQ_NEXT(rule, entries);
1636 if (rule == NULL) {
1637 error = EBUSY;
1423 splx(s);
1424 break;
1425 }
1426 bcopy(rule, &pr->rule, sizeof(struct pf_rule));
1638 break;
1639 }
1640 bcopy(rule, &pr->rule, sizeof(struct pf_rule));
1641 if (pf_anchor_copyout(ruleset, rule, pr)) {
1642 error = EBUSY;
1643 break;
1644 }
1427 pfi_dynaddr_copyout(&pr->rule.src.addr);
1428 pfi_dynaddr_copyout(&pr->rule.dst.addr);
1429 pf_tbladdr_copyout(&pr->rule.src.addr);
1430 pf_tbladdr_copyout(&pr->rule.dst.addr);
1645 pfi_dynaddr_copyout(&pr->rule.src.addr);
1646 pfi_dynaddr_copyout(&pr->rule.dst.addr);
1647 pf_tbladdr_copyout(&pr->rule.src.addr);
1648 pf_tbladdr_copyout(&pr->rule.dst.addr);
1649 pf_rtlabel_copyout(&pr->rule.src.addr);
1650 pf_rtlabel_copyout(&pr->rule.dst.addr);
1431 for (i = 0; i < PF_SKIP_COUNT; ++i)
1432 if (rule->skip[i].ptr == NULL)
1433 pr->rule.skip[i].nr = -1;
1434 else
1435 pr->rule.skip[i].nr =
1436 rule->skip[i].ptr->nr;
1651 for (i = 0; i < PF_SKIP_COUNT; ++i)
1652 if (rule->skip[i].ptr == NULL)
1653 pr->rule.skip[i].nr = -1;
1654 else
1655 pr->rule.skip[i].nr =
1656 rule->skip[i].ptr->nr;
1437 splx(s);
1438 break;
1439 }
1440
1441 case DIOCCHANGERULE: {
1442 struct pfioc_rule *pcr = (struct pfioc_rule *)addr;
1443 struct pf_ruleset *ruleset;
1444 struct pf_rule *oldrule = NULL, *newrule = NULL;
1445 u_int32_t nr = 0;

--- 6 unchanged lines hidden (view full) ---

1452 break;
1453 }
1454
1455 if (pcr->action < PF_CHANGE_ADD_HEAD ||
1456 pcr->action > PF_CHANGE_GET_TICKET) {
1457 error = EINVAL;
1458 break;
1459 }
1657 break;
1658 }
1659
1660 case DIOCCHANGERULE: {
1661 struct pfioc_rule *pcr = (struct pfioc_rule *)addr;
1662 struct pf_ruleset *ruleset;
1663 struct pf_rule *oldrule = NULL, *newrule = NULL;
1664 u_int32_t nr = 0;

--- 6 unchanged lines hidden (view full) ---

1671 break;
1672 }
1673
1674 if (pcr->action < PF_CHANGE_ADD_HEAD ||
1675 pcr->action > PF_CHANGE_GET_TICKET) {
1676 error = EINVAL;
1677 break;
1678 }
1460 ruleset = pf_find_ruleset(pcr->anchor, pcr->ruleset);
1679 ruleset = pf_find_ruleset(pcr->anchor);
1461 if (ruleset == NULL) {
1462 error = EINVAL;
1463 break;
1464 }
1465 rs_num = pf_get_ruleset_number(pcr->rule.action);
1466 if (rs_num >= PF_RULESET_MAX) {
1467 error = EINVAL;
1468 break;

--- 57 unchanged lines hidden (view full) ---

1526 error = EBUSY;
1527 else if (newrule->pqname[0] != 0) {
1528 if ((newrule->pqid =
1529 pf_qname2qid(newrule->pqname)) == 0)
1530 error = EBUSY;
1531 } else
1532 newrule->pqid = newrule->qid;
1533 }
1680 if (ruleset == NULL) {
1681 error = EINVAL;
1682 break;
1683 }
1684 rs_num = pf_get_ruleset_number(pcr->rule.action);
1685 if (rs_num >= PF_RULESET_MAX) {
1686 error = EINVAL;
1687 break;

--- 57 unchanged lines hidden (view full) ---

1745 error = EBUSY;
1746 else if (newrule->pqname[0] != 0) {
1747 if ((newrule->pqid =
1748 pf_qname2qid(newrule->pqname)) == 0)
1749 error = EBUSY;
1750 } else
1751 newrule->pqid = newrule->qid;
1752 }
1534#endif
1753#endif /* ALTQ */
1535 if (newrule->tagname[0])
1536 if ((newrule->tag =
1537 pf_tagname2tag(newrule->tagname)) == 0)
1538 error = EBUSY;
1539 if (newrule->match_tagname[0])
1540 if ((newrule->match_tag = pf_tagname2tag(
1541 newrule->match_tagname)) == 0)
1542 error = EBUSY;
1754 if (newrule->tagname[0])
1755 if ((newrule->tag =
1756 pf_tagname2tag(newrule->tagname)) == 0)
1757 error = EBUSY;
1758 if (newrule->match_tagname[0])
1759 if ((newrule->match_tag = pf_tagname2tag(
1760 newrule->match_tagname)) == 0)
1761 error = EBUSY;
1543
1544 if (newrule->rt && !newrule->direction)
1545 error = EINVAL;
1762 if (newrule->rt && !newrule->direction)
1763 error = EINVAL;
1764 if (pf_rtlabel_add(&newrule->src.addr) ||
1765 pf_rtlabel_add(&newrule->dst.addr))
1766 error = EBUSY;
1546 if (pfi_dynaddr_setup(&newrule->src.addr, newrule->af))
1547 error = EINVAL;
1548 if (pfi_dynaddr_setup(&newrule->dst.addr, newrule->af))
1549 error = EINVAL;
1550 if (pf_tbladdr_setup(ruleset, &newrule->src.addr))
1551 error = EINVAL;
1552 if (pf_tbladdr_setup(ruleset, &newrule->dst.addr))
1553 error = EINVAL;
1767 if (pfi_dynaddr_setup(&newrule->src.addr, newrule->af))
1768 error = EINVAL;
1769 if (pfi_dynaddr_setup(&newrule->dst.addr, newrule->af))
1770 error = EINVAL;
1771 if (pf_tbladdr_setup(ruleset, &newrule->src.addr))
1772 error = EINVAL;
1773 if (pf_tbladdr_setup(ruleset, &newrule->dst.addr))
1774 error = EINVAL;
1775 if (pf_anchor_setup(newrule, ruleset, pcr->anchor_call))
1776 error = EINVAL;
1554
1777
1778 if (newrule->overload_tblname[0]) {
1779 if ((newrule->overload_tbl = pfr_attach_table(
1780 ruleset, newrule->overload_tblname)) ==
1781 NULL)
1782 error = EINVAL;
1783 else
1784 newrule->overload_tbl->pfrkt_flags |=
1785 PFR_TFLAG_ACTIVE;
1786 }
1787
1555 pf_mv_pool(&pf_pabuf, &newrule->rpool.list);
1556 if (((((newrule->action == PF_NAT) ||
1557 (newrule->action == PF_RDR) ||
1558 (newrule->action == PF_BINAT) ||
1559 (newrule->rt > PF_FASTROUTE)) &&
1788 pf_mv_pool(&pf_pabuf, &newrule->rpool.list);
1789 if (((((newrule->action == PF_NAT) ||
1790 (newrule->action == PF_RDR) ||
1791 (newrule->action == PF_BINAT) ||
1792 (newrule->rt > PF_FASTROUTE)) &&
1560 !newrule->anchorname[0])) &&
1793 !pcr->anchor[0])) &&
1561 (TAILQ_FIRST(&newrule->rpool.list) == NULL))
1562 error = EINVAL;
1563
1564 if (error) {
1565 pf_rm_rule(NULL, newrule);
1566 break;
1567 }
1568 newrule->rpool.cur = TAILQ_FIRST(&newrule->rpool.list);
1569 newrule->evaluations = newrule->packets = 0;
1570 newrule->bytes = 0;
1571 }
1572 pf_empty_pool(&pf_pabuf);
1573
1794 (TAILQ_FIRST(&newrule->rpool.list) == NULL))
1795 error = EINVAL;
1796
1797 if (error) {
1798 pf_rm_rule(NULL, newrule);
1799 break;
1800 }
1801 newrule->rpool.cur = TAILQ_FIRST(&newrule->rpool.list);
1802 newrule->evaluations = newrule->packets = 0;
1803 newrule->bytes = 0;
1804 }
1805 pf_empty_pool(&pf_pabuf);
1806
1574 s = splsoftnet();
1575
1576 if (pcr->action == PF_CHANGE_ADD_HEAD)
1577 oldrule = TAILQ_FIRST(
1578 ruleset->rules[rs_num].active.ptr);
1579 else if (pcr->action == PF_CHANGE_ADD_TAIL)
1580 oldrule = TAILQ_LAST(
1581 ruleset->rules[rs_num].active.ptr, pf_rulequeue);
1582 else {
1583 oldrule = TAILQ_FIRST(
1584 ruleset->rules[rs_num].active.ptr);
1585 while ((oldrule != NULL) && (oldrule->nr != pcr->nr))
1586 oldrule = TAILQ_NEXT(oldrule, entries);
1587 if (oldrule == NULL) {
1588 if (newrule != NULL)
1589 pf_rm_rule(NULL, newrule);
1590 error = EINVAL;
1807 if (pcr->action == PF_CHANGE_ADD_HEAD)
1808 oldrule = TAILQ_FIRST(
1809 ruleset->rules[rs_num].active.ptr);
1810 else if (pcr->action == PF_CHANGE_ADD_TAIL)
1811 oldrule = TAILQ_LAST(
1812 ruleset->rules[rs_num].active.ptr, pf_rulequeue);
1813 else {
1814 oldrule = TAILQ_FIRST(
1815 ruleset->rules[rs_num].active.ptr);
1816 while ((oldrule != NULL) && (oldrule->nr != pcr->nr))
1817 oldrule = TAILQ_NEXT(oldrule, entries);
1818 if (oldrule == NULL) {
1819 if (newrule != NULL)
1820 pf_rm_rule(NULL, newrule);
1821 error = EINVAL;
1591 splx(s);
1592 break;
1593 }
1594 }
1595
1596 if (pcr->action == PF_CHANGE_REMOVE)
1597 pf_rm_rule(ruleset->rules[rs_num].active.ptr, oldrule);
1598 else {
1599 if (oldrule == NULL)

--- 9 unchanged lines hidden (view full) ---

1609 oldrule, newrule, entries);
1610 }
1611
1612 nr = 0;
1613 TAILQ_FOREACH(oldrule,
1614 ruleset->rules[rs_num].active.ptr, entries)
1615 oldrule->nr = nr++;
1616
1822 break;
1823 }
1824 }
1825
1826 if (pcr->action == PF_CHANGE_REMOVE)
1827 pf_rm_rule(ruleset->rules[rs_num].active.ptr, oldrule);
1828 else {
1829 if (oldrule == NULL)

--- 9 unchanged lines hidden (view full) ---

1839 oldrule, newrule, entries);
1840 }
1841
1842 nr = 0;
1843 TAILQ_FOREACH(oldrule,
1844 ruleset->rules[rs_num].active.ptr, entries)
1845 oldrule->nr = nr++;
1846
1847 ruleset->rules[rs_num].active.ticket++;
1848
1617 pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr);
1618 pf_remove_if_empty_ruleset(ruleset);
1849 pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr);
1850 pf_remove_if_empty_ruleset(ruleset);
1619 pf_update_anchor_rules();
1620
1851
1621 ruleset->rules[rs_num].active.ticket++;
1622 splx(s);
1623 break;
1624 }
1625
1626 case DIOCCLRSTATES: {
1627 struct pf_state *state;
1628 struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
1629 int killed = 0;
1630
1852 break;
1853 }
1854
1855 case DIOCCLRSTATES: {
1856 struct pf_state *state;
1857 struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
1858 int killed = 0;
1859
1631 s = splsoftnet();
1632 RB_FOREACH(state, pf_state_tree_id, &tree_id) {
1633 if (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname,
1634 state->u.s.kif->pfik_name)) {
1635 state->timeout = PFTM_PURGE;
1636#if NPFSYNC
1637 /* don't send out individual delete messages */
1638 state->sync_flags = PFSTATE_NOSYNC;
1639#endif
1640 killed++;
1641 }
1642 }
1643 pf_purge_expired_states();
1644 pf_status.states = 0;
1645 psk->psk_af = killed;
1646#if NPFSYNC
1647 pfsync_clear_states(pf_status.hostid, psk->psk_ifname);
1648#endif
1860 RB_FOREACH(state, pf_state_tree_id, &tree_id) {
1861 if (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname,
1862 state->u.s.kif->pfik_name)) {
1863 state->timeout = PFTM_PURGE;
1864#if NPFSYNC
1865 /* don't send out individual delete messages */
1866 state->sync_flags = PFSTATE_NOSYNC;
1867#endif
1868 killed++;
1869 }
1870 }
1871 pf_purge_expired_states();
1872 pf_status.states = 0;
1873 psk->psk_af = killed;
1874#if NPFSYNC
1875 pfsync_clear_states(pf_status.hostid, psk->psk_ifname);
1876#endif
1649 splx(s);
1650 break;
1651 }
1652
1653 case DIOCKILLSTATES: {
1654 struct pf_state *state;
1655 struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
1656 int killed = 0;
1657
1877 break;
1878 }
1879
1880 case DIOCKILLSTATES: {
1881 struct pf_state *state;
1882 struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
1883 int killed = 0;
1884
1658 s = splsoftnet();
1659 RB_FOREACH(state, pf_state_tree_id, &tree_id) {
1660 if ((!psk->psk_af || state->af == psk->psk_af)
1661 && (!psk->psk_proto || psk->psk_proto ==
1662 state->proto) &&
1885 RB_FOREACH(state, pf_state_tree_id, &tree_id) {
1886 if ((!psk->psk_af || state->af == psk->psk_af)
1887 && (!psk->psk_proto || psk->psk_proto ==
1888 state->proto) &&
1663 PF_MATCHA(psk->psk_src.not,
1889 PF_MATCHA(psk->psk_src.neg,
1664 &psk->psk_src.addr.v.a.addr,
1665 &psk->psk_src.addr.v.a.mask,
1666 &state->lan.addr, state->af) &&
1890 &psk->psk_src.addr.v.a.addr,
1891 &psk->psk_src.addr.v.a.mask,
1892 &state->lan.addr, state->af) &&
1667 PF_MATCHA(psk->psk_dst.not,
1893 PF_MATCHA(psk->psk_dst.neg,
1668 &psk->psk_dst.addr.v.a.addr,
1669 &psk->psk_dst.addr.v.a.mask,
1670 &state->ext.addr, state->af) &&
1671 (psk->psk_src.port_op == 0 ||
1672 pf_match_port(psk->psk_src.port_op,
1673 psk->psk_src.port[0], psk->psk_src.port[1],
1674 state->lan.port)) &&
1675 (psk->psk_dst.port_op == 0 ||
1676 pf_match_port(psk->psk_dst.port_op,
1677 psk->psk_dst.port[0], psk->psk_dst.port[1],
1678 state->ext.port)) &&
1679 (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname,
1680 state->u.s.kif->pfik_name))) {
1681 state->timeout = PFTM_PURGE;
1682 killed++;
1683 }
1684 }
1685 pf_purge_expired_states();
1894 &psk->psk_dst.addr.v.a.addr,
1895 &psk->psk_dst.addr.v.a.mask,
1896 &state->ext.addr, state->af) &&
1897 (psk->psk_src.port_op == 0 ||
1898 pf_match_port(psk->psk_src.port_op,
1899 psk->psk_src.port[0], psk->psk_src.port[1],
1900 state->lan.port)) &&
1901 (psk->psk_dst.port_op == 0 ||
1902 pf_match_port(psk->psk_dst.port_op,
1903 psk->psk_dst.port[0], psk->psk_dst.port[1],
1904 state->ext.port)) &&
1905 (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname,
1906 state->u.s.kif->pfik_name))) {
1907 state->timeout = PFTM_PURGE;
1908 killed++;
1909 }
1910 }
1911 pf_purge_expired_states();
1686 splx(s);
1687 psk->psk_af = killed;
1688 break;
1689 }
1690
1691 case DIOCADDSTATE: {
1692 struct pfioc_state *ps = (struct pfioc_state *)addr;
1693 struct pf_state *state;
1694 struct pfi_kif *kif;
1695
1696 if (ps->state.timeout >= PFTM_MAX &&
1697 ps->state.timeout != PFTM_UNTIL_PACKET) {
1698 error = EINVAL;
1699 break;
1700 }
1701 state = pool_get(&pf_state_pl, PR_NOWAIT);
1702 if (state == NULL) {
1703 error = ENOMEM;
1704 break;
1705 }
1912 psk->psk_af = killed;
1913 break;
1914 }
1915
1916 case DIOCADDSTATE: {
1917 struct pfioc_state *ps = (struct pfioc_state *)addr;
1918 struct pf_state *state;
1919 struct pfi_kif *kif;
1920
1921 if (ps->state.timeout >= PFTM_MAX &&
1922 ps->state.timeout != PFTM_UNTIL_PACKET) {
1923 error = EINVAL;
1924 break;
1925 }
1926 state = pool_get(&pf_state_pl, PR_NOWAIT);
1927 if (state == NULL) {
1928 error = ENOMEM;
1929 break;
1930 }
1706 s = splsoftnet();
1707 kif = pfi_lookup_create(ps->state.u.ifname);
1708 if (kif == NULL) {
1709 pool_put(&pf_state_pl, state);
1710 error = ENOENT;
1931 kif = pfi_lookup_create(ps->state.u.ifname);
1932 if (kif == NULL) {
1933 pool_put(&pf_state_pl, state);
1934 error = ENOENT;
1711 splx(s);
1712 break;
1713 }
1714 bcopy(&ps->state, state, sizeof(struct pf_state));
1715 bzero(&state->u, sizeof(state->u));
1716 state->rule.ptr = &pf_default_rule;
1717 state->nat_rule.ptr = NULL;
1718 state->anchor.ptr = NULL;
1719 state->rt_kif = NULL;
1935 break;
1936 }
1937 bcopy(&ps->state, state, sizeof(struct pf_state));
1938 bzero(&state->u, sizeof(state->u));
1939 state->rule.ptr = &pf_default_rule;
1940 state->nat_rule.ptr = NULL;
1941 state->anchor.ptr = NULL;
1942 state->rt_kif = NULL;
1720#ifdef __FreeBSD__
1721 state->creation = time_second;
1943 state->creation = time_second;
1722#else
1723 state->creation = time.tv_sec;
1724#endif
1725 state->pfsync_time = 0;
1726 state->packets[0] = state->packets[1] = 0;
1727 state->bytes[0] = state->bytes[1] = 0;
1728
1729 if (pf_insert_state(kif, state)) {
1730 pfi_maybe_destroy(kif);
1731 pool_put(&pf_state_pl, state);
1732 error = ENOMEM;
1733 }
1944 state->pfsync_time = 0;
1945 state->packets[0] = state->packets[1] = 0;
1946 state->bytes[0] = state->bytes[1] = 0;
1947
1948 if (pf_insert_state(kif, state)) {
1949 pfi_maybe_destroy(kif);
1950 pool_put(&pf_state_pl, state);
1951 error = ENOMEM;
1952 }
1734 splx(s);
1735 break;
1736 }
1737
1738 case DIOCGETSTATE: {
1739 struct pfioc_state *ps = (struct pfioc_state *)addr;
1740 struct pf_state *state;
1741 u_int32_t nr;
1742
1743 nr = 0;
1953 break;
1954 }
1955
1956 case DIOCGETSTATE: {
1957 struct pfioc_state *ps = (struct pfioc_state *)addr;
1958 struct pf_state *state;
1959 u_int32_t nr;
1960
1961 nr = 0;
1744 s = splsoftnet();
1745 RB_FOREACH(state, pf_state_tree_id, &tree_id) {
1746 if (nr >= ps->nr)
1747 break;
1748 nr++;
1749 }
1750 if (state == NULL) {
1751 error = EBUSY;
1962 RB_FOREACH(state, pf_state_tree_id, &tree_id) {
1963 if (nr >= ps->nr)
1964 break;
1965 nr++;
1966 }
1967 if (state == NULL) {
1968 error = EBUSY;
1752 splx(s);
1753 break;
1754 }
1755 bcopy(state, &ps->state, sizeof(struct pf_state));
1756 ps->state.rule.nr = state->rule.ptr->nr;
1757 ps->state.nat_rule.nr = (state->nat_rule.ptr == NULL) ?
1758 -1 : state->nat_rule.ptr->nr;
1759 ps->state.anchor.nr = (state->anchor.ptr == NULL) ?
1760 -1 : state->anchor.ptr->nr;
1969 break;
1970 }
1971 bcopy(state, &ps->state, sizeof(struct pf_state));
1972 ps->state.rule.nr = state->rule.ptr->nr;
1973 ps->state.nat_rule.nr = (state->nat_rule.ptr == NULL) ?
1974 -1 : state->nat_rule.ptr->nr;
1975 ps->state.anchor.nr = (state->anchor.ptr == NULL) ?
1976 -1 : state->anchor.ptr->nr;
1761 splx(s);
1762 ps->state.expire = pf_state_expires(state);
1977 ps->state.expire = pf_state_expires(state);
1763#ifdef __FreeBSD__
1764 if (ps->state.expire > time_second)
1765 ps->state.expire -= time_second;
1978 if (ps->state.expire > time_second)
1979 ps->state.expire -= time_second;
1766#else
1767 if (ps->state.expire > time.tv_sec)
1768 ps->state.expire -= time.tv_sec;
1769#endif
1770 else
1771 ps->state.expire = 0;
1772 break;
1773 }
1774
1775 case DIOCGETSTATES: {
1776 struct pfioc_states *ps = (struct pfioc_states *)addr;
1777 struct pf_state *state;
1778 struct pf_state *p, pstore;
1779 struct pfi_kif *kif;
1780 u_int32_t nr = 0;
1781 int space = ps->ps_len;
1782
1783 if (space == 0) {
1980 else
1981 ps->state.expire = 0;
1982 break;
1983 }
1984
1985 case DIOCGETSTATES: {
1986 struct pfioc_states *ps = (struct pfioc_states *)addr;
1987 struct pf_state *state;
1988 struct pf_state *p, pstore;
1989 struct pfi_kif *kif;
1990 u_int32_t nr = 0;
1991 int space = ps->ps_len;
1992
1993 if (space == 0) {
1784 s = splsoftnet();
1785 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states)
1786 nr += kif->pfik_states;
1994 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states)
1995 nr += kif->pfik_states;
1787 splx(s);
1788 ps->ps_len = sizeof(struct pf_state) * nr;
1996 ps->ps_len = sizeof(struct pf_state) * nr;
1789#ifdef __FreeBSD__
1790 PF_UNLOCK();
1791#endif
1792 return (0);
1997 break;
1793 }
1794
1998 }
1999
1795 s = splsoftnet();
1796 p = ps->ps_states;
1797 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states)
1798 RB_FOREACH(state, pf_state_tree_ext_gwy,
1799 &kif->pfik_ext_gwy) {
2000 p = ps->ps_states;
2001 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states)
2002 RB_FOREACH(state, pf_state_tree_ext_gwy,
2003 &kif->pfik_ext_gwy) {
1800#ifdef __FreeBSD__
1801 int secs = time_second;
2004 int secs = time_second;
1802#else
1803 int secs = time.tv_sec;
1804#endif
1805
1806 if ((nr+1) * sizeof(*p) > (unsigned)ps->ps_len)
1807 break;
1808
1809 bcopy(state, &pstore, sizeof(pstore));
1810 strlcpy(pstore.u.ifname, kif->pfik_name,
1811 sizeof(pstore.u.ifname));
1812 pstore.rule.nr = state->rule.ptr->nr;

--- 7 unchanged lines hidden (view full) ---

1820 pstore.expire -= secs;
1821 else
1822 pstore.expire = 0;
1823#ifdef __FreeBSD__
1824 PF_COPYOUT(&pstore, p, sizeof(*p), error);
1825#else
1826 error = copyout(&pstore, p, sizeof(*p));
1827#endif
2005
2006 if ((nr+1) * sizeof(*p) > (unsigned)ps->ps_len)
2007 break;
2008
2009 bcopy(state, &pstore, sizeof(pstore));
2010 strlcpy(pstore.u.ifname, kif->pfik_name,
2011 sizeof(pstore.u.ifname));
2012 pstore.rule.nr = state->rule.ptr->nr;

--- 7 unchanged lines hidden (view full) ---

2020 pstore.expire -= secs;
2021 else
2022 pstore.expire = 0;
2023#ifdef __FreeBSD__
2024 PF_COPYOUT(&pstore, p, sizeof(*p), error);
2025#else
2026 error = copyout(&pstore, p, sizeof(*p));
2027#endif
1828 if (error) {
1829 splx(s);
2028 if (error)
1830 goto fail;
2029 goto fail;
1831 }
1832 p++;
1833 nr++;
1834 }
1835 ps->ps_len = sizeof(struct pf_state) * nr;
2030 p++;
2031 nr++;
2032 }
2033 ps->ps_len = sizeof(struct pf_state) * nr;
1836 splx(s);
1837 break;
1838 }
1839
1840 case DIOCGETSTATUS: {
1841 struct pf_status *s = (struct pf_status *)addr;
1842 bcopy(&pf_status, s, sizeof(struct pf_status));
1843 pfi_fill_oldstatus(s);
1844 break;

--- 34 unchanged lines hidden (view full) ---

1879 key.proto = pnl->proto;
1880
1881 if (!pnl->proto ||
1882 PF_AZERO(&pnl->saddr, pnl->af) ||
1883 PF_AZERO(&pnl->daddr, pnl->af) ||
1884 !pnl->dport || !pnl->sport)
1885 error = EINVAL;
1886 else {
2034 break;
2035 }
2036
2037 case DIOCGETSTATUS: {
2038 struct pf_status *s = (struct pf_status *)addr;
2039 bcopy(&pf_status, s, sizeof(struct pf_status));
2040 pfi_fill_oldstatus(s);
2041 break;

--- 34 unchanged lines hidden (view full) ---

2076 key.proto = pnl->proto;
2077
2078 if (!pnl->proto ||
2079 PF_AZERO(&pnl->saddr, pnl->af) ||
2080 PF_AZERO(&pnl->daddr, pnl->af) ||
2081 !pnl->dport || !pnl->sport)
2082 error = EINVAL;
2083 else {
1887 s = splsoftnet();
1888
1889 /*
1890 * userland gives us source and dest of connection,
1891 * reverse the lookup so we ask for what happens with
1892 * the return traffic, enabling us to find it in the
1893 * state tree.
1894 */
1895 if (direction == PF_IN) {
1896 PF_ACPY(&key.ext.addr, &pnl->daddr, pnl->af);

--- 23 unchanged lines hidden (view full) ---

1920 state->af);
1921 pnl->rdport = state->gwy.port;
1922 PF_ACPY(&pnl->rsaddr, &pnl->saddr,
1923 pnl->af);
1924 pnl->rsport = pnl->sport;
1925 }
1926 } else
1927 error = ENOENT;
2084 /*
2085 * userland gives us source and dest of connection,
2086 * reverse the lookup so we ask for what happens with
2087 * the return traffic, enabling us to find it in the
2088 * state tree.
2089 */
2090 if (direction == PF_IN) {
2091 PF_ACPY(&key.ext.addr, &pnl->daddr, pnl->af);

--- 23 unchanged lines hidden (view full) ---

2115 state->af);
2116 pnl->rdport = state->gwy.port;
2117 PF_ACPY(&pnl->rsaddr, &pnl->saddr,
2118 pnl->af);
2119 pnl->rsport = pnl->sport;
2120 }
2121 } else
2122 error = ENOENT;
1928 splx(s);
1929 }
1930 break;
1931 }
1932
1933 case DIOCSETTIMEOUT: {
1934 struct pfioc_tm *pt = (struct pfioc_tm *)addr;
1935 int old;
1936

--- 60 unchanged lines hidden (view full) ---

1997 pf_status.debug = *level;
1998 break;
1999 }
2000
2001 case DIOCCLRRULECTRS: {
2002 struct pf_ruleset *ruleset = &pf_main_ruleset;
2003 struct pf_rule *rule;
2004
2123 }
2124 break;
2125 }
2126
2127 case DIOCSETTIMEOUT: {
2128 struct pfioc_tm *pt = (struct pfioc_tm *)addr;
2129 int old;
2130

--- 60 unchanged lines hidden (view full) ---

2191 pf_status.debug = *level;
2192 break;
2193 }
2194
2195 case DIOCCLRRULECTRS: {
2196 struct pf_ruleset *ruleset = &pf_main_ruleset;
2197 struct pf_rule *rule;
2198
2005 s = splsoftnet();
2006 TAILQ_FOREACH(rule,
2007 ruleset->rules[PF_RULESET_FILTER].active.ptr, entries)
2008 rule->evaluations = rule->packets =
2009 rule->bytes = 0;
2199 TAILQ_FOREACH(rule,
2200 ruleset->rules[PF_RULESET_FILTER].active.ptr, entries)
2201 rule->evaluations = rule->packets =
2202 rule->bytes = 0;
2010 splx(s);
2011 break;
2012 }
2013
2014#ifdef __FreeBSD__
2015 case DIOCGIFSPEED: {
2016 struct pf_ifspeed *psp = (struct pf_ifspeed *)addr;
2017 struct pf_ifspeed ps;
2018 struct ifnet *ifp;

--- 12 unchanged lines hidden (view full) ---

2031 }
2032#endif /* __FreeBSD__ */
2033
2034#ifdef ALTQ
2035 case DIOCSTARTALTQ: {
2036 struct pf_altq *altq;
2037
2038 /* enable all altq interfaces on active list */
2203 break;
2204 }
2205
2206#ifdef __FreeBSD__
2207 case DIOCGIFSPEED: {
2208 struct pf_ifspeed *psp = (struct pf_ifspeed *)addr;
2209 struct pf_ifspeed ps;
2210 struct ifnet *ifp;

--- 12 unchanged lines hidden (view full) ---

2223 }
2224#endif /* __FreeBSD__ */
2225
2226#ifdef ALTQ
2227 case DIOCSTARTALTQ: {
2228 struct pf_altq *altq;
2229
2230 /* enable all altq interfaces on active list */
2039 s = splsoftnet();
2040 TAILQ_FOREACH(altq, pf_altqs_active, entries) {
2041 if (altq->qname[0] == 0) {
2042 error = pf_enable_altq(altq);
2043 if (error != 0)
2044 break;
2045 }
2046 }
2047 if (error == 0)
2048 pf_altq_running = 1;
2231 TAILQ_FOREACH(altq, pf_altqs_active, entries) {
2232 if (altq->qname[0] == 0) {
2233 error = pf_enable_altq(altq);
2234 if (error != 0)
2235 break;
2236 }
2237 }
2238 if (error == 0)
2239 pf_altq_running = 1;
2049 splx(s);
2050 DPFPRINTF(PF_DEBUG_MISC, ("altq: started\n"));
2051 break;
2052 }
2053
2054 case DIOCSTOPALTQ: {
2055 struct pf_altq *altq;
2056
2057 /* disable all altq interfaces on active list */
2240 DPFPRINTF(PF_DEBUG_MISC, ("altq: started\n"));
2241 break;
2242 }
2243
2244 case DIOCSTOPALTQ: {
2245 struct pf_altq *altq;
2246
2247 /* disable all altq interfaces on active list */
2058 s = splsoftnet();
2059 TAILQ_FOREACH(altq, pf_altqs_active, entries) {
2060 if (altq->qname[0] == 0) {
2061 error = pf_disable_altq(altq);
2062 if (error != 0)
2063 break;
2064 }
2065 }
2066 if (error == 0)
2067 pf_altq_running = 0;
2248 TAILQ_FOREACH(altq, pf_altqs_active, entries) {
2249 if (altq->qname[0] == 0) {
2250 error = pf_disable_altq(altq);
2251 if (error != 0)
2252 break;
2253 }
2254 }
2255 if (error == 0)
2256 pf_altq_running = 0;
2068 splx(s);
2069 DPFPRINTF(PF_DEBUG_MISC, ("altq: stopped\n"));
2070 break;
2071 }
2072
2257 DPFPRINTF(PF_DEBUG_MISC, ("altq: stopped\n"));
2258 break;
2259 }
2260
2073 case DIOCBEGINALTQS: {
2074 u_int32_t *ticket = (u_int32_t *)addr;
2075
2076 error = pf_begin_altq(ticket);
2077 break;
2078 }
2079
2080 case DIOCADDALTQ: {
2081 struct pfioc_altq *pa = (struct pfioc_altq *)addr;
2082 struct pf_altq *altq, *a;
2083
2084 if (pa->ticket != ticket_altqs_inactive) {
2085 error = EBUSY;
2086 break;
2087 }

--- 35 unchanged lines hidden (view full) ---

2123 break;
2124 }
2125
2126 TAILQ_INSERT_TAIL(pf_altqs_inactive, altq, entries);
2127 bcopy(altq, &pa->altq, sizeof(struct pf_altq));
2128 break;
2129 }
2130
2261 case DIOCADDALTQ: {
2262 struct pfioc_altq *pa = (struct pfioc_altq *)addr;
2263 struct pf_altq *altq, *a;
2264
2265 if (pa->ticket != ticket_altqs_inactive) {
2266 error = EBUSY;
2267 break;
2268 }

--- 35 unchanged lines hidden (view full) ---

2304 break;
2305 }
2306
2307 TAILQ_INSERT_TAIL(pf_altqs_inactive, altq, entries);
2308 bcopy(altq, &pa->altq, sizeof(struct pf_altq));
2309 break;
2310 }
2311
2131 case DIOCCOMMITALTQS: {
2132 u_int32_t ticket = *(u_int32_t *)addr;
2133
2134 error = pf_commit_altq(ticket);
2135 break;
2136 }
2137
2138 case DIOCGETALTQS: {
2139 struct pfioc_altq *pa = (struct pfioc_altq *)addr;
2140 struct pf_altq *altq;
2141
2142 pa->nr = 0;
2312 case DIOCGETALTQS: {
2313 struct pfioc_altq *pa = (struct pfioc_altq *)addr;
2314 struct pf_altq *altq;
2315
2316 pa->nr = 0;
2143 s = splsoftnet();
2144 TAILQ_FOREACH(altq, pf_altqs_active, entries)
2145 pa->nr++;
2146 pa->ticket = ticket_altqs_active;
2317 TAILQ_FOREACH(altq, pf_altqs_active, entries)
2318 pa->nr++;
2319 pa->ticket = ticket_altqs_active;
2147 splx(s);
2148 break;
2149 }
2150
2151 case DIOCGETALTQ: {
2152 struct pfioc_altq *pa = (struct pfioc_altq *)addr;
2153 struct pf_altq *altq;
2154 u_int32_t nr;
2155
2156 if (pa->ticket != ticket_altqs_active) {
2157 error = EBUSY;
2158 break;
2159 }
2160 nr = 0;
2320 break;
2321 }
2322
2323 case DIOCGETALTQ: {
2324 struct pfioc_altq *pa = (struct pfioc_altq *)addr;
2325 struct pf_altq *altq;
2326 u_int32_t nr;
2327
2328 if (pa->ticket != ticket_altqs_active) {
2329 error = EBUSY;
2330 break;
2331 }
2332 nr = 0;
2161 s = splsoftnet();
2162 altq = TAILQ_FIRST(pf_altqs_active);
2163 while ((altq != NULL) && (nr < pa->nr)) {
2164 altq = TAILQ_NEXT(altq, entries);
2165 nr++;
2166 }
2167 if (altq == NULL) {
2168 error = EBUSY;
2333 altq = TAILQ_FIRST(pf_altqs_active);
2334 while ((altq != NULL) && (nr < pa->nr)) {
2335 altq = TAILQ_NEXT(altq, entries);
2336 nr++;
2337 }
2338 if (altq == NULL) {
2339 error = EBUSY;
2169 splx(s);
2170 break;
2171 }
2172 bcopy(altq, &pa->altq, sizeof(struct pf_altq));
2340 break;
2341 }
2342 bcopy(altq, &pa->altq, sizeof(struct pf_altq));
2173 splx(s);
2174 break;
2175 }
2176
2177 case DIOCCHANGEALTQ:
2178 /* CHANGEALTQ not supported yet! */
2179 error = ENODEV;
2180 break;
2181

--- 4 unchanged lines hidden (view full) ---

2186 int nbytes;
2187
2188 if (pq->ticket != ticket_altqs_active) {
2189 error = EBUSY;
2190 break;
2191 }
2192 nbytes = pq->nbytes;
2193 nr = 0;
2343 break;
2344 }
2345
2346 case DIOCCHANGEALTQ:
2347 /* CHANGEALTQ not supported yet! */
2348 error = ENODEV;
2349 break;
2350

--- 4 unchanged lines hidden (view full) ---

2355 int nbytes;
2356
2357 if (pq->ticket != ticket_altqs_active) {
2358 error = EBUSY;
2359 break;
2360 }
2361 nbytes = pq->nbytes;
2362 nr = 0;
2194 s = splsoftnet();
2195 altq = TAILQ_FIRST(pf_altqs_active);
2196 while ((altq != NULL) && (nr < pq->nr)) {
2197 altq = TAILQ_NEXT(altq, entries);
2198 nr++;
2199 }
2200 if (altq == NULL) {
2201 error = EBUSY;
2363 altq = TAILQ_FIRST(pf_altqs_active);
2364 while ((altq != NULL) && (nr < pq->nr)) {
2365 altq = TAILQ_NEXT(altq, entries);
2366 nr++;
2367 }
2368 if (altq == NULL) {
2369 error = EBUSY;
2202 splx(s);
2203 break;
2204 }
2205#ifdef __FreeBSD__
2206 PF_UNLOCK();
2207#endif
2208 error = altq_getqstats(altq, pq->buf, &nbytes);
2209#ifdef __FreeBSD__
2210 PF_LOCK();
2211#endif
2370 break;
2371 }
2372#ifdef __FreeBSD__
2373 PF_UNLOCK();
2374#endif
2375 error = altq_getqstats(altq, pq->buf, &nbytes);
2376#ifdef __FreeBSD__
2377 PF_LOCK();
2378#endif
2212 splx(s);
2213 if (error == 0) {
2214 pq->scheduler = altq->scheduler;
2215 pq->nbytes = nbytes;
2216 }
2217 break;
2218 }
2219#endif /* ALTQ */
2220

--- 50 unchanged lines hidden (view full) ---

2271 TAILQ_INSERT_TAIL(&pf_pabuf, pa, entries);
2272 break;
2273 }
2274
2275 case DIOCGETADDRS: {
2276 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
2277
2278 pp->nr = 0;
2379 if (error == 0) {
2380 pq->scheduler = altq->scheduler;
2381 pq->nbytes = nbytes;
2382 }
2383 break;
2384 }
2385#endif /* ALTQ */
2386

--- 50 unchanged lines hidden (view full) ---

2437 TAILQ_INSERT_TAIL(&pf_pabuf, pa, entries);
2438 break;
2439 }
2440
2441 case DIOCGETADDRS: {
2442 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
2443
2444 pp->nr = 0;
2279 s = splsoftnet();
2280 pool = pf_get_pool(pp->anchor, pp->ruleset, pp->ticket,
2281 pp->r_action, pp->r_num, 0, 1, 0);
2445 pool = pf_get_pool(pp->anchor, pp->ticket, pp->r_action,
2446 pp->r_num, 0, 1, 0);
2282 if (pool == NULL) {
2283 error = EBUSY;
2447 if (pool == NULL) {
2448 error = EBUSY;
2284 splx(s);
2285 break;
2286 }
2287 TAILQ_FOREACH(pa, &pool->list, entries)
2288 pp->nr++;
2449 break;
2450 }
2451 TAILQ_FOREACH(pa, &pool->list, entries)
2452 pp->nr++;
2289 splx(s);
2290 break;
2291 }
2292
2293 case DIOCGETADDR: {
2294 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
2295 u_int32_t nr = 0;
2296
2453 break;
2454 }
2455
2456 case DIOCGETADDR: {
2457 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
2458 u_int32_t nr = 0;
2459
2297 s = splsoftnet();
2298 pool = pf_get_pool(pp->anchor, pp->ruleset, pp->ticket,
2299 pp->r_action, pp->r_num, 0, 1, 1);
2460 pool = pf_get_pool(pp->anchor, pp->ticket, pp->r_action,
2461 pp->r_num, 0, 1, 1);
2300 if (pool == NULL) {
2301 error = EBUSY;
2462 if (pool == NULL) {
2463 error = EBUSY;
2302 splx(s);
2303 break;
2304 }
2305 pa = TAILQ_FIRST(&pool->list);
2306 while ((pa != NULL) && (nr < pp->nr)) {
2307 pa = TAILQ_NEXT(pa, entries);
2308 nr++;
2309 }
2310 if (pa == NULL) {
2311 error = EBUSY;
2464 break;
2465 }
2466 pa = TAILQ_FIRST(&pool->list);
2467 while ((pa != NULL) && (nr < pp->nr)) {
2468 pa = TAILQ_NEXT(pa, entries);
2469 nr++;
2470 }
2471 if (pa == NULL) {
2472 error = EBUSY;
2312 splx(s);
2313 break;
2314 }
2315 bcopy(pa, &pp->addr, sizeof(struct pf_pooladdr));
2316 pfi_dynaddr_copyout(&pp->addr.addr);
2317 pf_tbladdr_copyout(&pp->addr.addr);
2473 break;
2474 }
2475 bcopy(pa, &pp->addr, sizeof(struct pf_pooladdr));
2476 pfi_dynaddr_copyout(&pp->addr.addr);
2477 pf_tbladdr_copyout(&pp->addr.addr);
2318 splx(s);
2478 pf_rtlabel_copyout(&pp->addr.addr);
2319 break;
2320 }
2321
2322 case DIOCCHANGEADDR: {
2323 struct pfioc_pooladdr *pca = (struct pfioc_pooladdr *)addr;
2324 struct pf_pooladdr *oldpa = NULL, *newpa = NULL;
2325 struct pf_ruleset *ruleset;
2326

--- 4 unchanged lines hidden (view full) ---

2331 }
2332 if (pca->addr.addr.type != PF_ADDR_ADDRMASK &&
2333 pca->addr.addr.type != PF_ADDR_DYNIFTL &&
2334 pca->addr.addr.type != PF_ADDR_TABLE) {
2335 error = EINVAL;
2336 break;
2337 }
2338
2479 break;
2480 }
2481
2482 case DIOCCHANGEADDR: {
2483 struct pfioc_pooladdr *pca = (struct pfioc_pooladdr *)addr;
2484 struct pf_pooladdr *oldpa = NULL, *newpa = NULL;
2485 struct pf_ruleset *ruleset;
2486

--- 4 unchanged lines hidden (view full) ---

2491 }
2492 if (pca->addr.addr.type != PF_ADDR_ADDRMASK &&
2493 pca->addr.addr.type != PF_ADDR_DYNIFTL &&
2494 pca->addr.addr.type != PF_ADDR_TABLE) {
2495 error = EINVAL;
2496 break;
2497 }
2498
2339 ruleset = pf_find_ruleset(pca->anchor, pca->ruleset);
2499 ruleset = pf_find_ruleset(pca->anchor);
2340 if (ruleset == NULL) {
2341 error = EBUSY;
2342 break;
2343 }
2500 if (ruleset == NULL) {
2501 error = EBUSY;
2502 break;
2503 }
2344 pool = pf_get_pool(pca->anchor, pca->ruleset, pca->ticket,
2345 pca->r_action, pca->r_num, pca->r_last, 1, 1);
2504 pool = pf_get_pool(pca->anchor, pca->ticket, pca->r_action,
2505 pca->r_num, pca->r_last, 1, 1);
2346 if (pool == NULL) {
2347 error = EBUSY;
2348 break;
2349 }
2350 if (pca->action != PF_CHANGE_REMOVE) {
2351 newpa = pool_get(&pf_pooladdr_pl, PR_NOWAIT);
2352 if (newpa == NULL) {
2353 error = ENOMEM;

--- 28 unchanged lines hidden (view full) ---

2382 pfi_dynaddr_remove(&newpa->addr);
2383 pfi_detach_rule(newpa->kif);
2384 pool_put(&pf_pooladdr_pl, newpa);
2385 error = EINVAL;
2386 break;
2387 }
2388 }
2389
2506 if (pool == NULL) {
2507 error = EBUSY;
2508 break;
2509 }
2510 if (pca->action != PF_CHANGE_REMOVE) {
2511 newpa = pool_get(&pf_pooladdr_pl, PR_NOWAIT);
2512 if (newpa == NULL) {
2513 error = ENOMEM;

--- 28 unchanged lines hidden (view full) ---

2542 pfi_dynaddr_remove(&newpa->addr);
2543 pfi_detach_rule(newpa->kif);
2544 pool_put(&pf_pooladdr_pl, newpa);
2545 error = EINVAL;
2546 break;
2547 }
2548 }
2549
2390 s = splsoftnet();
2391
2392 if (pca->action == PF_CHANGE_ADD_HEAD)
2393 oldpa = TAILQ_FIRST(&pool->list);
2394 else if (pca->action == PF_CHANGE_ADD_TAIL)
2395 oldpa = TAILQ_LAST(&pool->list, pf_palist);
2396 else {
2397 int i = 0;
2398
2399 oldpa = TAILQ_FIRST(&pool->list);
2400 while ((oldpa != NULL) && (i < pca->nr)) {
2401 oldpa = TAILQ_NEXT(oldpa, entries);
2402 i++;
2403 }
2404 if (oldpa == NULL) {
2405 error = EINVAL;
2550 if (pca->action == PF_CHANGE_ADD_HEAD)
2551 oldpa = TAILQ_FIRST(&pool->list);
2552 else if (pca->action == PF_CHANGE_ADD_TAIL)
2553 oldpa = TAILQ_LAST(&pool->list, pf_palist);
2554 else {
2555 int i = 0;
2556
2557 oldpa = TAILQ_FIRST(&pool->list);
2558 while ((oldpa != NULL) && (i < pca->nr)) {
2559 oldpa = TAILQ_NEXT(oldpa, entries);
2560 i++;
2561 }
2562 if (oldpa == NULL) {
2563 error = EINVAL;
2406 splx(s);
2407 break;
2408 }
2409 }
2410
2411 if (pca->action == PF_CHANGE_REMOVE) {
2412 TAILQ_REMOVE(&pool->list, oldpa, entries);
2413 pfi_dynaddr_remove(&oldpa->addr);
2414 pf_tbladdr_remove(&oldpa->addr);

--- 8 unchanged lines hidden (view full) ---

2423 else
2424 TAILQ_INSERT_AFTER(&pool->list, oldpa,
2425 newpa, entries);
2426 }
2427
2428 pool->cur = TAILQ_FIRST(&pool->list);
2429 PF_ACPY(&pool->counter, &pool->cur->addr.v.a.addr,
2430 pca->af);
2564 break;
2565 }
2566 }
2567
2568 if (pca->action == PF_CHANGE_REMOVE) {
2569 TAILQ_REMOVE(&pool->list, oldpa, entries);
2570 pfi_dynaddr_remove(&oldpa->addr);
2571 pf_tbladdr_remove(&oldpa->addr);

--- 8 unchanged lines hidden (view full) ---

2580 else
2581 TAILQ_INSERT_AFTER(&pool->list, oldpa,
2582 newpa, entries);
2583 }
2584
2585 pool->cur = TAILQ_FIRST(&pool->list);
2586 PF_ACPY(&pool->counter, &pool->cur->addr.v.a.addr,
2587 pca->af);
2431 splx(s);
2432 break;
2433 }
2434
2588 break;
2589 }
2590
2435 case DIOCGETANCHORS: {
2436 struct pfioc_anchor *pa = (struct pfioc_anchor *)addr;
2437 struct pf_anchor *anchor;
2438
2439 pa->nr = 0;
2440 TAILQ_FOREACH(anchor, &pf_anchors, entries)
2441 pa->nr++;
2442 break;
2443 }
2444
2445 case DIOCGETANCHOR: {
2446 struct pfioc_anchor *pa = (struct pfioc_anchor *)addr;
2447 struct pf_anchor *anchor;
2448 u_int32_t nr = 0;
2449
2450 anchor = TAILQ_FIRST(&pf_anchors);
2451 while (anchor != NULL && nr < pa->nr) {
2452 anchor = TAILQ_NEXT(anchor, entries);
2453 nr++;
2454 }
2455 if (anchor == NULL)
2456 error = EBUSY;
2457 else
2458 bcopy(anchor->name, pa->name, sizeof(pa->name));
2459 break;
2460 }
2461
2462 case DIOCGETRULESETS: {
2463 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
2591 case DIOCGETRULESETS: {
2592 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
2464 struct pf_anchor *anchor;
2465 struct pf_ruleset *ruleset;
2593 struct pf_ruleset *ruleset;
2594 struct pf_anchor *anchor;
2466
2595
2467 pr->anchor[PF_ANCHOR_NAME_SIZE-1] = 0;
2468 if ((anchor = pf_find_anchor(pr->anchor)) == NULL) {
2596 pr->path[sizeof(pr->path) - 1] = 0;
2597 if ((ruleset = pf_find_ruleset(pr->path)) == NULL) {
2469 error = EINVAL;
2470 break;
2471 }
2472 pr->nr = 0;
2598 error = EINVAL;
2599 break;
2600 }
2601 pr->nr = 0;
2473 TAILQ_FOREACH(ruleset, &anchor->rulesets, entries)
2474 pr->nr++;
2602 if (ruleset->anchor == NULL) {
2603 /* XXX kludge for pf_main_ruleset */
2604 RB_FOREACH(anchor, pf_anchor_global, &pf_anchors)
2605 if (anchor->parent == NULL)
2606 pr->nr++;
2607 } else {
2608 RB_FOREACH(anchor, pf_anchor_node,
2609 &ruleset->anchor->children)
2610 pr->nr++;
2611 }
2475 break;
2476 }
2477
2478 case DIOCGETRULESET: {
2479 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
2612 break;
2613 }
2614
2615 case DIOCGETRULESET: {
2616 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
2480 struct pf_anchor *anchor;
2481 struct pf_ruleset *ruleset;
2617 struct pf_ruleset *ruleset;
2618 struct pf_anchor *anchor;
2482 u_int32_t nr = 0;
2483
2619 u_int32_t nr = 0;
2620
2484 if ((anchor = pf_find_anchor(pr->anchor)) == NULL) {
2621 pr->path[sizeof(pr->path) - 1] = 0;
2622 if ((ruleset = pf_find_ruleset(pr->path)) == NULL) {
2485 error = EINVAL;
2486 break;
2487 }
2623 error = EINVAL;
2624 break;
2625 }
2488 ruleset = TAILQ_FIRST(&anchor->rulesets);
2489 while (ruleset != NULL && nr < pr->nr) {
2490 ruleset = TAILQ_NEXT(ruleset, entries);
2491 nr++;
2626 pr->name[0] = 0;
2627 if (ruleset->anchor == NULL) {
2628 /* XXX kludge for pf_main_ruleset */
2629 RB_FOREACH(anchor, pf_anchor_global, &pf_anchors)
2630 if (anchor->parent == NULL && nr++ == pr->nr) {
2631 strlcpy(pr->name, anchor->name,
2632 sizeof(pr->name));
2633 break;
2634 }
2635 } else {
2636 RB_FOREACH(anchor, pf_anchor_node,
2637 &ruleset->anchor->children)
2638 if (nr++ == pr->nr) {
2639 strlcpy(pr->name, anchor->name,
2640 sizeof(pr->name));
2641 break;
2642 }
2492 }
2643 }
2493 if (ruleset == NULL)
2644 if (!pr->name[0])
2494 error = EBUSY;
2645 error = EBUSY;
2495 else
2496 bcopy(ruleset->name, pr->name, sizeof(pr->name));
2497 break;
2498 }
2499
2500 case DIOCRCLRTABLES: {
2501 struct pfioc_table *io = (struct pfioc_table *)addr;
2502
2503 if (io->pfrio_esize != 0) {
2504 error = ENODEV;

--- 174 unchanged lines hidden (view full) ---

2679 break;
2680 }
2681 error = pfr_tst_addrs(&io->pfrio_table, io->pfrio_buffer,
2682 io->pfrio_size, &io->pfrio_nmatch, io->pfrio_flags |
2683 PFR_FLAG_USERIOCTL);
2684 break;
2685 }
2686
2646 break;
2647 }
2648
2649 case DIOCRCLRTABLES: {
2650 struct pfioc_table *io = (struct pfioc_table *)addr;
2651
2652 if (io->pfrio_esize != 0) {
2653 error = ENODEV;

--- 174 unchanged lines hidden (view full) ---

2828 break;
2829 }
2830 error = pfr_tst_addrs(&io->pfrio_table, io->pfrio_buffer,
2831 io->pfrio_size, &io->pfrio_nmatch, io->pfrio_flags |
2832 PFR_FLAG_USERIOCTL);
2833 break;
2834 }
2835
2687 case DIOCRINABEGIN: {
2688 struct pfioc_table *io = (struct pfioc_table *)addr;
2689
2690 if (io->pfrio_esize != 0) {
2691 error = ENODEV;
2692 break;
2693 }
2694 error = pfr_ina_begin(&io->pfrio_table, &io->pfrio_ticket,
2695 &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
2696 break;
2697 }
2698
2699 case DIOCRINACOMMIT: {
2700 struct pfioc_table *io = (struct pfioc_table *)addr;
2701
2702 if (io->pfrio_esize != 0) {
2703 error = ENODEV;
2704 break;
2705 }
2706 error = pfr_ina_commit(&io->pfrio_table, io->pfrio_ticket,
2707 &io->pfrio_nadd, &io->pfrio_nchange, io->pfrio_flags |
2708 PFR_FLAG_USERIOCTL);
2709 break;
2710 }
2711
2712 case DIOCRINADEFINE: {
2713 struct pfioc_table *io = (struct pfioc_table *)addr;
2714
2715 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
2716 error = ENODEV;
2717 break;
2718 }
2719 error = pfr_ina_define(&io->pfrio_table, io->pfrio_buffer,
2720 io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddr,
2721 io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL);
2722 break;
2723 }
2724
2725 case DIOCOSFPADD: {
2726 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
2836 case DIOCRINADEFINE: {
2837 struct pfioc_table *io = (struct pfioc_table *)addr;
2838
2839 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
2840 error = ENODEV;
2841 break;
2842 }
2843 error = pfr_ina_define(&io->pfrio_table, io->pfrio_buffer,
2844 io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddr,
2845 io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL);
2846 break;
2847 }
2848
2849 case DIOCOSFPADD: {
2850 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
2727 s = splsoftnet();
2728 error = pf_osfp_add(io);
2851 error = pf_osfp_add(io);
2729 splx(s);
2730 break;
2731 }
2732
2733 case DIOCOSFPGET: {
2734 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
2852 break;
2853 }
2854
2855 case DIOCOSFPGET: {
2856 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
2735 s = splsoftnet();
2736 error = pf_osfp_get(io);
2857 error = pf_osfp_get(io);
2737 splx(s);
2738 break;
2739 }
2740
2741 case DIOCXBEGIN: {
2858 break;
2859 }
2860
2861 case DIOCXBEGIN: {
2742 struct pfioc_trans *io = (struct pfioc_trans *)addr;
2743 struct pfioc_trans_e ioe;
2744 struct pfr_table table;
2745 int i;
2862 struct pfioc_trans *io = (struct pfioc_trans *)
2863 addr;
2864 static struct pfioc_trans_e ioe;
2865 static struct pfr_table table;
2866 int i;
2746
2747 if (io->esize != sizeof(ioe)) {
2748 error = ENODEV;
2749 goto fail;
2750 }
2751 for (i = 0; i < io->size; i++) {
2752#ifdef __FreeBSD__
2753 PF_COPYIN(io->array+i, &ioe, sizeof(ioe), error);
2754 if (error) {
2755#else
2756 if (copyin(io->array+i, &ioe, sizeof(ioe))) {
2757#endif
2758 error = EFAULT;
2759 goto fail;
2760 }
2761 switch (ioe.rs_num) {
2762#ifdef ALTQ
2763 case PF_RULESET_ALTQ:
2867
2868 if (io->esize != sizeof(ioe)) {
2869 error = ENODEV;
2870 goto fail;
2871 }
2872 for (i = 0; i < io->size; i++) {
2873#ifdef __FreeBSD__
2874 PF_COPYIN(io->array+i, &ioe, sizeof(ioe), error);
2875 if (error) {
2876#else
2877 if (copyin(io->array+i, &ioe, sizeof(ioe))) {
2878#endif
2879 error = EFAULT;
2880 goto fail;
2881 }
2882 switch (ioe.rs_num) {
2883#ifdef ALTQ
2884 case PF_RULESET_ALTQ:
2764 if (ioe.anchor[0] || ioe.ruleset[0]) {
2885 if (ioe.anchor[0]) {
2765 error = EINVAL;
2766 goto fail;
2767 }
2768 if ((error = pf_begin_altq(&ioe.ticket)))
2769 goto fail;
2770 break;
2771#endif /* ALTQ */
2772 case PF_RULESET_TABLE:
2773 bzero(&table, sizeof(table));
2774 strlcpy(table.pfrt_anchor, ioe.anchor,
2775 sizeof(table.pfrt_anchor));
2886 error = EINVAL;
2887 goto fail;
2888 }
2889 if ((error = pf_begin_altq(&ioe.ticket)))
2890 goto fail;
2891 break;
2892#endif /* ALTQ */
2893 case PF_RULESET_TABLE:
2894 bzero(&table, sizeof(table));
2895 strlcpy(table.pfrt_anchor, ioe.anchor,
2896 sizeof(table.pfrt_anchor));
2776 strlcpy(table.pfrt_ruleset, ioe.ruleset,
2777 sizeof(table.pfrt_ruleset));
2778 if ((error = pfr_ina_begin(&table,
2779 &ioe.ticket, NULL, 0)))
2780 goto fail;
2781 break;
2782 default:
2783 if ((error = pf_begin_rules(&ioe.ticket,
2897 if ((error = pfr_ina_begin(&table,
2898 &ioe.ticket, NULL, 0)))
2899 goto fail;
2900 break;
2901 default:
2902 if ((error = pf_begin_rules(&ioe.ticket,
2784 ioe.rs_num, ioe.anchor, ioe.ruleset)))
2903 ioe.rs_num, ioe.anchor)))
2785 goto fail;
2786 break;
2787 }
2788#ifdef __FreeBSD__
2789 PF_COPYOUT(&ioe, io->array+i, sizeof(io->array[i]),
2790 error);
2791 if (error) {
2792#else
2793 if (copyout(&ioe, io->array+i, sizeof(io->array[i]))) {
2794#endif
2795 error = EFAULT;
2796 goto fail;
2797 }
2798 }
2799 break;
2800 }
2801
2802 case DIOCXROLLBACK: {
2904 goto fail;
2905 break;
2906 }
2907#ifdef __FreeBSD__
2908 PF_COPYOUT(&ioe, io->array+i, sizeof(io->array[i]),
2909 error);
2910 if (error) {
2911#else
2912 if (copyout(&ioe, io->array+i, sizeof(io->array[i]))) {
2913#endif
2914 error = EFAULT;
2915 goto fail;
2916 }
2917 }
2918 break;
2919 }
2920
2921 case DIOCXROLLBACK: {
2803 struct pfioc_trans *io = (struct pfioc_trans *)addr;
2804 struct pfioc_trans_e ioe;
2805 struct pfr_table table;
2806 int i;
2922 struct pfioc_trans *io = (struct pfioc_trans *)
2923 addr;
2924 static struct pfioc_trans_e ioe;
2925 static struct pfr_table table;
2926 int i;
2807
2808 if (io->esize != sizeof(ioe)) {
2809 error = ENODEV;
2810 goto fail;
2811 }
2812 for (i = 0; i < io->size; i++) {
2813#ifdef __FreeBSD__
2814 PF_COPYIN(io->array+i, &ioe, sizeof(ioe), error);
2815 if (error) {
2816#else
2817 if (copyin(io->array+i, &ioe, sizeof(ioe))) {
2818#endif
2819 error = EFAULT;
2820 goto fail;
2821 }
2822 switch (ioe.rs_num) {
2823#ifdef ALTQ
2824 case PF_RULESET_ALTQ:
2927
2928 if (io->esize != sizeof(ioe)) {
2929 error = ENODEV;
2930 goto fail;
2931 }
2932 for (i = 0; i < io->size; i++) {
2933#ifdef __FreeBSD__
2934 PF_COPYIN(io->array+i, &ioe, sizeof(ioe), error);
2935 if (error) {
2936#else
2937 if (copyin(io->array+i, &ioe, sizeof(ioe))) {
2938#endif
2939 error = EFAULT;
2940 goto fail;
2941 }
2942 switch (ioe.rs_num) {
2943#ifdef ALTQ
2944 case PF_RULESET_ALTQ:
2825 if (ioe.anchor[0] || ioe.ruleset[0]) {
2945 if (ioe.anchor[0]) {
2826 error = EINVAL;
2827 goto fail;
2828 }
2829 if ((error = pf_rollback_altq(ioe.ticket)))
2830 goto fail; /* really bad */
2831 break;
2832#endif /* ALTQ */
2833 case PF_RULESET_TABLE:
2834 bzero(&table, sizeof(table));
2835 strlcpy(table.pfrt_anchor, ioe.anchor,
2836 sizeof(table.pfrt_anchor));
2946 error = EINVAL;
2947 goto fail;
2948 }
2949 if ((error = pf_rollback_altq(ioe.ticket)))
2950 goto fail; /* really bad */
2951 break;
2952#endif /* ALTQ */
2953 case PF_RULESET_TABLE:
2954 bzero(&table, sizeof(table));
2955 strlcpy(table.pfrt_anchor, ioe.anchor,
2956 sizeof(table.pfrt_anchor));
2837 strlcpy(table.pfrt_ruleset, ioe.ruleset,
2838 sizeof(table.pfrt_ruleset));
2839 if ((error = pfr_ina_rollback(&table,
2840 ioe.ticket, NULL, 0)))
2841 goto fail; /* really bad */
2842 break;
2843 default:
2844 if ((error = pf_rollback_rules(ioe.ticket,
2957 if ((error = pfr_ina_rollback(&table,
2958 ioe.ticket, NULL, 0)))
2959 goto fail; /* really bad */
2960 break;
2961 default:
2962 if ((error = pf_rollback_rules(ioe.ticket,
2845 ioe.rs_num, ioe.anchor, ioe.ruleset)))
2963 ioe.rs_num, ioe.anchor)))
2846 goto fail; /* really bad */
2847 break;
2848 }
2849 }
2850 break;
2851 }
2852
2853 case DIOCXCOMMIT: {
2964 goto fail; /* really bad */
2965 break;
2966 }
2967 }
2968 break;
2969 }
2970
2971 case DIOCXCOMMIT: {
2854 struct pfioc_trans *io = (struct pfioc_trans *)addr;
2855 struct pfioc_trans_e ioe;
2856 struct pfr_table table;
2857 struct pf_ruleset *rs;
2858 int i;
2972 struct pfioc_trans *io = (struct pfioc_trans *)
2973 addr;
2974 static struct pfioc_trans_e ioe;
2975 static struct pfr_table table;
2976 struct pf_ruleset *rs;
2977 int i;
2859
2860 if (io->esize != sizeof(ioe)) {
2861 error = ENODEV;
2862 goto fail;
2863 }
2864 /* first makes sure everything will succeed */
2865 for (i = 0; i < io->size; i++) {
2866#ifdef __FreeBSD__
2867 PF_COPYIN(io->array+i, &ioe, sizeof(ioe), error);
2868 if (error) {
2869#else
2870 if (copyin(io->array+i, &ioe, sizeof(ioe))) {
2871#endif
2872 error = EFAULT;
2873 goto fail;
2874 }
2875 switch (ioe.rs_num) {
2876#ifdef ALTQ
2877 case PF_RULESET_ALTQ:
2978
2979 if (io->esize != sizeof(ioe)) {
2980 error = ENODEV;
2981 goto fail;
2982 }
2983 /* first makes sure everything will succeed */
2984 for (i = 0; i < io->size; i++) {
2985#ifdef __FreeBSD__
2986 PF_COPYIN(io->array+i, &ioe, sizeof(ioe), error);
2987 if (error) {
2988#else
2989 if (copyin(io->array+i, &ioe, sizeof(ioe))) {
2990#endif
2991 error = EFAULT;
2992 goto fail;
2993 }
2994 switch (ioe.rs_num) {
2995#ifdef ALTQ
2996 case PF_RULESET_ALTQ:
2878 if (ioe.anchor[0] || ioe.ruleset[0]) {
2997 if (ioe.anchor[0]) {
2879 error = EINVAL;
2880 goto fail;
2881 }
2882 if (!altqs_inactive_open || ioe.ticket !=
2883 ticket_altqs_inactive) {
2884 error = EBUSY;
2885 goto fail;
2886 }
2887 break;
2888#endif /* ALTQ */
2889 case PF_RULESET_TABLE:
2998 error = EINVAL;
2999 goto fail;
3000 }
3001 if (!altqs_inactive_open || ioe.ticket !=
3002 ticket_altqs_inactive) {
3003 error = EBUSY;
3004 goto fail;
3005 }
3006 break;
3007#endif /* ALTQ */
3008 case PF_RULESET_TABLE:
2890 rs = pf_find_ruleset(ioe.anchor, ioe.ruleset);
3009 rs = pf_find_ruleset(ioe.anchor);
2891 if (rs == NULL || !rs->topen || ioe.ticket !=
2892 rs->tticket) {
2893 error = EBUSY;
2894 goto fail;
2895 }
2896 break;
2897 default:
2898 if (ioe.rs_num < 0 || ioe.rs_num >=
2899 PF_RULESET_MAX) {
2900 error = EINVAL;
2901 goto fail;
2902 }
3010 if (rs == NULL || !rs->topen || ioe.ticket !=
3011 rs->tticket) {
3012 error = EBUSY;
3013 goto fail;
3014 }
3015 break;
3016 default:
3017 if (ioe.rs_num < 0 || ioe.rs_num >=
3018 PF_RULESET_MAX) {
3019 error = EINVAL;
3020 goto fail;
3021 }
2903 rs = pf_find_ruleset(ioe.anchor, ioe.ruleset);
3022 rs = pf_find_ruleset(ioe.anchor);
2904 if (rs == NULL ||
2905 !rs->rules[ioe.rs_num].inactive.open ||
2906 rs->rules[ioe.rs_num].inactive.ticket !=
2907 ioe.ticket) {
2908 error = EBUSY;
2909 goto fail;
2910 }
2911 break;

--- 16 unchanged lines hidden (view full) ---

2928 if ((error = pf_commit_altq(ioe.ticket)))
2929 goto fail; /* really bad */
2930 break;
2931#endif /* ALTQ */
2932 case PF_RULESET_TABLE:
2933 bzero(&table, sizeof(table));
2934 strlcpy(table.pfrt_anchor, ioe.anchor,
2935 sizeof(table.pfrt_anchor));
3023 if (rs == NULL ||
3024 !rs->rules[ioe.rs_num].inactive.open ||
3025 rs->rules[ioe.rs_num].inactive.ticket !=
3026 ioe.ticket) {
3027 error = EBUSY;
3028 goto fail;
3029 }
3030 break;

--- 16 unchanged lines hidden (view full) ---

3047 if ((error = pf_commit_altq(ioe.ticket)))
3048 goto fail; /* really bad */
3049 break;
3050#endif /* ALTQ */
3051 case PF_RULESET_TABLE:
3052 bzero(&table, sizeof(table));
3053 strlcpy(table.pfrt_anchor, ioe.anchor,
3054 sizeof(table.pfrt_anchor));
2936 strlcpy(table.pfrt_ruleset, ioe.ruleset,
2937 sizeof(table.pfrt_ruleset));
2938 if ((error = pfr_ina_commit(&table, ioe.ticket,
2939 NULL, NULL, 0)))
2940 goto fail; /* really bad */
2941 break;
2942 default:
2943 if ((error = pf_commit_rules(ioe.ticket,
3055 if ((error = pfr_ina_commit(&table, ioe.ticket,
3056 NULL, NULL, 0)))
3057 goto fail; /* really bad */
3058 break;
3059 default:
3060 if ((error = pf_commit_rules(ioe.ticket,
2944 ioe.rs_num, ioe.anchor, ioe.ruleset)))
3061 ioe.rs_num, ioe.anchor)))
2945 goto fail; /* really bad */
2946 break;
2947 }
2948 }
2949 break;
2950 }
2951
2952 case DIOCGETSRCNODES: {
2953 struct pfioc_src_nodes *psn = (struct pfioc_src_nodes *)addr;
2954 struct pf_src_node *n;
2955 struct pf_src_node *p, pstore;
2956 u_int32_t nr = 0;
2957 int space = psn->psn_len;
2958
2959 if (space == 0) {
3062 goto fail; /* really bad */
3063 break;
3064 }
3065 }
3066 break;
3067 }
3068
3069 case DIOCGETSRCNODES: {
3070 struct pfioc_src_nodes *psn = (struct pfioc_src_nodes *)addr;
3071 struct pf_src_node *n;
3072 struct pf_src_node *p, pstore;
3073 u_int32_t nr = 0;
3074 int space = psn->psn_len;
3075
3076 if (space == 0) {
2960 s = splsoftnet();
2961 RB_FOREACH(n, pf_src_tree, &tree_src_tracking)
2962 nr++;
3077 RB_FOREACH(n, pf_src_tree, &tree_src_tracking)
3078 nr++;
2963 splx(s);
2964 psn->psn_len = sizeof(struct pf_src_node) * nr;
3079 psn->psn_len = sizeof(struct pf_src_node) * nr;
2965#ifdef __FreeBSD__
2966 PF_UNLOCK();
2967#endif
2968 return (0);
3080 break;
2969 }
2970
3081 }
3082
2971 s = splsoftnet();
2972 p = psn->psn_src_nodes;
2973 RB_FOREACH(n, pf_src_tree, &tree_src_tracking) {
3083 p = psn->psn_src_nodes;
3084 RB_FOREACH(n, pf_src_tree, &tree_src_tracking) {
2974#ifdef __FreeBSD__
2975 int secs = time_second;
2976#else
2977 int secs = time.tv_sec;
2978#endif
3085 int secs = time_second, diff;
2979
2980 if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len)
2981 break;
2982
2983 bcopy(n, &pstore, sizeof(pstore));
2984 if (n->rule.ptr != NULL)
2985 pstore.rule.nr = n->rule.ptr->nr;
2986 pstore.creation = secs - pstore.creation;
2987 if (pstore.expire > secs)
2988 pstore.expire -= secs;
2989 else
2990 pstore.expire = 0;
3086
3087 if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len)
3088 break;
3089
3090 bcopy(n, &pstore, sizeof(pstore));
3091 if (n->rule.ptr != NULL)
3092 pstore.rule.nr = n->rule.ptr->nr;
3093 pstore.creation = secs - pstore.creation;
3094 if (pstore.expire > secs)
3095 pstore.expire -= secs;
3096 else
3097 pstore.expire = 0;
3098
3099 /* adjust the connection rate estimate */
3100 diff = secs - n->conn_rate.last;
3101 if (diff >= n->conn_rate.seconds)
3102 pstore.conn_rate.count = 0;
3103 else
3104 pstore.conn_rate.count -=
3105 n->conn_rate.count * diff /
3106 n->conn_rate.seconds;
3107
2991#ifdef __FreeBSD__
2992 PF_COPYOUT(&pstore, p, sizeof(*p), error);
2993#else
2994 error = copyout(&pstore, p, sizeof(*p));
2995#endif
3108#ifdef __FreeBSD__
3109 PF_COPYOUT(&pstore, p, sizeof(*p), error);
3110#else
3111 error = copyout(&pstore, p, sizeof(*p));
3112#endif
2996 if (error) {
2997 splx(s);
3113 if (error)
2998 goto fail;
3114 goto fail;
2999 }
3000 p++;
3001 nr++;
3002 }
3003 psn->psn_len = sizeof(struct pf_src_node) * nr;
3115 p++;
3116 nr++;
3117 }
3118 psn->psn_len = sizeof(struct pf_src_node) * nr;
3004 splx(s);
3005 break;
3006 }
3007
3008 case DIOCCLRSRCNODES: {
3009 struct pf_src_node *n;
3010 struct pf_state *state;
3011
3119 break;
3120 }
3121
3122 case DIOCCLRSRCNODES: {
3123 struct pf_src_node *n;
3124 struct pf_state *state;
3125
3012 s = splsoftnet();
3013 RB_FOREACH(state, pf_state_tree_id, &tree_id) {
3014 state->src_node = NULL;
3015 state->nat_src_node = NULL;
3016 }
3017 RB_FOREACH(n, pf_src_tree, &tree_src_tracking) {
3018 n->expire = 1;
3019 n->states = 0;
3020 }
3021 pf_purge_expired_src_nodes();
3022 pf_status.src_nodes = 0;
3126 RB_FOREACH(state, pf_state_tree_id, &tree_id) {
3127 state->src_node = NULL;
3128 state->nat_src_node = NULL;
3129 }
3130 RB_FOREACH(n, pf_src_tree, &tree_src_tracking) {
3131 n->expire = 1;
3132 n->states = 0;
3133 }
3134 pf_purge_expired_src_nodes();
3135 pf_status.src_nodes = 0;
3023 splx(s);
3024 break;
3025 }
3026
3027 case DIOCSETHOSTID: {
3028 u_int32_t *hostid = (u_int32_t *)addr;
3029
3136 break;
3137 }
3138
3139 case DIOCSETHOSTID: {
3140 u_int32_t *hostid = (u_int32_t *)addr;
3141
3030 if (*hostid == 0) {
3031 error = EINVAL;
3032 goto fail;
3033 }
3034 pf_status.hostid = *hostid;
3142 if (*hostid == 0)
3143 pf_status.hostid = arc4random();
3144 else
3145 pf_status.hostid = *hostid;
3035 break;
3036 }
3037
3038 case DIOCOSFPFLUSH:
3146 break;
3147 }
3148
3149 case DIOCOSFPFLUSH:
3039 s = splsoftnet();
3040 pf_osfp_flush();
3150 pf_osfp_flush();
3041 splx(s);
3042 break;
3043
3044 case DIOCIGETIFACES: {
3045 struct pfioc_iface *io = (struct pfioc_iface *)addr;
3046
3047 if (io->pfiio_esize != sizeof(struct pfi_if)) {
3048 error = ENODEV;
3049 break;

--- 6 unchanged lines hidden (view full) ---

3056 case DIOCICLRISTATS: {
3057 struct pfioc_iface *io = (struct pfioc_iface *)addr;
3058
3059 error = pfi_clr_istats(io->pfiio_name, &io->pfiio_nzero,
3060 io->pfiio_flags);
3061 break;
3062 }
3063
3151 break;
3152
3153 case DIOCIGETIFACES: {
3154 struct pfioc_iface *io = (struct pfioc_iface *)addr;
3155
3156 if (io->pfiio_esize != sizeof(struct pfi_if)) {
3157 error = ENODEV;
3158 break;

--- 6 unchanged lines hidden (view full) ---

3165 case DIOCICLRISTATS: {
3166 struct pfioc_iface *io = (struct pfioc_iface *)addr;
3167
3168 error = pfi_clr_istats(io->pfiio_name, &io->pfiio_nzero,
3169 io->pfiio_flags);
3170 break;
3171 }
3172
3173 case DIOCSETIFFLAG: {
3174 struct pfioc_iface *io = (struct pfioc_iface *)addr;
3175
3176 error = pfi_set_flags(io->pfiio_name, io->pfiio_flags);
3177 break;
3178 }
3179
3180 case DIOCCLRIFFLAG: {
3181 struct pfioc_iface *io = (struct pfioc_iface *)addr;
3182
3183 error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags);
3184 break;
3185 }
3186
3064 default:
3065 error = ENODEV;
3066 break;
3067 }
3068fail:
3069#ifdef __FreeBSD__
3070 PF_UNLOCK();
3187 default:
3188 error = ENODEV;
3189 break;
3190 }
3191fail:
3192#ifdef __FreeBSD__
3193 PF_UNLOCK();
3194#else
3195 splx(s);
3071#endif
3072 return (error);
3073}
3074
3075#ifdef __FreeBSD__
3076/*
3077 * XXX - Check for version missmatch!!!
3078 */

--- 63 unchanged lines hidden (view full) ---

3142 int error = 0;
3143 u_int32_t t[5];
3144 char nn = '\0';
3145
3146 callout_stop(&pf_expire_to);
3147
3148 pf_status.running = 0;
3149 do {
3196#endif
3197 return (error);
3198}
3199
3200#ifdef __FreeBSD__
3201/*
3202 * XXX - Check for version missmatch!!!
3203 */

--- 63 unchanged lines hidden (view full) ---

3267 int error = 0;
3268 u_int32_t t[5];
3269 char nn = '\0';
3270
3271 callout_stop(&pf_expire_to);
3272
3273 pf_status.running = 0;
3274 do {
3150 if ((error = pf_begin_rules(&t[0], PF_RULESET_SCRUB, &nn,
3151 &nn)) != 0) {
3275 if ((error = pf_begin_rules(&t[0], PF_RULESET_SCRUB, &nn))
3276 != 0) {
3152 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: SCRUB\n"));
3153 break;
3154 }
3277 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: SCRUB\n"));
3278 break;
3279 }
3155 if ((error = pf_begin_rules(&t[1], PF_RULESET_FILTER, &nn,
3156 &nn)) != 0) {
3280 if ((error = pf_begin_rules(&t[1], PF_RULESET_FILTER, &nn))
3281 != 0) {
3157 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: FILTER\n"));
3158 break; /* XXX: rollback? */
3159 }
3282 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: FILTER\n"));
3283 break; /* XXX: rollback? */
3284 }
3160 if ((error = pf_begin_rules(&t[2], PF_RULESET_NAT, &nn, &nn))
3285 if ((error = pf_begin_rules(&t[2], PF_RULESET_NAT, &nn))
3161 != 0) {
3162 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: NAT\n"));
3163 break; /* XXX: rollback? */
3164 }
3286 != 0) {
3287 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: NAT\n"));
3288 break; /* XXX: rollback? */
3289 }
3165 if ((error = pf_begin_rules(&t[3], PF_RULESET_BINAT, &nn, &nn))
3290 if ((error = pf_begin_rules(&t[3], PF_RULESET_BINAT, &nn))
3166 != 0) {
3167 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: BINAT\n"));
3168 break; /* XXX: rollback? */
3169 }
3291 != 0) {
3292 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: BINAT\n"));
3293 break; /* XXX: rollback? */
3294 }
3170 if ((error = pf_begin_rules(&t[4], PF_RULESET_RDR, &nn, &nn))
3295 if ((error = pf_begin_rules(&t[4], PF_RULESET_RDR, &nn))
3171 != 0) {
3172 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: RDR\n"));
3173 break; /* XXX: rollback? */
3174 }
3175
3176 /* XXX: these should always succeed here */
3296 != 0) {
3297 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: RDR\n"));
3298 break; /* XXX: rollback? */
3299 }
3300
3301 /* XXX: these should always succeed here */
3177 pf_commit_rules(t[0], PF_RULESET_SCRUB, &nn, &nn);
3178 pf_commit_rules(t[1], PF_RULESET_FILTER, &nn, &nn);
3179 pf_commit_rules(t[2], PF_RULESET_NAT, &nn, &nn);
3180 pf_commit_rules(t[3], PF_RULESET_BINAT, &nn, &nn);
3181 pf_commit_rules(t[4], PF_RULESET_RDR, &nn, &nn);
3302 pf_commit_rules(t[0], PF_RULESET_SCRUB, &nn);
3303 pf_commit_rules(t[1], PF_RULESET_FILTER, &nn);
3304 pf_commit_rules(t[2], PF_RULESET_NAT, &nn);
3305 pf_commit_rules(t[3], PF_RULESET_BINAT, &nn);
3306 pf_commit_rules(t[4], PF_RULESET_RDR, &nn);
3182
3183 if ((error = pf_clear_tables()) != 0)
3184 break;
3185
3186#ifdef ALTQ
3187 if ((error = pf_begin_altq(&t[0])) != 0) {
3188 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: ALTQ\n"));
3189 break;

--- 28 unchanged lines hidden (view full) ---

3218 int chk;
3219
3220 if ((*m)->m_pkthdr.len >= (int)sizeof(struct ip)) {
3221 /* if m_pkthdr.len is less than ip header, pf will handle. */
3222 h = mtod(*m, struct ip *);
3223 HTONS(h->ip_len);
3224 HTONS(h->ip_off);
3225 }
3307
3308 if ((error = pf_clear_tables()) != 0)
3309 break;
3310
3311#ifdef ALTQ
3312 if ((error = pf_begin_altq(&t[0])) != 0) {
3313 DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: ALTQ\n"));
3314 break;

--- 28 unchanged lines hidden (view full) ---

3343 int chk;
3344
3345 if ((*m)->m_pkthdr.len >= (int)sizeof(struct ip)) {
3346 /* if m_pkthdr.len is less than ip header, pf will handle. */
3347 h = mtod(*m, struct ip *);
3348 HTONS(h->ip_len);
3349 HTONS(h->ip_off);
3350 }
3226 chk = pf_test(PF_IN, ifp, m, inp);
3351 chk = pf_test(PF_IN, ifp, m, NULL, inp);
3227 if (chk && *m) {
3228 m_freem(*m);
3229 *m = NULL;
3230 }
3231 if (*m != NULL) {
3232 /* pf_test can change ip header location */
3233 h = mtod(*m, struct ip *);
3234 NTOHS(h->ip_len);

--- 23 unchanged lines hidden (view full) ---

3258 (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
3259 }
3260 if ((*m)->m_pkthdr.len >= (int)sizeof(*h)) {
3261 /* if m_pkthdr.len is less than ip header, pf will handle. */
3262 h = mtod(*m, struct ip *);
3263 HTONS(h->ip_len);
3264 HTONS(h->ip_off);
3265 }
3352 if (chk && *m) {
3353 m_freem(*m);
3354 *m = NULL;
3355 }
3356 if (*m != NULL) {
3357 /* pf_test can change ip header location */
3358 h = mtod(*m, struct ip *);
3359 NTOHS(h->ip_len);

--- 23 unchanged lines hidden (view full) ---

3383 (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
3384 }
3385 if ((*m)->m_pkthdr.len >= (int)sizeof(*h)) {
3386 /* if m_pkthdr.len is less than ip header, pf will handle. */
3387 h = mtod(*m, struct ip *);
3388 HTONS(h->ip_len);
3389 HTONS(h->ip_off);
3390 }
3266 chk = pf_test(PF_OUT, ifp, m, inp);
3391 chk = pf_test(PF_OUT, ifp, m, NULL, inp);
3267 if (chk && *m) {
3268 m_freem(*m);
3269 *m = NULL;
3270 }
3271 if (*m != NULL) {
3272 /* pf_test can change ip header location */
3273 h = mtod(*m, struct ip *);
3274 NTOHS(h->ip_len);

--- 7 unchanged lines hidden (view full) ---

3282pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
3283 struct inpcb *inp)
3284{
3285 /*
3286 * IPv6 does not affected ip_len/ip_off byte order changes.
3287 */
3288 int chk;
3289
3392 if (chk && *m) {
3393 m_freem(*m);
3394 *m = NULL;
3395 }
3396 if (*m != NULL) {
3397 /* pf_test can change ip header location */
3398 h = mtod(*m, struct ip *);
3399 NTOHS(h->ip_len);

--- 7 unchanged lines hidden (view full) ---

3407pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
3408 struct inpcb *inp)
3409{
3410 /*
3411 * IPv6 does not affected ip_len/ip_off byte order changes.
3412 */
3413 int chk;
3414
3290 chk = pf_test6(PF_IN, ifp, m, inp);
3415 chk = pf_test6(PF_IN, ifp, m, NULL, inp);
3291 if (chk && *m) {
3292 m_freem(*m);
3293 *m = NULL;
3294 }
3295 return chk;
3296}
3297
3298static int

--- 5 unchanged lines hidden (view full) ---

3304 */
3305 int chk;
3306
3307 /* We need a proper CSUM befor we start (s. OpenBSD ip_output) */
3308 if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
3309 in_delayed_cksum(*m);
3310 (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
3311 }
3416 if (chk && *m) {
3417 m_freem(*m);
3418 *m = NULL;
3419 }
3420 return chk;
3421}
3422
3423static int

--- 5 unchanged lines hidden (view full) ---

3429 */
3430 int chk;
3431
3432 /* We need a proper CSUM befor we start (s. OpenBSD ip_output) */
3433 if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
3434 in_delayed_cksum(*m);
3435 (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
3436 }
3312 chk = pf_test6(PF_OUT, ifp, m, inp);
3437 chk = pf_test6(PF_OUT, ifp, m, NULL, inp);
3313 if (chk && *m) {
3314 m_freem(*m);
3315 *m = NULL;
3316 }
3317 return chk;
3318}
3319#endif /* INET6 */
3320

--- 142 unchanged lines hidden ---
3438 if (chk && *m) {
3439 m_freem(*m);
3440 *m = NULL;
3441 }
3442 return chk;
3443}
3444#endif /* INET6 */
3445

--- 142 unchanged lines hidden ---