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 --- |