Deleted Added
full compact
if_pfsync.c (141584) if_pfsync.c (145836)
1/* $FreeBSD: head/sys/contrib/pf/net/if_pfsync.c 141584 2005-02-09 19:29:13Z mlaier $ */
2/* $OpenBSD: if_pfsync.c,v 1.26 2004/03/28 18:14:20 mcbride Exp $ */
1/* $FreeBSD: head/sys/contrib/pf/net/if_pfsync.c 145836 2005-05-03 16:43:32Z mlaier $ */
2/* $OpenBSD: if_pfsync.c,v 1.46 2005/02/20 15:58:38 mcbride 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
10 * are met:

--- 32 unchanged lines hidden (view full) ---

43#endif
44
45#include <sys/param.h>
46#include <sys/proc.h>
47#include <sys/systm.h>
48#include <sys/time.h>
49#include <sys/mbuf.h>
50#include <sys/socket.h>
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
10 * are met:

--- 32 unchanged lines hidden (view full) ---

43#endif
44
45#include <sys/param.h>
46#include <sys/proc.h>
47#include <sys/systm.h>
48#include <sys/time.h>
49#include <sys/mbuf.h>
50#include <sys/socket.h>
51#ifdef __FreeBSD__
52#include <sys/kernel.h>
51#include <sys/kernel.h>
52#ifdef __FreeBSD__
53#include <sys/endian.h>
53#include <sys/malloc.h>
54#include <sys/module.h>
55#include <sys/sockio.h>
56#include <sys/lock.h>
57#include <sys/mutex.h>
58#else
59#include <sys/ioctl.h>
60#include <sys/timeout.h>
61#endif
62
63#include <net/if.h>
64#if defined(__FreeBSD__)
65#include <net/if_clone.h>
66#endif
67#include <net/if_types.h>
68#include <net/route.h>
69#include <net/bpf.h>
54#include <sys/malloc.h>
55#include <sys/module.h>
56#include <sys/sockio.h>
57#include <sys/lock.h>
58#include <sys/mutex.h>
59#else
60#include <sys/ioctl.h>
61#include <sys/timeout.h>
62#endif
63
64#include <net/if.h>
65#if defined(__FreeBSD__)
66#include <net/if_clone.h>
67#endif
68#include <net/if_types.h>
69#include <net/route.h>
70#include <net/bpf.h>
71#include <netinet/tcp.h>
72#include <netinet/tcp_seq.h>
70
71#ifdef INET
72#include <netinet/in.h>
73#include <netinet/in_systm.h>
74#include <netinet/in_var.h>
75#include <netinet/ip.h>
76#include <netinet/ip_var.h>
77#endif
78
79#ifdef INET6
80#ifndef INET
81#include <netinet/in.h>
82#endif
83#include <netinet6/nd6.h>
84#endif /* INET6 */
85
73
74#ifdef INET
75#include <netinet/in.h>
76#include <netinet/in_systm.h>
77#include <netinet/in_var.h>
78#include <netinet/ip.h>
79#include <netinet/ip_var.h>
80#endif
81
82#ifdef INET6
83#ifndef INET
84#include <netinet/in.h>
85#endif
86#include <netinet6/nd6.h>
87#endif /* INET6 */
88
89#ifdef __FreeBSD__
90#include "opt_carp.h"
91#ifdef DEV_CARP
92#define NCARP 1
93#endif
94#else
95#include "carp.h"
96#endif
97#if NCARP > 0
98extern int carp_suppress_preempt;
99#endif
100
86#include <net/pfvar.h>
87#include <net/if_pfsync.h>
88
89#ifdef __FreeBSD__
90#define PFSYNCNAME "pfsync"
91#endif
92
93#define PFSYNC_MINMTU \

--- 4 unchanged lines hidden (view full) ---

98int pfsyncdebug;
99#else
100#define DPRINTF(x)
101#endif
102
103#ifndef __FreeBSD__
104struct pfsync_softc pfsyncif;
105#endif
101#include <net/pfvar.h>
102#include <net/if_pfsync.h>
103
104#ifdef __FreeBSD__
105#define PFSYNCNAME "pfsync"
106#endif
107
108#define PFSYNC_MINMTU \

--- 4 unchanged lines hidden (view full) ---

113int pfsyncdebug;
114#else
115#define DPRINTF(x)
116#endif
117
118#ifndef __FreeBSD__
119struct pfsync_softc pfsyncif;
120#endif
106int pfsync_sync_ok;
107struct pfsyncstats pfsyncstats;
108
109#ifdef __FreeBSD__
110
111/*
112 * Locking notes:
113 * Whenever we really touch/look at the state table we have to hold the
114 * PF_LOCK. Functions that do just the interface handling, grab the per

--- 16 unchanged lines hidden (view full) ---

131struct mbuf *pfsync_get_mbuf(struct pfsync_softc *, u_int8_t, void **);
132int pfsync_request_update(struct pfsync_state_upd *, struct in_addr *);
133int pfsync_sendout(struct pfsync_softc *);
134void pfsync_timeout(void *);
135void pfsync_send_bus(struct pfsync_softc *, u_int8_t);
136void pfsync_bulk_update(void *);
137void pfsync_bulkfail(void *);
138
121struct pfsyncstats pfsyncstats;
122
123#ifdef __FreeBSD__
124
125/*
126 * Locking notes:
127 * Whenever we really touch/look at the state table we have to hold the
128 * PF_LOCK. Functions that do just the interface handling, grab the per

--- 16 unchanged lines hidden (view full) ---

145struct mbuf *pfsync_get_mbuf(struct pfsync_softc *, u_int8_t, void **);
146int pfsync_request_update(struct pfsync_state_upd *, struct in_addr *);
147int pfsync_sendout(struct pfsync_softc *);
148void pfsync_timeout(void *);
149void pfsync_send_bus(struct pfsync_softc *, u_int8_t);
150void pfsync_bulk_update(void *);
151void pfsync_bulkfail(void *);
152
153int pfsync_sync_ok;
139#ifndef __FreeBSD__
140extern int ifqmaxlen;
141extern struct timeval time;
142extern struct timeval mono_time;
143extern int hz;
144#endif
145
146#ifdef __FreeBSD__

--- 75 unchanged lines hidden (view full) ---

222
223 pfsync_sync_ok = 1;
224 bzero(&pfsyncif, sizeof(pfsyncif));
225 pfsyncif.sc_mbuf = NULL;
226 pfsyncif.sc_mbuf_net = NULL;
227 pfsyncif.sc_statep.s = NULL;
228 pfsyncif.sc_statep_net.s = NULL;
229 pfsyncif.sc_maxupdates = 128;
154#ifndef __FreeBSD__
155extern int ifqmaxlen;
156extern struct timeval time;
157extern struct timeval mono_time;
158extern int hz;
159#endif
160
161#ifdef __FreeBSD__

--- 75 unchanged lines hidden (view full) ---

237
238 pfsync_sync_ok = 1;
239 bzero(&pfsyncif, sizeof(pfsyncif));
240 pfsyncif.sc_mbuf = NULL;
241 pfsyncif.sc_mbuf_net = NULL;
242 pfsyncif.sc_statep.s = NULL;
243 pfsyncif.sc_statep_net.s = NULL;
244 pfsyncif.sc_maxupdates = 128;
245 pfsyncif.sc_sync_peer.s_addr = INADDR_PFSYNC_GROUP;
230 pfsyncif.sc_sendaddr.s_addr = INADDR_PFSYNC_GROUP;
231 pfsyncif.sc_ureq_received = 0;
232 pfsyncif.sc_ureq_sent = 0;
233 ifp = &pfsyncif.sc_if;
234 strlcpy(ifp->if_xname, "pfsync0", sizeof ifp->if_xname);
235 ifp->if_softc = &pfsyncif;
236 ifp->if_ioctl = pfsyncioctl;
237 ifp->if_output = pfsyncoutput;

--- 80 unchanged lines hidden (view full) ---

318 pfi_maybe_destroy(kif);
319 return (ENOMEM);
320 }
321 bzero(st, sizeof(*st));
322
323 st->rule.ptr = r;
324 /* XXX get pointers to nat_rule and anchor */
325
246 pfsyncif.sc_sendaddr.s_addr = INADDR_PFSYNC_GROUP;
247 pfsyncif.sc_ureq_received = 0;
248 pfsyncif.sc_ureq_sent = 0;
249 ifp = &pfsyncif.sc_if;
250 strlcpy(ifp->if_xname, "pfsync0", sizeof ifp->if_xname);
251 ifp->if_softc = &pfsyncif;
252 ifp->if_ioctl = pfsyncioctl;
253 ifp->if_output = pfsyncoutput;

