pf_ioctl.c (126259) | pf_ioctl.c (126261) |
---|---|
1/* $FreeBSD: head/sys/contrib/pf/net/pf_ioctl.c 126261 2004-02-26 02:34:12Z mlaier $ */ |
|
1/* $OpenBSD: pf_ioctl.c,v 1.81 2003/08/22 21:50:34 david Exp $ */ 2 3/* 4 * Copyright (c) 2001 Daniel Hartmeier 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 --- 20 unchanged lines hidden (view full) --- 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 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 */ 36 | 2/* $OpenBSD: pf_ioctl.c,v 1.81 2003/08/22 21:50:34 david Exp $ */ 3 4/* 5 * Copyright (c) 2001 Daniel Hartmeier 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 20 unchanged lines hidden (view full) --- 30 * POSSIBILITY OF SUCH DAMAGE. 31 * 32 * Effort sponsored in part by the Defense Advanced Research Projects 33 * Agency (DARPA) and Air Force Research Laboratory, Air Force 34 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 35 * 36 */ 37 |
38#if defined(__FreeBSD__) 39#include "opt_inet.h" 40#include "opt_inet6.h" 41#endif 42 |
|
37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/mbuf.h> 40#include <sys/filio.h> 41#include <sys/fcntl.h> 42#include <sys/socket.h> 43#include <sys/socketvar.h> 44#include <sys/kernel.h> 45#include <sys/time.h> | 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/mbuf.h> 46#include <sys/filio.h> 47#include <sys/fcntl.h> 48#include <sys/socket.h> 49#include <sys/socketvar.h> 50#include <sys/kernel.h> 51#include <sys/time.h> |
52#include <sys/malloc.h> 53#if defined(__FreeBSD__) 54#include <sys/conf.h> 55#else |
|
46#include <sys/timeout.h> 47#include <sys/pool.h> | 56#include <sys/timeout.h> 57#include <sys/pool.h> |
48#include <sys/malloc.h> | 58#endif |
49 50#include <net/if.h> 51#include <net/if_types.h> 52#include <net/route.h> 53 54#include <netinet/in.h> 55#include <netinet/in_var.h> 56#include <netinet/in_systm.h> 57#include <netinet/ip.h> 58#include <netinet/ip_var.h> 59#include <netinet/ip_icmp.h> 60 61#include <net/pfvar.h> 62 63#ifdef INET6 64#include <netinet/ip6.h> 65#include <netinet/in_pcb.h> | 59 60#include <net/if.h> 61#include <net/if_types.h> 62#include <net/route.h> 63 64#include <netinet/in.h> 65#include <netinet/in_var.h> 66#include <netinet/in_systm.h> 67#include <netinet/ip.h> 68#include <netinet/ip_var.h> 69#include <netinet/ip_icmp.h> 70 71#include <net/pfvar.h> 72 73#ifdef INET6 74#include <netinet/ip6.h> 75#include <netinet/in_pcb.h> |
76#if defined(__FreeBSD__) && (__FreeBSD_version < 501108) 77#include <netinet6/ip6protosw.h> 78#endif |
|
66#endif /* INET6 */ 67 68#ifdef ALTQ 69#include <altq/altq.h> 70#endif 71 | 79#endif /* INET6 */ 80 81#ifdef ALTQ 82#include <altq/altq.h> 83#endif 84 |
85#if defined(__FreeBSD__) 86#if (__FreeBSD_version >= 500112) 87#include <sys/limits.h> 88#else 89#include <machine/limits.h> 90#endif 91#include <sys/lock.h> 92#include <sys/mutex.h> 93#if __FreeBSD_version < 501108 94#include <sys/protosw.h> 95#endif 96#include <net/pfil.h> 97#endif /* __FreeBSD__ */ 98 99#if defined(__FreeBSD__) 100void init_zone_var(void); 101void cleanup_pf_zone(void); 102int pfattach(void); 103#else |
|
72void pfattach(int); 73int pfopen(dev_t, int, int, struct proc *); 74int pfclose(dev_t, int, int, struct proc *); | 104void pfattach(int); 105int pfopen(dev_t, int, int, struct proc *); 106int pfclose(dev_t, int, int, struct proc *); |
107#endif |
|
75struct pf_pool *pf_get_pool(char *, char *, u_int32_t, 76 u_int8_t, u_int8_t, u_int8_t, u_int8_t, u_int8_t); 77int pf_get_ruleset_number(u_int8_t); 78void pf_init_ruleset(struct pf_ruleset *); 79void pf_mv_pool(struct pf_palist *, struct pf_palist *); 80void pf_empty_pool(struct pf_palist *); | 108struct pf_pool *pf_get_pool(char *, char *, u_int32_t, 109 u_int8_t, u_int8_t, u_int8_t, u_int8_t, u_int8_t); 110int pf_get_ruleset_number(u_int8_t); 111void pf_init_ruleset(struct pf_ruleset *); 112void pf_mv_pool(struct pf_palist *, struct pf_palist *); 113void pf_empty_pool(struct pf_palist *); |
114#if defined(__FreeBSD__) 115int pfioctl(dev_t, u_long, caddr_t, int, struct thread *); 116#else |
|
81int pfioctl(dev_t, u_long, caddr_t, int, struct proc *); | 117int pfioctl(dev_t, u_long, caddr_t, int, struct proc *); |
118#endif |
|
82 | 119 |
120#if defined(__FreeBSD__) 121extern struct callout pf_expire_to; 122#if __FreeBSD_version < 501108 123extern struct protosw inetsw[]; 124#endif 125#else |
|
83extern struct timeout pf_expire_to; | 126extern struct timeout pf_expire_to; |
127#endif |
|
84 85struct pf_rule pf_default_rule; 86 87#define TAGID_MAX 50000 88TAILQ_HEAD(pf_tags, pf_tagname) pf_tags = TAILQ_HEAD_INITIALIZER(pf_tags); 89 90#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x 91 | 128 129struct pf_rule pf_default_rule; 130 131#define TAGID_MAX 50000 132TAILQ_HEAD(pf_tags, pf_tagname) pf_tags = TAILQ_HEAD_INITIALIZER(pf_tags); 133 134#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x 135 |
136 137#if defined(__FreeBSD__) 138static dev_t pf_dev; 139 140/* 141 * XXX - These are new and need to be checked when moveing to a new version 142 */ 143static int pf_beginrules(void *addr); 144static int pf_commitrules(void *addr); 145#if defined(ALTQ) 146static int pf_beginaltqs(void *addr); 147static int pf_commitaltqs(void *addr); 148static int pf_stopaltq(void); 149#endif 150static void pf_clearstates(void); 151static int pf_clear_tables(void *addr); 152/* 153 * XXX - These are new and need to be checked when moveing to a new version 154 */ 155 156#if (__FreeBSD_version < 501108) 157static int pf_check_in(void *ip, int hlen, struct ifnet *ifp, int dir, 158 struct mbuf **m); 159static int pf_check_out(void *ip, int hlen, struct ifnet *ifp, int dir, 160 struct mbuf **m); 161#if defined(INET6) 162static int pf_check6_in(void *ip, int hlen, struct ifnet *ifp, int dir, 163 struct mbuf **m); 164static int pf_check6_out(void *ip, int hlen, struct ifnet *ifp, int dir, 165 struct mbuf **m); 166#endif 167#else /* (__FreeBSD_version >= 501108) */ 168static int pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, 169 int dir); 170static int pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, 171 int dir); 172#if defined(INET6) 173static int pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, 174 int dir); 175static int pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, 176 int dir); 177#endif 178#endif /* (__FreeBSD_version >= 501108) */ 179static int hook_pf(void); 180static int dehook_pf(void); 181static int shutdown_pf(void); 182static int pf_load(void); 183static int pf_unload(void); 184 185 186 187static struct cdevsw pf_cdevsw = { 188#if (__FreeBSD_version < 500105) 189 /* open */ noopen, 190 /* close */ noclose, 191 /* read */ noread, 192 /* write */ nowrite, 193 /* ioctl */ pfioctl, 194 /* poll */ nopoll, 195 /* mmap */ nommap, 196 /* strategy */ nostrategy, 197 /* name */ PF_NAME, 198 /* maj */ PF_CDEV_MAJOR, 199 /* dump */ nodump, 200 /* psize */ nopsize, 201 /* flags */ 0, 202 /* kqfilter */ nokqfilter, 203#elif (__FreeBSD_version < 501110) 204 .d_open = noopen, 205 .d_close = noclose, 206 .d_read = noread, 207 .d_write = nowrite, 208 .d_ioctl = pfioctl, 209 .d_poll = nopoll, 210 .d_mmap = nommap, 211 .d_strategy = nostrategy, 212 .d_name = PF_NAME, 213 .d_maj = MAJOR_AUTO, /* PF_CDEV_MAJOR */ 214 .d_dump = nodump, 215 .d_flags = 0, 216 .d_kqfilter = nokqfilter, 217#else 218 .d_ioctl = pfioctl, 219 .d_name = PF_NAME, 220 .d_version = D_VERSION, 221#endif 222}; 223#endif /* __FreeBSD__ */ 224 225#if defined(__FreeBSD__) 226static volatile int pf_pfil_hooked = 0; 227struct mtx pf_task_mtx; 228 |
|
92void | 229void |
230init_pf_mutex(void) 231{ 232 mtx_init(&pf_task_mtx, "pf task mtx", NULL, MTX_DEF); 233/* 234 * pf_altq_mtx is initialized at altq_subr.c. 235 * 236 * #if defined(ALTQ) && !defined(ALTQ3_COMPAT) 237 * mtx_init(&pf_altq_mtx, "pf altq mtx", NULL, MTX_DEF); 238 * #endif 239 */ 240} 241 242void 243destroy_pf_mutex(void) 244{ 245 mtx_destroy(&pf_task_mtx); 246/* 247 * pf_altq_mtx is initialized at altq_subr.c. 248 * 249 * #if defined(ALTQ) && !defined(ALTQ3_COMPAT) 250 * mtx_destroy(&pf_altq_mtx); 251 * #endif 252 */ 253} 254 255void 256init_zone_var(void) 257{ 258 pf_tree_pl = pf_rule_pl = pf_addr_pl = NULL; 259 pf_state_pl = pf_altq_pl = pf_pooladdr_pl = NULL; 260 pf_frent_pl = pf_frag_pl = pf_cache_pl = pf_cent_pl = NULL; 261 pf_state_scrub_pl = NULL; 262 pfr_ktable_pl = pfr_kentry_pl = NULL; 263} 264 265void 266cleanup_pf_zone(void) 267{ 268 UMA_DESTROY(pf_tree_pl); 269 UMA_DESTROY(pf_rule_pl); 270 UMA_DESTROY(pf_addr_pl); 271 UMA_DESTROY(pf_state_pl); 272 UMA_DESTROY(pf_altq_pl); 273 UMA_DESTROY(pf_pooladdr_pl); 274 UMA_DESTROY(pf_frent_pl); 275 UMA_DESTROY(pf_frag_pl); 276 UMA_DESTROY(pf_cache_pl); 277 UMA_DESTROY(pf_cent_pl); 278 UMA_DESTROY(pfr_ktable_pl); 279 UMA_DESTROY(pfr_kentry_pl); 280 UMA_DESTROY(pf_state_scrub_pl); 281} 282#endif /* __FreeBSD__ */ 283 284#if defined(__FreeBSD__) 285int 286pfattach(void) 287{ 288 u_int32_t *my_timeout = pf_default_rule.timeout; 289 int error = 1; 290 291 do { 292 UMA_CREATE(pf_tree_pl, struct pf_tree_node, "pftrpl"); 293 UMA_CREATE(pf_rule_pl, struct pf_rule, "pfrulepl"); 294 UMA_CREATE(pf_addr_pl, struct pf_addr_dyn, "pfaddrpl"); 295 UMA_CREATE(pf_state_pl, struct pf_state, "pfstatepl"); 296 UMA_CREATE(pf_altq_pl, struct pf_altq, "pfaltqpl"); 297 UMA_CREATE(pf_pooladdr_pl, struct pf_pooladdr, "pfpooladdrpl"); 298 UMA_CREATE(pfr_ktable_pl, struct pfr_ktable, "pfrktable"); 299 UMA_CREATE(pfr_kentry_pl, struct pfr_kentry, "pfrkentry"); 300 UMA_CREATE(pf_frent_pl, struct pf_frent, "pffrent"); 301 UMA_CREATE(pf_frag_pl, struct pf_fragment, "pffrag"); 302 UMA_CREATE(pf_cache_pl, struct pf_fragment, "pffrcache"); 303 UMA_CREATE(pf_cent_pl, struct pf_frcache, "pffrcent"); 304 UMA_CREATE(pf_state_scrub_pl, struct pf_state_scrub, 305 "pfstatescrub"); 306 error = 0; 307 } while(0); 308 if (error) { 309 cleanup_pf_zone(); 310 return (error); 311 } 312 pfr_initialize(); 313 if ( (error = pf_osfp_initialize()) ) { 314 cleanup_pf_zone(); 315 pf_osfp_cleanup(); 316 return (error); 317 } 318 319 pf_pool_limits[PF_LIMIT_STATES].pp = pf_state_pl; 320 pf_pool_limits[PF_LIMIT_STATES].limit = PFSTATE_HIWAT; 321 pf_pool_limits[PF_LIMIT_FRAGS].pp = pf_frent_pl; 322 pf_pool_limits[PF_LIMIT_FRAGS].limit = PFFRAG_FRENT_HIWAT; 323 uma_zone_set_max(pf_pool_limits[PF_LIMIT_STATES].pp, 324 pf_pool_limits[PF_LIMIT_STATES].limit); 325 326 RB_INIT(&tree_lan_ext); 327 RB_INIT(&tree_ext_gwy); 328 TAILQ_INIT(&pf_anchors); 329 pf_init_ruleset(&pf_main_ruleset); 330 TAILQ_INIT(&pf_altqs[0]); 331 TAILQ_INIT(&pf_altqs[1]); 332 TAILQ_INIT(&pf_pabuf); 333 pf_altqs_active = &pf_altqs[0]; 334 pf_altqs_inactive = &pf_altqs[1]; 335 336 /* default rule should never be garbage collected */ 337 pf_default_rule.entries.tqe_prev = &pf_default_rule.entries.tqe_next; 338 pf_default_rule.action = PF_PASS; 339 pf_default_rule.nr = -1; 340 341 /* initialize default timeouts */ 342 my_timeout[PFTM_TCP_FIRST_PACKET] = 120; /* First TCP packet */ 343 my_timeout[PFTM_TCP_OPENING] = 30; /* No response yet */ 344 my_timeout[PFTM_TCP_ESTABLISHED] = 24*60*60; /* Established */ 345 my_timeout[PFTM_TCP_CLOSING] = 15 * 60; /* Half closed */ 346 my_timeout[PFTM_TCP_FIN_WAIT] = 45; /* Got both FINs */ 347 my_timeout[PFTM_TCP_CLOSED] = 90; /* Got a RST */ 348 my_timeout[PFTM_UDP_FIRST_PACKET] = 60; /* First UDP packet */ 349 my_timeout[PFTM_UDP_SINGLE] = 30; /* Unidirectional */ 350 my_timeout[PFTM_UDP_MULTIPLE] = 60; /* Bidirectional */ 351 my_timeout[PFTM_ICMP_FIRST_PACKET] = 20; /* First ICMP packet */ 352 my_timeout[PFTM_ICMP_ERROR_REPLY] = 10; /* Got error response */ 353 my_timeout[PFTM_OTHER_FIRST_PACKET] = 60; /* First packet */ 354 my_timeout[PFTM_OTHER_SINGLE] = 30; /* Unidirectional */ 355 my_timeout[PFTM_OTHER_MULTIPLE] = 60; /* Bidirectional */ 356 my_timeout[PFTM_FRAG] = 30; /* Fragment expire */ 357 my_timeout[PFTM_INTERVAL] = 10; /* Expire interval */ 358 359 /* 360 * XXX 361 * The 2nd arg. 0 to callout_init(9) shoule be set to CALLOUT_MPSAFE 362 * if Gaint lock is removed from the network stack. 363 */ 364 callout_init(&pf_expire_to, 0); 365 callout_reset(&pf_expire_to, my_timeout[PFTM_INTERVAL] * hz, 366 pf_purge_timeout, &pf_expire_to); 367 368 pf_normalize_init(); 369 pf_status.debug = PF_DEBUG_URGENT; 370 pf_pfil_hooked = 0; 371 return (error); 372} 373#else /* !__FreeBSD__ */ 374void |
|
93pfattach(int num) 94{ 95 u_int32_t *timeout = pf_default_rule.timeout; 96 97 pool_init(&pf_tree_pl, sizeof(struct pf_tree_node), 0, 0, 0, "pftrpl", 98 NULL); 99 pool_init(&pf_rule_pl, sizeof(struct pf_rule), 0, 0, 0, "pfrulepl", 100 &pool_allocator_nointr); --- 23 unchanged lines hidden (view full) --- 124 125 /* default rule should never be garbage collected */ 126 pf_default_rule.entries.tqe_prev = &pf_default_rule.entries.tqe_next; 127 pf_default_rule.action = PF_PASS; 128 pf_default_rule.nr = -1; 129 130 /* initialize default timeouts */ 131 timeout[PFTM_TCP_FIRST_PACKET] = 120; /* First TCP packet */ | 375pfattach(int num) 376{ 377 u_int32_t *timeout = pf_default_rule.timeout; 378 379 pool_init(&pf_tree_pl, sizeof(struct pf_tree_node), 0, 0, 0, "pftrpl", 380 NULL); 381 pool_init(&pf_rule_pl, sizeof(struct pf_rule), 0, 0, 0, "pfrulepl", 382 &pool_allocator_nointr); --- 23 unchanged lines hidden (view full) --- 406 407 /* default rule should never be garbage collected */ 408 pf_default_rule.entries.tqe_prev = &pf_default_rule.entries.tqe_next; 409 pf_default_rule.action = PF_PASS; 410 pf_default_rule.nr = -1; 411 412 /* initialize default timeouts */ 413 timeout[PFTM_TCP_FIRST_PACKET] = 120; /* First TCP packet */ |
132 timeout[PFTM_TCP_OPENING] = 30; /* No response yet */ | 414 timeout[PFTM_TCP_OPENING] = 30; /* No response yet */ |
133 timeout[PFTM_TCP_ESTABLISHED] = 24*60*60; /* Established */ 134 timeout[PFTM_TCP_CLOSING] = 15 * 60; /* Half closed */ 135 timeout[PFTM_TCP_FIN_WAIT] = 45; /* Got both FINs */ 136 timeout[PFTM_TCP_CLOSED] = 90; /* Got a RST */ 137 timeout[PFTM_UDP_FIRST_PACKET] = 60; /* First UDP packet */ 138 timeout[PFTM_UDP_SINGLE] = 30; /* Unidirectional */ 139 timeout[PFTM_UDP_MULTIPLE] = 60; /* Bidirectional */ 140 timeout[PFTM_ICMP_FIRST_PACKET] = 20; /* First ICMP packet */ --- 5 unchanged lines hidden (view full) --- 146 timeout[PFTM_INTERVAL] = 10; /* Expire interval */ 147 148 timeout_set(&pf_expire_to, pf_purge_timeout, &pf_expire_to); 149 timeout_add(&pf_expire_to, timeout[PFTM_INTERVAL] * hz); 150 151 pf_normalize_init(); 152 pf_status.debug = PF_DEBUG_URGENT; 153} | 415 timeout[PFTM_TCP_ESTABLISHED] = 24*60*60; /* Established */ 416 timeout[PFTM_TCP_CLOSING] = 15 * 60; /* Half closed */ 417 timeout[PFTM_TCP_FIN_WAIT] = 45; /* Got both FINs */ 418 timeout[PFTM_TCP_CLOSED] = 90; /* Got a RST */ 419 timeout[PFTM_UDP_FIRST_PACKET] = 60; /* First UDP packet */ 420 timeout[PFTM_UDP_SINGLE] = 30; /* Unidirectional */ 421 timeout[PFTM_UDP_MULTIPLE] = 60; /* Bidirectional */ 422 timeout[PFTM_ICMP_FIRST_PACKET] = 20; /* First ICMP packet */ --- 5 unchanged lines hidden (view full) --- 428 timeout[PFTM_INTERVAL] = 10; /* Expire interval */ 429 430 timeout_set(&pf_expire_to, pf_purge_timeout, &pf_expire_to); 431 timeout_add(&pf_expire_to, timeout[PFTM_INTERVAL] * hz); 432 433 pf_normalize_init(); 434 pf_status.debug = PF_DEBUG_URGENT; 435} |
436#endif /* __FreeBSD__ */ |
|
154 | 437 |
438#if !defined(__FreeBSD__) |
|
155int 156pfopen(dev_t dev, int flags, int fmt, struct proc *p) 157{ 158 if (minor(dev) >= 1) 159 return (ENXIO); 160 return (0); 161} | 439int 440pfopen(dev_t dev, int flags, int fmt, struct proc *p) 441{ 442 if (minor(dev) >= 1) 443 return (ENXIO); 444 return (0); 445} |
446#endif |
|
162 | 447 |
448#if !defined(__FreeBSD__) |
|
163int 164pfclose(dev_t dev, int flags, int fmt, struct proc *p) 165{ 166 if (minor(dev) >= 1) 167 return (ENXIO); 168 return (0); 169} | 449int 450pfclose(dev_t dev, int flags, int fmt, struct proc *p) 451{ 452 if (minor(dev) >= 1) 453 return (ENXIO); 454 return (0); 455} |
456#endif |
|
170 171struct pf_pool * 172pf_get_pool(char *anchorname, char *rulesetname, u_int32_t ticket, 173 u_int8_t rule_action, u_int8_t rule_number, u_int8_t r_last, 174 u_int8_t active, u_int8_t check_ticket) 175{ 176 struct pf_ruleset *ruleset; 177 struct pf_rule *rule; --- 166 unchanged lines hidden (view full) --- 344} 345 346void 347pf_remove_if_empty_ruleset(struct pf_ruleset *ruleset) 348{ 349 struct pf_anchor *anchor; 350 int i; 351 | 457 458struct pf_pool * 459pf_get_pool(char *anchorname, char *rulesetname, u_int32_t ticket, 460 u_int8_t rule_action, u_int8_t rule_number, u_int8_t r_last, 461 u_int8_t active, u_int8_t check_ticket) 462{ 463 struct pf_ruleset *ruleset; 464 struct pf_rule *rule; --- 166 unchanged lines hidden (view full) --- 631} 632 633void 634pf_remove_if_empty_ruleset(struct pf_ruleset *ruleset) 635{ 636 struct pf_anchor *anchor; 637 int i; 638 |
352 if (ruleset == NULL || ruleset->anchor == NULL || ruleset->tables > 0 || ruleset->topen) | 639 if (ruleset == NULL || ruleset->anchor == NULL || ruleset->tables > 0 || 640 ruleset->topen) |
353 return; 354 for (i = 0; i < PF_RULESET_MAX; ++i) 355 if (!TAILQ_EMPTY(ruleset->rules[i].active.ptr) || 356 !TAILQ_EMPTY(ruleset->rules[i].inactive.ptr)) 357 return; 358 359 anchor = ruleset->anchor; 360 TAILQ_REMOVE(&anchor->rulesets, ruleset, entries); --- 132 unchanged lines hidden (view full) --- 493 TAILQ_REMOVE(&pf_tags, p, entries); 494 free(p, M_TEMP); 495 } 496 break; 497 } 498 } 499} 500 | 641 return; 642 for (i = 0; i < PF_RULESET_MAX; ++i) 643 if (!TAILQ_EMPTY(ruleset->rules[i].active.ptr) || 644 !TAILQ_EMPTY(ruleset->rules[i].inactive.ptr)) 645 return; 646 647 anchor = ruleset->anchor; 648 TAILQ_REMOVE(&anchor->rulesets, ruleset, entries); --- 132 unchanged lines hidden (view full) --- 781 TAILQ_REMOVE(&pf_tags, p, entries); 782 free(p, M_TEMP); 783 } 784 break; 785 } 786 } 787} 788 |
789#if defined(__FreeBSD__) |
|
501int | 790int |
791pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td) 792#else 793int |
|
502pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) | 794pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) |
795#endif |
|
503{ 504 struct pf_pooladdr *pa = NULL; 505 struct pf_pool *pool = NULL; 506 int s; 507 int error = 0; 508 509 /* XXX keep in sync with switch() below */ 510 if (securelevel > 1) --- 26 unchanged lines hidden (view full) --- 537 case DIOCRADDADDRS: 538 case DIOCRDELADDRS: 539 case DIOCRSETADDRS: 540 case DIOCRGETADDRS: 541 case DIOCRGETASTATS: 542 case DIOCRCLRASTATS: 543 case DIOCRTSTADDRS: 544 case DIOCOSFPGET: | 796{ 797 struct pf_pooladdr *pa = NULL; 798 struct pf_pool *pool = NULL; 799 int s; 800 int error = 0; 801 802 /* XXX keep in sync with switch() below */ 803 if (securelevel > 1) --- 26 unchanged lines hidden (view full) --- 830 case DIOCRADDADDRS: 831 case DIOCRDELADDRS: 832 case DIOCRSETADDRS: 833 case DIOCRGETADDRS: 834 case DIOCRGETASTATS: 835 case DIOCRCLRASTATS: 836 case DIOCRTSTADDRS: 837 case DIOCOSFPGET: |
838#if defined(__FreeBSD__) 839 case DIOCGIFSPEED: 840#endif |
|
545 break; 546 default: 547 return (EPERM); 548 } 549 550 if (!(flags & FWRITE)) 551 switch (cmd) { 552 case DIOCGETRULES: --- 13 unchanged lines hidden (view full) --- 566 case DIOCGETRULESETS: 567 case DIOCGETRULESET: 568 case DIOCRGETTABLES: 569 case DIOCRGETTSTATS: 570 case DIOCRGETADDRS: 571 case DIOCRGETASTATS: 572 case DIOCRTSTADDRS: 573 case DIOCOSFPGET: | 841 break; 842 default: 843 return (EPERM); 844 } 845 846 if (!(flags & FWRITE)) 847 switch (cmd) { 848 case DIOCGETRULES: --- 13 unchanged lines hidden (view full) --- 862 case DIOCGETRULESETS: 863 case DIOCGETRULESET: 864 case DIOCRGETTABLES: 865 case DIOCRGETTSTATS: 866 case DIOCRGETADDRS: 867 case DIOCRGETASTATS: 868 case DIOCRTSTADDRS: 869 case DIOCOSFPGET: |
870#if defined(__FreeBSD__) 871 case DIOCGIFSPEED: 872#endif |
|
574 break; 575 default: 576 return (EACCES); 577 } 578 | 873 break; 874 default: 875 return (EACCES); 876 } 877 |
878#if defined(__FreeBSD__) 879 PF_LOCK(); 880#endif 881 |
|
579 switch (cmd) { 580 581 case DIOCSTART: 582 if (pf_status.running) 583 error = EEXIST; 584 else { 585 u_int32_t states = pf_status.states; | 882 switch (cmd) { 883 884 case DIOCSTART: 885 if (pf_status.running) 886 error = EEXIST; 887 else { 888 u_int32_t states = pf_status.states; |
889#if defined(__FreeBSD__) 890 PF_UNLOCK(); 891 error = hook_pf(); 892 PF_LOCK(); 893 if (error) { 894 DPFPRINTF(PF_DEBUG_MISC, 895 ("pf: pfil registeration fail\n")); 896 break; 897 } 898#endif |
|
586 bzero(&pf_status, sizeof(struct pf_status)); 587 pf_status.running = 1; 588 pf_status.states = states; | 899 bzero(&pf_status, sizeof(struct pf_status)); 900 pf_status.running = 1; 901 pf_status.states = states; |
902#if defined(__FreeBSD__) 903 pf_status.since = time_second; 904#else |
|
589 pf_status.since = time.tv_sec; | 905 pf_status.since = time.tv_sec; |
906#endif |
|
590 if (status_ifp != NULL) | 907 if (status_ifp != NULL) |
908#if defined(__FreeBSD__) && (__FreeBSD_version < 501113) 909 snprintf(pf_status.ifname, IFNAMSIZ, "%s%d", 910 status_ifp->if_name, status_ifp->if_unit); 911#else |
|
591 strlcpy(pf_status.ifname, 592 status_ifp->if_xname, IFNAMSIZ); | 912 strlcpy(pf_status.ifname, 913 status_ifp->if_xname, IFNAMSIZ); |
914#endif |
|
593 DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n")); 594 } 595 break; 596 597 case DIOCSTOP: 598 if (!pf_status.running) 599 error = ENOENT; 600 else { 601 pf_status.running = 0; | 915 DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n")); 916 } 917 break; 918 919 case DIOCSTOP: 920 if (!pf_status.running) 921 error = ENOENT; 922 else { 923 pf_status.running = 0; |
924#if defined(__FreeBSD__) 925 PF_UNLOCK(); 926 error = dehook_pf(); 927 PF_LOCK(); 928 if (error) { 929 pf_status.running = 1; 930 DPFPRINTF(PF_DEBUG_MISC, 931 ("pf: pfil unregisteration failed\n")); 932 } 933#endif |
|
602 DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n")); 603 } 604 break; 605 606 case DIOCBEGINRULES: { 607 struct pfioc_rule *pr = (struct pfioc_rule *)addr; 608 struct pf_ruleset *ruleset; 609 struct pf_rule *rule; --- 493 unchanged lines hidden (view full) --- 1103 break; 1104 } 1105 s = splsoftnet(); 1106 bcopy(&ps->state, state, sizeof(struct pf_state)); 1107 state->rule.ptr = NULL; 1108 state->nat_rule.ptr = NULL; 1109 state->anchor.ptr = NULL; 1110 state->rt_ifp = NULL; | 934 DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n")); 935 } 936 break; 937 938 case DIOCBEGINRULES: { 939 struct pfioc_rule *pr = (struct pfioc_rule *)addr; 940 struct pf_ruleset *ruleset; 941 struct pf_rule *rule; --- 493 unchanged lines hidden (view full) --- 1435 break; 1436 } 1437 s = splsoftnet(); 1438 bcopy(&ps->state, state, sizeof(struct pf_state)); 1439 state->rule.ptr = NULL; 1440 state->nat_rule.ptr = NULL; 1441 state->anchor.ptr = NULL; 1442 state->rt_ifp = NULL; |
1443#if defined(__FreeBSD__) 1444 state->creation = time_second; 1445#else |
|
1111 state->creation = time.tv_sec; | 1446 state->creation = time.tv_sec; |
1447#endif |
|
1112 state->packets[0] = state->packets[1] = 0; 1113 state->bytes[0] = state->bytes[1] = 0; 1114 if (pf_insert_state(state)) { 1115 pool_put(&pf_state_pl, state); 1116 error = ENOMEM; 1117 } 1118 splx(s); 1119 break; --- 19 unchanged lines hidden (view full) --- 1139 bcopy(n->state, &ps->state, sizeof(struct pf_state)); 1140 ps->state.rule.nr = n->state->rule.ptr->nr; 1141 ps->state.nat_rule.nr = (n->state->nat_rule.ptr == NULL) ? 1142 -1 : n->state->nat_rule.ptr->nr; 1143 ps->state.anchor.nr = (n->state->anchor.ptr == NULL) ? 1144 -1 : n->state->anchor.ptr->nr; 1145 splx(s); 1146 ps->state.expire = pf_state_expires(n->state); | 1448 state->packets[0] = state->packets[1] = 0; 1449 state->bytes[0] = state->bytes[1] = 0; 1450 if (pf_insert_state(state)) { 1451 pool_put(&pf_state_pl, state); 1452 error = ENOMEM; 1453 } 1454 splx(s); 1455 break; --- 19 unchanged lines hidden (view full) --- 1475 bcopy(n->state, &ps->state, sizeof(struct pf_state)); 1476 ps->state.rule.nr = n->state->rule.ptr->nr; 1477 ps->state.nat_rule.nr = (n->state->nat_rule.ptr == NULL) ? 1478 -1 : n->state->nat_rule.ptr->nr; 1479 ps->state.anchor.nr = (n->state->anchor.ptr == NULL) ? 1480 -1 : n->state->anchor.ptr->nr; 1481 splx(s); 1482 ps->state.expire = pf_state_expires(n->state); |
1483#if defined(__FreeBSD__) 1484 if (ps->state.expire > time_second) 1485 ps->state.expire -= time_second; 1486#else |
|
1147 if (ps->state.expire > time.tv_sec) 1148 ps->state.expire -= time.tv_sec; | 1487 if (ps->state.expire > time.tv_sec) 1488 ps->state.expire -= time.tv_sec; |
1489#endif |
|
1149 else 1150 ps->state.expire = 0; 1151 break; 1152 } 1153 1154 case DIOCGETSTATES: { 1155 struct pfioc_states *ps = (struct pfioc_states *)addr; 1156 struct pf_tree_node *n; 1157 struct pf_state *p, pstore; 1158 u_int32_t nr = 0; 1159 int space = ps->ps_len; 1160 1161 if (space == 0) { 1162 s = splsoftnet(); 1163 RB_FOREACH(n, pf_state_tree, &tree_ext_gwy) 1164 nr++; 1165 splx(s); 1166 ps->ps_len = sizeof(struct pf_state) * nr; | 1490 else 1491 ps->state.expire = 0; 1492 break; 1493 } 1494 1495 case DIOCGETSTATES: { 1496 struct pfioc_states *ps = (struct pfioc_states *)addr; 1497 struct pf_tree_node *n; 1498 struct pf_state *p, pstore; 1499 u_int32_t nr = 0; 1500 int space = ps->ps_len; 1501 1502 if (space == 0) { 1503 s = splsoftnet(); 1504 RB_FOREACH(n, pf_state_tree, &tree_ext_gwy) 1505 nr++; 1506 splx(s); 1507 ps->ps_len = sizeof(struct pf_state) * nr; |
1508#if defined(__FreeBSD__) 1509 PF_UNLOCK(); 1510#endif |
|
1167 return (0); 1168 } 1169 1170 s = splsoftnet(); 1171 p = ps->ps_states; 1172 RB_FOREACH(n, pf_state_tree, &tree_ext_gwy) { | 1511 return (0); 1512 } 1513 1514 s = splsoftnet(); 1515 p = ps->ps_states; 1516 RB_FOREACH(n, pf_state_tree, &tree_ext_gwy) { |
1517#if defined(__FreeBSD__) 1518 int secs = time_second; 1519#else |
|
1173 int secs = time.tv_sec; | 1520 int secs = time.tv_sec; |
1521#endif |
|
1174 1175 if ((nr + 1) * sizeof(*p) > (unsigned)ps->ps_len) 1176 break; 1177 1178 bcopy(n->state, &pstore, sizeof(pstore)); 1179 pstore.rule.nr = n->state->rule.ptr->nr; 1180 pstore.nat_rule.nr = (n->state->nat_rule.ptr == NULL) ? 1181 -1 : n->state->nat_rule.ptr->nr; 1182 pstore.anchor.nr = (n->state->anchor.ptr == NULL) ? 1183 -1 : n->state->anchor.ptr->nr; 1184 pstore.creation = secs - pstore.creation; 1185 pstore.expire = pf_state_expires(n->state); 1186 if (pstore.expire > secs) 1187 pstore.expire -= secs; 1188 else 1189 pstore.expire = 0; | 1522 1523 if ((nr + 1) * sizeof(*p) > (unsigned)ps->ps_len) 1524 break; 1525 1526 bcopy(n->state, &pstore, sizeof(pstore)); 1527 pstore.rule.nr = n->state->rule.ptr->nr; 1528 pstore.nat_rule.nr = (n->state->nat_rule.ptr == NULL) ? 1529 -1 : n->state->nat_rule.ptr->nr; 1530 pstore.anchor.nr = (n->state->anchor.ptr == NULL) ? 1531 -1 : n->state->anchor.ptr->nr; 1532 pstore.creation = secs - pstore.creation; 1533 pstore.expire = pf_state_expires(n->state); 1534 if (pstore.expire > secs) 1535 pstore.expire -= secs; 1536 else 1537 pstore.expire = 0; |
1538#if defined(__FreeBSD__) 1539 PF_COPYOUT(&pstore, p, sizeof(*p), error); 1540#else |
|
1190 error = copyout(&pstore, p, sizeof(*p)); | 1541 error = copyout(&pstore, p, sizeof(*p)); |
1542#endif |
|
1191 if (error) { 1192 splx(s); 1193 goto fail; 1194 } 1195 p++; 1196 nr++; 1197 } 1198 ps->ps_len = sizeof(struct pf_state) * nr; --- 32 unchanged lines hidden (view full) --- 1231 u_int32_t debug = pf_status.debug; 1232 1233 bzero(&pf_status, sizeof(struct pf_status)); 1234 pf_status.running = running; 1235 pf_status.states = states; 1236 pf_status.since = since; 1237 pf_status.debug = debug; 1238 if (status_ifp != NULL) | 1543 if (error) { 1544 splx(s); 1545 goto fail; 1546 } 1547 p++; 1548 nr++; 1549 } 1550 ps->ps_len = sizeof(struct pf_state) * nr; --- 32 unchanged lines hidden (view full) --- 1583 u_int32_t debug = pf_status.debug; 1584 1585 bzero(&pf_status, sizeof(struct pf_status)); 1586 pf_status.running = running; 1587 pf_status.states = states; 1588 pf_status.since = since; 1589 pf_status.debug = debug; 1590 if (status_ifp != NULL) |
1591#if defined(__FreeBSD__) && (__FreeBSD_version < 501113) 1592 snprintf(pf_status.ifname, IFNAMSIZ, "%s%d", 1593 status_ifp->if_name, status_ifp->if_unit); 1594#else |
|
1239 strlcpy(pf_status.ifname, 1240 status_ifp->if_xname, IFNAMSIZ); | 1595 strlcpy(pf_status.ifname, 1596 status_ifp->if_xname, IFNAMSIZ); |
1597#endif |
|
1241 break; 1242 } 1243 1244 case DIOCNATLOOK: { 1245 struct pfioc_natlook *pnl = (struct pfioc_natlook *)addr; 1246 struct pf_state *st; 1247 struct pf_tree_node key; 1248 int direction = pnl->direction; --- 85 unchanged lines hidden (view full) --- 1334 case DIOCSETLIMIT: { 1335 struct pfioc_limit *pl = (struct pfioc_limit *)addr; 1336 int old_limit; 1337 1338 if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) { 1339 error = EINVAL; 1340 goto fail; 1341 } | 1598 break; 1599 } 1600 1601 case DIOCNATLOOK: { 1602 struct pfioc_natlook *pnl = (struct pfioc_natlook *)addr; 1603 struct pf_state *st; 1604 struct pf_tree_node key; 1605 int direction = pnl->direction; --- 85 unchanged lines hidden (view full) --- 1691 case DIOCSETLIMIT: { 1692 struct pfioc_limit *pl = (struct pfioc_limit *)addr; 1693 int old_limit; 1694 1695 if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) { 1696 error = EINVAL; 1697 goto fail; 1698 } |
1699#if defined(__FreeBSD__) 1700 uma_zone_set_max(pf_pool_limits[pl->index].pp, pl->limit); 1701#else |
|
1342 if (pool_sethardlimit(pf_pool_limits[pl->index].pp, 1343 pl->limit, NULL, 0) != 0) { 1344 error = EBUSY; 1345 goto fail; 1346 } | 1702 if (pool_sethardlimit(pf_pool_limits[pl->index].pp, 1703 pl->limit, NULL, 0) != 0) { 1704 error = EBUSY; 1705 goto fail; 1706 } |
1707#endif |
|
1347 old_limit = pf_pool_limits[pl->index].limit; 1348 pf_pool_limits[pl->index].limit = pl->limit; 1349 pl->limit = old_limit; 1350 break; 1351 } 1352 1353 case DIOCSETDEBUG: { 1354 u_int32_t *level = (u_int32_t *)addr; --- 10 unchanged lines hidden (view full) --- 1365 TAILQ_FOREACH(rule, 1366 ruleset->rules[PF_RULESET_FILTER].active.ptr, entries) 1367 rule->evaluations = rule->packets = 1368 rule->bytes = 0; 1369 splx(s); 1370 break; 1371 } 1372 | 1708 old_limit = pf_pool_limits[pl->index].limit; 1709 pf_pool_limits[pl->index].limit = pl->limit; 1710 pl->limit = old_limit; 1711 break; 1712 } 1713 1714 case DIOCSETDEBUG: { 1715 u_int32_t *level = (u_int32_t *)addr; --- 10 unchanged lines hidden (view full) --- 1726 TAILQ_FOREACH(rule, 1727 ruleset->rules[PF_RULESET_FILTER].active.ptr, entries) 1728 rule->evaluations = rule->packets = 1729 rule->bytes = 0; 1730 splx(s); 1731 break; 1732 } 1733 |
1734#if defined(__FreeBSD__) 1735 case DIOCGIFSPEED: { 1736 struct pf_ifspeed *psp = (struct pf_ifspeed *)addr; 1737 struct pf_ifspeed ps; 1738 struct ifnet *ifp; 1739 1740 if (psp->ifname[0] != 0) { 1741 /* Can we completely trust user-land? */ 1742 strlcpy(ps.ifname, psp->ifname, IFNAMSIZ); 1743 ifp = ifunit(ps.ifname); 1744 if (ifp ) 1745 psp->baudrate = ifp->if_baudrate; 1746 else 1747 error = EINVAL; 1748 } else 1749 error = EINVAL; 1750 break; 1751 } 1752#endif /* __FreeBSD__ */ 1753 |
|
1373#ifdef ALTQ 1374 case DIOCSTARTALTQ: { 1375 struct pf_altq *altq; 1376 struct ifnet *ifp; 1377 struct tb_profile tb; 1378 1379 /* enable all altq interfaces on active list */ 1380 s = splsoftnet(); --- 10 unchanged lines hidden (view full) --- 1391 /* set tokenbucket regulator */ 1392 tb.rate = altq->ifbandwidth; 1393 tb.depth = altq->tbrsize; 1394 error = tbr_set(&ifp->if_snd, &tb); 1395 if (error != 0) 1396 break; 1397 } 1398 } | 1754#ifdef ALTQ 1755 case DIOCSTARTALTQ: { 1756 struct pf_altq *altq; 1757 struct ifnet *ifp; 1758 struct tb_profile tb; 1759 1760 /* enable all altq interfaces on active list */ 1761 s = splsoftnet(); --- 10 unchanged lines hidden (view full) --- 1772 /* set tokenbucket regulator */ 1773 tb.rate = altq->ifbandwidth; 1774 tb.depth = altq->tbrsize; 1775 error = tbr_set(&ifp->if_snd, &tb); 1776 if (error != 0) 1777 break; 1778 } 1779 } |
1780#if defined(__FreeBSD__) 1781 if (error == 0) { 1782 mtx_lock(&pf_altq_mtx); 1783 pfaltq_running = 1; 1784 mtx_unlock(&pf_altq_mtx); 1785 } 1786#else |
|
1399 if (error == 0) 1400 pfaltq_running = 1; | 1787 if (error == 0) 1788 pfaltq_running = 1; |
1789#endif |
|
1401 splx(s); 1402 DPFPRINTF(PF_DEBUG_MISC, ("altq: started\n")); 1403 break; 1404 } 1405 1406 case DIOCSTOPALTQ: { 1407 struct pf_altq *altq; 1408 struct ifnet *ifp; --- 15 unchanged lines hidden (view full) --- 1424 } 1425 /* clear tokenbucket regulator */ 1426 tb.rate = 0; 1427 err = tbr_set(&ifp->if_snd, &tb); 1428 if (err != 0 && error == 0) 1429 error = err; 1430 } 1431 } | 1790 splx(s); 1791 DPFPRINTF(PF_DEBUG_MISC, ("altq: started\n")); 1792 break; 1793 } 1794 1795 case DIOCSTOPALTQ: { 1796 struct pf_altq *altq; 1797 struct ifnet *ifp; --- 15 unchanged lines hidden (view full) --- 1813 } 1814 /* clear tokenbucket regulator */ 1815 tb.rate = 0; 1816 err = tbr_set(&ifp->if_snd, &tb); 1817 if (err != 0 && error == 0) 1818 error = err; 1819 } 1820 } |
1821#if defined(__FreeBSD__) 1822 if (error == 0) { 1823 mtx_lock(&pf_altq_mtx); 1824 pfaltq_running = 0; 1825 mtx_unlock(&pf_altq_mtx); 1826 } 1827#else |
|
1432 if (error == 0) 1433 pfaltq_running = 0; | 1828 if (error == 0) 1829 pfaltq_running = 0; |
1830#endif |
|
1434 splx(s); 1435 DPFPRINTF(PF_DEBUG_MISC, ("altq: stopped\n")); 1436 break; 1437 } 1438 1439 case DIOCBEGINALTQS: { 1440 u_int32_t *ticket = (u_int32_t *)addr; 1441 struct pf_altq *altq; 1442 1443 /* Purge the old altq list */ 1444 while ((altq = TAILQ_FIRST(pf_altqs_inactive)) != NULL) { 1445 TAILQ_REMOVE(pf_altqs_inactive, altq, entries); 1446 if (altq->qname[0] == 0) { 1447 /* detach and destroy the discipline */ | 1831 splx(s); 1832 DPFPRINTF(PF_DEBUG_MISC, ("altq: stopped\n")); 1833 break; 1834 } 1835 1836 case DIOCBEGINALTQS: { 1837 u_int32_t *ticket = (u_int32_t *)addr; 1838 struct pf_altq *altq; 1839 1840 /* Purge the old altq list */ 1841 while ((altq = TAILQ_FIRST(pf_altqs_inactive)) != NULL) { 1842 TAILQ_REMOVE(pf_altqs_inactive, altq, entries); 1843 if (altq->qname[0] == 0) { 1844 /* detach and destroy the discipline */ |
1845#if defined(__FreeBSD__) 1846 PF_UNLOCK(); 1847#endif |
|
1448 error = altq_remove(altq); | 1848 error = altq_remove(altq); |
1849#if defined(__FreeBSD__) 1850 PF_LOCK(); 1851#endif |
|
1449 } 1450 pool_put(&pf_altq_pl, altq); 1451 } 1452 *ticket = ++ticket_altqs_inactive; 1453 break; 1454 } 1455 1456 case DIOCADDALTQ: { --- 20 unchanged lines hidden (view full) --- 1477 if (strncmp(a->ifname, altq->ifname, 1478 IFNAMSIZ) == 0 && a->qname[0] == 0) { 1479 altq->altq_disc = a->altq_disc; 1480 break; 1481 } 1482 } 1483 } 1484 | 1852 } 1853 pool_put(&pf_altq_pl, altq); 1854 } 1855 *ticket = ++ticket_altqs_inactive; 1856 break; 1857 } 1858 1859 case DIOCADDALTQ: { --- 20 unchanged lines hidden (view full) --- 1880 if (strncmp(a->ifname, altq->ifname, 1881 IFNAMSIZ) == 0 && a->qname[0] == 0) { 1882 altq->altq_disc = a->altq_disc; 1883 break; 1884 } 1885 } 1886 } 1887 |
1888#if defined(__FreeBSD__) 1889 PF_UNLOCK(); 1890#endif |
|
1485 error = altq_add(altq); | 1891 error = altq_add(altq); |
1892#if defined(__FreeBSD__) 1893 PF_LOCK(); 1894#endif |
|
1486 if (error) { 1487 pool_put(&pf_altq_pl, altq); 1488 break; 1489 } 1490 1491 TAILQ_INSERT_TAIL(pf_altqs_inactive, altq, entries); 1492 bcopy(altq, &pa->altq, sizeof(struct pf_altq)); 1493 break; --- 18 unchanged lines hidden (view full) --- 1512 pf_altqs_active = pf_altqs_inactive; 1513 pf_altqs_inactive = old_altqs; 1514 ticket_altqs_active = ticket_altqs_inactive; 1515 1516 /* Attach new disciplines */ 1517 TAILQ_FOREACH(altq, pf_altqs_active, entries) { 1518 if (altq->qname[0] == 0) { 1519 /* attach the discipline */ | 1895 if (error) { 1896 pool_put(&pf_altq_pl, altq); 1897 break; 1898 } 1899 1900 TAILQ_INSERT_TAIL(pf_altqs_inactive, altq, entries); 1901 bcopy(altq, &pa->altq, sizeof(struct pf_altq)); 1902 break; --- 18 unchanged lines hidden (view full) --- 1921 pf_altqs_active = pf_altqs_inactive; 1922 pf_altqs_inactive = old_altqs; 1923 ticket_altqs_active = ticket_altqs_inactive; 1924 1925 /* Attach new disciplines */ 1926 TAILQ_FOREACH(altq, pf_altqs_active, entries) { 1927 if (altq->qname[0] == 0) { 1928 /* attach the discipline */ |
1929#if defined(__FreeBSD__) 1930 PF_UNLOCK(); 1931#endif |
|
1520 error = altq_pfattach(altq); | 1932 error = altq_pfattach(altq); |
1933#if defined(__FreeBSD__) 1934 PF_LOCK(); 1935#endif |
|
1521 if (error) { 1522 splx(s); 1523 goto fail; 1524 } 1525 } 1526 } 1527 1528 /* Purge the old altq list */ 1529 while ((altq = TAILQ_FIRST(pf_altqs_inactive)) != NULL) { 1530 TAILQ_REMOVE(pf_altqs_inactive, altq, entries); 1531 if (altq->qname[0] == 0) { 1532 /* detach and destroy the discipline */ | 1936 if (error) { 1937 splx(s); 1938 goto fail; 1939 } 1940 } 1941 } 1942 1943 /* Purge the old altq list */ 1944 while ((altq = TAILQ_FIRST(pf_altqs_inactive)) != NULL) { 1945 TAILQ_REMOVE(pf_altqs_inactive, altq, entries); 1946 if (altq->qname[0] == 0) { 1947 /* detach and destroy the discipline */ |
1948#if defined(__FreeBSD__) 1949 PF_UNLOCK(); 1950#endif |
|
1533 err = altq_pfdetach(altq); 1534 if (err != 0 && error == 0) 1535 error = err; 1536 err = altq_remove(altq); 1537 if (err != 0 && error == 0) 1538 error = err; | 1951 err = altq_pfdetach(altq); 1952 if (err != 0 && error == 0) 1953 error = err; 1954 err = altq_remove(altq); 1955 if (err != 0 && error == 0) 1956 error = err; |
1957#if defined(__FreeBSD__) 1958 PF_LOCK(); 1959#endif |
|
1539 } 1540 pool_put(&pf_altq_pl, altq); 1541 } 1542 splx(s); 1543 1544 /* update queue IDs */ 1545 pf_rule_set_qid( 1546 pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); --- 69 unchanged lines hidden (view full) --- 1616 altq = TAILQ_NEXT(altq, entries); 1617 nr++; 1618 } 1619 if (altq == NULL) { 1620 error = EBUSY; 1621 splx(s); 1622 break; 1623 } | 1960 } 1961 pool_put(&pf_altq_pl, altq); 1962 } 1963 splx(s); 1964 1965 /* update queue IDs */ 1966 pf_rule_set_qid( 1967 pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); --- 69 unchanged lines hidden (view full) --- 2037 altq = TAILQ_NEXT(altq, entries); 2038 nr++; 2039 } 2040 if (altq == NULL) { 2041 error = EBUSY; 2042 splx(s); 2043 break; 2044 } |
2045#if defined(__FreeBSD__) 2046 PF_UNLOCK(); 2047#endif |
|
1624 error = altq_getqstats(altq, pq->buf, &nbytes); | 2048 error = altq_getqstats(altq, pq->buf, &nbytes); |
2049#if defined(__FreeBSD__) 2050 PF_LOCK(); 2051#endif |
|
1625 splx(s); 1626 if (error == 0) { 1627 pq->scheduler = altq->scheduler; 1628 pq->nbytes = nbytes; 1629 } 1630 break; 1631 } 1632#endif /* ALTQ */ --- 515 unchanged lines hidden (view full) --- 2148 break; 2149 } 2150 2151 default: 2152 error = ENODEV; 2153 break; 2154 } 2155fail: | 2052 splx(s); 2053 if (error == 0) { 2054 pq->scheduler = altq->scheduler; 2055 pq->nbytes = nbytes; 2056 } 2057 break; 2058 } 2059#endif /* ALTQ */ --- 515 unchanged lines hidden (view full) --- 2575 break; 2576 } 2577 2578 default: 2579 error = ENODEV; 2580 break; 2581 } 2582fail: |
2583#if defined(__FreeBSD__) 2584 PF_UNLOCK(); 2585#endif 2586 return (error); 2587} |
|
2156 | 2588 |
2589#if defined(__FreeBSD__) 2590/* 2591 * XXX - Check for version missmatch!!! 2592 */ 2593static int 2594pf_beginrules(void *addr) 2595{ 2596 struct pfioc_rule *pr = (struct pfioc_rule *)addr; 2597 struct pf_ruleset *ruleset; 2598 struct pf_rule *rule; 2599 int rs_num; 2600 int error = 0; 2601 2602 do { 2603 ruleset = pf_find_or_create_ruleset(pr->anchor, pr->ruleset); 2604 if (ruleset == NULL) { 2605 error = EINVAL; 2606 break; 2607 } 2608 rs_num = pf_get_ruleset_number(pr->rule.action); 2609 if (rs_num >= PF_RULESET_MAX) { 2610 error = EINVAL; 2611 break; 2612 } 2613 while ((rule = 2614 TAILQ_FIRST(ruleset->rules[rs_num].inactive.ptr)) != NULL) 2615 pf_rm_rule(ruleset->rules[rs_num].inactive.ptr, rule); 2616 pr->ticket = ++ruleset->rules[rs_num].inactive.ticket; 2617 } while(0); 2618 |
|
2157 return (error); 2158} | 2619 return (error); 2620} |
2621 2622static int 2623pf_commitrules(void *addr) 2624{ 2625 struct pfioc_rule *pr = (struct pfioc_rule *)addr; 2626 struct pf_ruleset *ruleset; 2627 struct pf_rulequeue *old_rules; 2628 struct pf_rule *rule; 2629 int rs_num, s; 2630 int error = 0; 2631 2632 do { 2633 ruleset = pf_find_ruleset(pr->anchor, pr->ruleset); 2634 if (ruleset == NULL) { 2635 error = EINVAL; 2636 break; 2637 } 2638 rs_num = pf_get_ruleset_number(pr->rule.action); 2639 if (rs_num >= PF_RULESET_MAX) { 2640 error = EINVAL; 2641 break; 2642 } 2643 if (pr->ticket != ruleset->rules[rs_num].inactive.ticket) { 2644 error = EBUSY; 2645 break; 2646 } 2647 2648#ifdef ALTQ 2649 /* set queue IDs */ 2650 if (rs_num == PF_RULESET_FILTER) 2651 pf_rule_set_qid(ruleset->rules[rs_num].inactive.ptr); 2652#endif 2653 2654 /* Swap rules, keep the old. */ 2655 s = splsoftnet(); 2656 old_rules = ruleset->rules[rs_num].active.ptr; 2657 ruleset->rules[rs_num].active.ptr = 2658 ruleset->rules[rs_num].inactive.ptr; 2659 ruleset->rules[rs_num].inactive.ptr = old_rules; 2660 ruleset->rules[rs_num].active.ticket = 2661 ruleset->rules[rs_num].inactive.ticket; 2662 pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr); 2663 2664 /* Purge the old rule list. */ 2665 while ((rule = TAILQ_FIRST(old_rules)) != NULL) 2666 pf_rm_rule(old_rules, rule); 2667 pf_remove_if_empty_ruleset(ruleset); 2668 pf_update_anchor_rules(); 2669 splx(s); 2670 } while (0); 2671 2672 return (error); 2673} 2674 2675#if defined(ALTQ) 2676static int 2677pf_beginaltqs(void *addr) 2678{ 2679 u_int32_t *ticket = (u_int32_t *)addr; 2680 struct pf_altq *altq; 2681 int error = 0; 2682 2683 /* Purge the old altq list */ 2684 while ((altq = TAILQ_FIRST(pf_altqs_inactive)) != NULL) { 2685 TAILQ_REMOVE(pf_altqs_inactive, altq, entries); 2686 if (altq->qname[0] == 0) { 2687#if defined(__FreeBSD__) 2688 PF_UNLOCK(); 2689#endif 2690 /* detach and destroy the discipline */ 2691 error = altq_remove(altq); 2692#if defined(__FreeBSD__) 2693 PF_LOCK(); 2694#endif 2695 } 2696 uma_zfree(pf_altq_pl, altq); 2697 } 2698 *ticket = ++ticket_altqs_inactive; 2699 2700 return (error); 2701} 2702 2703static int 2704pf_commitaltqs(void *addr) 2705{ 2706 u_int32_t *ticket = (u_int32_t *)addr; 2707 struct pf_altqqueue *old_altqs; 2708 struct pf_altq *altq; 2709 struct pf_anchor *anchor; 2710 struct pf_ruleset *ruleset; 2711 int err; 2712 int s; 2713 int error = 0; 2714 2715 do { 2716 if (*ticket != ticket_altqs_inactive) { 2717 error = EBUSY; 2718 break; 2719 } 2720 2721 /* Swap altqs, keep the old. */ 2722 s = splsoftnet(); 2723 old_altqs = pf_altqs_active; 2724 pf_altqs_active = pf_altqs_inactive; 2725 pf_altqs_inactive = old_altqs; 2726 ticket_altqs_active = ticket_altqs_inactive; 2727 2728 /* Attach new disciplines */ 2729 TAILQ_FOREACH(altq, pf_altqs_active, entries) { 2730 if (altq->qname[0] == 0) { 2731 /* attach the discipline */ 2732#if defined(__FreeBSD__) 2733 PF_UNLOCK(); 2734#endif 2735 error = altq_pfattach(altq); 2736#if defined(__FreeBSD__) 2737 PF_LOCK(); 2738#endif 2739 if (error) { 2740 splx(s); 2741 goto altq_fail; 2742 } 2743 } 2744 } 2745 2746 /* Purge the old altq list */ 2747 while ((altq = TAILQ_FIRST(pf_altqs_inactive)) != NULL) { 2748 TAILQ_REMOVE(pf_altqs_inactive, altq, entries); 2749 if (altq->qname[0] == 0) { 2750 /* detach and destroy the discipline */ 2751#if defined(__FreeBSD__) 2752 PF_UNLOCK(); 2753#endif 2754 err = altq_pfdetach(altq); 2755 if (err != 0 && error == 0) 2756 error = err; 2757 err = altq_remove(altq); 2758 if (err != 0 && error == 0) 2759 error = err; 2760#if defined(__FreeBSD__) 2761 PF_LOCK(); 2762#endif 2763 } 2764 uma_zfree(pf_altq_pl, altq); 2765 } 2766 splx(s); 2767 2768 /* update queue IDs */ 2769 pf_rule_set_qid( 2770 pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 2771 TAILQ_FOREACH(anchor, &pf_anchors, entries) { 2772 TAILQ_FOREACH(ruleset, &anchor->rulesets, entries) { 2773 pf_rule_set_qid( 2774 ruleset->rules[PF_RULESET_FILTER].active.ptr 2775 ); 2776 } 2777 } 2778 } while (0); 2779 2780altq_fail: 2781 2782 return (error); 2783} 2784 2785static int 2786pf_stopaltq(void) 2787{ 2788 struct pf_altq *altq; 2789 struct ifnet *ifp; 2790 struct tb_profile tb; 2791 int err; 2792 int s; 2793 int error = 0; 2794 2795 do { 2796 /* disable all altq interfaces on active list */ 2797 s = splsoftnet(); 2798 TAILQ_FOREACH(altq, pf_altqs_active, entries) { 2799 if (altq->qname[0] == 0) { 2800 if ((ifp = ifunit(altq->ifname)) == NULL) { 2801 error = EINVAL; 2802 break; 2803 } 2804 if (ifp->if_snd.altq_type != ALTQT_NONE) { 2805 err = altq_disable(&ifp->if_snd); 2806 if (err != 0 && error == 0) 2807 error = err; 2808 } 2809 /* clear tokenbucket regulator */ 2810 tb.rate = 0; 2811 err = tbr_set(&ifp->if_snd, &tb); 2812 if (err != 0 && error == 0) 2813 error = err; 2814 } 2815 } 2816#if defined(__FreeBSD__) 2817 if (error == 0) { 2818 mtx_lock(&pf_altq_mtx); 2819 pfaltq_running = 0; 2820 mtx_unlock(&pf_altq_mtx); 2821 } 2822#else 2823 if (error == 0) 2824 pfaltq_running = 0; 2825#endif 2826 splx(s); 2827 } while (0); 2828 2829 return (error); 2830} 2831#endif 2832 2833static void 2834pf_clearstates(void) 2835{ 2836 struct pf_tree_node *n; 2837 int s; 2838 2839 s = splsoftnet(); 2840 RB_FOREACH(n, pf_state_tree, &tree_ext_gwy) 2841 n->state->timeout = PFTM_PURGE; 2842 pf_purge_expired_states(); 2843 pf_status.states = 0; 2844 splx(s); 2845} 2846 2847static int 2848pf_clear_tables(void *addr) 2849{ 2850 struct pfioc_table *io = (struct pfioc_table *)addr; 2851 int error; 2852 2853 error = pfr_clr_tables(&io->pfrio_table, &io->pfrio_ndel, 2854 io->pfrio_flags); 2855 2856 return (error); 2857} 2858 2859static int 2860shutdown_pf(void) 2861{ 2862 struct pfioc_rule pr; 2863#if defined(ALTQ) 2864 struct pfioc_altq pa; 2865#endif 2866 struct pfioc_table io; 2867 int error = 0; 2868 2869 callout_stop(&pf_expire_to); 2870 2871 PF_LOCK(); 2872 pf_status.running = 0; 2873 do { 2874#if defined(ALTQ) 2875 if ((error = pf_stopaltq())) { 2876 DPFPRINTF(PF_DEBUG_MISC, 2877 ("ALTQ: stop(%i)\n", error)); 2878 break; 2879 } 2880#endif 2881 bzero(&pr, sizeof(pr)); 2882 pr.rule.action = PF_SCRUB; 2883 if ((error = pf_beginrules(&pr))) { 2884 DPFPRINTF(PF_DEBUG_MISC, 2885 ("PF_SCRUB: begin(%i)\n", error)); 2886 break; 2887 } 2888 if ((error = pf_commitrules(&pr))) { 2889 DPFPRINTF(PF_DEBUG_MISC, 2890 ("PF_SCRUB: commit(%i)\n", error)); 2891 break; 2892 } 2893 2894 pr.rule.action = PF_PASS; 2895 if ((error = pf_beginrules(&pr))) { 2896 DPFPRINTF(PF_DEBUG_MISC, 2897 ("PF_PASS: begin(%i)\n", error)); 2898 break; 2899 } 2900 if ((error = pf_commitrules(&pr))) { 2901 DPFPRINTF(PF_DEBUG_MISC, 2902 ("PF_PASS: commit(%i)\n", error)); 2903 break; 2904 } 2905 2906/* 2907 * XXX not sure, but can't hurt: 2908 */ 2909 bzero(&pr, sizeof(pr)); 2910 pr.rule.action = PF_NAT; 2911 if ((error = pf_beginrules(&pr))) { 2912 DPFPRINTF(PF_DEBUG_MISC, 2913 ("PF_NAT: begin(%i)\n", error)); 2914 break; 2915 } 2916 if ((error = pf_commitrules(&pr))) { 2917 DPFPRINTF(PF_DEBUG_MISC, 2918 ("PF_NAT: commit(%i)\n", error)); 2919 break; 2920 } 2921 2922 pr.rule.action = PF_BINAT; 2923 if ((error = pf_beginrules(&pr))) { 2924 DPFPRINTF(PF_DEBUG_MISC, 2925 ("PF_BINAT: begin(%i)\n", error)); 2926 break; 2927 } 2928 if ((error = pf_commitrules(&pr))) { 2929 DPFPRINTF(PF_DEBUG_MISC, 2930 ("PF_BINAT: begin(%i)\n", error)); 2931 break; 2932 } 2933 2934 pr.rule.action = PF_RDR; 2935 if ((error = pf_beginrules(&pr))) { 2936 DPFPRINTF(PF_DEBUG_MISC, 2937 ("PF_RDR: begin(%i)\n", error)); 2938 break; 2939 } 2940 if ((error = pf_commitrules(&pr))) { 2941 DPFPRINTF(PF_DEBUG_MISC, 2942 ("PF_RDR: commit(%i)\n", error)); 2943 break; 2944 } 2945 2946#if defined(ALTQ) 2947 bzero(&pa, sizeof(pa)); 2948 if ((error = pf_beginaltqs(&pa))) { 2949 DPFPRINTF(PF_DEBUG_MISC, 2950 ("ALTQ: begin(%i)\n", error)); 2951 break; 2952 } 2953 if ((error = pf_commitaltqs(&pa))) { 2954 DPFPRINTF(PF_DEBUG_MISC, 2955 ("ALTQ: commit(%i)\n", error)); 2956 break; 2957 } 2958#endif 2959 pf_clearstates(); 2960 2961 bzero(&io, sizeof(io)); 2962 if ((error = pf_clear_tables(&io))) { 2963 DPFPRINTF(PF_DEBUG_MISC, 2964 ("TABLES: clear(%i)\n", error)); 2965 break; 2966 } 2967 pf_osfp_flush(); 2968 } while(0); 2969 2970 PF_UNLOCK(); 2971 return (error); 2972} 2973 2974static int 2975#if (__FreeBSD_version < 501108) 2976pf_check_in(void *ip, int hlen, struct ifnet *ifp, int dir, struct mbuf **m) 2977#else 2978pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir) 2979#endif 2980{ 2981 /* 2982 * XXX Wed Jul 9 22:03:16 2003 UTC 2983 * OpenBSD has changed its byte ordering convention on ip_len/ip_off 2984 * in network stack. OpenBSD's network stack have converted 2985 * ip_len/ip_off to host byte order frist as FreeBSD. 2986 * Now this is not true anymore , so we should convert back to network 2987 * byte order. 2988 */ 2989 struct ip *h = NULL; 2990 int chk; 2991 2992 if ((*m)->m_pkthdr.len >= (int)sizeof(struct ip)) { 2993 /* if m_pkthdr.len is less than ip header, pf will handle. */ 2994 h = mtod(*m, struct ip *); 2995 HTONS(h->ip_len); 2996 HTONS(h->ip_off); 2997 } 2998 chk = pf_test(PF_IN, ifp, m); 2999 if (chk && *m) { 3000 m_freem(*m); 3001 *m = NULL; 3002 } 3003 if (*m != NULL) { 3004 /* pf_test can change ip header location */ 3005 h = mtod(*m, struct ip *); 3006 NTOHS(h->ip_len); 3007 NTOHS(h->ip_off); 3008 } 3009 return chk; 3010} 3011 3012static int 3013#if (__FreeBSD_version < 501108) 3014pf_check_out(void *ip, int hlen, struct ifnet *ifp, int dir, struct mbuf **m) 3015#else 3016pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir) 3017#endif 3018{ 3019 /* 3020 * XXX Wed Jul 9 22:03:16 2003 UTC 3021 * OpenBSD has changed its byte ordering convention on ip_len/ip_off 3022 * in network stack. OpenBSD's network stack have converted 3023 * ip_len/ip_off to host byte order frist as FreeBSD. 3024 * Now this is not true anymore , so we should convert back to network 3025 * byte order. 3026 */ 3027 struct ip *h = NULL; 3028 int chk; 3029 3030 /* We need a proper CSUM befor we start (s. OpenBSD ip_output) */ 3031 if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { 3032 in_delayed_cksum(*m); 3033 (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; 3034 } 3035 if ((*m)->m_pkthdr.len >= (int)sizeof(*h)) { 3036 /* if m_pkthdr.len is less than ip header, pf will handle. */ 3037 h = mtod(*m, struct ip *); 3038 HTONS(h->ip_len); 3039 HTONS(h->ip_off); 3040 } 3041 chk = pf_test(PF_OUT, ifp, m); 3042 if (chk && *m) { 3043 m_freem(*m); 3044 *m = NULL; 3045 } 3046 if (*m != NULL) { 3047 /* pf_test can change ip header location */ 3048 h = mtod(*m, struct ip *); 3049 NTOHS(h->ip_len); 3050 NTOHS(h->ip_off); 3051 } 3052 return chk; 3053} 3054 3055#ifdef INET6 3056static int 3057#if (__FreeBSD_version < 501108) 3058pf_check6_in(void *ip, int hlen, struct ifnet *ifp, int dir, struct mbuf **m) 3059#else 3060pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir) 3061#endif 3062{ 3063 /* 3064 * IPv6 does not affected ip_len/ip_off byte order changes. 3065 */ 3066 int chk; 3067 3068 chk = pf_test6(PF_IN, ifp, m); 3069 if (chk && *m) { 3070 m_freem(*m); 3071 *m = NULL; 3072 } 3073 return chk; 3074} 3075 3076static int 3077#if (__FreeBSD_version < 501108) 3078pf_check6_out(void *ip, int hlen, struct ifnet *ifp, int dir, struct mbuf **m) 3079#else 3080pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir) 3081#endif 3082{ 3083 /* 3084 * IPv6 does not affected ip_len/ip_off byte order changes. 3085 */ 3086 int chk; 3087 3088 /* We need a proper CSUM befor we start (s. OpenBSD ip_output) */ 3089 if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { 3090 in_delayed_cksum(*m); 3091 (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; 3092 } 3093 chk = pf_test6(PF_OUT, ifp, m); 3094 if (chk && *m) { 3095 m_freem(*m); 3096 *m = NULL; 3097 } 3098 return chk; 3099} 3100#endif /* INET6 */ 3101 3102static int 3103hook_pf(void) 3104{ 3105#if (__FreeBSD_version >= 501108) 3106 struct pfil_head *pfh_inet; 3107#if defined(INET6) 3108 struct pfil_head *pfh_inet6; 3109#endif 3110#endif 3111 3112 PF_ASSERT(MA_NOTOWNED); 3113 3114 if (pf_pfil_hooked) 3115 return (0); 3116 3117#if (__FreeBSD_version < 501108) 3118 /* 3119 * XXX 3120 * There is no easy way to get pfil header pointer with address 3121 * family such as AF_INET, AF_INET6. 3122 * Needs direct variable reference. 3123 */ 3124 3125 pfil_add_hook(pf_check_in, PFIL_IN, 3126 &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); 3127 pfil_add_hook(pf_check_out, PFIL_OUT, 3128 &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); 3129#if defined(INET6) 3130 pfil_add_hook(pf_check6_in, PFIL_IN, 3131 &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh); 3132 pfil_add_hook(pf_check6_out, PFIL_OUT, 3133 &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh); 3134#endif 3135#else /* __FreeBSD_version >= 501108 */ 3136 pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET); 3137 if (pfh_inet == NULL) 3138 return (ESRCH); /* XXX */ 3139 pfil_add_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet); 3140 pfil_add_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet); 3141#if defined(INET6) 3142 pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6); 3143 if (pfh_inet6 == NULL) { 3144 pfil_remove_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK, 3145 pfh_inet); 3146 pfil_remove_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK, 3147 pfh_inet); 3148 return (ESRCH); /* XXX */ 3149 } 3150 pfil_add_hook(pf_check6_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet6); 3151 pfil_add_hook(pf_check6_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet6); 3152#endif 3153#endif /* __FreeBSD_version >= 501108 */ 3154 3155 pf_pfil_hooked = 1; 3156 return (0); 3157} 3158 3159static int 3160dehook_pf(void) 3161{ 3162#if (__FreeBSD_version >= 501108) 3163 struct pfil_head *pfh_inet; 3164#if defined(INET6) 3165 struct pfil_head *pfh_inet6; 3166#endif 3167#endif 3168 3169 PF_ASSERT(MA_NOTOWNED); 3170 3171 if (pf_pfil_hooked == 0) 3172 return (0); 3173 3174#if (__FreeBSD_version < 501108) 3175 pfil_remove_hook(pf_check_in, PFIL_IN, 3176 &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); 3177 pfil_remove_hook(pf_check_out, PFIL_OUT, 3178 &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); 3179#if defined(INET6) 3180 pfil_remove_hook(pf_check6_in, PFIL_IN, 3181 &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh); 3182 pfil_remove_hook(pf_check6_out, PFIL_OUT, 3183 &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh); 3184#endif 3185#else /* __FreeBSD_version >= 501108 */ 3186 pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET); 3187 if (pfh_inet == NULL) 3188 return (ESRCH); /* XXX */ 3189 pfil_remove_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK, 3190 pfh_inet); 3191 pfil_remove_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK, 3192 pfh_inet); 3193#if defined(INET6) 3194 pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6); 3195 if (pfh_inet6 == NULL) 3196 return (ESRCH); /* XXX */ 3197 pfil_remove_hook(pf_check6_in, NULL, PFIL_IN | PFIL_WAITOK, 3198 pfh_inet6); 3199 pfil_remove_hook(pf_check6_out, NULL, PFIL_OUT | PFIL_WAITOK, 3200 pfh_inet6); 3201#endif 3202#endif /* __FreeBSD_version >= 501108 */ 3203 3204 pf_pfil_hooked = 0; 3205 return (0); 3206} 3207 3208static int 3209pf_load(void) 3210{ 3211 init_zone_var(); 3212 init_pf_mutex(); 3213 pf_dev = make_dev(&pf_cdevsw, 0, 0, 0, 0600, PF_NAME); 3214 if (pfattach() < 0) { 3215 destroy_dev(pf_dev); 3216 destroy_pf_mutex(); 3217 return (ENOMEM); 3218 } 3219#if defined(ALTQ) 3220 mtx_lock(&pf_altq_mtx); 3221 ++pfaltq_ref; 3222 mtx_unlock(&pf_altq_mtx); 3223#endif 3224 printf("pf: $Name: $\n"); 3225 return (0); 3226} 3227 3228static int 3229pf_unload(void) 3230{ 3231 int error = 0; 3232 3233 PF_LOCK(); 3234 pf_status.running = 0; 3235 PF_UNLOCK(); 3236 error = dehook_pf(); 3237 if (error) { 3238 /* 3239 * Should not happen! 3240 * XXX Due to error code ESRCH, kldunload will show 3241 * a message like 'No such process'. 3242 */ 3243 printf("%s : pfil unregisteration fail\n", __FUNCTION__); 3244 return error; 3245 } 3246 shutdown_pf(); 3247 cleanup_pf_zone(); 3248 pf_osfp_cleanup(); 3249 destroy_dev(pf_dev); 3250#if defined(ALTQ) 3251 mtx_lock(&pf_altq_mtx); 3252 --pfaltq_ref; 3253 mtx_unlock(&pf_altq_mtx); 3254#endif 3255 destroy_pf_mutex(); 3256 return error; 3257} 3258 3259static int 3260pf_modevent(module_t mod, int type, void *data) 3261{ 3262 int error = 0; 3263 3264 switch(type) { 3265 case MOD_LOAD: 3266 error = pf_load(); 3267 break; 3268 3269 case MOD_UNLOAD: 3270 error = pf_unload(); 3271 break; 3272 default: 3273 error = EINVAL; 3274 break; 3275 } 3276 return error; 3277} 3278 3279static moduledata_t pf_mod = { 3280 "pf", 3281 pf_modevent, 3282 0 3283}; 3284 3285DECLARE_MODULE(pf, pf_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 3286MODULE_DEPEND(pf, pflog, PFLOG_MINVER, PFLOG_PREFVER, PFLOG_MAXVER); 3287MODULE_DEPEND(pf, pfsync, PFSYNC_MINVER, PFSYNC_PREFVER, PFSYNC_MAXVER); 3288#if defined(ALTQ) 3289MODULE_DEPEND(pf, pfaltq, PFALTQ_MINVER, PFALTQ_PREFVER, PFALTQ_MAXVER); 3290#endif 3291MODULE_VERSION(pf, PF_MODVER); 3292#endif /* __FreeBSD__ */ |
|