Deleted Added
full compact
pf_ioctl.c (285830) pf_ioctl.c (286014)
1/*-
2 * Copyright (c) 2001 Daniel Hartmeier
3 * Copyright (c) 2002,2003 Henning Brauer
4 * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

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

31 * Effort sponsored in part by the Defense Advanced Research Projects
32 * Agency (DARPA) and Air Force Research Laboratory, Air Force
33 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
34 *
35 * $OpenBSD: pf_ioctl.c,v 1.213 2009/02/15 21:46:12 mbalmer Exp $
36 */
37
38#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2001 Daniel Hartmeier
3 * Copyright (c) 2002,2003 Henning Brauer
4 * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

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

31 * Effort sponsored in part by the Defense Advanced Research Projects
32 * Agency (DARPA) and Air Force Research Laboratory, Air Force
33 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
34 *
35 * $OpenBSD: pf_ioctl.c,v 1.213 2009/02/15 21:46:12 mbalmer Exp $
36 */
37
38#include <sys/cdefs.h>
39__FBSDID("$FreeBSD: releng/10.2/sys/netpfil/pf/pf_ioctl.c 277581 2015-01-23 18:15:15Z glebius $");
39__FBSDID("$FreeBSD: releng/10.2/sys/netpfil/pf/pf_ioctl.c 286014 2015-07-29 14:16:25Z glebius $");
40
41#include "opt_inet.h"
42#include "opt_inet6.h"
43#include "opt_bpf.h"
44#include "opt_pf.h"
45
46#include <sys/param.h>
47#include <sys/bus.h>

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

183 .d_version = D_VERSION,
184};
185
186static volatile VNET_DEFINE(int, pf_pfil_hooked);
187#define V_pf_pfil_hooked VNET(pf_pfil_hooked)
188VNET_DEFINE(int, pf_end_threads);
189
190struct rwlock pf_rules_lock;
40
41#include "opt_inet.h"
42#include "opt_inet6.h"
43#include "opt_bpf.h"
44#include "opt_pf.h"
45
46#include <sys/param.h>
47#include <sys/bus.h>

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

183 .d_version = D_VERSION,
184};
185
186static volatile VNET_DEFINE(int, pf_pfil_hooked);
187#define V_pf_pfil_hooked VNET(pf_pfil_hooked)
188VNET_DEFINE(int, pf_end_threads);
189
190struct rwlock pf_rules_lock;
191struct sx pf_ioctl_lock;
191
192/* pfsync */
193pfsync_state_import_t *pfsync_state_import_ptr = NULL;
194pfsync_insert_state_t *pfsync_insert_state_ptr = NULL;
195pfsync_update_state_t *pfsync_update_state_ptr = NULL;
196pfsync_delete_state_t *pfsync_delete_state_ptr = NULL;
197pfsync_clear_states_t *pfsync_clear_states_ptr = NULL;
198pfsync_defer_t *pfsync_defer_ptr = NULL;

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

