pf_if.c (130611) | pf_if.c (130613) |
---|---|
1/* $FreeBSD: head/sys/contrib/pf/net/pf_if.c 130613 2004-06-16 23:24:02Z mlaier $ */ |
|
1/* $OpenBSD: pf_if.c,v 1.11 2004/03/15 11:38:23 cedric Exp $ */ 2 3/* 4 * Copyright (c) 2001 Daniel Hartmeier 5 * Copyright (c) 2003 Cedric Berger 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 16 unchanged lines hidden (view full) --- 25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 | 2/* $OpenBSD: pf_if.c,v 1.11 2004/03/15 11:38:23 cedric Exp $ */ 3 4/* 5 * Copyright (c) 2001 Daniel Hartmeier 6 * Copyright (c) 2003 Cedric Berger 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without --- 16 unchanged lines hidden (view full) --- 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 |
34#if defined(__FreeBSD__) 35#include "opt_inet.h" 36#include "opt_inet6.h" 37#endif 38 |
|
33#include <sys/param.h> 34#include <sys/systm.h> | 39#include <sys/param.h> 40#include <sys/systm.h> |
41#ifdef __FreeBSD__ 42#include <sys/malloc.h> 43#endif |
|
35#include <sys/mbuf.h> 36#include <sys/filio.h> 37#include <sys/socket.h> 38#include <sys/socketvar.h> 39#include <sys/kernel.h> | 44#include <sys/mbuf.h> 45#include <sys/filio.h> 46#include <sys/socket.h> 47#include <sys/socketvar.h> 48#include <sys/kernel.h> |
49#ifndef __FreeBSD__ |
|
40#include <sys/device.h> | 50#include <sys/device.h> |
51#endif |
|
41#include <sys/time.h> 42 43#include <net/if.h> 44#include <net/if_types.h> 45 46#include <netinet/in.h> 47#include <netinet/in_var.h> 48#include <netinet/in_systm.h> --- 11 unchanged lines hidden (view full) --- 60 if ((flags & ~(oklist)) & \ 61 PFI_FLAG_ALLMASK) \ 62 return (EINVAL); \ 63 } while (0) 64 65#define senderr(e) do { rv = (e); goto _bad; } while (0) 66 67struct pfi_kif **pfi_index2kif; | 52#include <sys/time.h> 53 54#include <net/if.h> 55#include <net/if_types.h> 56 57#include <netinet/in.h> 58#include <netinet/in_var.h> 59#include <netinet/in_systm.h> --- 11 unchanged lines hidden (view full) --- 71 if ((flags & ~(oklist)) & \ 72 PFI_FLAG_ALLMASK) \ 73 return (EINVAL); \ 74 } while (0) 75 76#define senderr(e) do { rv = (e); goto _bad; } while (0) 77 78struct pfi_kif **pfi_index2kif; |
68struct pfi_kif *pfi_self; | 79struct pfi_kif *pfi_self, *pfi_dummy; |
69int pfi_indexlim; 70struct pfi_ifhead pfi_ifs; 71struct pfi_statehead pfi_statehead; 72int pfi_ifcnt; | 80int pfi_indexlim; 81struct pfi_ifhead pfi_ifs; 82struct pfi_statehead pfi_statehead; 83int pfi_ifcnt; |
84#ifdef __FreeBSD__ 85uma_zone_t pfi_addr_pl; 86#else |
|
73struct pool pfi_addr_pl; | 87struct pool pfi_addr_pl; |
88#endif |
|
74long pfi_update = 1; 75struct pfr_addr *pfi_buffer; 76int pfi_buffer_cnt; 77int pfi_buffer_max; 78char pfi_reserved_anchor[PF_ANCHOR_NAME_SIZE] = 79 PF_RESERVED_ANCHOR; 80char pfi_interface_ruleset[PF_RULESET_NAME_SIZE] = 81 PF_INTERFACE_RULESET; | 89long pfi_update = 1; 90struct pfr_addr *pfi_buffer; 91int pfi_buffer_cnt; 92int pfi_buffer_max; 93char pfi_reserved_anchor[PF_ANCHOR_NAME_SIZE] = 94 PF_RESERVED_ANCHOR; 95char pfi_interface_ruleset[PF_RULESET_NAME_SIZE] = 96 PF_INTERFACE_RULESET; |
97#ifdef __FreeBSD__ 98eventhandler_tag pfi_clone_cookie = NULL; 99eventhandler_tag pfi_attach_cookie = NULL; 100eventhandler_tag pfi_detach_cookie = NULL; 101#endif |
|
82 83void pfi_dynaddr_update(void *); 84void pfi_kifaddr_update(void *); 85void pfi_table_update(struct pfr_ktable *, struct pfi_kif *, 86 int, int); 87void pfi_instance_add(struct ifnet *, int, int); 88void pfi_address_add(struct sockaddr *, int, int); 89int pfi_if_compare(struct pfi_kif *, struct pfi_kif *); 90struct pfi_kif *pfi_if_create(const char *, struct pfi_kif *, int); 91void pfi_copy_group(char *, const char *, int); 92void pfi_dynamic_drivers(void); 93void pfi_newgroup(const char *, int); 94int pfi_skip_if(const char *, struct pfi_kif *, int); 95int pfi_unmask(void *); 96void pfi_dohooks(struct pfi_kif *); | 102 103void pfi_dynaddr_update(void *); 104void pfi_kifaddr_update(void *); 105void pfi_table_update(struct pfr_ktable *, struct pfi_kif *, 106 int, int); 107void pfi_instance_add(struct ifnet *, int, int); 108void pfi_address_add(struct sockaddr *, int, int); 109int pfi_if_compare(struct pfi_kif *, struct pfi_kif *); 110struct pfi_kif *pfi_if_create(const char *, struct pfi_kif *, int); 111void pfi_copy_group(char *, const char *, int); 112void pfi_dynamic_drivers(void); 113void pfi_newgroup(const char *, int); 114int pfi_skip_if(const char *, struct pfi_kif *, int); 115int pfi_unmask(void *); 116void pfi_dohooks(struct pfi_kif *); |
117#ifdef __FreeBSD__ 118void pfi_kifaddr_update_event(void *, struct ifnet *); 119void pfi_attach_clone_event(void * __unused, struct if_clone *); 120void pfi_attach_ifnet_event(void * __unused, struct ifnet *); 121void pfi_detach_ifnet_event(void * __unused, struct ifnet *); 122#endif |
|
97 98RB_PROTOTYPE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare); 99RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare); 100 101#define PFI_DYNAMIC_BUSES { "pcmcia", "cardbus", "uhub" } 102#define PFI_BUFFER_MAX 0x10000 | 123 124RB_PROTOTYPE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare); 125RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare); 126 127#define PFI_DYNAMIC_BUSES { "pcmcia", "cardbus", "uhub" } 128#define PFI_BUFFER_MAX 0x10000 |
129#ifdef __FreeBSD__ 130MALLOC_DEFINE(PFI_MTYPE, "pf_if", "pf interface table"); 131#else |
|
103#define PFI_MTYPE M_IFADDR | 132#define PFI_MTYPE M_IFADDR |
133#endif |
|
104 105void 106pfi_initialize(void) 107{ | 134 135void 136pfi_initialize(void) 137{ |
138#ifdef __FreeBSD__ 139 struct ifnet *ifp; 140#endif 141 |
|
108 if (pfi_self != NULL) /* already initialized */ 109 return; 110 111 TAILQ_INIT(&pfi_statehead); | 142 if (pfi_self != NULL) /* already initialized */ 143 return; 144 145 TAILQ_INIT(&pfi_statehead); |
146#ifndef __FreeBSD__ |
|
112 pool_init(&pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, 0, 0, 113 "pfiaddrpl", &pool_allocator_nointr); | 147 pool_init(&pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, 0, 0, 148 "pfiaddrpl", &pool_allocator_nointr); |
149#endif |
|
114 pfi_buffer_max = 64; 115 pfi_buffer = malloc(pfi_buffer_max * sizeof(*pfi_buffer), 116 PFI_MTYPE, M_WAITOK); 117 pfi_self = pfi_if_create("self", NULL, PFI_IFLAG_GROUP); 118 pfi_dynamic_drivers(); | 150 pfi_buffer_max = 64; 151 pfi_buffer = malloc(pfi_buffer_max * sizeof(*pfi_buffer), 152 PFI_MTYPE, M_WAITOK); 153 pfi_self = pfi_if_create("self", NULL, PFI_IFLAG_GROUP); 154 pfi_dynamic_drivers(); |
155#ifdef __FreeBSD__ 156 PF_LOCK(); 157 IFNET_RLOCK(); 158 TAILQ_FOREACH(ifp, &ifnet, if_link) 159 if (ifp->if_dunit != IF_DUNIT_NONE) { 160 IFNET_RUNLOCK(); 161 pfi_attach_ifnet(ifp); 162 IFNET_RLOCK(); 163 } 164 IFNET_RUNLOCK(); 165 PF_UNLOCK(); 166 pfi_dummy = pfi_if_create("notyet", pfi_self, 167 PFI_IFLAG_GROUP | PFI_IFLAG_DYNAMIC); 168 pfi_attach_cookie = EVENTHANDLER_REGISTER(ifnet_arrival_event, 169 pfi_attach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY); 170 pfi_detach_cookie = EVENTHANDLER_REGISTER(ifnet_departure_event, 171 pfi_detach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY); 172 pfi_clone_cookie = EVENTHANDLER_REGISTER(if_clone_event, 173 pfi_attach_clone_event, NULL, EVENTHANDLER_PRI_ANY); 174#endif |
|
119} 120 | 175} 176 |
177#ifdef __FreeBSD__ |
|
121void | 178void |
179pfi_cleanup(void) 180{ 181 struct pfi_kif *p, key; 182 struct ifnet *ifp; 183 184 PF_ASSERT(MA_OWNED); 185 PF_UNLOCK(); 186 187 EVENTHANDLER_DEREGISTER(ifnet_arrival_event, pfi_attach_cookie); 188 EVENTHANDLER_DEREGISTER(ifnet_departure_event, pfi_detach_cookie); 189 EVENTHANDLER_DEREGISTER(if_clone_event, pfi_clone_cookie); 190 191 IFNET_RLOCK(); 192 /* release PFI_IFLAG_INSTANCE */ 193 TAILQ_FOREACH(ifp, &ifnet, if_link) { 194 strlcpy(key.pfik_name, ifp->if_xname, sizeof(key.pfik_name)); 195 p = RB_FIND(pfi_ifhead, &pfi_ifs, &key); 196 if (p != NULL) { 197 PF_LOCK(); 198 pfi_detach_ifnet(ifp); 199 PF_UNLOCK(); 200 } 201 } 202 IFNET_RUNLOCK(); 203 204 PF_LOCK(); 205 /* XXX clear all other interface group */ 206 while ((p = RB_MIN(pfi_ifhead, &pfi_ifs))) { 207 RB_REMOVE(pfi_ifhead, &pfi_ifs, p); 208 209 free(p->pfik_ah_head, PFI_MTYPE); 210 free(p, PFI_MTYPE); 211 } 212 free(pfi_index2kif, PFI_MTYPE); 213 free(pfi_buffer, PFI_MTYPE); 214 pfi_index2kif = NULL; 215 pfi_buffer = NULL; 216 pfi_self = NULL; 217} 218 219/* 220 * Wrapper functions for FreeBSD eventhandler 221 */ 222void 223pfi_kifaddr_update_event(void *arg, struct ifnet *ifp) 224{ 225 struct pfi_kif *p = arg; 226 227 PF_LOCK(); 228 /* 229 * Check to see if it is 'our' interface as we do not have per 230 * interface hooks and thus get an update for every interface. 231 */ 232 if (p && p->pfik_ifp == ifp) 233 pfi_kifaddr_update(p); 234 PF_UNLOCK(); 235} 236 237void 238pfi_attach_clone_event(void *arg __unused, struct if_clone *ifc) 239{ 240 PF_LOCK(); 241 pfi_attach_clone(ifc); 242 PF_UNLOCK(); 243} 244 245void 246pfi_attach_ifnet_event(void *arg __unused, struct ifnet *ifp) 247{ 248 PF_LOCK(); 249 if (ifp->if_dunit != IF_DUNIT_NONE) 250 pfi_attach_ifnet(ifp); 251 PF_UNLOCK(); 252} 253 254void 255pfi_detach_ifnet_event(void *arg __unused, struct ifnet *ifp) 256{ 257 PF_LOCK(); 258 pfi_detach_ifnet(ifp); 259 PF_UNLOCK(); 260} 261#endif /* __FreeBSD__ */ 262 263void |
|
122pfi_attach_clone(struct if_clone *ifc) 123{ 124 pfi_initialize(); 125 pfi_newgroup(ifc->ifc_name, PFI_IFLAG_CLONABLE); 126} 127 128void 129pfi_attach_ifnet(struct ifnet *ifp) 130{ 131 struct pfi_kif *p, *q, key; 132 int s; | 264pfi_attach_clone(struct if_clone *ifc) 265{ 266 pfi_initialize(); 267 pfi_newgroup(ifc->ifc_name, PFI_IFLAG_CLONABLE); 268} 269 270void 271pfi_attach_ifnet(struct ifnet *ifp) 272{ 273 struct pfi_kif *p, *q, key; 274 int s; |
275#ifdef __FreeBSD__ 276 int realname; 277#endif |
|
133 134 pfi_initialize(); 135 s = splsoftnet(); 136 pfi_update++; 137 if (ifp->if_index >= pfi_indexlim) { 138 /* 139 * grow pfi_index2kif, similar to ifindex2ifnet code in if.c 140 */ --- 4 unchanged lines hidden (view full) --- 145 if (pfi_indexlim == 0) 146 pfi_indexlim = 64; 147 while (ifp->if_index >= pfi_indexlim) 148 pfi_indexlim <<= 1; 149 150 m = oldlim * sizeof(struct pfi_kif *); 151 mp = pfi_index2kif; 152 n = pfi_indexlim * sizeof(struct pfi_kif *); | 278 279 pfi_initialize(); 280 s = splsoftnet(); 281 pfi_update++; 282 if (ifp->if_index >= pfi_indexlim) { 283 /* 284 * grow pfi_index2kif, similar to ifindex2ifnet code in if.c 285 */ --- 4 unchanged lines hidden (view full) --- 290 if (pfi_indexlim == 0) 291 pfi_indexlim = 64; 292 while (ifp->if_index >= pfi_indexlim) 293 pfi_indexlim <<= 1; 294 295 m = oldlim * sizeof(struct pfi_kif *); 296 mp = pfi_index2kif; 297 n = pfi_indexlim * sizeof(struct pfi_kif *); |
298#ifdef __FreeBSD__ 299 np = malloc(n, PFI_MTYPE, M_NOWAIT); 300#else |
|
153 np = malloc(n, PFI_MTYPE, M_DONTWAIT); | 301 np = malloc(n, PFI_MTYPE, M_DONTWAIT); |
302#endif |
|
154 if (np == NULL) 155 panic("pfi_attach_ifnet: " 156 "cannot allocate translation table"); 157 bzero(np, n); 158 if (mp != NULL) 159 bcopy(mp, np, m); 160 pfi_index2kif = np; 161 if (mp != NULL) 162 free(mp, PFI_MTYPE); 163 } 164 165 strlcpy(key.pfik_name, ifp->if_xname, sizeof(key.pfik_name)); 166 p = RB_FIND(pfi_ifhead, &pfi_ifs, &key); | 303 if (np == NULL) 304 panic("pfi_attach_ifnet: " 305 "cannot allocate translation table"); 306 bzero(np, n); 307 if (mp != NULL) 308 bcopy(mp, np, m); 309 pfi_index2kif = np; 310 if (mp != NULL) 311 free(mp, PFI_MTYPE); 312 } 313 314 strlcpy(key.pfik_name, ifp->if_xname, sizeof(key.pfik_name)); 315 p = RB_FIND(pfi_ifhead, &pfi_ifs, &key); |
316#ifdef __FreeBSD__ 317 /* some additional trickery for placeholders */ 318 if ((p == NULL) || (p->pfik_parent == pfi_dummy)) { 319 /* are we looking at a renamed instance or not? */ 320 pfi_copy_group(key.pfik_name, ifp->if_xname, 321 sizeof(key.pfik_name)); 322 realname = (strncmp(key.pfik_name, ifp->if_dname, 323 sizeof(key.pfik_name)) == 0); 324 /* add group */ 325 /* we can change if_xname, hence use if_dname as group id */ 326 pfi_copy_group(key.pfik_name, ifp->if_dname, 327 sizeof(key.pfik_name)); 328 q = RB_FIND(pfi_ifhead, &pfi_ifs, &key); 329 if (q == NULL) 330 q = pfi_if_create(key.pfik_name, pfi_self, 331 PFI_IFLAG_GROUP|PFI_IFLAG_DYNAMIC); 332 else if (q->pfik_parent == pfi_dummy) { 333 q->pfik_parent = pfi_self; 334 q->pfik_flags = (PFI_IFLAG_GROUP | PFI_IFLAG_DYNAMIC); 335 } 336 if (q == NULL) 337 panic("pfi_attach_ifnet: " 338 "cannot allocate '%s' group", key.pfik_name); 339 340 /* add/modify interface */ 341 if (p == NULL) 342 p = pfi_if_create(ifp->if_xname, q, 343 realname?PFI_IFLAG_INSTANCE:PFI_IFLAG_PLACEHOLDER); 344 else { 345 /* remove from the dummy group */ 346 /* XXX: copy stats? We should not have any!!! */ 347 pfi_dummy->pfik_delcnt++; 348 TAILQ_REMOVE(&pfi_dummy->pfik_grouphead, p, 349 pfik_instances); 350 /* move to the right group */ 351 p->pfik_parent = q; 352 q->pfik_addcnt++; 353 TAILQ_INSERT_TAIL(&q->pfik_grouphead, p, 354 pfik_instances); 355 if (realname) { 356 p->pfik_flags &= ~PFI_IFLAG_PLACEHOLDER; 357 p->pfik_flags |= PFI_IFLAG_INSTANCE; 358 } 359 } 360 if (p == NULL) 361 panic("pfi_attach_ifnet: " 362 "cannot allocate '%s' interface", ifp->if_xname); 363#else |
|
167 if (p == NULL) { 168 /* add group */ 169 pfi_copy_group(key.pfik_name, ifp->if_xname, 170 sizeof(key.pfik_name)); 171 q = RB_FIND(pfi_ifhead, &pfi_ifs, &key); 172 if (q == NULL) 173 q = pfi_if_create(key.pfik_name, pfi_self, PFI_IFLAG_GROUP); | 364 if (p == NULL) { 365 /* add group */ 366 pfi_copy_group(key.pfik_name, ifp->if_xname, 367 sizeof(key.pfik_name)); 368 q = RB_FIND(pfi_ifhead, &pfi_ifs, &key); 369 if (q == NULL) 370 q = pfi_if_create(key.pfik_name, pfi_self, PFI_IFLAG_GROUP); |
371 else if (q->pfik_parent == pfi_dummy) { 372 q->pfik_parent = pfi_self; 373 q->pfik_flags = (PFI_IFLAG_GROUP | PFI_IFLAG_DYNAMIC); 374 } |
|
174 if (q == NULL) 175 panic("pfi_attach_ifnet: " 176 "cannot allocate '%s' group", key.pfik_name); 177 178 /* add interface */ 179 p = pfi_if_create(ifp->if_xname, q, PFI_IFLAG_INSTANCE); 180 if (p == NULL) 181 panic("pfi_attach_ifnet: " 182 "cannot allocate '%s' interface", ifp->if_xname); | 375 if (q == NULL) 376 panic("pfi_attach_ifnet: " 377 "cannot allocate '%s' group", key.pfik_name); 378 379 /* add interface */ 380 p = pfi_if_create(ifp->if_xname, q, PFI_IFLAG_INSTANCE); 381 if (p == NULL) 382 panic("pfi_attach_ifnet: " 383 "cannot allocate '%s' interface", ifp->if_xname); |
384#endif |
|
183 } else 184 q = p->pfik_parent; 185 p->pfik_ifp = ifp; 186 p->pfik_flags |= PFI_IFLAG_ATTACHED; | 385 } else 386 q = p->pfik_parent; 387 p->pfik_ifp = ifp; 388 p->pfik_flags |= PFI_IFLAG_ATTACHED; |
389#ifdef __FreeBSD__ 390 PF_UNLOCK(); 391 p->pfik_ah_cookie = EVENTHANDLER_REGISTER(ifaddr_event, 392 pfi_kifaddr_update_event, p, EVENTHANDLER_PRI_ANY); 393 PF_LOCK(); 394#else |
|
187 p->pfik_ah_cookie = 188 hook_establish(ifp->if_addrhooks, 1, pfi_kifaddr_update, p); | 395 p->pfik_ah_cookie = 396 hook_establish(ifp->if_addrhooks, 1, pfi_kifaddr_update, p); |
397#endif |
|
189 pfi_index2kif[ifp->if_index] = p; 190 pfi_dohooks(p); 191 splx(s); 192} 193 194void 195pfi_detach_ifnet(struct ifnet *ifp) 196{ --- 5 unchanged lines hidden (view full) --- 202 s = splsoftnet(); 203 pfi_update++; 204 p = RB_FIND(pfi_ifhead, &pfi_ifs, &key); 205 if (p == NULL) { 206 printf("pfi_detach_ifnet: cannot find %s", ifp->if_xname); 207 splx(s); 208 return; 209 } | 398 pfi_index2kif[ifp->if_index] = p; 399 pfi_dohooks(p); 400 splx(s); 401} 402 403void 404pfi_detach_ifnet(struct ifnet *ifp) 405{ --- 5 unchanged lines hidden (view full) --- 411 s = splsoftnet(); 412 pfi_update++; 413 p = RB_FIND(pfi_ifhead, &pfi_ifs, &key); 414 if (p == NULL) { 415 printf("pfi_detach_ifnet: cannot find %s", ifp->if_xname); 416 splx(s); 417 return; 418 } |
419#ifdef __FreeBSD__ 420 PF_UNLOCK(); 421 EVENTHANDLER_DEREGISTER(ifaddr_event, p->pfik_ah_cookie); 422 PF_LOCK(); 423#else |
|
210 hook_disestablish(p->pfik_ifp->if_addrhooks, p->pfik_ah_cookie); | 424 hook_disestablish(p->pfik_ifp->if_addrhooks, p->pfik_ah_cookie); |
425#endif |
|
211 q = p->pfik_parent; 212 p->pfik_ifp = NULL; 213 p->pfik_flags &= ~PFI_IFLAG_ATTACHED; 214 pfi_index2kif[ifp->if_index] = NULL; 215 pfi_dohooks(p); 216 pfi_maybe_destroy(p); 217 splx(s); 218} --- 4 unchanged lines hidden (view full) --- 223 struct pfi_kif *p, *q, key; 224 int s; 225 226 s = splsoftnet(); 227 p = pfi_lookup_if(name); 228 if (p == NULL) { 229 pfi_copy_group(key.pfik_name, name, sizeof(key.pfik_name)); 230 q = pfi_lookup_if(key.pfik_name); | 426 q = p->pfik_parent; 427 p->pfik_ifp = NULL; 428 p->pfik_flags &= ~PFI_IFLAG_ATTACHED; 429 pfi_index2kif[ifp->if_index] = NULL; 430 pfi_dohooks(p); 431 pfi_maybe_destroy(p); 432 splx(s); 433} --- 4 unchanged lines hidden (view full) --- 438 struct pfi_kif *p, *q, key; 439 int s; 440 441 s = splsoftnet(); 442 p = pfi_lookup_if(name); 443 if (p == NULL) { 444 pfi_copy_group(key.pfik_name, name, sizeof(key.pfik_name)); 445 q = pfi_lookup_if(key.pfik_name); |
446#ifdef __FreeBSD__ 447 if ((q != NULL) && (q->pfik_parent != pfi_dummy)) 448 p = pfi_if_create(name, q, PFI_IFLAG_INSTANCE); 449 else { 450 if (pfi_dummy == NULL) 451 panic("no 'notyet' dummy group"); 452 p = pfi_if_create(name, pfi_dummy, 453 PFI_IFLAG_PLACEHOLDER); 454 } 455#else |
|
231 if (q != NULL) 232 p = pfi_if_create(name, q, PFI_IFLAG_INSTANCE); | 456 if (q != NULL) 457 p = pfi_if_create(name, q, PFI_IFLAG_INSTANCE); |
458#endif |
|
233 } 234 splx(s); 235 return (p); 236} 237 238struct pfi_kif * 239pfi_attach_rule(const char *name) 240{ --- 221 unchanged lines hidden (view full) --- 462 if (pfi_buffer_cnt >= pfi_buffer_max) { 463 int new_max = pfi_buffer_max * 2; 464 465 if (new_max > PFI_BUFFER_MAX) { 466 printf("pfi_address_add: address buffer full (%d/%d)\n", 467 pfi_buffer_cnt, PFI_BUFFER_MAX); 468 return; 469 } | 459 } 460 splx(s); 461 return (p); 462} 463 464struct pfi_kif * 465pfi_attach_rule(const char *name) 466{ --- 221 unchanged lines hidden (view full) --- 688 if (pfi_buffer_cnt >= pfi_buffer_max) { 689 int new_max = pfi_buffer_max * 2; 690 691 if (new_max > PFI_BUFFER_MAX) { 692 printf("pfi_address_add: address buffer full (%d/%d)\n", 693 pfi_buffer_cnt, PFI_BUFFER_MAX); 694 return; 695 } |
696#ifdef __FreeBSD__ |
|
470 p = malloc(new_max * sizeof(*pfi_buffer), PFI_MTYPE, | 697 p = malloc(new_max * sizeof(*pfi_buffer), PFI_MTYPE, |
698 M_NOWAIT); 699#else 700 p = malloc(new_max * sizeof(*pfi_buffer), PFI_MTYPE, |
|
471 M_DONTWAIT); | 701 M_DONTWAIT); |
702#endif |
|
472 if (p == NULL) { 473 printf("pfi_address_add: no memory to grow buffer " 474 "(%d/%d)\n", pfi_buffer_cnt, PFI_BUFFER_MAX); 475 return; 476 } 477 memcpy(pfi_buffer, p, pfi_buffer_cnt * sizeof(*pfi_buffer)); 478 /* no need to zero buffer */ 479 free(pfi_buffer, PFI_MTYPE); --- 67 unchanged lines hidden (view full) --- 547 return (strncmp(p->pfik_name, q->pfik_name, IFNAMSIZ)); 548} 549 550struct pfi_kif * 551pfi_if_create(const char *name, struct pfi_kif *q, int flags) 552{ 553 struct pfi_kif *p; 554 | 703 if (p == NULL) { 704 printf("pfi_address_add: no memory to grow buffer " 705 "(%d/%d)\n", pfi_buffer_cnt, PFI_BUFFER_MAX); 706 return; 707 } 708 memcpy(pfi_buffer, p, pfi_buffer_cnt * sizeof(*pfi_buffer)); 709 /* no need to zero buffer */ 710 free(pfi_buffer, PFI_MTYPE); --- 67 unchanged lines hidden (view full) --- 778 return (strncmp(p->pfik_name, q->pfik_name, IFNAMSIZ)); 779} 780 781struct pfi_kif * 782pfi_if_create(const char *name, struct pfi_kif *q, int flags) 783{ 784 struct pfi_kif *p; 785 |
786#ifdef __FreeBSD__ 787 p = malloc(sizeof(*p), PFI_MTYPE, M_NOWAIT); 788#else |
|
555 p = malloc(sizeof(*p), PFI_MTYPE, M_DONTWAIT); | 789 p = malloc(sizeof(*p), PFI_MTYPE, M_DONTWAIT); |
790#endif |
|
556 if (p == NULL) 557 return (NULL); 558 bzero(p, sizeof(*p)); | 791 if (p == NULL) 792 return (NULL); 793 bzero(p, sizeof(*p)); |
794#ifdef __FreeBSD__ |
|
559 p->pfik_ah_head = malloc(sizeof(*p->pfik_ah_head), PFI_MTYPE, | 795 p->pfik_ah_head = malloc(sizeof(*p->pfik_ah_head), PFI_MTYPE, |
796 M_NOWAIT); 797#else 798 p->pfik_ah_head = malloc(sizeof(*p->pfik_ah_head), PFI_MTYPE, |
|
560 M_DONTWAIT); | 799 M_DONTWAIT); |
800#endif |
|
561 if (p->pfik_ah_head == NULL) { 562 free(p, PFI_MTYPE); 563 return (NULL); 564 } 565 bzero(p->pfik_ah_head, sizeof(*p->pfik_ah_head)); 566 TAILQ_INIT(p->pfik_ah_head); 567 TAILQ_INIT(&p->pfik_grouphead); 568 strlcpy(p->pfik_name, name, sizeof(p->pfik_name)); 569 RB_INIT(&p->pfik_lan_ext); 570 RB_INIT(&p->pfik_ext_gwy); 571 p->pfik_flags = flags; 572 p->pfik_parent = q; | 801 if (p->pfik_ah_head == NULL) { 802 free(p, PFI_MTYPE); 803 return (NULL); 804 } 805 bzero(p->pfik_ah_head, sizeof(*p->pfik_ah_head)); 806 TAILQ_INIT(p->pfik_ah_head); 807 TAILQ_INIT(&p->pfik_grouphead); 808 strlcpy(p->pfik_name, name, sizeof(p->pfik_name)); 809 RB_INIT(&p->pfik_lan_ext); 810 RB_INIT(&p->pfik_ext_gwy); 811 p->pfik_flags = flags; 812 p->pfik_parent = q; |
813#ifdef __FreeBSD__ 814 p->pfik_tzero = time_second; 815#else |
|
573 p->pfik_tzero = time.tv_sec; | 816 p->pfik_tzero = time.tv_sec; |
817#endif |
|
574 575 RB_INSERT(pfi_ifhead, &pfi_ifs, p); 576 if (q != NULL) { 577 q->pfik_addcnt++; 578 TAILQ_INSERT_TAIL(&q->pfik_grouphead, p, pfik_instances); 579 } 580 pfi_ifcnt++; 581 return (p); 582} 583 584int 585pfi_maybe_destroy(struct pfi_kif *p) 586{ 587 int i, j, k, s; 588 struct pfi_kif *q = p->pfik_parent; 589 590 if ((p->pfik_flags & (PFI_IFLAG_ATTACHED | PFI_IFLAG_GROUP)) || 591 p->pfik_rules > 0 || p->pfik_states > 0) | 818 819 RB_INSERT(pfi_ifhead, &pfi_ifs, p); 820 if (q != NULL) { 821 q->pfik_addcnt++; 822 TAILQ_INSERT_TAIL(&q->pfik_grouphead, p, pfik_instances); 823 } 824 pfi_ifcnt++; 825 return (p); 826} 827 828int 829pfi_maybe_destroy(struct pfi_kif *p) 830{ 831 int i, j, k, s; 832 struct pfi_kif *q = p->pfik_parent; 833 834 if ((p->pfik_flags & (PFI_IFLAG_ATTACHED | PFI_IFLAG_GROUP)) || 835 p->pfik_rules > 0 || p->pfik_states > 0) |
836#ifdef __FreeBSD__ 837 if (!(p->pfik_flags & PFI_IFLAG_PLACEHOLDER)) 838#endif |
|
592 return (0); 593 594 s = splsoftnet(); 595 if (q != NULL) { 596 for (i = 0; i < 2; i++) 597 for (j = 0; j < 2; j++) 598 for (k = 0; k < 2; k++) { 599 q->pfik_bytes[i][j][k] += 600 p->pfik_bytes[i][j][k]; 601 q->pfik_packets[i][j][k] += 602 p->pfik_packets[i][j][k]; | 839 return (0); 840 841 s = splsoftnet(); 842 if (q != NULL) { 843 for (i = 0; i < 2; i++) 844 for (j = 0; j < 2; j++) 845 for (k = 0; k < 2; k++) { 846 q->pfik_bytes[i][j][k] += 847 p->pfik_bytes[i][j][k]; 848 q->pfik_packets[i][j][k] += 849 p->pfik_packets[i][j][k]; |
850#ifdef __FreeBSD__ 851 /* clear stats in case we return to the dummy group */ 852 p->pfik_bytes[i][j][k] = 0; 853 p->pfik_packets[i][j][k] = 0; 854#endif |
|
603 } 604 q->pfik_delcnt++; 605 TAILQ_REMOVE(&q->pfik_grouphead, p, pfik_instances); 606 } | 855 } 856 q->pfik_delcnt++; 857 TAILQ_REMOVE(&q->pfik_grouphead, p, pfik_instances); 858 } |
859#ifdef __FreeBSD__ 860 if (p->pfik_rules > 0 || p->pfik_states > 0) { 861 /* move back to the dummy group */ 862 p->pfik_parent = pfi_dummy; 863 pfi_dummy->pfik_addcnt++; 864 TAILQ_INSERT_TAIL(&pfi_dummy->pfik_grouphead, p, 865 pfik_instances); 866 return (0); 867 } 868#endif |
|
607 pfi_ifcnt--; 608 RB_REMOVE(pfi_ifhead, &pfi_ifs, p); 609 splx(s); 610 611 free(p->pfik_ah_head, PFI_MTYPE); 612 free(p, PFI_MTYPE); 613 return (1); 614} --- 7 unchanged lines hidden (view full) --- 622 } 623 if (m > 0) 624 *p++ = '\0'; 625} 626 627void 628pfi_dynamic_drivers(void) 629{ | 869 pfi_ifcnt--; 870 RB_REMOVE(pfi_ifhead, &pfi_ifs, p); 871 splx(s); 872 873 free(p->pfik_ah_head, PFI_MTYPE); 874 free(p, PFI_MTYPE); 875 return (1); 876} --- 7 unchanged lines hidden (view full) --- 884 } 885 if (m > 0) 886 *p++ = '\0'; 887} 888 889void 890pfi_dynamic_drivers(void) 891{ |
892#ifdef __FreeBSD__ 893 struct ifnet *ifp; 894 895/* 896 * For FreeBSD basically every interface is "dynamic" as we can unload 897 * modules e.g. 898 */ 899 900 IFNET_RLOCK(); 901 TAILQ_FOREACH(ifp, &ifnet, if_link) { 902 if (ifp->if_dunit == IF_DUNIT_NONE) 903 continue; 904 pfi_newgroup(ifp->if_dname, PFI_IFLAG_DYNAMIC); 905 } 906 IFNET_RUNLOCK(); 907#else |
|
630 char *buses[] = PFI_DYNAMIC_BUSES; 631 int nbuses = sizeof(buses)/sizeof(buses[0]); 632 int enabled[sizeof(buses)/sizeof(buses[0])]; 633 struct device *dev; 634 struct cfdata *cf; 635 struct cfdriver *drv; 636 short *p; 637 int i; --- 19 unchanged lines hidden (view full) --- 657 break; 658 if (i < nbuses) { 659 pfi_newgroup(cf->cf_driver->cd_name, 660 PFI_IFLAG_DYNAMIC); 661 break; 662 } 663 } 664 } | 908 char *buses[] = PFI_DYNAMIC_BUSES; 909 int nbuses = sizeof(buses)/sizeof(buses[0]); 910 int enabled[sizeof(buses)/sizeof(buses[0])]; 911 struct device *dev; 912 struct cfdata *cf; 913 struct cfdriver *drv; 914 short *p; 915 int i; --- 19 unchanged lines hidden (view full) --- 935 break; 936 if (i < nbuses) { 937 pfi_newgroup(cf->cf_driver->cd_name, 938 PFI_IFLAG_DYNAMIC); 939 break; 940 } 941 } 942 } |
943#endif |
|
665} 666 667void 668pfi_newgroup(const char *name, int flags) 669{ 670 struct pfi_kif *p; 671 672 p = pfi_lookup_if(name); --- 32 unchanged lines hidden (view full) --- 705 splx(s); 706} 707 708int 709pfi_clr_istats(const char *name, int *nzero, int flags) 710{ 711 struct pfi_kif *p; 712 int n = 0, s; | 944} 945 946void 947pfi_newgroup(const char *name, int flags) 948{ 949 struct pfi_kif *p; 950 951 p = pfi_lookup_if(name); --- 32 unchanged lines hidden (view full) --- 984 splx(s); 985} 986 987int 988pfi_clr_istats(const char *name, int *nzero, int flags) 989{ 990 struct pfi_kif *p; 991 int n = 0, s; |
992#ifdef __FreeBSD__ 993 long tzero = time_second; 994#else |
|
713 long tzero = time.tv_sec; | 995 long tzero = time.tv_sec; |
996#endif |
|
714 715 s = splsoftnet(); 716 ACCEPT_FLAGS(PFI_FLAG_GROUP|PFI_FLAG_INSTANCE); 717 RB_FOREACH(p, pfi_ifhead, &pfi_ifs) { 718 if (pfi_skip_if(name, p, flags)) 719 continue; 720 bzero(p->pfik_packets, sizeof(p->pfik_packets)); 721 bzero(p->pfik_bytes, sizeof(p->pfik_bytes)); --- 6 unchanged lines hidden (view full) --- 728 return (0); 729} 730 731int 732pfi_get_ifaces(const char *name, struct pfi_if *buf, int *size, int flags) 733{ 734 struct pfi_kif *p; 735 int s, n = 0; | 997 998 s = splsoftnet(); 999 ACCEPT_FLAGS(PFI_FLAG_GROUP|PFI_FLAG_INSTANCE); 1000 RB_FOREACH(p, pfi_ifhead, &pfi_ifs) { 1001 if (pfi_skip_if(name, p, flags)) 1002 continue; 1003 bzero(p->pfik_packets, sizeof(p->pfik_packets)); 1004 bzero(p->pfik_bytes, sizeof(p->pfik_bytes)); --- 6 unchanged lines hidden (view full) --- 1011 return (0); 1012} 1013 1014int 1015pfi_get_ifaces(const char *name, struct pfi_if *buf, int *size, int flags) 1016{ 1017 struct pfi_kif *p; 1018 int s, n = 0; |
1019#ifdef __FreeBSD__ 1020 int ec; 1021#endif |
|
736 737 ACCEPT_FLAGS(PFI_FLAG_GROUP|PFI_FLAG_INSTANCE); 738 s = splsoftnet(); 739 RB_FOREACH(p, pfi_ifhead, &pfi_ifs) { 740 if (pfi_skip_if(name, p, flags)) 741 continue; 742 if (*size > n++) { 743 if (!p->pfik_tzero) 744 p->pfik_tzero = boottime.tv_sec; | 1022 1023 ACCEPT_FLAGS(PFI_FLAG_GROUP|PFI_FLAG_INSTANCE); 1024 s = splsoftnet(); 1025 RB_FOREACH(p, pfi_ifhead, &pfi_ifs) { 1026 if (pfi_skip_if(name, p, flags)) 1027 continue; 1028 if (*size > n++) { 1029 if (!p->pfik_tzero) 1030 p->pfik_tzero = boottime.tv_sec; |
1031#ifdef __FreeBSD__ 1032 PF_COPYOUT(p, buf++, sizeof(*buf), ec); 1033 if (ec) { 1034#else |
|
745 if (copyout(p, buf++, sizeof(*buf))) { | 1035 if (copyout(p, buf++, sizeof(*buf))) { |
1036#endif |
|
746 splx(s); 747 return (EFAULT); 748 } 749 } 750 } 751 splx(s); 752 *size = n; 753 return (0); --- 87 unchanged lines hidden --- | 1037 splx(s); 1038 return (EFAULT); 1039 } 1040 } 1041 } 1042 splx(s); 1043 *size = n; 1044 return (0); --- 87 unchanged lines hidden --- |