--- 80 unchanged lines hidden (view full) ---

334 pfi_maybe_destroy(kif);
335 return (ENOMEM);
336 }
337 bzero(st, sizeof(*st));
338
339 st->rule.ptr = r;
340 /* XXX get pointers to nat_rule and anchor */
341
342 /* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */
343 r->states++;
344
326 /* fill in the rest of the state entry */
327 pf_state_host_ntoh(&sp->lan, &st->lan);
328 pf_state_host_ntoh(&sp->gwy, &st->gwy);
329 pf_state_host_ntoh(&sp->ext, &st->ext);
330
331 pf_state_peer_ntoh(&sp->src, &st->src);
332 pf_state_peer_ntoh(&sp->dst, &st->dst);
333
334 bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr));
345 /* fill in the rest of the state entry */
346 pf_state_host_ntoh(&sp->lan, &st->lan);
347 pf_state_host_ntoh(&sp->gwy, &st->gwy);
348 pf_state_host_ntoh(&sp->ext, &st->ext);
349
350 pf_state_peer_ntoh(&sp->src, &st->src);
351 pf_state_peer_ntoh(&sp->dst, &st->dst);
352
353 bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr));
335#ifdef __FreeBSD__
336 st->creation = ntohl(sp->creation) + time_second;
354 st->creation = time_second - ntohl(sp->creation);
337 st->expire = ntohl(sp->expire) + time_second;
355 st->expire = ntohl(sp->expire) + time_second;
338#else
339 st->creation = ntohl(sp->creation) + time.tv_sec;
340 st->expire = ntohl(sp->expire) + time.tv_sec;
341#endif
342
343 st->af = sp->af;
344 st->proto = sp->proto;
345 st->direction = sp->direction;
346 st->log = sp->log;
347 st->timeout = sp->timeout;
348 st->allow_opts = sp->allow_opts;
349
350 bcopy(sp->id, &st->id, sizeof(st->id));
351 st->creatorid = sp->creatorid;
356
357 st->af = sp->af;
358 st->proto = sp->proto;
359 st->direction = sp->direction;
360 st->log = sp->log;
361 st->timeout = sp->timeout;
362 st->allow_opts = sp->allow_opts;
363
364 bcopy(sp->id, &st->id, sizeof(st->id));
365 st->creatorid = sp->creatorid;
352 st->sync_flags = sp->sync_flags | PFSTATE_FROMSYNC;
366 st->sync_flags = PFSTATE_FROMSYNC;
353
354
355 if (pf_insert_state(kif, st)) {
356 pfi_maybe_destroy(kif);
367
368
369 if (pf_insert_state(kif, st)) {
370 pfi_maybe_destroy(kif);
371 /* XXX when we have nat_rule/anchors, use STATE_DEC_COUNTERS */
372 r->states--;
357 pool_put(&pf_state_pl, st);
358 return (EINVAL);
359 }
360
361 return (0);
362}
363
364void

--- 14 unchanged lines hidden (view full) ---

379 struct pfsync_state *sp;
380 struct pfsync_state_upd *up;
381 struct pfsync_state_del *dp;
382 struct pfsync_state_clr *cp;
383 struct pfsync_state_upd_req *rup;
384 struct pfsync_state_bus *bus;
385 struct in_addr src;
386 struct mbuf *mp;
373 pool_put(&pf_state_pl, st);
374 return (EINVAL);
375 }
376
377 return (0);
378}
379
380void

--- 14 unchanged lines hidden (view full) ---

395 struct pfsync_state *sp;
396 struct pfsync_state_upd *up;
397 struct pfsync_state_del *dp;
398 struct pfsync_state_clr *cp;
399 struct pfsync_state_upd_req *rup;
400 struct pfsync_state_bus *bus;
401 struct in_addr src;
402 struct mbuf *mp;
387 int iplen, action, error, i, s, count, offp;
403 int iplen, action, error, i, s, count, offp, sfail, stale = 0;
388
389 pfsyncstats.pfsyncs_ipackets++;
390
391 /* verify that we have a sync interface configured */
392 if (!sc->sc_sync_ifp || !pf_status.running) /* XXX PF_LOCK? */
393 goto done;
394
395 /* verify that the packet came in on the right interface */

--- 39 unchanged lines hidden (view full) ---

435 goto done;
436 }
437
438 /* Cheaper to grab this now than having to mess with mbufs later */
439 src = ip->ip_src;
440
441 switch (action) {
442 case PFSYNC_ACT_CLR: {
404
405 pfsyncstats.pfsyncs_ipackets++;
406
407 /* verify that we have a sync interface configured */
408 if (!sc->sc_sync_ifp || !pf_status.running) /* XXX PF_LOCK? */
409 goto done;
410
411 /* verify that the packet came in on the right interface */

--- 39 unchanged lines hidden (view full) ---

451 goto done;
452 }
453
454 /* Cheaper to grab this now than having to mess with mbufs later */
455 src = ip->ip_src;
456
457 switch (action) {
458 case PFSYNC_ACT_CLR: {
459 struct pf_state *nexts;
443 struct pfi_kif *kif;
444 u_int32_t creatorid;
445 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
446 sizeof(*cp), &offp)) == NULL) {
447 pfsyncstats.pfsyncs_badlen++;
448 return;
449 }
450 cp = (struct pfsync_state_clr *)(mp->m_data + offp);
451 creatorid = cp->creatorid;
452
453 s = splsoftnet();
454#ifdef __FreeBSD__
455 PF_LOCK();
456#endif
457 if (cp->ifname[0] == '\0') {
460 struct pfi_kif *kif;
461 u_int32_t creatorid;
462 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
463 sizeof(*cp), &offp)) == NULL) {
464 pfsyncstats.pfsyncs_badlen++;
465 return;
466 }
467 cp = (struct pfsync_state_clr *)(mp->m_data + offp);
468 creatorid = cp->creatorid;
469
470 s = splsoftnet();
471#ifdef __FreeBSD__
472 PF_LOCK();
473#endif
474 if (cp->ifname[0] == '\0') {
458 RB_FOREACH(st, pf_state_tree_id, &tree_id) {
459 if (st->creatorid == creatorid)
475 for (st = RB_MIN(pf_state_tree_id, &tree_id);
476 st; st = nexts) {
477 nexts = RB_NEXT(pf_state_tree_id, &tree_id, st);
478 if (st->creatorid == creatorid) {
460 st->timeout = PFTM_PURGE;
479 st->timeout = PFTM_PURGE;
480 pf_purge_expired_state(st);
481 }
461 }
462 } else {
463 kif = pfi_lookup_if(cp->ifname);
464 if (kif == NULL) {
465 if (pf_status.debug >= PF_DEBUG_MISC)
466 printf("pfsync_input: PFSYNC_ACT_CLR "
467 "bad interface: %s\n", cp->ifname);
468 splx(s);
469#ifdef __FreeBSD__
470 PF_UNLOCK();
471#endif
472 goto done;
473 }
482 }
483 } else {
484 kif = pfi_lookup_if(cp->ifname);
485 if (kif == NULL) {
486 if (pf_status.debug >= PF_DEBUG_MISC)
487 printf("pfsync_input: PFSYNC_ACT_CLR "
488 "bad interface: %s\n", cp->ifname);
489 splx(s);
490#ifdef __FreeBSD__
491 PF_UNLOCK();
492#endif
493 goto done;
494 }
474 RB_FOREACH(st, pf_state_tree_lan_ext,
475 &kif->pfik_lan_ext) {
476 if (st->creatorid == creatorid)
495 for (st = RB_MIN(pf_state_tree_lan_ext,
496 &kif->pfik_lan_ext); st; st = nexts) {
497 nexts = RB_NEXT(pf_state_tree_lan_ext,
498 &kif->pfik_lan_ext, st);
499 if (st->creatorid == creatorid) {
477 st->timeout = PFTM_PURGE;
500 st->timeout = PFTM_PURGE;
501 pf_purge_expired_state(st);
502 }
478 }
479 }
503 }
504 }
480 pf_purge_expired_states();
481#ifdef __FreeBSD__
482 PF_UNLOCK();
483#endif
484 splx(s);
485
486 break;
487 }
488 case PFSYNC_ACT_INS:

--- 46 unchanged lines hidden (view full) ---

