if_pfsync.c (126259) | if_pfsync.c (126261) |
---|---|
1/* $FreeBSD: head/sys/contrib/pf/net/if_pfsync.c 126261 2004-02-26 02:34:12Z mlaier $ */ |
|
1/* $OpenBSD: if_pfsync.c,v 1.6 2003/06/21 09:07:01 djm Exp $ */ 2 3/* 4 * Copyright (c) 2002 Michael Shalayeff 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 --- 12 unchanged lines hidden (view full) --- 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26 * THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 | 2/* $OpenBSD: if_pfsync.c,v 1.6 2003/06/21 09:07:01 djm Exp $ */ 3 4/* 5 * Copyright (c) 2002 Michael Shalayeff 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 --- 12 unchanged lines hidden (view full) --- 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 |
30#if defined(__FreeBSD__) && __FreeBSD__ >= 5 31#include "opt_inet.h" 32#include "opt_inet6.h" 33#endif 34 35#if !defined(__FreeBSD__) |
|
29#include "bpfilter.h" 30#include "pfsync.h" | 36#include "bpfilter.h" 37#include "pfsync.h" |
38#elif __FreeBSD__ >= 5 39#include "opt_bpf.h" 40#define NBPFILTER DEV_BPF 41#include "opt_pf.h" 42#define NPFSYNC DEV_PFSYNC 43#endif |
|
31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/time.h> 35#include <sys/mbuf.h> 36#include <sys/socket.h> | 44 45#include <sys/param.h> 46#include <sys/systm.h> 47#include <sys/time.h> 48#include <sys/mbuf.h> 49#include <sys/socket.h> |
50#if defined(__FreeBSD__) 51#include <sys/kernel.h> 52#include <sys/malloc.h> 53#include <sys/sockio.h> 54#else |
|
37#include <sys/ioctl.h> 38#include <sys/timeout.h> | 55#include <sys/ioctl.h> 56#include <sys/timeout.h> |
57#endif |
|
39 40#include <net/if.h> 41#include <net/if_types.h> 42#include <net/route.h> 43#include <net/bpf.h> 44 45#ifdef INET 46#include <netinet/in.h> --- 5 unchanged lines hidden (view full) --- 52#include <netinet/in.h> 53#endif 54#include <netinet6/nd6.h> 55#endif /* INET6 */ 56 57#include <net/pfvar.h> 58#include <net/if_pfsync.h> 59 | 58 59#include <net/if.h> 60#include <net/if_types.h> 61#include <net/route.h> 62#include <net/bpf.h> 63 64#ifdef INET 65#include <netinet/in.h> --- 5 unchanged lines hidden (view full) --- 71#include <netinet/in.h> 72#endif 73#include <netinet6/nd6.h> 74#endif /* INET6 */ 75 76#include <net/pfvar.h> 77#include <net/if_pfsync.h> 78 |
79#if defined(__FreeBSD__) 80#define PFSYNCNAME "pfsync" 81#endif 82 |
|
60#define PFSYNC_MINMTU \ 61 (sizeof(struct pfsync_header) + sizeof(struct pf_state)) 62 63#ifdef PFSYNCDEBUG 64#define DPRINTF(x) do { if (pfsyncdebug) printf x ; } while (0) 65int pfsyncdebug; 66#else 67#define DPRINTF(x) 68#endif 69 | 83#define PFSYNC_MINMTU \ 84 (sizeof(struct pfsync_header) + sizeof(struct pf_state)) 85 86#ifdef PFSYNCDEBUG 87#define DPRINTF(x) do { if (pfsyncdebug) printf x ; } while (0) 88int pfsyncdebug; 89#else 90#define DPRINTF(x) 91#endif 92 |
93#if !defined(__FreeBSD__) |
|
70struct pfsync_softc pfsyncif; | 94struct pfsync_softc pfsyncif; |
95#endif |
|
71 | 96 |
97#if defined(__FreeBSD__) 98void pfsync_clone_destroy(struct ifnet *); 99int pfsync_clone_create(struct if_clone *, int); 100#else |
|
72void pfsyncattach(int); | 101void pfsyncattach(int); |
102#endif |
|
73void pfsync_setmtu(struct pfsync_softc *sc, int); 74int pfsyncoutput(struct ifnet *, struct mbuf *, struct sockaddr *, 75 struct rtentry *); 76int pfsyncioctl(struct ifnet *, u_long, caddr_t); 77void pfsyncstart(struct ifnet *); 78 79struct mbuf *pfsync_get_mbuf(struct pfsync_softc *sc, u_int8_t action); 80int pfsync_sendout(struct pfsync_softc *sc); 81void pfsync_timeout(void *v); 82 | 103void pfsync_setmtu(struct pfsync_softc *sc, int); 104int pfsyncoutput(struct ifnet *, struct mbuf *, struct sockaddr *, 105 struct rtentry *); 106int pfsyncioctl(struct ifnet *, u_long, caddr_t); 107void pfsyncstart(struct ifnet *); 108 109struct mbuf *pfsync_get_mbuf(struct pfsync_softc *sc, u_int8_t action); 110int pfsync_sendout(struct pfsync_softc *sc); 111void pfsync_timeout(void *v); 112 |
113#if !defined(__FreeBSD__) |
|
83extern int ifqmaxlen; | 114extern int ifqmaxlen; |
115#endif |
|
84 | 116 |
117#if defined(__FreeBSD__) 118static MALLOC_DEFINE(M_PFSYNC, PFSYNCNAME, "Packet Filter State Sync. Interface"); 119static LIST_HEAD(pfsync_list, pfsync_softc) pfsync_list; 120struct if_clone pfsync_cloner = IF_CLONE_INITIALIZER(PFSYNCNAME, 121 pfsync_clone_create, pfsync_clone_destroy, 1, IF_MAXUNIT); 122 |
|
85void | 123void |
124pfsync_clone_destroy(struct ifnet *ifp) 125{ 126 struct pfsync_softc *sc; 127 128 sc = ifp->if_softc; 129 callout_stop(&sc->sc_tmo); 130 131 /* 132 * Does we really need this? 133 */ 134 IF_DRAIN(&ifp->if_snd); 135 136#if NBPFILTER > 0 137 bpfdetach(ifp); 138#endif 139 if_detach(ifp); 140 LIST_REMOVE(sc, sc_next); 141 free(sc, M_PFSYNC); 142} 143#endif /* __FreeBSD__ */ 144 145#if defined(__FreeBSD__) 146int 147pfsync_clone_create(struct if_clone *ifc, int unit) 148{ 149 struct pfsync_softc *sc; 150 151 MALLOC(sc, struct pfsync_softc *, sizeof(*sc), M_PFSYNC, 152 M_WAITOK|M_ZERO); 153 154 sc->sc_count = 8; 155#if (__FreeBSD_version < 501113) 156 sc->sc_if.if_name = PFSYNCNAME; 157 sc->sc_if.if_unit = unit; 158#else 159 if_initname(&sc->sc_if, ifc->ifc_name, unit); 160#endif 161 sc->sc_if.if_ioctl = pfsyncioctl; 162 sc->sc_if.if_output = pfsyncoutput; 163 sc->sc_if.if_start = pfsyncstart; 164 sc->sc_if.if_type = IFT_PFSYNC; 165 sc->sc_if.if_snd.ifq_maxlen = ifqmaxlen; 166 sc->sc_if.if_hdrlen = PFSYNC_HDRLEN; 167 sc->sc_if.if_baudrate = IF_Mbps(100); 168 sc->sc_if.if_softc = sc; 169 pfsync_setmtu(sc, MCLBYTES); 170 /* 171 * XXX 172 * The 2nd arg. 0 to callout_init(9) shoule be set to CALLOUT_MPSAFE 173 * if Gaint lock is removed from the network stack. 174 */ 175 callout_init(&sc->sc_tmo, 0); 176 if_attach(&sc->sc_if); 177 178 LIST_INSERT_HEAD(&pfsync_list, sc, sc_next); 179#if NBPFILTER > 0 180 bpfattach(&sc->sc_if, DLT_PFSYNC, PFSYNC_HDRLEN); 181#endif 182 183 return (0); 184} 185#else /* !__FreeBSD__ */ 186void |
|
86pfsyncattach(int npfsync) 87{ 88 struct ifnet *ifp; 89 90 pfsyncif.sc_mbuf = NULL; 91 pfsyncif.sc_ptr = NULL; 92 pfsyncif.sc_count = 8; 93 ifp = &pfsyncif.sc_if; --- 10 unchanged lines hidden (view full) --- 104 timeout_set(&pfsyncif.sc_tmo, pfsync_timeout, &pfsyncif); 105 if_attach(ifp); 106 if_alloc_sadl(ifp); 107 108#if NBPFILTER > 0 109 bpfattach(&pfsyncif.sc_if.if_bpf, ifp, DLT_PFSYNC, PFSYNC_HDRLEN); 110#endif 111} | 187pfsyncattach(int npfsync) 188{ 189 struct ifnet *ifp; 190 191 pfsyncif.sc_mbuf = NULL; 192 pfsyncif.sc_ptr = NULL; 193 pfsyncif.sc_count = 8; 194 ifp = &pfsyncif.sc_if; --- 10 unchanged lines hidden (view full) --- 205 timeout_set(&pfsyncif.sc_tmo, pfsync_timeout, &pfsyncif); 206 if_attach(ifp); 207 if_alloc_sadl(ifp); 208 209#if NBPFILTER > 0 210 bpfattach(&pfsyncif.sc_if.if_bpf, ifp, DLT_PFSYNC, PFSYNC_HDRLEN); 211#endif 212} |
213#endif |
|
112 113/* 114 * Start output on the pfsync interface. 115 */ 116void 117pfsyncstart(struct ifnet *ifp) 118{ 119 struct mbuf *m; | 214 215/* 216 * Start output on the pfsync interface. 217 */ 218void 219pfsyncstart(struct ifnet *ifp) 220{ 221 struct mbuf *m; |
222#if defined(__FreeBSD__) && defined(ALTQ) 223 struct ifaltq *ifq; 224#else 225 struct ifqueue *ifq; 226#endif |
|
120 int s; 121 | 227 int s; 228 |
229#if defined(__FreeBSD__) 230 ifq = &ifp->if_snd; 231#endif |
|
122 for (;;) { 123 s = splimp(); | 232 for (;;) { 233 s = splimp(); |
234#if defined(__FreeBSD__) 235 IF_LOCK(ifq); 236 _IF_DROP(ifq); 237 _IF_DEQUEUE(ifq, m); 238 IF_UNLOCK(ifq); 239#else |
|
124 IF_DROP(&ifp->if_snd); 125 IF_DEQUEUE(&ifp->if_snd, m); | 240 IF_DROP(&ifp->if_snd); 241 IF_DEQUEUE(&ifp->if_snd, m); |
242#endif |
|
126 splx(s); 127 128 if (m == NULL) 129 return; 130 else 131 m_freem(m); 132 } 133} --- 53 unchanged lines hidden (view full) --- 187 sc->sc_count * sizeof(struct pf_state); 188} 189 190struct mbuf * 191pfsync_get_mbuf(sc, action) 192 struct pfsync_softc *sc; 193 u_int8_t action; 194{ | 243 splx(s); 244 245 if (m == NULL) 246 return; 247 else 248 m_freem(m); 249 } 250} --- 53 unchanged lines hidden (view full) --- 304 sc->sc_count * sizeof(struct pf_state); 305} 306 307struct mbuf * 308pfsync_get_mbuf(sc, action) 309 struct pfsync_softc *sc; 310 u_int8_t action; 311{ |
312#if !defined(__FreeBSD__) |
|
195 extern int hz; | 313 extern int hz; |
314#endif |
|
196 struct pfsync_header *h; 197 struct mbuf *m; 198 int len; 199 200 MGETHDR(m, M_DONTWAIT, MT_DATA); 201 if (m == NULL) { 202 sc->sc_if.if_oerrors++; 203 return (NULL); --- 14 unchanged lines hidden (view full) --- 218 h = mtod(m, struct pfsync_header *); 219 h->version = PFSYNC_VERSION; 220 h->af = 0; 221 h->count = 0; 222 h->action = action; 223 224 sc->sc_mbuf = m; 225 sc->sc_ptr = (struct pf_state *)((char *)h + PFSYNC_HDRLEN); | 315 struct pfsync_header *h; 316 struct mbuf *m; 317 int len; 318 319 MGETHDR(m, M_DONTWAIT, MT_DATA); 320 if (m == NULL) { 321 sc->sc_if.if_oerrors++; 322 return (NULL); --- 14 unchanged lines hidden (view full) --- 337 h = mtod(m, struct pfsync_header *); 338 h->version = PFSYNC_VERSION; 339 h->af = 0; 340 h->count = 0; 341 h->action = action; 342 343 sc->sc_mbuf = m; 344 sc->sc_ptr = (struct pf_state *)((char *)h + PFSYNC_HDRLEN); |
345#if defined(__FreeBSD__) 346 callout_reset(&sc->sc_tmo, hz, pfsync_timeout, 347 LIST_FIRST(&pfsync_list)); 348#else |
|
226 timeout_add(&sc->sc_tmo, hz); | 349 timeout_add(&sc->sc_tmo, hz); |
350#endif |
|
227 228 return (m); 229} 230 | 351 352 return (m); 353} 354 |
355/* 356 * XXX: This function should be called with PF_LOCK held as it references 357 * pf_state. 358 */ |
|
231int 232pfsync_pack_state(action, st) 233 u_int8_t action; 234 struct pf_state *st; 235{ | 359int 360pfsync_pack_state(action, st) 361 u_int8_t action; 362 struct pf_state *st; 363{ |
364#if defined(__FreeBSD__) 365 struct pfsync_softc *sc = LIST_FIRST(&pfsync_list); 366#else |
|
236 extern struct timeval time; 237 struct ifnet *ifp = &pfsyncif.sc_if; 238 struct pfsync_softc *sc = ifp->if_softc; | 367 extern struct timeval time; 368 struct ifnet *ifp = &pfsyncif.sc_if; 369 struct pfsync_softc *sc = ifp->if_softc; |
370#endif |
|
239 struct pfsync_header *h; 240 struct pf_state *sp; 241 struct pf_rule *r = st->rule.ptr; 242 struct mbuf *m; 243 u_long secs; 244 int s, ret; 245 246 if (action >= PFSYNC_ACT_MAX) 247 return (EINVAL); 248 | 371 struct pfsync_header *h; 372 struct pf_state *sp; 373 struct pf_rule *r = st->rule.ptr; 374 struct mbuf *m; 375 u_long secs; 376 int s, ret; 377 378 if (action >= PFSYNC_ACT_MAX) 379 return (EINVAL); 380 |
381#if defined(__FreeBSD__) 382 /* 383 * XXX 384 * If we need to check mutex owned, PF_LOCK should be 385 * declared in pflog.ko. :-( 386 * 387 * PF_LOCK_ASSERT(); 388 */ 389 KASSERT((!LIST_EMPTY(&pfsync_list)), ("pfsync: no interface")); 390#endif |
|
249 s = splnet(); 250 m = sc->sc_mbuf; 251 if (m == NULL) { 252 if ((m = pfsync_get_mbuf(sc, action)) == NULL) { 253 splx(s); 254 return (ENOMEM); 255 } 256 h = mtod(m, struct pfsync_header *); --- 16 unchanged lines hidden (view full) --- 273 bcopy(&st->lan, &sp->lan, sizeof(sp->lan)); 274 bcopy(&st->gwy, &sp->gwy, sizeof(sp->gwy)); 275 bcopy(&st->ext, &sp->ext, sizeof(sp->ext)); 276 277 pf_state_peer_hton(&st->src, &sp->src); 278 pf_state_peer_hton(&st->dst, &sp->dst); 279 280 bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr)); | 391 s = splnet(); 392 m = sc->sc_mbuf; 393 if (m == NULL) { 394 if ((m = pfsync_get_mbuf(sc, action)) == NULL) { 395 splx(s); 396 return (ENOMEM); 397 } 398 h = mtod(m, struct pfsync_header *); --- 16 unchanged lines hidden (view full) --- 415 bcopy(&st->lan, &sp->lan, sizeof(sp->lan)); 416 bcopy(&st->gwy, &sp->gwy, sizeof(sp->gwy)); 417 bcopy(&st->ext, &sp->ext, sizeof(sp->ext)); 418 419 pf_state_peer_hton(&st->src, &sp->src); 420 pf_state_peer_hton(&st->dst, &sp->dst); 421 422 bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr)); |
423#if defined(__FreeBSD__) 424 secs = time_second; 425#else |
|
281 secs = time.tv_sec; | 426 secs = time.tv_sec; |
427#endif |
|
282 sp->creation = htonl(secs - st->creation); 283 if (st->expire <= secs) 284 sp->expire = htonl(0); 285 else 286 sp->expire = htonl(st->expire - secs); 287 sp->packets[0] = htonl(st->packets[0]); 288 sp->packets[1] = htonl(st->packets[1]); 289 sp->bytes[0] = htonl(st->bytes[0]); --- 15 unchanged lines hidden (view full) --- 305 splx(s); 306 return (0); 307} 308 309int 310pfsync_clear_state(st) 311 struct pf_state *st; 312{ | 428 sp->creation = htonl(secs - st->creation); 429 if (st->expire <= secs) 430 sp->expire = htonl(0); 431 else 432 sp->expire = htonl(st->expire - secs); 433 sp->packets[0] = htonl(st->packets[0]); 434 sp->packets[1] = htonl(st->packets[1]); 435 sp->bytes[0] = htonl(st->bytes[0]); --- 15 unchanged lines hidden (view full) --- 451 splx(s); 452 return (0); 453} 454 455int 456pfsync_clear_state(st) 457 struct pf_state *st; 458{ |
459#if defined(__FreeBSD__) 460 struct pfsync_softc *sc = LIST_FIRST(&pfsync_list); 461#else |
|
313 struct ifnet *ifp = &pfsyncif.sc_if; 314 struct pfsync_softc *sc = ifp->if_softc; | 462 struct ifnet *ifp = &pfsyncif.sc_if; 463 struct pfsync_softc *sc = ifp->if_softc; |
464#endif |
|
315 struct mbuf *m = sc->sc_mbuf; 316 int s, ret; 317 318 s = splnet(); 319 if (m == NULL && (m = pfsync_get_mbuf(sc, PFSYNC_ACT_CLR)) == NULL) { 320 splx(s); 321 return (ENOMEM); 322 } --- 4 unchanged lines hidden (view full) --- 327} 328 329void 330pfsync_timeout(void *v) 331{ 332 struct pfsync_softc *sc = v; 333 int s; 334 | 465 struct mbuf *m = sc->sc_mbuf; 466 int s, ret; 467 468 s = splnet(); 469 if (m == NULL && (m = pfsync_get_mbuf(sc, PFSYNC_ACT_CLR)) == NULL) { 470 splx(s); 471 return (ENOMEM); 472 } --- 4 unchanged lines hidden (view full) --- 477} 478 479void 480pfsync_timeout(void *v) 481{ 482 struct pfsync_softc *sc = v; 483 int s; 484 |
485 /* We don't need PF_LOCK/PF_UNLOCK here! */ |
|
335 s = splnet(); 336 pfsync_sendout(sc); 337 splx(s); 338} 339 340int 341pfsync_sendout(sc) 342 struct pfsync_softc *sc; 343{ 344 struct ifnet *ifp = &sc->sc_if; 345 struct mbuf *m = sc->sc_mbuf; 346 | 486 s = splnet(); 487 pfsync_sendout(sc); 488 splx(s); 489} 490 491int 492pfsync_sendout(sc) 493 struct pfsync_softc *sc; 494{ 495 struct ifnet *ifp = &sc->sc_if; 496 struct mbuf *m = sc->sc_mbuf; 497 |
498#if defined(__FreeBSD__) 499 callout_stop(&sc->sc_tmo); 500#else |
|
347 timeout_del(&sc->sc_tmo); | 501 timeout_del(&sc->sc_tmo); |
502#endif |
|
348 sc->sc_mbuf = NULL; 349 sc->sc_ptr = NULL; 350 | 503 sc->sc_mbuf = NULL; 504 sc->sc_ptr = NULL; 505 |
506#if defined(__FreeBSD__) 507 KASSERT(m != NULL, ("pfsync_sendout: null mbuf")); 508#endif |
|
351#if NBPFILTER > 0 352 if (ifp->if_bpf) 353 bpf_mtap(ifp->if_bpf, m); 354#endif 355 356 m_freem(m); 357 358 return (0); 359} | 509#if NBPFILTER > 0 510 if (ifp->if_bpf) 511 bpf_mtap(ifp->if_bpf, m); 512#endif 513 514 m_freem(m); 515 516 return (0); 517} |
518 519 520#if defined(__FreeBSD__) 521static int 522pfsync_modevent(module_t mod, int type, void *data) 523{ 524 int error = 0; 525 526 switch (type) { 527 case MOD_LOAD: 528 LIST_INIT(&pfsync_list); 529 if_clone_attach(&pfsync_cloner); 530 printf("pfsync: $Name: $\n"); 531 break; 532 533 case MOD_UNLOAD: 534 if_clone_detach(&pfsync_cloner); 535 while (!LIST_EMPTY(&pfsync_list)) 536 pfsync_clone_destroy( 537 &LIST_FIRST(&pfsync_list)->sc_if); 538 break; 539 540 default: 541 error = EINVAL; 542 break; 543 } 544 545 return error; 546} 547 548static moduledata_t pfsync_mod = { 549 "pfsync", 550 pfsync_modevent, 551 0 552}; 553 554#define PFSYNC_MODVER 1 555 556DECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 557MODULE_VERSION(pfsync, PFSYNC_MODVER); 558#endif /* __FreeBSD__ */ |
|