1085 default:
1086 return (EACCES);
1087 }
1088
1089 CURVNET_SET(TD_TO_VNET(td));
1090
1091 switch (cmd) {
1092 case DIOCSTART:
192
193/* pfsync */
194pfsync_state_import_t *pfsync_state_import_ptr = NULL;
195pfsync_insert_state_t *pfsync_insert_state_ptr = NULL;
196pfsync_update_state_t *pfsync_update_state_ptr = NULL;
197pfsync_delete_state_t *pfsync_delete_state_ptr = NULL;
198pfsync_clear_states_t *pfsync_clear_states_ptr = NULL;
199pfsync_defer_t *pfsync_defer_ptr = NULL;

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

1086 default:
1087 return (EACCES);
1088 }
1089
1090 CURVNET_SET(TD_TO_VNET(td));
1091
1092 switch (cmd) {
1093 case DIOCSTART:
1093 PF_RULES_WLOCK();
1094 sx_xlock(&pf_ioctl_lock);
1094 if (V_pf_status.running)
1095 error = EEXIST;
1096 else {
1097 int cpu;
1098
1095 if (V_pf_status.running)
1096 error = EEXIST;
1097 else {
1098 int cpu;
1099
1099 PF_RULES_WUNLOCK();
1100 error = hook_pf();
1101 if (error) {
1102 DPFPRINTF(PF_DEBUG_MISC,
1103 ("pf: pfil registration failed\n"));
1104 break;
1105 }
1100 error = hook_pf();
1101 if (error) {
1102 DPFPRINTF(PF_DEBUG_MISC,
1103 ("pf: pfil registration failed\n"));
1104 break;
1105 }
1106 PF_RULES_WLOCK();
1107 V_pf_status.running = 1;
1108 V_pf_status.since = time_second;
1109
1110 CPU_FOREACH(cpu)
1111 V_pf_stateid[cpu] = time_second;
1112
1113 DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n"));
1114 }
1106 V_pf_status.running = 1;
1107 V_pf_status.since = time_second;
1108
1109 CPU_FOREACH(cpu)
1110 V_pf_stateid[cpu] = time_second;
1111
1112 DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n"));
1113 }
1115 PF_RULES_WUNLOCK();
1116 break;
1117
1118 case DIOCSTOP:
1114 break;
1115
1116 case DIOCSTOP:
1119 PF_RULES_WLOCK();
1117 sx_xlock(&pf_ioctl_lock);
1120 if (!V_pf_status.running)
1121 error = ENOENT;
1122 else {
1123 V_pf_status.running = 0;
1118 if (!V_pf_status.running)
1119 error = ENOENT;
1120 else {
1121 V_pf_status.running = 0;
1124 PF_RULES_WUNLOCK();
1125 error = dehook_pf();
1126 if (error) {
1127 V_pf_status.running = 1;
1128 DPFPRINTF(PF_DEBUG_MISC,
1129 ("pf: pfil unregistration failed\n"));
1130 }
1122 error = dehook_pf();
1123 if (error) {
1124 V_pf_status.running = 1;
1125 DPFPRINTF(PF_DEBUG_MISC,
1126 ("pf: pfil unregistration failed\n"));
1127 }
1131 PF_RULES_WLOCK();
1132 V_pf_status.since = time_second;
1133 DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n"));
1134 }
1128 V_pf_status.since = time_second;
1129 DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n"));
1130 }
1135 PF_RULES_WUNLOCK();
1136 break;
1137
1138 case DIOCADDRULE: {
1139 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
1140 struct pf_ruleset *ruleset;
1141 struct pf_rule *rule, *tail;
1142 struct pf_pooladdr *pa;
1143 struct pfi_kif *kif = NULL;

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

3251 break;
3252 }
3253
3254 default:
3255 error = ENODEV;
3256 break;
3257 }
3258fail:
1131 break;
1132
1133 case DIOCADDRULE: {
1134 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
1135 struct pf_ruleset *ruleset;
1136 struct pf_rule *rule, *tail;
1137 struct pf_pooladdr *pa;
1138 struct pfi_kif *kif = NULL;

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

3246 break;
3247 }
3248
3249 default:
3250 error = ENODEV;
3251 break;
3252 }
3253fail:
3254 if (sx_xlocked(&pf_ioctl_lock))
3255 sx_xunlock(&pf_ioctl_lock);
3259 CURVNET_RESTORE();
3260
3261 return (error);
3262}
3263
3264void
3265pfsync_state_export(struct pfsync_state *sp, struct pf_state *st)
3266{

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

3428 if (PF_MATCHA(psnk->psnk_src.neg,
3429 &psnk->psnk_src.addr.v.a.addr,
3430 &psnk->psnk_src.addr.v.a.mask,
3431 &sn->addr, sn->af) &&
3432 PF_MATCHA(psnk->psnk_dst.neg,
3433 &psnk->psnk_dst.addr.v.a.addr,
3434 &psnk->psnk_dst.addr.v.a.mask,
3435 &sn->raddr, sn->af)) {
3256 CURVNET_RESTORE();
3257
3258 return (error);
3259}
3260
3261void
3262pfsync_state_export(struct pfsync_state *sp, struct pf_state *st)
3263{

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

3425 if (PF_MATCHA(psnk->psnk_src.neg,
3426 &psnk->psnk_src.addr.v.a.addr,
3427 &psnk->psnk_src.addr.v.a.mask,
3428 &sn->addr, sn->af) &&
3429 PF_MATCHA(psnk->psnk_dst.neg,
3430 &psnk->psnk_dst.addr.v.a.addr,
3431 &psnk->psnk_dst.addr.v.a.mask,
3432 &sn->raddr, sn->af)) {
3436 pf_unlink_src_node_locked(sn);
3433 pf_unlink_src_node(sn);
3437 LIST_INSERT_HEAD(&kill, sn, entry);
3438 sn->expire = 1;
3439 }
3440 PF_HASHROW_UNLOCK(sh);
3441 }
3442
3443 for (int i = 0; i <= pf_hashmask; i++) {
3444 struct pf_idhash *ih = &V_pf_idhash[i];
3445 struct pf_state *s;
3446
3447 PF_HASHROW_LOCK(ih);
3448 LIST_FOREACH(s, &ih->states, entry) {
3434 LIST_INSERT_HEAD(&kill, sn, entry);
3435 sn->expire = 1;
3436 }
3437 PF_HASHROW_UNLOCK(sh);
3438 }
3439
3440 for (int i = 0; i <= pf_hashmask; i++) {
3441 struct pf_idhash *ih = &V_pf_idhash[i];
3442 struct pf_state *s;
3443
3444 PF_HASHROW_LOCK(ih);
3445 LIST_FOREACH(s, &ih->states, entry) {
3449 if (s->src_node && s->src_node->expire == 1) {
3450#ifdef INVARIANTS
3451 s->src_node->states--;
3452#endif
3446 if (s->src_node && s->src_node->expire == 1)
3453 s->src_node = NULL;
3447 s->src_node = NULL;
3454 }
3455 if (s->nat_src_node && s->nat_src_node->expire == 1) {
3456#ifdef INVARIANTS
3457 s->nat_src_node->states--;
3458#endif
3448 if (s->nat_src_node && s->nat_src_node->expire == 1)
3459 s->nat_src_node = NULL;
3449 s->nat_src_node = NULL;
3460 }
3461 }
3462 PF_HASHROW_UNLOCK(ih);
3463 }
3464
3465 psnk->psnk_killed = pf_free_src_nodes(&kill);
3466}
3467
3468/*

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

3723 V_pf_end_threads = 0;
3724 TAILQ_INIT(&V_pf_tags);
3725 TAILQ_INIT(&V_pf_qids);
3726 CURVNET_RESTORE();
3727 }
3728 VNET_LIST_RUNLOCK();
3729
3730 rw_init(&pf_rules_lock, "pf rulesets");
3450 }
3451 PF_HASHROW_UNLOCK(ih);
3452 }
3453
3454 psnk->psnk_killed = pf_free_src_nodes(&kill);
3455}
3456
3457/*

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

3712 V_pf_end_threads = 0;
3713 TAILQ_INIT(&V_pf_tags);
3714 TAILQ_INIT(&V_pf_qids);
3715 CURVNET_RESTORE();
3716 }
3717 VNET_LIST_RUNLOCK();
3718
3719 rw_init(&pf_rules_lock, "pf rulesets");
3720 sx_init(&pf_ioctl_lock, "pf ioctl");
3731
3732 pf_dev = make_dev(&pf_cdevsw, 0, 0, 0, 0600, PF_NAME);
3733 if ((error = pfattach()) != 0)
3734 return (error);
3735
3736 return (0);
3737}
3738
3739static int
3740pf_unload(void)
3741{
3742 int error = 0;
3743
3721
3722 pf_dev = make_dev(&pf_cdevsw, 0, 0, 0, 0600, PF_NAME);
3723 if ((error = pfattach()) != 0)
3724 return (error);
3725
3726 return (0);
3727}
3728
3729static int
3730pf_unload(void)
3731{
3732 int error = 0;
3733
3744 PF_RULES_WLOCK();
3745 V_pf_status.running = 0;
3734 V_pf_status.running = 0;
3746 PF_RULES_WUNLOCK();
3747 swi_remove(V_pf_swi_cookie);
3748 error = dehook_pf();
3749 if (error) {
3750 /*
3751 * Should not happen!
3752 * XXX Due to error code ESRCH, kldunload will show
3753 * a message like 'No such process'.
3754 */
3755 printf("%s : pfil unregisteration fail\n", __FUNCTION__);
3756 return error;
3757 }
3758 PF_RULES_WLOCK();
3759 shutdown_pf();
3760 V_pf_end_threads = 1;
3761 while (V_pf_end_threads < 2) {
3762 wakeup_one(pf_purge_thread);
3763 rw_sleep(pf_purge_thread, &pf_rules_lock, 0, "pftmo", 0);
3764 }
3735 swi_remove(V_pf_swi_cookie);
3736 error = dehook_pf();
3737 if (error) {
3738 /*
3739 * Should not happen!
3740 * XXX Due to error code ESRCH, kldunload will show
3741 * a message like 'No such process'.
3742 */
3743 printf("%s : pfil unregisteration fail\n", __FUNCTION__);
3744 return error;
3745 }
3746 PF_RULES_WLOCK();
3747 shutdown_pf();
3748 V_pf_end_threads = 1;
3749 while (V_pf_end_threads < 2) {
3750 wakeup_one(pf_purge_thread);
3751 rw_sleep(pf_purge_thread, &pf_rules_lock, 0, "pftmo", 0);
3752 }
3753 PF_RULES_WUNLOCK();
3765 pf_normalize_cleanup();
3766 pfi_cleanup();
3767 pfr_cleanup();
3768 pf_osfp_flush();
3769 pf_cleanup();
3770 if (IS_DEFAULT_VNET(curvnet))
3771 pf_mtag_cleanup();
3754 pf_normalize_cleanup();
3755 pfi_cleanup();
3756 pfr_cleanup();
3757 pf_osfp_flush();
3758 pf_cleanup();
3759 if (IS_DEFAULT_VNET(curvnet))
3760 pf_mtag_cleanup();
3772 PF_RULES_WUNLOCK();
3773 destroy_dev(pf_dev);
3774 rw_destroy(&pf_rules_lock);
3761 destroy_dev(pf_dev);
3762 rw_destroy(&pf_rules_lock);
3763 sx_destroy(&pf_ioctl_lock);
3775
3776 return (error);
3777}
3778
3779static int
3780pf_modevent(module_t mod, int type, void *data)
3781{
3782 int error = 0;

--- 30 unchanged lines hidden ---
3764
3765 return (error);
3766}
3767
3768static int
3769pf_modevent(module_t mod, int type, void *data)
3770{
3771 int error = 0;

--- 30 unchanged lines hidden ---