535 }
536
537 s = splsoftnet();
538#ifdef __FreeBSD__
539 PF_LOCK();
540#endif
541 for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp);
542 i < count; i++, sp++) {
505#ifdef __FreeBSD__
506 PF_UNLOCK();
507#endif
508 splx(s);
509
510 break;
511 }
512 case PFSYNC_ACT_INS:

--- 46 unchanged lines hidden (view full) ---

559 }
560
561 s = splsoftnet();
562#ifdef __FreeBSD__
563 PF_LOCK();
564#endif
565 for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp);
566 i < count; i++, sp++) {
567 int flags = PFSYNC_FLAG_STALE;
568
543 /* check for invalid values */
544 if (sp->timeout >= PFTM_MAX ||
545 sp->src.state > PF_TCPS_PROXY_DST ||
546 sp->dst.state > PF_TCPS_PROXY_DST) {
547 if (pf_status.debug >= PF_DEBUG_MISC)
548 printf("pfsync_insert: PFSYNC_ACT_UPD: "
549 "invalid value\n");
550 pfsyncstats.pfsyncs_badstate++;

--- 5 unchanged lines hidden (view full) ---

556
557 st = pf_find_state_byid(&key);
558 if (st == NULL) {
559 /* insert the update */
560 if (pfsync_insert_net_state(sp))
561 pfsyncstats.pfsyncs_badstate++;
562 continue;
563 }
569 /* check for invalid values */
570 if (sp->timeout >= PFTM_MAX ||
571 sp->src.state > PF_TCPS_PROXY_DST ||
572 sp->dst.state > PF_TCPS_PROXY_DST) {
573 if (pf_status.debug >= PF_DEBUG_MISC)
574 printf("pfsync_insert: PFSYNC_ACT_UPD: "
575 "invalid value\n");
576 pfsyncstats.pfsyncs_badstate++;

--- 5 unchanged lines hidden (view full) ---

582
583 st = pf_find_state_byid(&key);
584 if (st == NULL) {
585 /* insert the update */
586 if (pfsync_insert_net_state(sp))
587 pfsyncstats.pfsyncs_badstate++;
588 continue;
589 }
564 pf_state_peer_ntoh(&sp->src, &st->src);
565 pf_state_peer_ntoh(&sp->dst, &st->dst);
590 sfail = 0;
591 if (st->proto == IPPROTO_TCP) {
592 /*
593 * The state should never go backwards except
594 * for syn-proxy states. Neither should the
595 * sequence window slide backwards.
596 */
597 if (st->src.state > sp->src.state &&
598 (st->src.state < PF_TCPS_PROXY_SRC ||
599 sp->src.state >= PF_TCPS_PROXY_SRC))
600 sfail = 1;
601 else if (SEQ_GT(st->src.seqlo,
602 ntohl(sp->src.seqlo)))
603 sfail = 3;
604 else if (st->dst.state > sp->dst.state) {
605 /* There might still be useful
606 * information about the src state here,
607 * so import that part of the update,
608 * then "fail" so we send the updated
609 * state back to the peer who is missing
610 * our what we know. */
611 pf_state_peer_ntoh(&sp->src, &st->src);
612 /* XXX do anything with timeouts? */
613 sfail = 7;
614 flags = 0;
615 } else if (st->dst.state >= TCPS_SYN_SENT &&
616 SEQ_GT(st->dst.seqlo, ntohl(sp->dst.seqlo)))
617 sfail = 4;
618 } else {
619 /*
620 * Non-TCP protocol state machine always go
621 * forwards
622 */
623 if (st->src.state > sp->src.state)
624 sfail = 5;
625 else if ( st->dst.state > sp->dst.state)
626 sfail = 6;
627 }
628 if (sfail) {
629 if (pf_status.debug >= PF_DEBUG_MISC)
630 printf("pfsync: %s stale update "
631 "(%d) id: %016llx "
632 "creatorid: %08x\n",
633 (sfail < 7 ? "ignoring"
634 : "partial"), sfail,
566#ifdef __FreeBSD__
635#ifdef __FreeBSD__
567 st->expire = ntohl(sp->expire) + time_second;
636 (unsigned long long)be64toh(st->id),
568#else
637#else
569 st->expire = ntohl(sp->expire) + time.tv_sec;
638 betoh64(st->id),
570#endif
639#endif
571 st->timeout = sp->timeout;
640 ntohl(st->creatorid));
641 pfsyncstats.pfsyncs_badstate++;
572
642
643 if (!(sp->sync_flags & PFSTATE_STALE)) {
644 /* we have a better state, send it */
645 if (sc->sc_mbuf != NULL && !stale)
646 pfsync_sendout(sc);
647 stale++;
648 if (!st->sync_flags)
649 pfsync_pack_state(
650 PFSYNC_ACT_UPD, st, flags);
651 }
652 continue;
653 }
654 pf_state_peer_ntoh(&sp->src, &st->src);
655 pf_state_peer_ntoh(&sp->dst, &st->dst);
656 st->expire = ntohl(sp->expire) + time_second;
657 st->timeout = sp->timeout;
573 }
658 }
659 if (stale && sc->sc_mbuf != NULL)
660 pfsync_sendout(sc);
574#ifdef __FreeBSD__
575 PF_UNLOCK();
576#endif
577 splx(s);
578 break;
579 /*
580 * It's not strictly necessary for us to support the "uncompressed"
581 * delete action, but it's relatively simple and maintains consistency.

--- 14 unchanged lines hidden (view full) ---

596 bcopy(sp->id, &key.id, sizeof(key.id));
597 key.creatorid = sp->creatorid;
598
599 st = pf_find_state_byid(&key);
600 if (st == NULL) {
601 pfsyncstats.pfsyncs_badstate++;
602 continue;
603 }
661#ifdef __FreeBSD__
662 PF_UNLOCK();
663#endif
664 splx(s);
665 break;
666 /*
667 * It's not strictly necessary for us to support the "uncompressed"
668 * delete action, but it's relatively simple and maintains consistency.

--- 14 unchanged lines hidden (view full) ---

683 bcopy(sp->id, &key.id, sizeof(key.id));
684 key.creatorid = sp->creatorid;
685
686 st = pf_find_state_byid(&key);
687 if (st == NULL) {
688 pfsyncstats.pfsyncs_badstate++;
689 continue;
690 }
604 /*
605 * XXX
606 * pf_purge_expired_states() is expensive,
607 * we really want to purge the state directly.
608 */
609 st->timeout = PFTM_PURGE;
610 st->sync_flags |= PFSTATE_FROMSYNC;
691 st->timeout = PFTM_PURGE;
692 st->sync_flags |= PFSTATE_FROMSYNC;
693 pf_purge_expired_state(st);
611 }
694 }
612 pf_purge_expired_states();
613#ifdef __FreeBSD__
614 PF_UNLOCK();
615#endif
616 splx(s);
617 break;
618 case PFSYNC_ACT_UPD_C: {
619 int update_requested = 0;
620

--- 22 unchanged lines hidden (view full) ---

643 }
644
645 bcopy(up->id, &key.id, sizeof(key.id));
646 key.creatorid = up->creatorid;
647
648 st = pf_find_state_byid(&key);
649 if (st == NULL) {
650 /* We don't have this state. Ask for it. */
695#ifdef __FreeBSD__
696 PF_UNLOCK();
697#endif
698 splx(s);
699 break;
700 case PFSYNC_ACT_UPD_C: {
701 int update_requested = 0;
702

--- 22 unchanged lines hidden (view full) ---

725 }
726
727 bcopy(up->id, &key.id, sizeof(key.id));
728 key.creatorid = up->creatorid;
729
730 st = pf_find_state_byid(&key);
731 if (st == NULL) {
732 /* We don't have this state. Ask for it. */
651 pfsync_request_update(up, &src);
733 error = pfsync_request_update(up, &src);
734 if (error == ENOMEM) {
735 splx(s);
736 goto done;
737 }
652 update_requested = 1;
653 pfsyncstats.pfsyncs_badstate++;
654 continue;
655 }
738 update_requested = 1;
739 pfsyncstats.pfsyncs_badstate++;
740 continue;
741 }
656 pf_state_peer_ntoh(&up->src, &st->src);
657 pf_state_peer_ntoh(&up->dst, &st->dst);
742 sfail = 0;
743 if (st->proto == IPPROTO_TCP) {
744 /*
745 * The state should never go backwards except
746 * for syn-proxy states. Neither should the
747 * sequence window slide backwards.
748 */
749 if (st->src.state > up->src.state &&
750 (st->src.state < PF_TCPS_PROXY_SRC ||
751 up->src.state >= PF_TCPS_PROXY_SRC))
752 sfail = 1;
753 else if (st->dst.state > up->dst.state)
754 sfail = 2;
755 else if (SEQ_GT(st->src.seqlo,
756 ntohl(up->src.seqlo)))
757 sfail = 3;
758 else if (st->dst.state >= TCPS_SYN_SENT &&
759 SEQ_GT(st->dst.seqlo, ntohl(up->dst.seqlo)))
760 sfail = 4;
761 } else {
762 /*
763 * Non-TCP protocol state machine always go
764 * forwards
765 */
766 if (st->src.state > up->src.state)
767 sfail = 5;
768 else if (st->dst.state > up->dst.state)
769 sfail = 6;
770 }
771 if (sfail) {
772 if (pf_status.debug >= PF_DEBUG_MISC)
773 printf("pfsync: ignoring stale update "
774 "(%d) id: %016llx "
775 "creatorid: %08x\n", sfail,
658#ifdef __FreeBSD__
776#ifdef __FreeBSD__
659 st->expire = ntohl(up->expire) + time_second;
777 (unsigned long long)be64toh(st->id),
660#else
778#else
661 st->expire = ntohl(up->expire) + time.tv_sec;
779 betoh64(st->id),
662#endif
780#endif
781 ntohl(st->creatorid));
782 pfsyncstats.pfsyncs_badstate++;
783
784 /* we have a better state, send it out */
785 if ((!stale || update_requested) &&
786 sc->sc_mbuf != NULL) {
787 pfsync_sendout(sc);
788 update_requested = 0;
789 }
790 stale++;
791 if (!st->sync_flags)
792 pfsync_pack_state(PFSYNC_ACT_UPD, st,
793 PFSYNC_FLAG_STALE);
794 continue;
795 }
796 pf_state_peer_ntoh(&up->src, &st->src);
797 pf_state_peer_ntoh(&up->dst, &st->dst);
798 st->expire = ntohl(up->expire) + time_second;
663 st->timeout = up->timeout;
664 }
799 st->timeout = up->timeout;
800 }
665 if (update_requested)
801 if ((update_requested || stale) && sc->sc_mbuf)
666 pfsync_sendout(sc);
667#ifdef __FreeBSD__
668 PF_UNLOCK();
669#endif
670 splx(s);
671 break;
672 }
673 case PFSYNC_ACT_DEL_C:

--- 12 unchanged lines hidden (view full) ---

686 bcopy(dp->id, &key.id, sizeof(key.id));
687 key.creatorid = dp->creatorid;
688
689 st = pf_find_state_byid(&key);
690 if (st == NULL) {
691 pfsyncstats.pfsyncs_badstate++;
692 continue;
693 }
802 pfsync_sendout(sc);
803#ifdef __FreeBSD__
804 PF_UNLOCK();
805#endif
806 splx(s);
807 break;
808 }
809 case PFSYNC_ACT_DEL_C:

--- 12 unchanged lines hidden (view full) ---

822 bcopy(dp->id, &key.id, sizeof(key.id));
823 key.creatorid = dp->creatorid;
824
825 st = pf_find_state_byid(&key);
826 if (st == NULL) {
827 pfsyncstats.pfsyncs_badstate++;
828 continue;
829 }
694 /*
695 * XXX
696 * pf_purge_expired_states() is expensive,
697 * we really want to purge the state directly.
698 */
699 st->timeout = PFTM_PURGE;
700 st->sync_flags |= PFSTATE_FROMSYNC;
830 st->timeout = PFTM_PURGE;
831 st->sync_flags |= PFSTATE_FROMSYNC;
832 pf_purge_expired_state(st);
701 }
833 }
702 pf_purge_expired_states();
703#ifdef __FreeBSD__
704 PF_UNLOCK();
705#endif
706 splx(s);
707 break;
708 case PFSYNC_ACT_INS_F:
709 case PFSYNC_ACT_DEL_F:
710 /* not implemented */
711 break;
712 case PFSYNC_ACT_UREQ:
713 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
714 count * sizeof(*rup), &offp)) == NULL) {
715 pfsyncstats.pfsyncs_badlen++;
716 return;
717 }
718
719 s = splsoftnet();
834#ifdef __FreeBSD__
835 PF_UNLOCK();
836#endif
837 splx(s);
838 break;
839 case PFSYNC_ACT_INS_F:
840 case PFSYNC_ACT_DEL_F:
841 /* not implemented */
842 break;
843 case PFSYNC_ACT_UREQ:
844 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
845 count * sizeof(*rup), &offp)) == NULL) {
846 pfsyncstats.pfsyncs_badlen++;
847 return;
848 }
849
850 s = splsoftnet();
720 /* XXX send existing. pfsync_pack_state should handle this. */
721#ifdef __FreeBSD__
722 PF_LOCK();
723#endif
724 if (sc->sc_mbuf != NULL)
725 pfsync_sendout(sc);
726 for (i = 0,
727 rup = (struct pfsync_state_upd_req *)(mp->m_data + offp);
728 i < count; i++, rup++) {
729 bcopy(rup->id, &key.id, sizeof(key.id));
730 key.creatorid = rup->creatorid;
731
732 if (key.id == 0 && key.creatorid == 0) {
851#ifdef __FreeBSD__
852 PF_LOCK();
853#endif
854 if (sc->sc_mbuf != NULL)
855 pfsync_sendout(sc);
856 for (i = 0,
857 rup = (struct pfsync_state_upd_req *)(mp->m_data + offp);
858 i < count; i++, rup++) {
859 bcopy(rup->id, &key.id, sizeof(key.id));
860 key.creatorid = rup->creatorid;
861
862 if (key.id == 0 && key.creatorid == 0) {
733#ifdef __FreeBSD__
734 sc->sc_ureq_received = time_uptime;
863 sc->sc_ureq_received = time_uptime;
735#else
736 sc->sc_ureq_received = mono_time.tv_sec;
737#endif
738 if (pf_status.debug >= PF_DEBUG_MISC)
739 printf("pfsync: received "
740 "bulk update request\n");
741 pfsync_send_bus(sc, PFSYNC_BUS_START);
742#ifdef __FreeBSD__
743 callout_reset(&sc->sc_bulk_tmo, 1 * hz,
744 pfsync_bulk_update,
745 LIST_FIRST(&pfsync_list));
746#else
747 timeout_add(&sc->sc_bulk_tmo, 1 * hz);
748#endif
749 } else {
750 st = pf_find_state_byid(&key);
751 if (st == NULL) {
752 pfsyncstats.pfsyncs_badstate++;
753 continue;
754 }
864 if (pf_status.debug >= PF_DEBUG_MISC)
865 printf("pfsync: received "
866 "bulk update request\n");
867 pfsync_send_bus(sc, PFSYNC_BUS_START);
868#ifdef __FreeBSD__
869 callout_reset(&sc->sc_bulk_tmo, 1 * hz,
870 pfsync_bulk_update,
871 LIST_FIRST(&pfsync_list));
872#else
873 timeout_add(&sc->sc_bulk_tmo, 1 * hz);
874#endif
875 } else {
876 st = pf_find_state_byid(&key);
877 if (st == NULL) {
878 pfsyncstats.pfsyncs_badstate++;
879 continue;
880 }
755 pfsync_pack_state(PFSYNC_ACT_UPD, st, 0);
881 if (!st->sync_flags)
882 pfsync_pack_state(PFSYNC_ACT_UPD,
883 st, 0);
756 }
757 }
758 if (sc->sc_mbuf != NULL)
759 pfsync_sendout(sc);
760#ifdef __FreeBSD__
761 PF_UNLOCK();
762#endif
763 splx(s);

--- 21 unchanged lines hidden (view full) ---

785 pf_pool_limits[PF_LIMIT_STATES].limit /
786 (PFSYNC_BULKPACKETS * sc->sc_maxcount));
787#endif
788 if (pf_status.debug >= PF_DEBUG_MISC)
789 printf("pfsync: received bulk "
790 "update start\n");
791 break;
792 case PFSYNC_BUS_END:
884 }
885 }
886 if (sc->sc_mbuf != NULL)
887 pfsync_sendout(sc);
888#ifdef __FreeBSD__
889 PF_UNLOCK();
890#endif
891 splx(s);

--- 21 unchanged lines hidden (view full) ---

