if_pfsync.c revision 126261
1126261Smlaier/* $FreeBSD: head/sys/contrib/pf/net/if_pfsync.c 126261 2004-02-26 02:34:12Z 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 30126261Smlaier#if defined(__FreeBSD__) && __FreeBSD__ >= 5 31126261Smlaier#include "opt_inet.h" 32126261Smlaier#include "opt_inet6.h" 33126261Smlaier#endif 34126261Smlaier 35126261Smlaier#if !defined(__FreeBSD__) 36126258Smlaier#include "bpfilter.h" 37126258Smlaier#include "pfsync.h" 38126261Smlaier#elif __FreeBSD__ >= 5 39126261Smlaier#include "opt_bpf.h" 40126261Smlaier#define NBPFILTER DEV_BPF 41126261Smlaier#include "opt_pf.h" 42126261Smlaier#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> 50126261Smlaier#if defined(__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 79126261Smlaier#if defined(__FreeBSD__) 80126261Smlaier#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 93126261Smlaier#if !defined(__FreeBSD__) 94126258Smlaierstruct pfsync_softc pfsyncif; 95126261Smlaier#endif 96126258Smlaier 97126261Smlaier#if defined(__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 113126261Smlaier#if !defined(__FreeBSD__) 114126258Smlaierextern int ifqmaxlen; 115126261Smlaier#endif 116126258Smlaier 117126261Smlaier#if defined(__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#endif /* __FreeBSD__ */ 144126261Smlaier 145126261Smlaier#if defined(__FreeBSD__) 146126261Smlaierint 147126261Smlaierpfsync_clone_create(struct if_clone *ifc, int unit) 148126261Smlaier{ 149126261Smlaier struct pfsync_softc *sc; 150126261Smlaier 151126261Smlaier MALLOC(sc, struct pfsync_softc *, sizeof(*sc), M_PFSYNC, 152126261Smlaier M_WAITOK|M_ZERO); 153126261Smlaier 154126261Smlaier sc->sc_count = 8; 155126261Smlaier#if (__FreeBSD_version < 501113) 156126261Smlaier sc->sc_if.if_name = PFSYNCNAME; 157126261Smlaier sc->sc_if.if_unit = unit; 158126261Smlaier#else 159126261Smlaier if_initname(&sc->sc_if, ifc->ifc_name, unit); 160126261Smlaier#endif 161126261Smlaier sc->sc_if.if_ioctl = pfsyncioctl; 162126261Smlaier sc->sc_if.if_output = pfsyncoutput; 163126261Smlaier sc->sc_if.if_start = pfsyncstart; 164126261Smlaier sc->sc_if.if_type = IFT_PFSYNC; 165126261Smlaier sc->sc_if.if_snd.ifq_maxlen = ifqmaxlen; 166126261Smlaier sc->sc_if.if_hdrlen = PFSYNC_HDRLEN; 167126261Smlaier sc->sc_if.if_baudrate = IF_Mbps(100); 168126261Smlaier sc->sc_if.if_softc = sc; 169126261Smlaier pfsync_setmtu(sc, MCLBYTES); 170126261Smlaier /* 171126261Smlaier * XXX 172126261Smlaier * The 2nd arg. 0 to callout_init(9) shoule be set to CALLOUT_MPSAFE 173126261Smlaier * if Gaint lock is removed from the network stack. 174126261Smlaier */ 175126261Smlaier callout_init(&sc->sc_tmo, 0); 176126261Smlaier if_attach(&sc->sc_if); 177126261Smlaier 178126261Smlaier LIST_INSERT_HEAD(&pfsync_list, sc, sc_next); 179126261Smlaier#if NBPFILTER > 0 180126261Smlaier bpfattach(&sc->sc_if, DLT_PFSYNC, PFSYNC_HDRLEN); 181126261Smlaier#endif 182126261Smlaier 183126261Smlaier return (0); 184126261Smlaier} 185126261Smlaier#else /* !__FreeBSD__ */ 186126261Smlaiervoid 187126258Smlaierpfsyncattach(int npfsync) 188126258Smlaier{ 189126258Smlaier struct ifnet *ifp; 190126258Smlaier 191126258Smlaier pfsyncif.sc_mbuf = NULL; 192126258Smlaier pfsyncif.sc_ptr = NULL; 193126258Smlaier pfsyncif.sc_count = 8; 194126258Smlaier ifp = &pfsyncif.sc_if; 195126258Smlaier strlcpy(ifp->if_xname, "pfsync0", sizeof ifp->if_xname); 196126258Smlaier ifp->if_softc = &pfsyncif; 197126258Smlaier ifp->if_ioctl = pfsyncioctl; 198126258Smlaier ifp->if_output = pfsyncoutput; 199126258Smlaier ifp->if_start = pfsyncstart; 200126258Smlaier ifp->if_type = IFT_PFSYNC; 201126258Smlaier ifp->if_snd.ifq_maxlen = ifqmaxlen; 202126258Smlaier ifp->if_hdrlen = PFSYNC_HDRLEN; 203126258Smlaier ifp->if_baudrate = IF_Mbps(100); 204126258Smlaier pfsync_setmtu(&pfsyncif, MCLBYTES); 205126258Smlaier timeout_set(&pfsyncif.sc_tmo, pfsync_timeout, &pfsyncif); 206126258Smlaier if_attach(ifp); 207126258Smlaier if_alloc_sadl(ifp); 208126258Smlaier 209126258Smlaier#if NBPFILTER > 0 210126258Smlaier bpfattach(&pfsyncif.sc_if.if_bpf, ifp, DLT_PFSYNC, PFSYNC_HDRLEN); 211126258Smlaier#endif 212126258Smlaier} 213126261Smlaier#endif 214126258Smlaier 215126258Smlaier/* 216126258Smlaier * Start output on the pfsync interface. 217126258Smlaier */ 218126258Smlaiervoid 219126258Smlaierpfsyncstart(struct ifnet *ifp) 220126258Smlaier{ 221126258Smlaier struct mbuf *m; 222126261Smlaier#if defined(__FreeBSD__) && defined(ALTQ) 223126261Smlaier struct ifaltq *ifq; 224126261Smlaier#else 225126261Smlaier struct ifqueue *ifq; 226126261Smlaier#endif 227126258Smlaier int s; 228126258Smlaier 229126261Smlaier#if defined(__FreeBSD__) 230126261Smlaier ifq = &ifp->if_snd; 231126261Smlaier#endif 232126258Smlaier for (;;) { 233126258Smlaier s = splimp(); 234126261Smlaier#if defined(__FreeBSD__) 235126261Smlaier IF_LOCK(ifq); 236126261Smlaier _IF_DROP(ifq); 237126261Smlaier _IF_DEQUEUE(ifq, m); 238126261Smlaier IF_UNLOCK(ifq); 239126261Smlaier#else 240126258Smlaier IF_DROP(&ifp->if_snd); 241126258Smlaier IF_DEQUEUE(&ifp->if_snd, m); 242126261Smlaier#endif 243126258Smlaier splx(s); 244126258Smlaier 245126258Smlaier if (m == NULL) 246126258Smlaier return; 247126258Smlaier else 248126258Smlaier m_freem(m); 249126258Smlaier } 250126258Smlaier} 251126258Smlaier 252126258Smlaierint 253126258Smlaierpfsyncoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 254126258Smlaier struct rtentry *rt) 255126258Smlaier{ 256126258Smlaier m_freem(m); 257126258Smlaier return (0); 258126258Smlaier} 259126258Smlaier 260126258Smlaier/* ARGSUSED */ 261126258Smlaierint 262126258Smlaierpfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 263126258Smlaier{ 264126258Smlaier struct pfsync_softc *sc = ifp->if_softc; 265126258Smlaier struct ifreq *ifr = (struct ifreq *)data; 266126258Smlaier int s; 267126258Smlaier 268126258Smlaier switch (cmd) { 269126258Smlaier case SIOCSIFADDR: 270126258Smlaier case SIOCAIFADDR: 271126258Smlaier case SIOCSIFDSTADDR: 272126258Smlaier case SIOCSIFFLAGS: 273126258Smlaier if (ifp->if_flags & IFF_UP) 274126258Smlaier ifp->if_flags |= IFF_RUNNING; 275126258Smlaier else 276126258Smlaier ifp->if_flags &= ~IFF_RUNNING; 277126258Smlaier break; 278126258Smlaier case SIOCSIFMTU: 279126258Smlaier if (ifr->ifr_mtu < PFSYNC_MINMTU) 280126258Smlaier return (EINVAL); 281126258Smlaier if (ifr->ifr_mtu > MCLBYTES) 282126258Smlaier ifr->ifr_mtu = MCLBYTES; 283126258Smlaier s = splnet(); 284126258Smlaier if (ifr->ifr_mtu < ifp->if_mtu) 285126258Smlaier pfsync_sendout(sc); 286126258Smlaier pfsync_setmtu(sc, ifr->ifr_mtu); 287126258Smlaier splx(s); 288126258Smlaier break; 289126258Smlaier default: 290126258Smlaier return (ENOTTY); 291126258Smlaier } 292126258Smlaier 293126258Smlaier return (0); 294126258Smlaier} 295126258Smlaier 296126258Smlaiervoid 297126258Smlaierpfsync_setmtu(sc, mtu) 298126258Smlaier struct pfsync_softc *sc; 299126258Smlaier int mtu; 300126258Smlaier{ 301126258Smlaier sc->sc_count = (mtu - sizeof(struct pfsync_header)) / 302126258Smlaier sizeof(struct pf_state); 303126258Smlaier sc->sc_if.if_mtu = sizeof(struct pfsync_header) + 304126258Smlaier sc->sc_count * sizeof(struct pf_state); 305126258Smlaier} 306126258Smlaier 307126258Smlaierstruct mbuf * 308126258Smlaierpfsync_get_mbuf(sc, action) 309126258Smlaier struct pfsync_softc *sc; 310126258Smlaier u_int8_t action; 311126258Smlaier{ 312126261Smlaier#if !defined(__FreeBSD__) 313126258Smlaier extern int hz; 314126261Smlaier#endif 315126258Smlaier struct pfsync_header *h; 316126258Smlaier struct mbuf *m; 317126258Smlaier int len; 318126258Smlaier 319126258Smlaier MGETHDR(m, M_DONTWAIT, MT_DATA); 320126258Smlaier if (m == NULL) { 321126258Smlaier sc->sc_if.if_oerrors++; 322126258Smlaier return (NULL); 323126258Smlaier } 324126258Smlaier 325126258Smlaier len = sc->sc_if.if_mtu; 326126258Smlaier if (len > MHLEN) { 327126258Smlaier MCLGET(m, M_DONTWAIT); 328126258Smlaier if ((m->m_flags & M_EXT) == 0) { 329126258Smlaier m_free(m); 330126258Smlaier sc->sc_if.if_oerrors++; 331126258Smlaier return (NULL); 332126258Smlaier } 333126258Smlaier } 334126258Smlaier m->m_pkthdr.rcvif = NULL; 335126258Smlaier m->m_pkthdr.len = m->m_len = len; 336126258Smlaier 337126258Smlaier h = mtod(m, struct pfsync_header *); 338126258Smlaier h->version = PFSYNC_VERSION; 339126258Smlaier h->af = 0; 340126258Smlaier h->count = 0; 341126258Smlaier h->action = action; 342126258Smlaier 343126258Smlaier sc->sc_mbuf = m; 344126258Smlaier sc->sc_ptr = (struct pf_state *)((char *)h + PFSYNC_HDRLEN); 345126261Smlaier#if defined(__FreeBSD__) 346126261Smlaier callout_reset(&sc->sc_tmo, hz, pfsync_timeout, 347126261Smlaier LIST_FIRST(&pfsync_list)); 348126261Smlaier#else 349126258Smlaier timeout_add(&sc->sc_tmo, hz); 350126261Smlaier#endif 351126258Smlaier 352126258Smlaier return (m); 353126258Smlaier} 354126258Smlaier 355126261Smlaier/* 356126261Smlaier * XXX: This function should be called with PF_LOCK held as it references 357126261Smlaier * pf_state. 358126261Smlaier */ 359126258Smlaierint 360126258Smlaierpfsync_pack_state(action, st) 361126258Smlaier u_int8_t action; 362126258Smlaier struct pf_state *st; 363126258Smlaier{ 364126261Smlaier#if defined(__FreeBSD__) 365126261Smlaier struct pfsync_softc *sc = LIST_FIRST(&pfsync_list); 366126261Smlaier#else 367126258Smlaier extern struct timeval time; 368126258Smlaier struct ifnet *ifp = &pfsyncif.sc_if; 369126258Smlaier struct pfsync_softc *sc = ifp->if_softc; 370126261Smlaier#endif 371126258Smlaier struct pfsync_header *h; 372126258Smlaier struct pf_state *sp; 373126258Smlaier struct pf_rule *r = st->rule.ptr; 374126258Smlaier struct mbuf *m; 375126258Smlaier u_long secs; 376126258Smlaier int s, ret; 377126258Smlaier 378126258Smlaier if (action >= PFSYNC_ACT_MAX) 379126258Smlaier return (EINVAL); 380126258Smlaier 381126261Smlaier#if defined(__FreeBSD__) 382126261Smlaier /* 383126261Smlaier * XXX 384126261Smlaier * If we need to check mutex owned, PF_LOCK should be 385126261Smlaier * declared in pflog.ko. :-( 386126261Smlaier * 387126261Smlaier * PF_LOCK_ASSERT(); 388126261Smlaier */ 389126261Smlaier KASSERT((!LIST_EMPTY(&pfsync_list)), ("pfsync: no interface")); 390126261Smlaier#endif 391126258Smlaier s = splnet(); 392126258Smlaier m = sc->sc_mbuf; 393126258Smlaier if (m == NULL) { 394126258Smlaier if ((m = pfsync_get_mbuf(sc, action)) == NULL) { 395126258Smlaier splx(s); 396126258Smlaier return (ENOMEM); 397126258Smlaier } 398126258Smlaier h = mtod(m, struct pfsync_header *); 399126258Smlaier } else { 400126258Smlaier h = mtod(m, struct pfsync_header *); 401126258Smlaier if (h->action != action) { 402126258Smlaier pfsync_sendout(sc); 403126258Smlaier if ((m = pfsync_get_mbuf(sc, action)) == NULL) { 404126258Smlaier splx(s); 405126258Smlaier return (ENOMEM); 406126258Smlaier } 407126258Smlaier h = mtod(m, struct pfsync_header *); 408126258Smlaier } 409126258Smlaier } 410126258Smlaier 411126258Smlaier sp = sc->sc_ptr++; 412126258Smlaier h->count++; 413126258Smlaier bzero(sp, sizeof(*sp)); 414126258Smlaier 415126258Smlaier bcopy(&st->lan, &sp->lan, sizeof(sp->lan)); 416126258Smlaier bcopy(&st->gwy, &sp->gwy, sizeof(sp->gwy)); 417126258Smlaier bcopy(&st->ext, &sp->ext, sizeof(sp->ext)); 418126258Smlaier 419126258Smlaier pf_state_peer_hton(&st->src, &sp->src); 420126258Smlaier pf_state_peer_hton(&st->dst, &sp->dst); 421126258Smlaier 422126258Smlaier bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr)); 423126261Smlaier#if defined(__FreeBSD__) 424126261Smlaier secs = time_second; 425126261Smlaier#else 426126258Smlaier secs = time.tv_sec; 427126261Smlaier#endif 428126258Smlaier sp->creation = htonl(secs - st->creation); 429126258Smlaier if (st->expire <= secs) 430126258Smlaier sp->expire = htonl(0); 431126258Smlaier else 432126258Smlaier sp->expire = htonl(st->expire - secs); 433126258Smlaier sp->packets[0] = htonl(st->packets[0]); 434126258Smlaier sp->packets[1] = htonl(st->packets[1]); 435126258Smlaier sp->bytes[0] = htonl(st->bytes[0]); 436126258Smlaier sp->bytes[1] = htonl(st->bytes[1]); 437126258Smlaier if (r == NULL) 438126258Smlaier sp->rule.nr = htonl(-1); 439126258Smlaier else 440126258Smlaier sp->rule.nr = htonl(r->nr); 441126258Smlaier sp->af = st->af; 442126258Smlaier sp->proto = st->proto; 443126258Smlaier sp->direction = st->direction; 444126258Smlaier sp->log = st->log; 445126258Smlaier sp->allow_opts = st->allow_opts; 446126258Smlaier 447126258Smlaier ret = 0; 448126258Smlaier if (h->count == sc->sc_count) 449126258Smlaier ret = pfsync_sendout(sc); 450126258Smlaier 451126258Smlaier splx(s); 452126258Smlaier return (0); 453126258Smlaier} 454126258Smlaier 455126258Smlaierint 456126258Smlaierpfsync_clear_state(st) 457126258Smlaier struct pf_state *st; 458126258Smlaier{ 459126261Smlaier#if defined(__FreeBSD__) 460126261Smlaier struct pfsync_softc *sc = LIST_FIRST(&pfsync_list); 461126261Smlaier#else 462126258Smlaier struct ifnet *ifp = &pfsyncif.sc_if; 463126258Smlaier struct pfsync_softc *sc = ifp->if_softc; 464126261Smlaier#endif 465126258Smlaier struct mbuf *m = sc->sc_mbuf; 466126258Smlaier int s, ret; 467126258Smlaier 468126258Smlaier s = splnet(); 469126258Smlaier if (m == NULL && (m = pfsync_get_mbuf(sc, PFSYNC_ACT_CLR)) == NULL) { 470126258Smlaier splx(s); 471126258Smlaier return (ENOMEM); 472126258Smlaier } 473126258Smlaier 474126258Smlaier ret = (pfsync_sendout(sc)); 475126258Smlaier splx(s); 476126258Smlaier return (ret); 477126258Smlaier} 478126258Smlaier 479126258Smlaiervoid 480126258Smlaierpfsync_timeout(void *v) 481126258Smlaier{ 482126258Smlaier struct pfsync_softc *sc = v; 483126258Smlaier int s; 484126258Smlaier 485126261Smlaier /* We don't need PF_LOCK/PF_UNLOCK here! */ 486126258Smlaier s = splnet(); 487126258Smlaier pfsync_sendout(sc); 488126258Smlaier splx(s); 489126258Smlaier} 490126258Smlaier 491126258Smlaierint 492126258Smlaierpfsync_sendout(sc) 493126258Smlaier struct pfsync_softc *sc; 494126258Smlaier{ 495126258Smlaier struct ifnet *ifp = &sc->sc_if; 496126258Smlaier struct mbuf *m = sc->sc_mbuf; 497126258Smlaier 498126261Smlaier#if defined(__FreeBSD__) 499126261Smlaier callout_stop(&sc->sc_tmo); 500126261Smlaier#else 501126258Smlaier timeout_del(&sc->sc_tmo); 502126261Smlaier#endif 503126258Smlaier sc->sc_mbuf = NULL; 504126258Smlaier sc->sc_ptr = NULL; 505126258Smlaier 506126261Smlaier#if defined(__FreeBSD__) 507126261Smlaier KASSERT(m != NULL, ("pfsync_sendout: null mbuf")); 508126261Smlaier#endif 509126258Smlaier#if NBPFILTER > 0 510126258Smlaier if (ifp->if_bpf) 511126258Smlaier bpf_mtap(ifp->if_bpf, m); 512126258Smlaier#endif 513126258Smlaier 514126258Smlaier m_freem(m); 515126258Smlaier 516126258Smlaier return (0); 517126258Smlaier} 518126261Smlaier 519126261Smlaier 520126261Smlaier#if defined(__FreeBSD__) 521126261Smlaierstatic int 522126261Smlaierpfsync_modevent(module_t mod, int type, void *data) 523126261Smlaier{ 524126261Smlaier int error = 0; 525126261Smlaier 526126261Smlaier switch (type) { 527126261Smlaier case MOD_LOAD: 528126261Smlaier LIST_INIT(&pfsync_list); 529126261Smlaier if_clone_attach(&pfsync_cloner); 530126261Smlaier printf("pfsync: $Name: $\n"); 531126261Smlaier break; 532126261Smlaier 533126261Smlaier case MOD_UNLOAD: 534126261Smlaier if_clone_detach(&pfsync_cloner); 535126261Smlaier while (!LIST_EMPTY(&pfsync_list)) 536126261Smlaier pfsync_clone_destroy( 537126261Smlaier &LIST_FIRST(&pfsync_list)->sc_if); 538126261Smlaier break; 539126261Smlaier 540126261Smlaier default: 541126261Smlaier error = EINVAL; 542126261Smlaier break; 543126261Smlaier } 544126261Smlaier 545126261Smlaier return error; 546126261Smlaier} 547126261Smlaier 548126261Smlaierstatic moduledata_t pfsync_mod = { 549126261Smlaier "pfsync", 550126261Smlaier pfsync_modevent, 551126261Smlaier 0 552126261Smlaier}; 553126261Smlaier 554126261Smlaier#define PFSYNC_MODVER 1 555126261Smlaier 556126261SmlaierDECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 557126261SmlaierMODULE_VERSION(pfsync, PFSYNC_MODVER); 558126261Smlaier#endif /* __FreeBSD__ */ 559