Deleted Added
full compact
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__ */