913 pf_pool_limits[PF_LIMIT_STATES].limit /
914 (PFSYNC_BULKPACKETS * sc->sc_maxcount));
915#endif
916 if (pf_status.debug >= PF_DEBUG_MISC)
917 printf("pfsync: received bulk "
918 "update start\n");
919 break;
920 case PFSYNC_BUS_END:
793#ifdef __FreeBSD__
794 if (time_uptime - ntohl(bus->endtime) >=
921 if (time_uptime - ntohl(bus->endtime) >=
795#else
796 if (mono_time.tv_sec - ntohl(bus->endtime) >=
797#endif
798 sc->sc_ureq_sent) {
799 /* that's it, we're happy */
800 sc->sc_ureq_sent = 0;
801 sc->sc_bulk_tries = 0;
802#ifdef __FreeBSD__
803 callout_stop(&sc->sc_bulkfail_tmo);
804#else
805 timeout_del(&sc->sc_bulkfail_tmo);
806#endif
922 sc->sc_ureq_sent) {
923 /* that's it, we're happy */
924 sc->sc_ureq_sent = 0;
925 sc->sc_bulk_tries = 0;
926#ifdef __FreeBSD__
927 callout_stop(&sc->sc_bulkfail_tmo);
928#else
929 timeout_del(&sc->sc_bulkfail_tmo);
930#endif
931#if NCARP > 0 /* XXX_IMPORT */
932 if (!pfsync_sync_ok)
933 carp_suppress_preempt--;
934#endif
807 pfsync_sync_ok = 1;
808 if (pf_status.debug >= PF_DEBUG_MISC)
809 printf("pfsync: received valid "
810 "bulk update end\n");
811 } else {
812 if (pf_status.debug >= PF_DEBUG_MISC)
813 printf("pfsync: received invalid "
814 "bulk update end: bad timestamp\n");

--- 59 unchanged lines hidden (view full) ---

874 splx(s);
875 break;
876 case SIOCGETPFSYNC:
877#ifdef __FreeBSD__
878 /* XXX: read unlocked */
879#endif
880 bzero(&pfsyncr, sizeof(pfsyncr));
881 if (sc->sc_sync_ifp)
935 pfsync_sync_ok = 1;
936 if (pf_status.debug >= PF_DEBUG_MISC)
937 printf("pfsync: received valid "
938 "bulk update end\n");
939 } else {
940 if (pf_status.debug >= PF_DEBUG_MISC)
941 printf("pfsync: received invalid "
942 "bulk update end: bad timestamp\n");

--- 59 unchanged lines hidden (view full) ---

1002 splx(s);
1003 break;
1004 case SIOCGETPFSYNC:
1005#ifdef __FreeBSD__
1006 /* XXX: read unlocked */
1007#endif
1008 bzero(&pfsyncr, sizeof(pfsyncr));
1009 if (sc->sc_sync_ifp)
882 strlcpy(pfsyncr.pfsyncr_syncif,
1010 strlcpy(pfsyncr.pfsyncr_syncdev,
883 sc->sc_sync_ifp->if_xname, IFNAMSIZ);
1011 sc->sc_sync_ifp->if_xname, IFNAMSIZ);
1012 pfsyncr.pfsyncr_syncpeer = sc->sc_sync_peer;
884 pfsyncr.pfsyncr_maxupdates = sc->sc_maxupdates;
885 if ((error = copyout(&pfsyncr, ifr->ifr_data, sizeof(pfsyncr))))
886 return (error);
887 break;
888 case SIOCSETPFSYNC:
889#ifdef __FreeBSD__
890 if ((error = suser(curthread)) != 0)
891#else
892 if ((error = suser(p, p->p_acflag)) != 0)
893#endif
894 return (error);
895 if ((error = copyin(ifr->ifr_data, &pfsyncr, sizeof(pfsyncr))))
896 return (error);
897
1013 pfsyncr.pfsyncr_maxupdates = sc->sc_maxupdates;
1014 if ((error = copyout(&pfsyncr, ifr->ifr_data, sizeof(pfsyncr))))
1015 return (error);
1016 break;
1017 case SIOCSETPFSYNC:
1018#ifdef __FreeBSD__
1019 if ((error = suser(curthread)) != 0)
1020#else
1021 if ((error = suser(p, p->p_acflag)) != 0)
1022#endif
1023 return (error);
1024 if ((error = copyin(ifr->ifr_data, &pfsyncr, sizeof(pfsyncr))))
1025 return (error);
1026
1027 if (pfsyncr.pfsyncr_syncpeer.s_addr == 0)
1028 sc->sc_sync_peer.s_addr = INADDR_PFSYNC_GROUP;
1029 else
1030 sc->sc_sync_peer.s_addr =
1031 pfsyncr.pfsyncr_syncpeer.s_addr;
1032
898 if (pfsyncr.pfsyncr_maxupdates > 255)
899 return (EINVAL);
900#ifdef __FreeBSD__
901 PF_LOCK();
902#endif
903 sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates;
904
1033 if (pfsyncr.pfsyncr_maxupdates > 255)
1034 return (EINVAL);
1035#ifdef __FreeBSD__
1036 PF_LOCK();
1037#endif
1038 sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates;
1039
905 if (pfsyncr.pfsyncr_syncif[0] == 0) {
1040 if (pfsyncr.pfsyncr_syncdev[0] == 0) {
906 sc->sc_sync_ifp = NULL;
907 if (sc->sc_mbuf_net != NULL) {
908 /* Don't keep stale pfsync packets around. */
909 s = splnet();
910 m_freem(sc->sc_mbuf_net);
911 sc->sc_mbuf_net = NULL;
912 sc->sc_statep_net.s = NULL;
913 splx(s);
914 }
1041 sc->sc_sync_ifp = NULL;
1042 if (sc->sc_mbuf_net != NULL) {
1043 /* Don't keep stale pfsync packets around. */
1044 s = splnet();
1045 m_freem(sc->sc_mbuf_net);
1046 sc->sc_mbuf_net = NULL;
1047 sc->sc_statep_net.s = NULL;
1048 splx(s);
1049 }
1050 if (imo->imo_num_memberships > 0) {
1051 in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
1052 imo->imo_multicast_ifp = NULL;
1053 }
915#ifdef __FreeBSD__
916 PF_UNLOCK();
917#endif
918 break;
919 }
1054#ifdef __FreeBSD__
1055 PF_UNLOCK();
1056#endif
1057 break;
1058 }
920 if ((sifp = ifunit(pfsyncr.pfsyncr_syncif)) == NULL) {
1059
1060 if ((sifp = ifunit(pfsyncr.pfsyncr_syncdev)) == NULL) {
921#ifdef __FreeBSD__
922 PF_UNLOCK();
923#endif
924 return (EINVAL);
925 }
1061#ifdef __FreeBSD__
1062 PF_UNLOCK();
1063#endif
1064 return (EINVAL);
1065 }
926 else if (sifp == sc->sc_sync_ifp) {
927#ifdef __FreeBSD__
928 PF_UNLOCK();
929#endif
930 break;
931 }
932
933 s = splnet();
934#ifdef __FreeBSD__
935 if (sifp->if_mtu < SCP2IFP(sc)->if_mtu ||
936#else
937 if (sifp->if_mtu < sc->sc_if.if_mtu ||
938#endif
939 (sc->sc_sync_ifp != NULL &&

--- 8 unchanged lines hidden (view full) ---

948 pfsync_setmtu(sc, sc->sc_if.if_mtu);
949#endif
950
951 if (imo->imo_num_memberships > 0) {
952 in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
953 imo->imo_multicast_ifp = NULL;
954 }
955
1066
1067 s = splnet();
1068#ifdef __FreeBSD__
1069 if (sifp->if_mtu < SCP2IFP(sc)->if_mtu ||
1070#else
1071 if (sifp->if_mtu < sc->sc_if.if_mtu ||
1072#endif
1073 (sc->sc_sync_ifp != NULL &&

--- 8 unchanged lines hidden (view full) ---

1082 pfsync_setmtu(sc, sc->sc_if.if_mtu);
1083#endif
1084
1085 if (imo->imo_num_memberships > 0) {
1086 in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
1087 imo->imo_multicast_ifp = NULL;
1088 }
1089
956 if (sc->sc_sync_ifp) {
1090 if (sc->sc_sync_ifp &&
1091 sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
957 struct in_addr addr;
958
1092 struct in_addr addr;
1093
1094 if (!(sc->sc_sync_ifp->if_flags & IFF_MULTICAST)) {
1095 sc->sc_sync_ifp = NULL;
959#ifdef __FreeBSD__
1096#ifdef __FreeBSD__
1097 PF_UNLOCK();
1098#endif
1099 splx(s);
1100 return (EADDRNOTAVAIL);
1101 }
1102#ifdef __FreeBSD__
960 PF_UNLOCK(); /* addmulti mallocs w/ WAITOK */
961 addr.s_addr = htonl(INADDR_PFSYNC_GROUP);
962#else
963 addr.s_addr = INADDR_PFSYNC_GROUP;
964#endif
1103 PF_UNLOCK(); /* addmulti mallocs w/ WAITOK */
1104 addr.s_addr = htonl(INADDR_PFSYNC_GROUP);
1105#else
1106 addr.s_addr = INADDR_PFSYNC_GROUP;
1107#endif
1108
965 if ((imo->imo_membership[0] =
966 in_addmulti(&addr, sc->sc_sync_ifp)) == NULL) {
1109 if ((imo->imo_membership[0] =
1110 in_addmulti(&addr, sc->sc_sync_ifp)) == NULL) {
1111 sc->sc_sync_ifp = NULL;
967 splx(s);
968 return (ENOBUFS);
969 }
970 imo->imo_num_memberships++;
971 imo->imo_multicast_ifp = sc->sc_sync_ifp;
972 imo->imo_multicast_ttl = PFSYNC_DFLTTL;
973 imo->imo_multicast_loop = 0;
1112 splx(s);
1113 return (ENOBUFS);
1114 }
1115 imo->imo_num_memberships++;
1116 imo->imo_multicast_ifp = sc->sc_sync_ifp;
1117 imo->imo_multicast_ttl = PFSYNC_DFLTTL;
1118 imo->imo_multicast_loop = 0;
1119 }
974
1120
1121 if (sc->sc_sync_ifp ||
1122 sc->sc_sendaddr.s_addr != INADDR_PFSYNC_GROUP) {
975 /* Request a full state table update. */
976#ifdef __FreeBSD__
977 PF_LOCK();
1123 /* Request a full state table update. */
1124#ifdef __FreeBSD__
1125 PF_LOCK();
1126#endif
978 sc->sc_ureq_sent = time_uptime;
1127 sc->sc_ureq_sent = time_uptime;
979#else
980 sc->sc_ureq_sent = mono_time.tv_sec;
1128#if NCARP > 0
1129 if (pfsync_sync_ok)
1130 carp_suppress_preempt++;
981#endif
982 pfsync_sync_ok = 0;
983 if (pf_status.debug >= PF_DEBUG_MISC)
984 printf("pfsync: requesting bulk update\n");
985#ifdef __FreeBSD__
986 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz,
987 pfsync_bulkfail, LIST_FIRST(&pfsync_list));
988#else
989 timeout_add(&sc->sc_bulkfail_tmo, 5 * hz);
990#endif
1131#endif
1132 pfsync_sync_ok = 0;
1133 if (pf_status.debug >= PF_DEBUG_MISC)
1134 printf("pfsync: requesting bulk update\n");
1135#ifdef __FreeBSD__
1136 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz,
1137 pfsync_bulkfail, LIST_FIRST(&pfsync_list));
1138#else
1139 timeout_add(&sc->sc_bulkfail_tmo, 5 * hz);
1140#endif
991 pfsync_request_update(NULL, NULL);
1141 error = pfsync_request_update(NULL, NULL);
1142 if (error == ENOMEM) {
1143#ifdef __FreeBSD__
1144 PF_UNLOCK();
1145#endif
1146 splx(s);
1147 return (ENOMEM);
1148 }
992 pfsync_sendout(sc);
993 }
994#ifdef __FreeBSD__
995 PF_UNLOCK();
996#endif
997 splx(s);
998
999 break;

--- 104 unchanged lines hidden (view full) ---

1104 LIST_FIRST(&pfsync_list));
1105#else
1106 timeout_add(&sc->sc_tmo, hz);
1107#endif
1108 return (m);
1109}
1110
1111int
1149 pfsync_sendout(sc);
1150 }
1151#ifdef __FreeBSD__
1152 PF_UNLOCK();
1153#endif
1154 splx(s);
1155
1156 break;

--- 104 unchanged lines hidden (view full) ---

1261 LIST_FIRST(&pfsync_list));
1262#else
1263 timeout_add(&sc->sc_tmo, hz);
1264#endif
1265 return (m);
1266}
1267
1268int
1112pfsync_pack_state(u_int8_t action, struct pf_state *st, int compress)
1269pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags)
1113{
1114#ifdef __FreeBSD__
1115 struct ifnet *ifp = SCP2IFP(LIST_FIRST(&pfsync_list));
1116#else
1117 struct ifnet *ifp = &pfsyncif.sc_if;
1118#endif
1119 struct pfsync_softc *sc = ifp->if_softc;
1120 struct pfsync_header *h, *h_net;

--- 7 unchanged lines hidden (view full) ---

1128
1129#ifdef __FreeBSD__
1130 PF_ASSERT(MA_OWNED);
1131#endif
1132 /*
1133 * If a packet falls in the forest and there's nobody around to
1134 * hear, does it make a sound?
1135 */
1270{
1271#ifdef __FreeBSD__
1272 struct ifnet *ifp = SCP2IFP(LIST_FIRST(&pfsync_list));
1273#else
1274 struct ifnet *ifp = &pfsyncif.sc_if;
1275#endif
1276 struct pfsync_softc *sc = ifp->if_softc;
1277 struct pfsync_header *h, *h_net;

--- 7 unchanged lines hidden (view full) ---

1285
1286#ifdef __FreeBSD__
1287 PF_ASSERT(MA_OWNED);
1288#endif
1289 /*
1290 * If a packet falls in the forest and there's nobody around to
1291 * hear, does it make a sound?
1292 */
1136 if (ifp->if_bpf == NULL && sc->sc_sync_ifp == NULL) {
1293 if (ifp->if_bpf == NULL && sc->sc_sync_ifp == NULL &&
1294 sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
1137 /* Don't leave any stale pfsync packets hanging around. */
1138 if (sc->sc_mbuf != NULL) {
1139 m_freem(sc->sc_mbuf);
1140 sc->sc_mbuf = NULL;
1141 sc->sc_statep.s = NULL;
1142 }
1143 return (0);
1144 }

--- 37 unchanged lines hidden (view full) ---

1182 break;
1183 }
1184 usp++;
1185 }
1186 }
1187 }
1188 }
1189
1295 /* Don't leave any stale pfsync packets hanging around. */
1296 if (sc->sc_mbuf != NULL) {
1297 m_freem(sc->sc_mbuf);
1298 sc->sc_mbuf = NULL;
1299 sc->sc_statep.s = NULL;
1300 }
1301 return (0);
1302 }

