if_pfsync.c revision 127145
1126261Smlaier/* $FreeBSD: head/sys/contrib/pf/net/if_pfsync.c 127145 2004-03-17 21:11:02Z mlaier $ */ 2126258Smlaier/* $OpenBSD: if_pfsync.c,v 1.6 2003/06/21 09:07:01 djm Exp $ */ 3126258Smlaier 4126258Smlaier/* 5126258Smlaier * Copyright (c) 2002 Michael Shalayeff 6126258Smlaier * All rights reserved. 7126258Smlaier * 8126258Smlaier * Redistribution and use in source and binary forms, with or without 9126258Smlaier * modification, are permitted provided that the following conditions 10126258Smlaier * are met: 11126258Smlaier * 1. Redistributions of source code must retain the above copyright 12126258Smlaier * notice, this list of conditions and the following disclaimer. 13126258Smlaier * 2. Redistributions in binary form must reproduce the above copyright 14126258Smlaier * notice, this list of conditions and the following disclaimer in the 15126258Smlaier * documentation and/or other materials provided with the distribution. 16126258Smlaier * 17126258Smlaier * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18126258Smlaier * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19126258Smlaier * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20126258Smlaier * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 21126258Smlaier * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22126258Smlaier * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23126258Smlaier * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24126258Smlaier * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25126258Smlaier * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26126258Smlaier * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27126258Smlaier * THE POSSIBILITY OF SUCH DAMAGE. 28126258Smlaier */ 29126258Smlaier 30127145Smlaier#ifdef __FreeBSD__ 31126261Smlaier#include "opt_inet.h" 32126261Smlaier#include "opt_inet6.h" 33126261Smlaier#endif 34126261Smlaier 35127145Smlaier#ifndef __FreeBSD__ 36126258Smlaier#include "bpfilter.h" 37126258Smlaier#include "pfsync.h" 38126261Smlaier#elif __FreeBSD__ >= 5 39126261Smlaier#include "opt_bpf.h" 40126261Smlaier#include "opt_pf.h" 41127145Smlaier#define NBPFILTER DEV_BPF 42127145Smlaier#define NPFSYNC DEV_PFSYNC 43126261Smlaier#endif 44126258Smlaier 45126258Smlaier#include <sys/param.h> 46126258Smlaier#include <sys/systm.h> 47126258Smlaier#include <sys/time.h> 48126258Smlaier#include <sys/mbuf.h> 49126258Smlaier#include <sys/socket.h> 50127145Smlaier#ifdef __FreeBSD__ 51126261Smlaier#include <sys/kernel.h> 52126261Smlaier#include <sys/malloc.h> 53126261Smlaier#include <sys/sockio.h> 54126261Smlaier#else 55126258Smlaier#include <sys/ioctl.h> 56126258Smlaier#include <sys/timeout.h> 57126261Smlaier#endif 58126258Smlaier 59126258Smlaier#include <net/if.h> 60126258Smlaier#include <net/if_types.h> 61126258Smlaier#include <net/route.h> 62126258Smlaier#include <net/bpf.h> 63126258Smlaier 64126258Smlaier#ifdef INET 65126258Smlaier#include <netinet/in.h> 66126258Smlaier#include <netinet/in_var.h> 67126258Smlaier#endif 68126258Smlaier 69126258Smlaier#ifdef INET6 70126258Smlaier#ifndef INET 71126258Smlaier#include <netinet/in.h> 72126258Smlaier#endif 73126258Smlaier#include <netinet6/nd6.h> 74126258Smlaier#endif /* INET6 */ 75126258Smlaier 76126258Smlaier#include <net/pfvar.h> 77126258Smlaier#include <net/if_pfsync.h> 78126258Smlaier 79127145Smlaier#ifdef __FreeBSD__ 80127145Smlaier#define PFSYNCNAME "pfsync" 81126261Smlaier#endif 82126261Smlaier 83126258Smlaier#define PFSYNC_MINMTU \ 84126258Smlaier (sizeof(struct pfsync_header) + sizeof(struct pf_state)) 85126258Smlaier 86126258Smlaier#ifdef PFSYNCDEBUG 87126258Smlaier#define DPRINTF(x) do { if (pfsyncdebug) printf x ; } while (0) 88126258Smlaierint pfsyncdebug; 89126258Smlaier#else 90126258Smlaier#define DPRINTF(x) 91126258Smlaier#endif 92126258Smlaier 93127145Smlaier#ifndef __FreeBSD__ 94126258Smlaierstruct pfsync_softc pfsyncif; 95126261Smlaier#endif 96126258Smlaier 97127145Smlaier#ifdef __FreeBSD__ 98126261Smlaiervoid pfsync_clone_destroy(struct ifnet *); 99126261Smlaierint pfsync_clone_create(struct if_clone *, int); 100126261Smlaier#else 101126258Smlaiervoid pfsyncattach(int); 102126261Smlaier#endif 103126258Smlaiervoid pfsync_setmtu(struct pfsync_softc *sc, int); 104126258Smlaierint pfsyncoutput(struct ifnet *, struct mbuf *, struct sockaddr *, 105126258Smlaier struct rtentry *); 106126258Smlaierint pfsyncioctl(struct ifnet *, u_long, caddr_t); 107126258Smlaiervoid pfsyncstart(struct ifnet *); 108126258Smlaier 109126258Smlaierstruct mbuf *pfsync_get_mbuf(struct pfsync_softc *sc, u_int8_t action); 110126258Smlaierint pfsync_sendout(struct pfsync_softc *sc); 111126258Smlaiervoid pfsync_timeout(void *v); 112126258Smlaier 113127145Smlaier#ifndef __FreeBSD__ 114126258Smlaierextern int ifqmaxlen; 115126261Smlaier#endif 116126258Smlaier 117127145Smlaier#ifdef __FreeBSD__ 118126261Smlaierstatic MALLOC_DEFINE(M_PFSYNC, PFSYNCNAME, "Packet Filter State Sync. Interface"); 119126261Smlaierstatic LIST_HEAD(pfsync_list, pfsync_softc) pfsync_list; 120126261Smlaierstruct if_clone pfsync_cloner = IF_CLONE_INITIALIZER(PFSYNCNAME, 121126261Smlaier pfsync_clone_create, pfsync_clone_destroy, 1, IF_MAXUNIT); 122126261Smlaier 123126258Smlaiervoid 124126261Smlaierpfsync_clone_destroy(struct ifnet *ifp) 125126261Smlaier{ 126126261Smlaier struct pfsync_softc *sc; 127126261Smlaier 128126261Smlaier sc = ifp->if_softc; 129126261Smlaier callout_stop(&sc->sc_tmo); 130126261Smlaier 131126261Smlaier /* 132126261Smlaier * Does we really need this? 133126261Smlaier */ 134126261Smlaier IF_DRAIN(&ifp->if_snd); 135126261Smlaier 136126261Smlaier#if NBPFILTER > 0 137126261Smlaier bpfdetach(ifp); 138126261Smlaier#endif 139126261Smlaier if_detach(ifp); 140126261Smlaier LIST_REMOVE(sc, sc_next); 141126261Smlaier free(sc, M_PFSYNC); 142126261Smlaier} 143126261Smlaier 144126261Smlaierint 145126261Smlaierpfsync_clone_create(struct if_clone *ifc, int unit) 146126261Smlaier{ 147126261Smlaier struct pfsync_softc *sc; 148126261Smlaier 149126261Smlaier MALLOC(sc, struct pfsync_softc *, sizeof(*sc), M_PFSYNC, 150126261Smlaier M_WAITOK|M_ZERO); 151126261Smlaier 152126261Smlaier sc->sc_count = 8; 153126261Smlaier#if (__FreeBSD_version < 501113) 154126261Smlaier sc->sc_if.if_name = PFSYNCNAME; 155126261Smlaier sc->sc_if.if_unit = unit; 156126261Smlaier#else 157126261Smlaier if_initname(&sc->sc_if, ifc->ifc_name, unit); 158126261Smlaier#endif 159126261Smlaier sc->sc_if.if_ioctl = pfsyncioctl; 160126261Smlaier sc->sc_if.if_output = pfsyncoutput; 161126261Smlaier sc->sc_if.if_start = pfsyncstart; 162126261Smlaier sc->sc_if.if_type = IFT_PFSYNC; 163126261Smlaier sc->sc_if.if_snd.ifq_maxlen = ifqmaxlen; 164126261Smlaier sc->sc_if.if_hdrlen = PFSYNC_HDRLEN; 165126261Smlaier sc->sc_if.if_baudrate = IF_Mbps(100); 166126261Smlaier sc->sc_if.if_softc = sc; 167126261Smlaier pfsync_setmtu(sc, MCLBYTES); 168126261Smlaier /* 169126261Smlaier * XXX 170126261Smlaier * The 2nd arg. 0 to callout_init(9) shoule be set to CALLOUT_MPSAFE 171126261Smlaier * if Gaint lock is removed from the network stack. 172126261Smlaier */ 173126261Smlaier callout_init(&sc->sc_tmo, 0); 174126261Smlaier if_attach(&sc->sc_if); 175126261Smlaier 176126261Smlaier LIST_INSERT_HEAD(&pfsync_list, sc, sc_next); 177126261Smlaier#if NBPFILTER > 0 178126261Smlaier bpfattach(&sc->sc_if, DLT_PFSYNC, PFSYNC_HDRLEN); 179126261Smlaier#endif 180126261Smlaier 181126261Smlaier return (0); 182126261Smlaier} 183126261Smlaier#else /* !__FreeBSD__ */ 184126261Smlaiervoid 185126258Smlaierpfsyncattach(int npfsync) 186126258Smlaier{ 187126258Smlaier struct ifnet *ifp; 188126258Smlaier 189126258Smlaier pfsyncif.sc_mbuf = NULL; 190126258Smlaier pfsyncif.sc_ptr = NULL; 191126258Smlaier pfsyncif.sc_count = 8; 192126258Smlaier ifp = &pfsyncif.sc_if; 193126258Smlaier strlcpy(ifp->if_xname, "pfsync0", sizeof ifp->if_xname); 194126258Smlaier ifp->if_softc = &pfsyncif; 195126258Smlaier ifp->if_ioctl = pfsyncioctl; 196126258Smlaier ifp->if_output = pfsyncoutput; 197126258Smlaier ifp->if_start = pfsyncstart; 198126258Smlaier ifp->if_type = IFT_PFSYNC; 199126258Smlaier ifp->if_snd.ifq_maxlen = ifqmaxlen; 200126258Smlaier ifp->if_hdrlen = PFSYNC_HDRLEN; 201126258Smlaier ifp->if_baudrate = IF_Mbps(100); 202126258Smlaier pfsync_setmtu(&pfsyncif, MCLBYTES); 203126258Smlaier timeout_set(&pfsyncif.sc_tmo, pfsync_timeout, &pfsyncif); 204126258Smlaier if_attach(ifp); 205126258Smlaier if_alloc_sadl(ifp); 206126258Smlaier 207126258Smlaier#if NBPFILTER > 0 208126258Smlaier bpfattach(&pfsyncif.sc_if.if_bpf, ifp, DLT_PFSYNC, PFSYNC_HDRLEN); 209126258Smlaier#endif 210126258Smlaier} 211126261Smlaier#endif 212126258Smlaier 213126258Smlaier/* 214126258Smlaier * Start output on the pfsync interface. 215126258Smlaier */ 216126258Smlaiervoid 217126258Smlaierpfsyncstart(struct ifnet *ifp) 218126258Smlaier{ 219126258Smlaier struct mbuf *m; 220126261Smlaier#if defined(__FreeBSD__) && defined(ALTQ) 221126261Smlaier struct ifaltq *ifq; 222126261Smlaier#else 223126261Smlaier struct ifqueue *ifq; 224126261Smlaier#endif 225126258Smlaier int s; 226126258Smlaier 227127145Smlaier#ifdef __FreeBSD__ 228126261Smlaier ifq = &ifp->if_snd; 229126261Smlaier#endif 230126258Smlaier for (;;) { 231126258Smlaier s = splimp(); 232127145Smlaier#ifdef __FreeBSD__ 233126261Smlaier IF_LOCK(ifq); 234126261Smlaier _IF_DROP(ifq); 235126261Smlaier _IF_DEQUEUE(ifq, m); 236126261Smlaier IF_UNLOCK(ifq); 237126261Smlaier#else 238126258Smlaier IF_DROP(&ifp->if_snd); 239126258Smlaier IF_DEQUEUE(&ifp->if_snd, m); 240126261Smlaier#endif 241126258Smlaier splx(s); 242126258Smlaier 243126258Smlaier if (m == NULL) 244126258Smlaier return; 245126258Smlaier else 246126258Smlaier m_freem(m); 247126258Smlaier } 248126258Smlaier} 249126258Smlaier 250126258Smlaierint 251126258Smlaierpfsyncoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 252126258Smlaier struct rtentry *rt) 253126258Smlaier{ 254126258Smlaier m_freem(m); 255126258Smlaier return (0); 256126258Smlaier} 257126258Smlaier 258126258Smlaier/* ARGSUSED */ 259126258Smlaierint 260126258Smlaierpfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 261126258Smlaier{ 262126258Smlaier struct pfsync_softc *sc = ifp->if_softc; 263126258Smlaier struct ifreq *ifr = (struct ifreq *)data; 264126258Smlaier int s; 265126258Smlaier 266126258Smlaier switch (cmd) { 267126258Smlaier case SIOCSIFADDR: 268126258Smlaier case SIOCAIFADDR: 269126258Smlaier case SIOCSIFDSTADDR: 270126258Smlaier case SIOCSIFFLAGS: 271126258Smlaier if (ifp->if_flags & IFF_UP) 272126258Smlaier ifp->if_flags |= IFF_RUNNING; 273126258Smlaier else 274126258Smlaier ifp->if_flags &= ~IFF_RUNNING; 275126258Smlaier break; 276126258Smlaier case SIOCSIFMTU: 277126258Smlaier if (ifr->ifr_mtu < PFSYNC_MINMTU) 278126258Smlaier return (EINVAL); 279126258Smlaier if (ifr->ifr_mtu > MCLBYTES) 280126258Smlaier ifr->ifr_mtu = MCLBYTES; 281126258Smlaier s = splnet(); 282126258Smlaier if (ifr->ifr_mtu < ifp->if_mtu) 283126258Smlaier pfsync_sendout(sc); 284126258Smlaier pfsync_setmtu(sc, ifr->ifr_mtu); 285126258Smlaier splx(s); 286126258Smlaier break; 287126258Smlaier default: 288126258Smlaier return (ENOTTY); 289126258Smlaier } 290126258Smlaier 291126258Smlaier return (0); 292126258Smlaier} 293126258Smlaier 294126258Smlaiervoid 295126258Smlaierpfsync_setmtu(sc, mtu) 296126258Smlaier struct pfsync_softc *sc; 297126258Smlaier int mtu; 298126258Smlaier{ 299126258Smlaier sc->sc_count = (mtu - sizeof(struct pfsync_header)) / 300126258Smlaier sizeof(struct pf_state); 301126258Smlaier sc->sc_if.if_mtu = sizeof(struct pfsync_header) + 302126258Smlaier sc->sc_count * sizeof(struct pf_state); 303126258Smlaier} 304126258Smlaier 305126258Smlaierstruct mbuf * 306126258Smlaierpfsync_get_mbuf(sc, action) 307126258Smlaier struct pfsync_softc *sc; 308126258Smlaier u_int8_t action; 309126258Smlaier{ 310127145Smlaier#ifndef __FreeBSD__ 311126258Smlaier extern int hz; 312126261Smlaier#endif 313126258Smlaier struct pfsync_header *h; 314126258Smlaier struct mbuf *m; 315126258Smlaier int len; 316126258Smlaier 317126258Smlaier MGETHDR(m, M_DONTWAIT, MT_DATA); 318126258Smlaier if (m == NULL) { 319126258Smlaier sc->sc_if.if_oerrors++; 320126258Smlaier return (NULL); 321126258Smlaier } 322126258Smlaier 323126258Smlaier len = sc->sc_if.if_mtu; 324126258Smlaier if (len > MHLEN) { 325126258Smlaier MCLGET(m, M_DONTWAIT); 326126258Smlaier if ((m->m_flags & M_EXT) == 0) { 327126258Smlaier m_free(m); 328126258Smlaier sc->sc_if.if_oerrors++; 329126258Smlaier return (NULL); 330126258Smlaier } 331126258Smlaier } 332126258Smlaier m->m_pkthdr.rcvif = NULL; 333126258Smlaier m->m_pkthdr.len = m->m_len = len; 334126258Smlaier 335126258Smlaier h = mtod(m, struct pfsync_header *); 336126258Smlaier h->version = PFSYNC_VERSION; 337126258Smlaier h->af = 0; 338126258Smlaier h->count = 0; 339126258Smlaier h->action = action; 340126258Smlaier 341126258Smlaier sc->sc_mbuf = m; 342126258Smlaier sc->sc_ptr = (struct pf_state *)((char *)h + PFSYNC_HDRLEN); 343127145Smlaier#ifdef __FreeBSD__ 344126261Smlaier callout_reset(&sc->sc_tmo, hz, pfsync_timeout, 345126261Smlaier LIST_FIRST(&pfsync_list)); 346126261Smlaier#else 347126258Smlaier timeout_add(&sc->sc_tmo, hz); 348126261Smlaier#endif 349126258Smlaier 350126258Smlaier return (m); 351126258Smlaier} 352126258Smlaier 353126261Smlaier/* 354126261Smlaier * XXX: This function should be called with PF_LOCK held as it references 355126261Smlaier * pf_state. 356126261Smlaier */ 357126258Smlaierint 358126258Smlaierpfsync_pack_state(action, st) 359126258Smlaier u_int8_t action; 360126258Smlaier struct pf_state *st; 361126258Smlaier{ 362127145Smlaier#ifdef __FreeBSD__ 363126261Smlaier struct pfsync_softc *sc = LIST_FIRST(&pfsync_list); 364126261Smlaier#else 365126258Smlaier extern struct timeval time; 366126258Smlaier struct ifnet *ifp = &pfsyncif.sc_if; 367126258Smlaier struct pfsync_softc *sc = ifp->if_softc; 368126261Smlaier#endif 369126258Smlaier struct pfsync_header *h; 370126258Smlaier struct pf_state *sp; 371126258Smlaier struct pf_rule *r = st->rule.ptr; 372126258Smlaier struct mbuf *m; 373126258Smlaier u_long secs; 374126258Smlaier int s, ret; 375126258Smlaier 376126258Smlaier if (action >= PFSYNC_ACT_MAX) 377126258Smlaier return (EINVAL); 378126258Smlaier 379127145Smlaier#ifdef __FreeBSD__ 380126261Smlaier /* 381126261Smlaier * XXX 382126261Smlaier * If we need to check mutex owned, PF_LOCK should be 383127145Smlaier * declared in pflog.ko. 384126261Smlaier * 385126261Smlaier * PF_LOCK_ASSERT(); 386126261Smlaier */ 387126261Smlaier KASSERT((!LIST_EMPTY(&pfsync_list)), ("pfsync: no interface")); 388126261Smlaier#endif 389126258Smlaier s = splnet(); 390126258Smlaier m = sc->sc_mbuf; 391126258Smlaier if (m == NULL) { 392126258Smlaier if ((m = pfsync_get_mbuf(sc, action)) == NULL) { 393126258Smlaier splx(s); 394126258Smlaier return (ENOMEM); 395126258Smlaier } 396126258Smlaier h = mtod(m, struct pfsync_header *); 397126258Smlaier } else { 398126258Smlaier h = mtod(m, struct pfsync_header *); 399126258Smlaier if (h->action != action) { 400126258Smlaier pfsync_sendout(sc); 401126258Smlaier if ((m = pfsync_get_mbuf(sc, action)) == NULL) { 402126258Smlaier splx(s); 403126258Smlaier return (ENOMEM); 404126258Smlaier } 405126258Smlaier h = mtod(m, struct pfsync_header *); 406126258Smlaier } 407126258Smlaier } 408126258Smlaier 409126258Smlaier sp = sc->sc_ptr++; 410126258Smlaier h->count++; 411126258Smlaier bzero(sp, sizeof(*sp)); 412126258Smlaier 413126258Smlaier bcopy(&st->lan, &sp->lan, sizeof(sp->lan)); 414126258Smlaier bcopy(&st->gwy, &sp->gwy, sizeof(sp->gwy)); 415126258Smlaier bcopy(&st->ext, &sp->ext, sizeof(sp->ext)); 416126258Smlaier 417126258Smlaier pf_state_peer_hton(&st->src, &sp->src); 418126258Smlaier pf_state_peer_hton(&st->dst, &sp->dst); 419126258Smlaier 420126258Smlaier bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr)); 421127145Smlaier#ifdef __FreeBSD__ 422126261Smlaier secs = time_second; 423126261Smlaier#else 424126258Smlaier secs = time.tv_sec; 425126261Smlaier#endif 426126258Smlaier sp->creation = htonl(secs - st->creation); 427126258Smlaier if (st->expire <= secs) 428126258Smlaier sp->expire = htonl(0); 429126258Smlaier else 430126258Smlaier sp->expire = htonl(st->expire - secs); 431126258Smlaier sp->packets[0] = htonl(st->packets[0]); 432126258Smlaier sp->packets[1] = htonl(st->packets[1]); 433126258Smlaier sp->bytes[0] = htonl(st->bytes[0]); 434126258Smlaier sp->bytes[1] = htonl(st->bytes[1]); 435126258Smlaier if (r == NULL) 436126258Smlaier sp->rule.nr = htonl(-1); 437126258Smlaier else 438126258Smlaier sp->rule.nr = htonl(r->nr); 439126258Smlaier sp->af = st->af; 440126258Smlaier sp->proto = st->proto; 441126258Smlaier sp->direction = st->direction; 442126258Smlaier sp->log = st->log; 443126258Smlaier sp->allow_opts = st->allow_opts; 444126258Smlaier 445126258Smlaier ret = 0; 446126258Smlaier if (h->count == sc->sc_count) 447126258Smlaier ret = pfsync_sendout(sc); 448126258Smlaier 449126258Smlaier splx(s); 450126258Smlaier return (0); 451126258Smlaier} 452126258Smlaier 453126258Smlaierint 454126258Smlaierpfsync_clear_state(st) 455126258Smlaier struct pf_state *st; 456126258Smlaier{ 457127145Smlaier#ifdef __FreeBSD__ 458126261Smlaier struct pfsync_softc *sc = LIST_FIRST(&pfsync_list); 459126261Smlaier#else 460126258Smlaier struct ifnet *ifp = &pfsyncif.sc_if; 461126258Smlaier struct pfsync_softc *sc = ifp->if_softc; 462126261Smlaier#endif 463126258Smlaier struct mbuf *m = sc->sc_mbuf; 464126258Smlaier int s, ret; 465126258Smlaier 466126258Smlaier s = splnet(); 467126258Smlaier if (m == NULL && (m = pfsync_get_mbuf(sc, PFSYNC_ACT_CLR)) == NULL) { 468126258Smlaier splx(s); 469126258Smlaier return (ENOMEM); 470126258Smlaier } 471126258Smlaier 472126258Smlaier ret = (pfsync_sendout(sc)); 473126258Smlaier splx(s); 474126258Smlaier return (ret); 475126258Smlaier} 476126258Smlaier 477126258Smlaiervoid 478126258Smlaierpfsync_timeout(void *v) 479126258Smlaier{ 480126258Smlaier struct pfsync_softc *sc = v; 481126258Smlaier int s; 482126258Smlaier 483126261Smlaier /* We don't need PF_LOCK/PF_UNLOCK here! */ 484126258Smlaier s = splnet(); 485126258Smlaier pfsync_sendout(sc); 486126258Smlaier splx(s); 487126258Smlaier} 488126258Smlaier 489126258Smlaierint 490126258Smlaierpfsync_sendout(sc) 491126258Smlaier struct pfsync_softc *sc; 492126258Smlaier{ 493126258Smlaier struct ifnet *ifp = &sc->sc_if; 494126258Smlaier struct mbuf *m = sc->sc_mbuf; 495126258Smlaier 496127145Smlaier#ifdef __FreeBSD__ 497126261Smlaier callout_stop(&sc->sc_tmo); 498126261Smlaier#else 499126258Smlaier timeout_del(&sc->sc_tmo); 500126261Smlaier#endif 501126258Smlaier sc->sc_mbuf = NULL; 502126258Smlaier sc->sc_ptr = NULL; 503126258Smlaier 504127145Smlaier#ifdef __FreeBSD__ 505126261Smlaier KASSERT(m != NULL, ("pfsync_sendout: null mbuf")); 506126261Smlaier#endif 507126258Smlaier#if NBPFILTER > 0 508126258Smlaier if (ifp->if_bpf) 509126258Smlaier bpf_mtap(ifp->if_bpf, m); 510126258Smlaier#endif 511126258Smlaier 512126258Smlaier m_freem(m); 513126258Smlaier 514126258Smlaier return (0); 515126258Smlaier} 516126261Smlaier 517126261Smlaier 518127145Smlaier#ifdef __FreeBSD__ 519126261Smlaierstatic int 520126261Smlaierpfsync_modevent(module_t mod, int type, void *data) 521126261Smlaier{ 522126261Smlaier int error = 0; 523126261Smlaier 524126261Smlaier switch (type) { 525126261Smlaier case MOD_LOAD: 526126261Smlaier LIST_INIT(&pfsync_list); 527126261Smlaier if_clone_attach(&pfsync_cloner); 528126261Smlaier break; 529126261Smlaier 530126261Smlaier case MOD_UNLOAD: 531126261Smlaier if_clone_detach(&pfsync_cloner); 532126261Smlaier while (!LIST_EMPTY(&pfsync_list)) 533126261Smlaier pfsync_clone_destroy( 534126261Smlaier &LIST_FIRST(&pfsync_list)->sc_if); 535126261Smlaier break; 536126261Smlaier 537126261Smlaier default: 538126261Smlaier error = EINVAL; 539126261Smlaier break; 540126261Smlaier } 541126261Smlaier 542126261Smlaier return error; 543126261Smlaier} 544126261Smlaier 545126261Smlaierstatic moduledata_t pfsync_mod = { 546126261Smlaier "pfsync", 547126261Smlaier pfsync_modevent, 548126261Smlaier 0 549126261Smlaier}; 550126261Smlaier 551126261Smlaier#define PFSYNC_MODVER 1 552126261Smlaier 553126261SmlaierDECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 554126261SmlaierMODULE_VERSION(pfsync, PFSYNC_MODVER); 555126261Smlaier#endif /* __FreeBSD__ */ 556