--- 37 unchanged lines hidden (view full) ---

1340 break;
1341 }
1342 usp++;
1343 }
1344 }
1345 }
1346 }
1347
1190#ifdef __FreeBSD__
1191 secs = time_second;
1192
1193 st->pfsync_time = time_uptime;
1348 secs = time_second;
1349
1350 st->pfsync_time = time_uptime;
1194#else
1195 secs = time.tv_sec;
1196
1197 st->pfsync_time = mono_time.tv_sec;
1198#endif
1199 TAILQ_REMOVE(&state_updates, st, u.s.entry_updates);
1200 TAILQ_INSERT_TAIL(&state_updates, st, u.s.entry_updates);
1201
1202 if (sp == NULL) {
1203 /* not a "duplicate" update */
1204 i = 255;
1205 sp = sc->sc_statep.s++;
1206 sc->sc_mbuf->m_pkthdr.len =

--- 26 unchanged lines hidden (view full) ---

1233 sp->anchor = htonl(r->nr);
1234 sp->af = st->af;
1235 sp->proto = st->proto;
1236 sp->direction = st->direction;
1237 sp->log = st->log;
1238 sp->allow_opts = st->allow_opts;
1239 sp->timeout = st->timeout;
1240
1351 TAILQ_REMOVE(&state_updates, st, u.s.entry_updates);
1352 TAILQ_INSERT_TAIL(&state_updates, st, u.s.entry_updates);
1353
1354 if (sp == NULL) {
1355 /* not a "duplicate" update */
1356 i = 255;
1357 sp = sc->sc_statep.s++;
1358 sc->sc_mbuf->m_pkthdr.len =

--- 26 unchanged lines hidden (view full) ---

1385 sp->anchor = htonl(r->nr);
1386 sp->af = st->af;
1387 sp->proto = st->proto;
1388 sp->direction = st->direction;
1389 sp->log = st->log;
1390 sp->allow_opts = st->allow_opts;
1391 sp->timeout = st->timeout;
1392
1241 sp->sync_flags = st->sync_flags & PFSTATE_NOSYNC;
1393 if (flags & PFSYNC_FLAG_STALE)
1394 sp->sync_flags |= PFSTATE_STALE;
1242 }
1243
1244 pf_state_peer_hton(&st->src, &sp->src);
1245 pf_state_peer_hton(&st->dst, &sp->dst);
1246
1247 if (st->expire <= secs)
1248 sp->expire = htonl(0);
1249 else
1250 sp->expire = htonl(st->expire - secs);
1251
1252 /* do we need to build "compressed" actions for network transfer? */
1395 }
1396
1397 pf_state_peer_hton(&st->src, &sp->src);
1398 pf_state_peer_hton(&st->dst, &sp->dst);
1399
1400 if (st->expire <= secs)
1401 sp->expire = htonl(0);
1402 else
1403 sp->expire = htonl(st->expire - secs);
1404
1405 /* do we need to build "compressed" actions for network transfer? */
1253 if (sc->sc_sync_ifp && compress) {
1406 if (sc->sc_sync_ifp && flags & PFSYNC_FLAG_COMPRESS) {
1254 switch (action) {
1255 case PFSYNC_ACT_UPD:
1256 newaction = PFSYNC_ACT_UPD_C;
1257 break;
1258 case PFSYNC_ACT_DEL:
1259 newaction = PFSYNC_ACT_DEL_C;
1260 break;
1261 default:

--- 61 unchanged lines hidden (view full) ---

1323#ifdef __FreeBSD__
1324 struct ifnet *ifp = SCP2IFP(LIST_FIRST(&pfsync_list));
1325#else
1326 struct ifnet *ifp = &pfsyncif.sc_if;
1327#endif
1328 struct pfsync_header *h;
1329 struct pfsync_softc *sc = ifp->if_softc;
1330 struct pfsync_state_upd_req *rup;
1407 switch (action) {
1408 case PFSYNC_ACT_UPD:
1409 newaction = PFSYNC_ACT_UPD_C;
1410 break;
1411 case PFSYNC_ACT_DEL:
1412 newaction = PFSYNC_ACT_DEL_C;
1413 break;
1414 default:

--- 61 unchanged lines hidden (view full) ---

1476#ifdef __FreeBSD__
1477 struct ifnet *ifp = SCP2IFP(LIST_FIRST(&pfsync_list));
1478#else
1479 struct ifnet *ifp = &pfsyncif.sc_if;
1480#endif
1481 struct pfsync_header *h;
1482 struct pfsync_softc *sc = ifp->if_softc;
1483 struct pfsync_state_upd_req *rup;
1331 int s = 0, ret = 0; /* make the compiler happy */
1484 int ret = 0;
1332
1333#ifdef __FreeBSD__
1334 PF_ASSERT(MA_OWNED);
1335#endif
1336 if (sc->sc_mbuf == NULL) {
1337 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ,
1485
1486#ifdef __FreeBSD__
1487 PF_ASSERT(MA_OWNED);
1488#endif
1489 if (sc->sc_mbuf == NULL) {
1490 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ,
1338 (void *)&sc->sc_statep.s)) == NULL) {
1339 splx(s);
1491 (void *)&sc->sc_statep.s)) == NULL)
1340 return (ENOMEM);
1492 return (ENOMEM);
1341 }
1342 h = mtod(sc->sc_mbuf, struct pfsync_header *);
1343 } else {
1344 h = mtod(sc->sc_mbuf, struct pfsync_header *);
1345 if (h->action != PFSYNC_ACT_UREQ) {
1346 pfsync_sendout(sc);
1347 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ,
1493 h = mtod(sc->sc_mbuf, struct pfsync_header *);
1494 } else {
1495 h = mtod(sc->sc_mbuf, struct pfsync_header *);
1496 if (h->action != PFSYNC_ACT_UREQ) {
1497 pfsync_sendout(sc);
1498 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ,
1348 (void *)&sc->sc_statep.s)) == NULL) {
1349 splx(s);
1499 (void *)&sc->sc_statep.s)) == NULL)
1350 return (ENOMEM);
1500 return (ENOMEM);
1351 }
1352 h = mtod(sc->sc_mbuf, struct pfsync_header *);
1353 }
1354 }
1355
1356 if (src != NULL)
1357 sc->sc_sendaddr = *src;
1358 sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*rup);
1359 h->count++;

--- 56 unchanged lines hidden (view full) ---

1416#endif
1417 pfsync_sendout(sc);
1418#ifdef __FreeBSD__
1419 PF_UNLOCK();
1420#endif
1421 splx(s);
1422}
1423
1501 h = mtod(sc->sc_mbuf, struct pfsync_header *);
1502 }
1503 }
1504
1505 if (src != NULL)
1506 sc->sc_sendaddr = *src;
1507 sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*rup);
1508 h->count++;

--- 56 unchanged lines hidden (view full) ---

1565#endif
1566 pfsync_sendout(sc);
1567#ifdef __FreeBSD__
1568 PF_UNLOCK();
1569#endif
1570 splx(s);
1571}
1572
1573/* This must be called in splnet() */
1424void
1425pfsync_send_bus(struct pfsync_softc *sc, u_int8_t status)
1426{
1427 struct pfsync_state_bus *bus;
1428
1429#ifdef __FreeBSD__
1430 PF_ASSERT(MA_OWNED);
1431#endif
1432 if (sc->sc_mbuf != NULL)
1433 pfsync_sendout(sc);
1434
1435 if (pfsync_sync_ok &&
1436 (sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_BUS,
1437 (void *)&sc->sc_statep.b)) != NULL) {
1438 sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*bus);
1439 bus = sc->sc_statep.b;
1440 bus->creatorid = pf_status.hostid;
1441 bus->status = status;
1574void
1575pfsync_send_bus(struct pfsync_softc *sc, u_int8_t status)
1576{
1577 struct pfsync_state_bus *bus;
1578
1579#ifdef __FreeBSD__
1580 PF_ASSERT(MA_OWNED);
1581#endif
1582 if (sc->sc_mbuf != NULL)
1583 pfsync_sendout(sc);
1584
1585 if (pfsync_sync_ok &&
1586 (sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_BUS,
1587 (void *)&sc->sc_statep.b)) != NULL) {
1588 sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*bus);
1589 bus = sc->sc_statep.b;
1590 bus->creatorid = pf_status.hostid;
1591 bus->status = status;
1442#ifdef __FreeBSD__
1443 bus->endtime = htonl(time_uptime - sc->sc_ureq_received);
1592 bus->endtime = htonl(time_uptime - sc->sc_ureq_received);
1444#else
1445 bus->endtime = htonl(mono_time.tv_sec - sc->sc_ureq_received);
1446#endif
1447 pfsync_sendout(sc);
1448 }
1449}
1450
1451void
1452pfsync_bulk_update(void *v)
1453{
1454 struct pfsync_softc *sc = v;

--- 24 unchanged lines hidden (view full) ---

1479#endif
1480 if (pf_status.debug >= PF_DEBUG_MISC)
1481 printf("pfsync: bulk update complete\n");
1482 break;
1483 } else {
1484 /* send an update and move to end of list */
1485 if (!state->sync_flags)
1486 pfsync_pack_state(PFSYNC_ACT_UPD, state, 0);
1593 pfsync_sendout(sc);
1594 }
1595}
1596
1597void
1598pfsync_bulk_update(void *v)
1599{
1600 struct pfsync_softc *sc = v;

--- 24 unchanged lines hidden (view full) ---

1625#endif
1626 if (pf_status.debug >= PF_DEBUG_MISC)
1627 printf("pfsync: bulk update complete\n");
1628 break;
1629 } else {
1630 /* send an update and move to end of list */
1631 if (!state->sync_flags)
1632 pfsync_pack_state(PFSYNC_ACT_UPD, state, 0);
1487#ifdef __FreeBSD__
1488 state->pfsync_time = time_uptime;
1633 state->pfsync_time = time_uptime;
1489#else
1490 state->pfsync_time = mono_time.tv_sec;
1491#endif
1492 TAILQ_REMOVE(&state_updates, state, u.s.entry_updates);
1493 TAILQ_INSERT_TAIL(&state_updates, state,
1494 u.s.entry_updates);
1495
1496 /* look again for more in a bit */
1497#ifdef __FreeBSD__
1498 callout_reset(&sc->sc_bulk_tmo, 1, pfsync_timeout,
1499 LIST_FIRST(&pfsync_list));

--- 9 unchanged lines hidden (view full) ---

1509 PF_UNLOCK();
1510#endif
1511}
1512
1513void
1514pfsync_bulkfail(void *v)
1515{
1516 struct pfsync_softc *sc = v;
1634 TAILQ_REMOVE(&state_updates, state, u.s.entry_updates);
1635 TAILQ_INSERT_TAIL(&state_updates, state,
1636 u.s.entry_updates);
1637
1638 /* look again for more in a bit */
1639#ifdef __FreeBSD__
1640 callout_reset(&sc->sc_bulk_tmo, 1, pfsync_timeout,
1641 LIST_FIRST(&pfsync_list));

--- 9 unchanged lines hidden (view full) ---

1651 PF_UNLOCK();
1652#endif
1653}
1654
1655void
1656pfsync_bulkfail(void *v)
1657{
1658 struct pfsync_softc *sc = v;
1659 int s, error;
1517
1518#ifdef __FreeBSD__
1519 PF_LOCK();
1520#endif
1521 if (sc->sc_bulk_tries++ < PFSYNC_MAX_BULKTRIES) {
1522 /* Try again in a bit */
1523#ifdef __FreeBSD__
1524 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, pfsync_bulkfail,
1525 LIST_FIRST(&pfsync_list));
1526#else
1527 timeout_add(&sc->sc_bulkfail_tmo, 5 * hz);
1528#endif
1660
1661#ifdef __FreeBSD__
1662 PF_LOCK();
1663#endif
1664 if (sc->sc_bulk_tries++ < PFSYNC_MAX_BULKTRIES) {
1665 /* Try again in a bit */
1666#ifdef __FreeBSD__
1667 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, pfsync_bulkfail,
1668 LIST_FIRST(&pfsync_list));
1669#else
1670 timeout_add(&sc->sc_bulkfail_tmo, 5 * hz);
1671#endif
1529 pfsync_request_update(NULL, NULL);
1530 pfsync_sendout(sc);
1672 s = splnet();
1673 error = pfsync_request_update(NULL, NULL);
1674 if (error == ENOMEM) {
1675 if (pf_status.debug >= PF_DEBUG_MISC)
1676 printf("pfsync: cannot allocate mbufs for "
1677 "bulk update\n");
1678 } else
1679 pfsync_sendout(sc);
1680 splx(s);
1531 } else {
1532 /* Pretend like the transfer was ok */
1533 sc->sc_ureq_sent = 0;
1534 sc->sc_bulk_tries = 0;
1681 } else {
1682 /* Pretend like the transfer was ok */
1683 sc->sc_ureq_sent = 0;
1684 sc->sc_bulk_tries = 0;
1685#if NCARP > 0
1686 if (!pfsync_sync_ok)
1687 carp_suppress_preempt--;
1688#endif
1535 pfsync_sync_ok = 1;
1536 if (pf_status.debug >= PF_DEBUG_MISC)
1537 printf("pfsync: failed to receive "
1538 "bulk update status\n");
1539#ifdef __FreeBSD__
1540 callout_stop(&sc->sc_bulkfail_tmo);
1541#else
1542 timeout_del(&sc->sc_bulkfail_tmo);
1543#endif
1544 }
1545#ifdef __FreeBSD__
1546 PF_UNLOCK();
1547#endif
1548}
1549
1689 pfsync_sync_ok = 1;
1690 if (pf_status.debug >= PF_DEBUG_MISC)
1691 printf("pfsync: failed to receive "
1692 "bulk update status\n");
1693#ifdef __FreeBSD__
1694 callout_stop(&sc->sc_bulkfail_tmo);
1695#else
1696 timeout_del(&sc->sc_bulkfail_tmo);
1697#endif
1698 }
1699#ifdef __FreeBSD__
1700 PF_UNLOCK();
1701#endif
1702}
1703
1704/* This must be called in splnet() */
1550int
1551pfsync_sendout(sc)
1552 struct pfsync_softc *sc;
1553{
1554#if NBPFILTER > 0
1555# ifdef __FreeBSD__
1556 struct ifnet *ifp = SCP2IFP(sc);
1557# else

--- 25 unchanged lines hidden (view full) ---

1583
1584 if (sc->sc_mbuf_net) {
1585 m_freem(m);
1586 m = sc->sc_mbuf_net;
1587 sc->sc_mbuf_net = NULL;
1588 sc->sc_statep_net.s = NULL;
1589 }
1590
1705int
1706pfsync_sendout(sc)
1707 struct pfsync_softc *sc;
1708{
1709#if NBPFILTER > 0
1710# ifdef __FreeBSD__
1711 struct ifnet *ifp = SCP2IFP(sc);
1712# else

--- 25 unchanged lines hidden (view full) ---

1738
1739 if (sc->sc_mbuf_net) {
1740 m_freem(m);
1741 m = sc->sc_mbuf_net;
1742 sc->sc_mbuf_net = NULL;
1743 sc->sc_statep_net.s = NULL;
1744 }
1745
1591 if (sc->sc_sync_ifp) {
1746 if (sc->sc_sync_ifp || sc->sc_sync_peer.s_addr != INADDR_PFSYNC_GROUP) {
1592 struct ip *ip;
1747 struct ip *ip;
1593 struct ifaddr *ifa;
1594 struct sockaddr sa;
1595
1596 M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
1597 if (m == NULL) {
1598 pfsyncstats.pfsyncs_onomem++;
1599 return (0);
1600 }
1601 ip = mtod(m, struct ip *);

--- 11 unchanged lines hidden (view full) ---

1613#else
1614 ip->ip_off = htons(IP_DF);
1615#endif
1616 ip->ip_ttl = PFSYNC_DFLTTL;
1617 ip->ip_p = IPPROTO_PFSYNC;
1618 ip->ip_sum = 0;
1619
1620 bzero(&sa, sizeof(sa));
1748 struct sockaddr sa;
1749
1750 M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
1751 if (m == NULL) {
1752 pfsyncstats.pfsyncs_onomem++;
1753 return (0);
1754 }
1755 ip = mtod(m, struct ip *);

--- 11 unchanged lines hidden (view full) ---

1767#else
1768 ip->ip_off = htons(IP_DF);
1769#endif
1770 ip->ip_ttl = PFSYNC_DFLTTL;
1771 ip->ip_p = IPPROTO_PFSYNC;
1772 ip->ip_sum = 0;
1773
1774 bzero(&sa, sizeof(sa));
1621 sa.sa_family = AF_INET;
1622 ifa = ifaof_ifpforaddr(&sa, sc->sc_sync_ifp);
1623 if (ifa == NULL)
1624 return (0);
1625 ip->ip_src.s_addr = ifatoia(ifa)->ia_addr.sin_addr.s_addr;
1775 ip->ip_src.s_addr = INADDR_ANY;
1626
1627#ifdef __FreeBSD__
1628 if (sc->sc_sendaddr.s_addr == htonl(INADDR_PFSYNC_GROUP))
1629#else
1630 if (sc->sc_sendaddr.s_addr == INADDR_PFSYNC_GROUP)
1631#endif
1632 m->m_flags |= M_MCAST;
1633 ip->ip_dst = sc->sc_sendaddr;
1634#ifdef __FreeBSD__
1776
1777#ifdef __FreeBSD__
1778 if (sc->sc_sendaddr.s_addr == htonl(INADDR_PFSYNC_GROUP))
1779#else
1780 if (sc->sc_sendaddr.s_addr == INADDR_PFSYNC_GROUP)
1781#endif
1782 m->m_flags |= M_MCAST;
1783 ip->ip_dst = sc->sc_sendaddr;
1784#ifdef __FreeBSD__
1635 sc->sc_sendaddr.s_addr = htonl(INADDR_PFSYNC_GROUP);
1785 /* XXX_IMPORT */
1786 sc->sc_sendaddr.s_addr = htonl(sc->sc_sync_peer.s_addr);
1636#else
1787#else
1637 sc->sc_sendaddr.s_addr = INADDR_PFSYNC_GROUP;
1788 sc->sc_sendaddr.s_addr = sc->sc_sync_peer.s_addr;
1638#endif
1639
1640 pfsyncstats.pfsyncs_opackets++;
1641
1642#ifdef __FreeBSD__
1643 PF_UNLOCK();
1644#endif
1645 if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL))

--- 50 unchanged lines hidden ---
1789#endif
1790
1791 pfsyncstats.pfsyncs_opackets++;
1792
1793#ifdef __FreeBSD__
1794 PF_UNLOCK();
1795#endif
1796 if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL))

--- 50 unchanged lines hidden ---