Lines Matching +full:pd +full:- +full:revision

1 /*-
2 * SPDX-License-Identifier: (BSD-2-Clause AND ISC)
30 /*-
49 * Revisions picked from OpenBSD after revision 1.110 import:
50 * 1.119 - don't m_copydata() beyond the len of mbuf in pfsync_input()
51 * 1.118, 1.124, 1.148, 1.149, 1.151, 1.171 - fixes to bulk updates
52 * 1.120, 1.175 - use monotonic time_uptime
53 * 1.122 - reduce number of updates for non-TCP sessions
54 * 1.125, 1.127 - rewrite merge or stale processing
55 * 1.128 - cleanups
56 * 1.146 - bzero() mbuf before sparsely filling it with data
57 * 1.170 - SIOCSIFMTU checks
58 * 1.126, 1.142 - deferred packets processing
59 * 1.173 - correct expire time processing
201 /* Map queue to pf_kstate->sync_state */
214 /* Map pf_kstate->sync_state to queue */
285 #define PFSYNC_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
286 #define PFSYNC_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
287 #define PFSYNC_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
289 #define PFSYNC_BUCKET_LOCK(b) mtx_lock(&(b)->b_mtx)
290 #define PFSYNC_BUCKET_UNLOCK(b) mtx_unlock(&(b)->b_mtx)
291 #define PFSYNC_BUCKET_LOCK_ASSERT(b) mtx_assert(&(b)->b_mtx, MA_OWNED)
293 #define PFSYNC_BLOCK(sc) mtx_lock(&(sc)->sc_bulk_mtx)
294 #define PFSYNC_BUNLOCK(sc) mtx_unlock(&(sc)->sc_bulk_mtx)
295 #define PFSYNC_BLOCK_ASSERT(sc) mtx_assert(&(sc)->sc_bulk_mtx, MA_OWNED)
404 sc->sc_flags |= PFSYNCF_OK; in pfsync_clone_create()
405 sc->sc_maxupdates = 128; in pfsync_clone_create()
406 sc->sc_version = PFSYNC_MSG_VERSION_DEFAULT; in pfsync_clone_create()
407 sc->sc_buckets = mallocarray(pfsync_buckets, sizeof(*sc->sc_buckets), in pfsync_clone_create()
410 b = &sc->sc_buckets[c]; in pfsync_clone_create()
411 mtx_init(&b->b_mtx, "pfsync bucket", NULL, MTX_DEF); in pfsync_clone_create()
413 b->b_id = c; in pfsync_clone_create()
414 b->b_sc = sc; in pfsync_clone_create()
415 b->b_len = PFSYNC_MINPKT; in pfsync_clone_create()
418 TAILQ_INIT(&b->b_qs[q]); in pfsync_clone_create()
420 TAILQ_INIT(&b->b_upd_req_list); in pfsync_clone_create()
421 TAILQ_INIT(&b->b_deferrals); in pfsync_clone_create()
423 callout_init(&b->b_tmo, 1); in pfsync_clone_create()
425 b->b_snd.ifq_maxlen = ifqmaxlen; in pfsync_clone_create()
428 ifp = sc->sc_ifp = if_alloc(IFT_PFSYNC); in pfsync_clone_create()
430 ifp->if_softc = sc; in pfsync_clone_create()
431 ifp->if_ioctl = pfsyncioctl; in pfsync_clone_create()
432 ifp->if_output = pfsyncoutput; in pfsync_clone_create()
433 ifp->if_hdrlen = sizeof(struct pfsync_header); in pfsync_clone_create()
434 ifp->if_mtu = ETHERMTU; in pfsync_clone_create()
435 mtx_init(&sc->sc_mtx, pfsyncname, NULL, MTX_DEF); in pfsync_clone_create()
436 mtx_init(&sc->sc_bulk_mtx, "pfsync bulk", NULL, MTX_DEF); in pfsync_clone_create()
437 callout_init_mtx(&sc->sc_bulk_tmo, &sc->sc_bulk_mtx, 0); in pfsync_clone_create()
438 callout_init_mtx(&sc->sc_bulkfail_tmo, &sc->sc_bulk_mtx, 0); in pfsync_clone_create()
452 struct pfsync_softc *sc = ifp->if_softc; in pfsync_clone_destroy()
457 b = &sc->sc_buckets[c]; in pfsync_clone_destroy()
464 while (b->b_deferred > 0) { in pfsync_clone_destroy()
465 struct pfsync_deferral *pd = in pfsync_clone_destroy() local
466 TAILQ_FIRST(&b->b_deferrals); in pfsync_clone_destroy()
468 ret = callout_stop(&pd->pd_tmo); in pfsync_clone_destroy()
471 pfsync_undefer(pd, 1); in pfsync_clone_destroy()
473 callout_drain(&pd->pd_tmo); in pfsync_clone_destroy()
477 MPASS(b->b_deferred == 0); in pfsync_clone_destroy()
478 MPASS(TAILQ_EMPTY(&b->b_deferrals)); in pfsync_clone_destroy()
481 free(b->b_plus, M_PFSYNC); in pfsync_clone_destroy()
482 b->b_plus = NULL; in pfsync_clone_destroy()
483 b->b_pluslen = 0; in pfsync_clone_destroy()
485 callout_drain(&b->b_tmo); in pfsync_clone_destroy()
488 callout_drain(&sc->sc_bulkfail_tmo); in pfsync_clone_destroy()
489 callout_drain(&sc->sc_bulk_tmo); in pfsync_clone_destroy()
491 if (!(sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) in pfsync_clone_destroy()
492 (*carp_demote_adj_p)(-V_pfsync_carp_adj, "pfsync destroy"); in pfsync_clone_destroy()
500 mtx_destroy(&sc->sc_mtx); in pfsync_clone_destroy()
501 mtx_destroy(&sc->sc_bulk_mtx); in pfsync_clone_destroy()
504 b = &sc->sc_buckets[c]; in pfsync_clone_destroy()
505 mtx_destroy(&b->b_mtx); in pfsync_clone_destroy()
507 free(sc->sc_buckets, M_PFSYNC); in pfsync_clone_destroy()
517 if (s->scrub.scrub_flag && d->scrub == NULL) { in pfsync_alloc_scrub_memory()
518 d->scrub = uma_zalloc(V_pf_state_scrub_z, M_NOWAIT | M_ZERO); in pfsync_alloc_scrub_memory()
519 if (d->scrub == NULL) in pfsync_alloc_scrub_memory()
549 if (sp->pfs_1301.creatorid == 0) { in pfsync_state_import()
552 ntohl(sp->pfs_1301.creatorid)); in pfsync_state_import()
560 if ((kif = orig_kif = pfi_kkif_find(sp->pfs_1301.ifname)) == NULL) { in pfsync_state_import()
563 sp->pfs_1301.ifname); in pfsync_state_import()
572 * But s->orig_kif still points to a real interface. Don't abort in pfsync_state_import()
574 * but the state is not interface-bound. in pfsync_state_import()
577 orig_kif = pfi_kkif_find(sp->pfs_1500.orig_ifname); in pfsync_state_import()
585 sp->pfs_1500.orig_ifname); in pfsync_state_import()
597 if (sp->pfs_1301.rule != htonl(-1) && sp->pfs_1301.anchor == htonl(-1) && in pfsync_state_import()
598 (flags & (PFSYNC_SI_IOCTL | PFSYNC_SI_CKSUM)) && ntohl(sp->pfs_1301.rule) < in pfsync_state_import()
602 if (ntohl(sp->pfs_1301.rule) == n++) in pfsync_state_import()
616 struct pf_kpool *pool = &r->route; in pfsync_state_import()
619 if (TAILQ_EMPTY(&pool->list)) in pfsync_state_import()
620 pool = &r->rdr; in pfsync_state_import()
630 rpool_first = TAILQ_FIRST(&(pool->list)); in pfsync_state_import()
639 rt = r->rt; in pfsync_state_import()
640 rt_kif = rpool_first->kif; in pfsync_state_import()
643 * not support af-to nor prefer-ipv6-nexthop in pfsync_state_import()
646 rt_af = r->af; in pfsync_state_import()
647 } else if (!PF_AZERO(&sp->pfs_1301.rt_addr, sp->pfs_1301.af)) { in pfsync_state_import()
657 wire_af = stack_af = sp->pfs_1301.af; in pfsync_state_import()
658 wire_proto = stack_proto = sp->pfs_1301.proto; in pfsync_state_import()
665 if (sp->pfs_1400.rt) { in pfsync_state_import()
666 rt_kif = pfi_kkif_find(sp->pfs_1400.rt_ifname); in pfsync_state_import()
670 __func__, sp->pfs_1400.rt_ifname); in pfsync_state_import()
673 rt = sp->pfs_1400.rt; in pfsync_state_import()
676 * not support af-to nor prefer-ipv6-nexthop in pfsync_state_import()
679 rt_af = sp->pfs_1400.af; in pfsync_state_import()
681 wire_af = stack_af = sp->pfs_1400.af; in pfsync_state_import()
682 wire_proto = stack_proto = sp->pfs_1400.proto; in pfsync_state_import()
689 if (sp->pfs_1500.rt) { in pfsync_state_import()
690 rt_kif = pfi_kkif_find(sp->pfs_1500.rt_ifname); in pfsync_state_import()
694 __func__, sp->pfs_1500.rt_ifname); in pfsync_state_import()
697 rt = sp->pfs_1500.rt; in pfsync_state_import()
698 rt_af = sp->pfs_1500.rt_af; in pfsync_state_import()
700 wire_af = sp->pfs_1500.wire_af; in pfsync_state_import()
701 stack_af = sp->pfs_1500.stack_af; in pfsync_state_import()
702 wire_proto = sp->pfs_1500.wire_proto; in pfsync_state_import()
703 stack_proto = sp->pfs_1500.stack_proto; in pfsync_state_import()
707 if ((r->max_states && in pfsync_state_import()
708 counter_u64_fetch(r->states_cur) >= r->max_states)) in pfsync_state_import()
722 bcopy(&sp->pfs_1301.key, key, sizeof(struct pfsync_state_key) * 2); in pfsync_state_import()
726 kw = &sp->pfs_1301.key[PF_SK_WIRE]; in pfsync_state_import()
727 ks = &sp->pfs_1301.key[PF_SK_STACK]; in pfsync_state_import()
731 PF_ANEQ(&kw->addr[0], &ks->addr[0], wire_af) || in pfsync_state_import()
732 PF_ANEQ(&kw->addr[1], &ks->addr[1], wire_af) || in pfsync_state_import()
733 kw->port[0] != ks->port[0] || in pfsync_state_import()
734 kw->port[1] != ks->port[1]) { in pfsync_state_import()
742 if (pfsync_alloc_scrub_memory(&sp->pfs_1301.src, &st->src) || in pfsync_state_import()
743 pfsync_alloc_scrub_memory(&sp->pfs_1301.dst, &st->dst)) in pfsync_state_import()
747 skw->addr[0] = kw->addr[0]; in pfsync_state_import()
748 skw->addr[1] = kw->addr[1]; in pfsync_state_import()
749 skw->port[0] = kw->port[0]; in pfsync_state_import()
750 skw->port[1] = kw->port[1]; in pfsync_state_import()
751 skw->proto = wire_proto; in pfsync_state_import()
752 skw->af = wire_af; in pfsync_state_import()
754 sks->addr[0] = ks->addr[0]; in pfsync_state_import()
755 sks->addr[1] = ks->addr[1]; in pfsync_state_import()
756 sks->port[0] = ks->port[0]; in pfsync_state_import()
757 sks->port[1] = ks->port[1]; in pfsync_state_import()
758 sks->proto = stack_proto; in pfsync_state_import()
759 sks->af = stack_af; in pfsync_state_import()
763 st->creation = (time_uptime - ntohl(sp->pfs_1301.creation)) * 1000; in pfsync_state_import()
764 st->act.rt = rt; in pfsync_state_import()
765 st->act.rt_kif = rt_kif; in pfsync_state_import()
766 st->act.rt_af = rt_af; in pfsync_state_import()
770 st->state_flags = sp->pfs_1301.state_flags; in pfsync_state_import()
771 st->direction = sp->pfs_1301.direction; in pfsync_state_import()
772 st->act.log = sp->pfs_1301.log; in pfsync_state_import()
773 st->timeout = sp->pfs_1301.timeout; in pfsync_state_import()
775 bcopy(&sp->pfs_1301.rt_addr, &st->act.rt_addr, in pfsync_state_import()
776 sizeof(st->act.rt_addr)); in pfsync_state_import()
784 st->state_flags &= ~PFSTATE_SETMASK; in pfsync_state_import()
792 st->act.qid = r->qid; in pfsync_state_import()
793 st->act.pqid = r->pqid; in pfsync_state_import()
794 st->act.rtableid = r->rtableid; in pfsync_state_import()
795 if (r->scrub_flags & PFSTATE_SETTOS) in pfsync_state_import()
796 st->act.set_tos = r->set_tos; in pfsync_state_import()
797 st->act.min_ttl = r->min_ttl; in pfsync_state_import()
798 st->act.max_mss = r->max_mss; in pfsync_state_import()
799 st->state_flags |= (r->scrub_flags & in pfsync_state_import()
803 if (r->dnpipe || r->dnrpipe) { in pfsync_state_import()
804 if (r->free_flags & PFRULE_DN_IS_PIPE) in pfsync_state_import()
805 st->state_flags |= PFSTATE_DN_IS_PIPE; in pfsync_state_import()
807 st->state_flags &= ~PFSTATE_DN_IS_PIPE; in pfsync_state_import()
809 st->act.dnpipe = r->dnpipe; in pfsync_state_import()
810 st->act.dnrpipe = r->dnrpipe; in pfsync_state_import()
814 st->state_flags = ntohs(sp->pfs_1400.state_flags); in pfsync_state_import()
815 st->direction = sp->pfs_1400.direction; in pfsync_state_import()
816 st->act.log = sp->pfs_1400.log; in pfsync_state_import()
817 st->timeout = sp->pfs_1400.timeout; in pfsync_state_import()
818 st->act.qid = ntohs(sp->pfs_1400.qid); in pfsync_state_import()
819 st->act.pqid = ntohs(sp->pfs_1400.pqid); in pfsync_state_import()
820 st->act.dnpipe = ntohs(sp->pfs_1400.dnpipe); in pfsync_state_import()
821 st->act.dnrpipe = ntohs(sp->pfs_1400.dnrpipe); in pfsync_state_import()
822 st->act.rtableid = ntohl(sp->pfs_1400.rtableid); in pfsync_state_import()
823 st->act.min_ttl = sp->pfs_1400.min_ttl; in pfsync_state_import()
824 st->act.set_tos = sp->pfs_1400.set_tos; in pfsync_state_import()
825 st->act.max_mss = ntohs(sp->pfs_1400.max_mss); in pfsync_state_import()
826 st->act.set_prio[0] = sp->pfs_1400.set_prio[0]; in pfsync_state_import()
827 st->act.set_prio[1] = sp->pfs_1400.set_prio[1]; in pfsync_state_import()
829 bcopy(&sp->pfs_1400.rt_addr, &st->act.rt_addr, in pfsync_state_import()
830 sizeof(st->act.rt_addr)); in pfsync_state_import()
833 st->state_flags = ntohs(sp->pfs_1500.state_flags); in pfsync_state_import()
834 st->direction = sp->pfs_1500.direction; in pfsync_state_import()
835 st->act.log = sp->pfs_1500.log; in pfsync_state_import()
836 st->timeout = sp->pfs_1500.timeout; in pfsync_state_import()
837 st->act.qid = ntohs(sp->pfs_1500.qid); in pfsync_state_import()
838 st->act.pqid = ntohs(sp->pfs_1500.pqid); in pfsync_state_import()
839 st->act.dnpipe = ntohs(sp->pfs_1500.dnpipe); in pfsync_state_import()
840 st->act.dnrpipe = ntohs(sp->pfs_1500.dnrpipe); in pfsync_state_import()
841 st->act.rtableid = ntohl(sp->pfs_1500.rtableid); in pfsync_state_import()
842 st->act.min_ttl = sp->pfs_1500.min_ttl; in pfsync_state_import()
843 st->act.set_tos = sp->pfs_1500.set_tos; in pfsync_state_import()
844 st->act.max_mss = ntohs(sp->pfs_1500.max_mss); in pfsync_state_import()
845 st->act.set_prio[0] = sp->pfs_1500.set_prio[0]; in pfsync_state_import()
846 st->act.set_prio[1] = sp->pfs_1500.set_prio[1]; in pfsync_state_import()
848 bcopy(&sp->pfs_1500.rt_addr, &st->act.rt_addr, in pfsync_state_import()
849 sizeof(st->act.rt_addr)); in pfsync_state_import()
850 if (sp->pfs_1500.tagname[0] != 0) in pfsync_state_import()
851 st->tag = pf_tagname2tag(sp->pfs_1500.tagname); in pfsync_state_import()
858 st->expire = pf_get_uptime(); in pfsync_state_import()
859 if (sp->pfs_1301.expire) { in pfsync_state_import()
861 timeout = r->timeout[st->timeout]; in pfsync_state_import()
863 timeout = V_pf_default_rule.timeout[st->timeout]; in pfsync_state_import()
865 /* sp->expire may have been adaptively scaled by export. */ in pfsync_state_import()
866 st->expire -= (timeout - ntohl(sp->pfs_1301.expire)) * 1000; in pfsync_state_import()
869 if (! (st->act.rtableid == -1 || in pfsync_state_import()
870 (st->act.rtableid >= 0 && st->act.rtableid < rt_numfibs))) in pfsync_state_import()
873 st->id = sp->pfs_1301.id; in pfsync_state_import()
874 st->creatorid = sp->pfs_1301.creatorid; in pfsync_state_import()
875 pf_state_peer_ntoh(&sp->pfs_1301.src, &st->src); in pfsync_state_import()
876 pf_state_peer_ntoh(&sp->pfs_1301.dst, &st->dst); in pfsync_state_import()
878 st->rule = r; in pfsync_state_import()
879 st->nat_rule = NULL; in pfsync_state_import()
880 st->anchor = NULL; in pfsync_state_import()
882 st->pfsync_time = time_uptime; in pfsync_state_import()
883 st->sync_state = PFSYNC_S_NONE; in pfsync_state_import()
886 st->state_flags |= PFSTATE_NOSYNC; in pfsync_state_import()
892 counter_u64_add(r->states_cur, 1); in pfsync_state_import()
893 counter_u64_add(r->states_tot, 1); in pfsync_state_import()
896 st->state_flags &= ~PFSTATE_NOSYNC; in pfsync_state_import()
897 if (st->state_flags & PFSTATE_ACK) { in pfsync_state_import()
906 st->state_flags &= ~PFSTATE_ACK; in pfsync_state_import()
921 st->timeout = PFTM_UNLINKED; /* appease an assert */ in pfsync_state_import()
947 if (!sc || !sc->sc_sync_if || !V_pf_status.running || in pfsync_input()
948 (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) in pfsync_input()
952 if (sc->sc_sync_if != m->m_pkthdr.rcvif) { in pfsync_input()
957 if_inc_counter(sc->sc_ifp, IFCOUNTER_IPACKETS, 1); in pfsync_input()
958 if_inc_counter(sc->sc_ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); in pfsync_input()
960 if (ip->ip_ttl != PFSYNC_DFLTTL) { in pfsync_input()
965 offset = ip->ip_hl << 2; in pfsync_input()
966 if (m->m_pkthdr.len < offset + sizeof(*ph)) { in pfsync_input()
971 if (offset + sizeof(*ph) > m->m_len) { in pfsync_input()
981 if (ph->version != PFSYNC_VERSION) { in pfsync_input()
986 len = ntohs(ph->len) + offset; in pfsync_input()
987 if (m->m_pkthdr.len < len) { in pfsync_input()
997 if (!bcmp(&ph->pfcksum, &V_pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH)) in pfsync_input()
1001 while (offset <= len - sizeof(subh)) { in pfsync_input()
1014 if (rv == -1) { in pfsync_input()
1049 if (!sc || !sc->sc_sync_if || !V_pf_status.running || in pfsync6_input()
1050 (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) in pfsync6_input()
1054 if (sc->sc_sync_if != m->m_pkthdr.rcvif) { in pfsync6_input()
1059 if_inc_counter(sc->sc_ifp, IFCOUNTER_IPACKETS, 1); in pfsync6_input()
1060 if_inc_counter(sc->sc_ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); in pfsync6_input()
1062 if (ip6->ip6_hlim != PFSYNC_DFLTTL) { in pfsync6_input()
1069 if (m->m_pkthdr.len < offset + sizeof(*ph)) { in pfsync6_input()
1074 if (offset + sizeof(*ph) > m->m_len) { in pfsync6_input()
1084 if (ph->version != PFSYNC_VERSION) { in pfsync6_input()
1089 len = ntohs(ph->len) + offset; in pfsync6_input()
1090 if (m->m_pkthdr.len < len) { in pfsync6_input()
1100 if (!bcmp(&ph->pfcksum, &V_pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH)) in pfsync6_input()
1104 while (offset <= len - sizeof(subh)) { in pfsync6_input()
1117 if (rv == -1) { in pfsync6_input()
1144 return (-1); in pfsync_in_clr()
1146 clr = (struct pfsync_clr *)(mp->m_data + offp); in pfsync_in_clr()
1160 LIST_FOREACH(s, &ih->states, entry) { in pfsync_in_clr()
1161 if (s->creatorid == creatorid) { in pfsync_in_clr()
1162 s->state_flags |= PFSTATE_NOSYNC; in pfsync_in_clr()
1198 return (-1); in pfsync_in_ins()
1206 return (-1); in pfsync_in_ins()
1208 sa = (union pfsync_state_union *)(mp->m_data + offp); in pfsync_in_ins()
1216 af = sp->pfs_1301.af; in pfsync_in_ins()
1217 timeout = sp->pfs_1301.timeout; in pfsync_in_ins()
1218 direction = sp->pfs_1301.direction; in pfsync_in_ins()
1221 af = sp->pfs_1500.wire_af; in pfsync_in_ins()
1222 timeout = sp->pfs_1500.timeout; in pfsync_in_ins()
1223 direction = sp->pfs_1500.direction; in pfsync_in_ins()
1229 sp->pfs_1301.src.state > PF_TCPS_PROXY_DST || in pfsync_in_ins()
1230 sp->pfs_1301.dst.state > PF_TCPS_PROXY_DST || in pfsync_in_ins()
1259 return (-1); in pfsync_in_iack()
1261 iaa = (struct pfsync_ins_ack *)(mp->m_data + offp); in pfsync_in_iack()
1266 st = pf_find_state_byid(ia->id, ia->creatorid); in pfsync_in_iack()
1270 if (st->state_flags & PFSTATE_ACK) { in pfsync_in_iack()
1293 * for syn-proxy states. Neither should the in pfsync_upd_tcp()
1296 if ((st->src.state > src->state && in pfsync_upd_tcp()
1297 (st->src.state < PF_TCPS_PROXY_SRC || in pfsync_upd_tcp()
1298 src->state >= PF_TCPS_PROXY_SRC)) || in pfsync_upd_tcp()
1300 (st->src.state == src->state && in pfsync_upd_tcp()
1301 SEQ_GT(st->src.seqlo, ntohl(src->seqlo)))) in pfsync_upd_tcp()
1304 pf_state_peer_ntoh(src, &st->src); in pfsync_upd_tcp()
1306 if ((st->dst.state > dst->state) || in pfsync_upd_tcp()
1308 (st->dst.state >= TCPS_SYN_SENT && in pfsync_upd_tcp()
1309 SEQ_GT(st->dst.seqlo, ntohl(dst->seqlo)))) in pfsync_upd_tcp()
1312 pf_state_peer_ntoh(dst, &st->dst); in pfsync_upd_tcp()
1342 return (-1); in pfsync_in_upd()
1350 return (-1); in pfsync_in_upd()
1352 sa = (union pfsync_state_union *)(mp->m_data + offp); in pfsync_in_upd()
1360 timeout = sp->pfs_1301.timeout; in pfsync_in_upd()
1363 timeout = sp->pfs_1500.timeout; in pfsync_in_upd()
1369 sp->pfs_1301.src.state > PF_TCPS_PROXY_DST || in pfsync_in_upd()
1370 sp->pfs_1301.dst.state > PF_TCPS_PROXY_DST) { in pfsync_in_upd()
1379 st = pf_find_state_byid(sp->pfs_1301.id, sp->pfs_1301.creatorid); in pfsync_in_upd()
1387 if (st->state_flags & PFSTATE_ACK) { in pfsync_in_upd()
1391 if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP) in pfsync_in_upd()
1392 sync = pfsync_upd_tcp(st, &sp->pfs_1301.src, &sp->pfs_1301.dst); in pfsync_in_upd()
1397 * Non-TCP protocol state machine always go in pfsync_in_upd()
1400 if (st->src.state > sp->pfs_1301.src.state) in pfsync_in_upd()
1403 pf_state_peer_ntoh(&sp->pfs_1301.src, &st->src); in pfsync_in_upd()
1404 if (st->dst.state > sp->pfs_1301.dst.state) in pfsync_in_upd()
1407 pf_state_peer_ntoh(&sp->pfs_1301.dst, &st->dst); in pfsync_in_upd()
1410 pfsync_alloc_scrub_memory(&sp->pfs_1301.dst, &st->dst); in pfsync_in_upd()
1411 pf_state_peer_ntoh(&sp->pfs_1301.dst, &st->dst); in pfsync_in_upd()
1412 st->expire = pf_get_uptime(); in pfsync_in_upd()
1413 st->timeout = timeout; in pfsync_in_upd()
1415 st->pfsync_time = time_uptime; in pfsync_in_upd()
1445 return (-1); in pfsync_in_upd_c()
1447 ua = (struct pfsync_upd_c *)(mp->m_data + offp); in pfsync_in_upd_c()
1453 if (up->timeout >= PFTM_MAX || in pfsync_in_upd_c()
1454 up->src.state > PF_TCPS_PROXY_DST || in pfsync_in_upd_c()
1455 up->dst.state > PF_TCPS_PROXY_DST) { in pfsync_in_upd_c()
1465 st = pf_find_state_byid(up->id, up->creatorid); in pfsync_in_upd_c()
1468 PFSYNC_BUCKET_LOCK(&sc->sc_buckets[0]); in pfsync_in_upd_c()
1469 pfsync_request_update(up->creatorid, up->id); in pfsync_in_upd_c()
1470 PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[0]); in pfsync_in_upd_c()
1474 if (st->state_flags & PFSTATE_ACK) { in pfsync_in_upd_c()
1478 if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP) in pfsync_in_upd_c()
1479 sync = pfsync_upd_tcp(st, &up->src, &up->dst); in pfsync_in_upd_c()
1484 * Non-TCP protocol state machine always go in pfsync_in_upd_c()
1487 if (st->src.state > up->src.state) in pfsync_in_upd_c()
1490 pf_state_peer_ntoh(&up->src, &st->src); in pfsync_in_upd_c()
1491 if (st->dst.state > up->dst.state) in pfsync_in_upd_c()
1494 pf_state_peer_ntoh(&up->dst, &st->dst); in pfsync_in_upd_c()
1497 pfsync_alloc_scrub_memory(&up->dst, &st->dst); in pfsync_in_upd_c()
1498 pf_state_peer_ntoh(&up->dst, &st->dst); in pfsync_in_upd_c()
1499 st->expire = pf_get_uptime(); in pfsync_in_upd_c()
1500 st->timeout = up->timeout; in pfsync_in_upd_c()
1502 st->pfsync_time = time_uptime; in pfsync_in_upd_c()
1531 return (-1); in pfsync_in_ureq()
1533 ura = (struct pfsync_upd_req *)(mp->m_data + offp); in pfsync_in_ureq()
1538 if (ur->id == 0 && ur->creatorid == 0) in pfsync_in_ureq()
1541 st = pf_find_state_byid(ur->id, ur->creatorid); in pfsync_in_ureq()
1546 if (st->state_flags & PFSTATE_NOSYNC) { in pfsync_in_ureq()
1571 return (-1); in pfsync_in_del_c()
1573 sa = (struct pfsync_del_c *)(mp->m_data + offp); in pfsync_in_del_c()
1578 st = pf_find_state_byid(sp->id, sp->creatorid); in pfsync_in_del_c()
1584 st->state_flags |= PFSTATE_NOSYNC; in pfsync_in_del_c()
1603 if (sc->sc_ureq_sent == 0) { in pfsync_in_bus()
1612 return (-1); in pfsync_in_bus()
1614 bus = (struct pfsync_bus *)(mp->m_data + offp); in pfsync_in_bus()
1616 switch (bus->status) { in pfsync_in_bus()
1618 callout_reset(&sc->sc_bulkfail_tmo, 4 * hz + in pfsync_in_bus()
1620 ((sc->sc_ifp->if_mtu - PFSYNC_MINPKT) / in pfsync_in_bus()
1628 if (time_uptime - ntohl(bus->endtime) >= in pfsync_in_bus()
1629 sc->sc_ureq_sent) { in pfsync_in_bus()
1631 sc->sc_ureq_sent = 0; in pfsync_in_bus()
1632 sc->sc_bulk_tries = 0; in pfsync_in_bus()
1633 callout_stop(&sc->sc_bulkfail_tmo); in pfsync_in_bus()
1634 if (!(sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) in pfsync_in_bus()
1635 (*carp_demote_adj_p)(-V_pfsync_carp_adj, in pfsync_in_bus()
1637 sc->sc_flags |= PFSYNCF_OK; in pfsync_in_bus()
1668 return (-1); in pfsync_in_tdb()
1670 tp = (struct pfsync_tdb *)(mp->m_data + offp); in pfsync_in_tdb()
1680 /* Update an in-kernel tdb. Silently fail if no tdb is found. */
1688 if (ntohl(pt->spi) <= SPI_RESERVED_MAX || in pfsync_update_net_tdb()
1689 (pt->dst.sa.sa_family != AF_INET && in pfsync_update_net_tdb()
1690 pt->dst.sa.sa_family != AF_INET6)) in pfsync_update_net_tdb()
1693 tdb = gettdb(pt->spi, &pt->dst, pt->sproto); in pfsync_update_net_tdb()
1695 pt->rpl = ntohl(pt->rpl); in pfsync_update_net_tdb()
1696 pt->cur_bytes = (unsigned long long)be64toh(pt->cur_bytes); in pfsync_update_net_tdb()
1699 if (pt->rpl < tdb->tdb_rpl || in pfsync_update_net_tdb()
1700 pt->cur_bytes < tdb->tdb_cur_bytes) { in pfsync_update_net_tdb()
1704 tdb->tdb_rpl = pt->rpl; in pfsync_update_net_tdb()
1705 tdb->tdb_cur_bytes = pt->cur_bytes; in pfsync_update_net_tdb()
1722 if (offset != m->m_pkthdr.len) in pfsync_in_eof()
1727 return (-1); in pfsync_in_eof()
1736 return (-1); in pfsync_in_error()
1751 struct pfsync_softc *sc = ifp->if_softc; in pfsyncioctl()
1761 if (ifp->if_flags & IFF_UP) { in pfsyncioctl()
1762 ifp->if_drv_flags |= IFF_DRV_RUNNING; in pfsyncioctl()
1766 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; in pfsyncioctl()
1772 if (!sc->sc_sync_if || in pfsyncioctl()
1773 ifr->ifr_mtu <= PFSYNC_MINPKT || in pfsyncioctl()
1774 ifr->ifr_mtu > sc->sc_sync_if->if_mtu) in pfsyncioctl()
1776 if (ifr->ifr_mtu < ifp->if_mtu) { in pfsyncioctl()
1778 PFSYNC_BUCKET_LOCK(&sc->sc_buckets[c]); in pfsyncioctl()
1779 if (sc->sc_buckets[c].b_len > PFSYNC_MINPKT) in pfsyncioctl()
1781 PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[c]); in pfsyncioctl()
1784 ifp->if_mtu = ifr->ifr_mtu; in pfsyncioctl()
1789 if (sc->sc_sync_if) { in pfsyncioctl()
1791 sc->sc_sync_if->if_xname, IFNAMSIZ); in pfsyncioctl()
1793 pfsyncr.pfsyncr_syncpeer = ((struct sockaddr_in *)&sc->sc_sync_peer)->sin_addr; in pfsyncioctl()
1794 pfsyncr.pfsyncr_maxupdates = sc->sc_maxupdates; in pfsyncioctl()
1795 pfsyncr.pfsyncr_defer = sc->sc_flags; in pfsyncioctl()
1808 if (sc->sc_sync_if) in pfsyncioctl()
1809 nvlist_add_string(nvl, "syncdev", sc->sc_sync_if->if_xname); in pfsyncioctl()
1810 nvlist_add_number(nvl, "maxupdates", sc->sc_maxupdates); in pfsyncioctl()
1811 nvlist_add_number(nvl, "flags", sc->sc_flags); in pfsyncioctl()
1812 nvlist_add_number(nvl, "version", sc->sc_version); in pfsyncioctl()
1813 if ((nvl_syncpeer = pfsync_sockaddr_to_syncpeer_nvlist(&sc->sc_sync_peer)) != NULL) in pfsyncioctl()
1824 if (nvbuflen > ifr->ifr_cap_nv.buf_length) { in pfsyncioctl()
1825 ifr->ifr_cap_nv.length = nvbuflen; in pfsyncioctl()
1826 ifr->ifr_cap_nv.buffer = NULL; in pfsyncioctl()
1832 ifr->ifr_cap_nv.length = nvbuflen; in pfsyncioctl()
1833 error = copyout(packed, ifr->ifr_cap_nv.buffer, nvbuflen); in pfsyncioctl()
1865 if (ifr->ifr_cap_nv.length > IFR_CAP_NV_MAXBUFSIZE) in pfsyncioctl()
1868 data = malloc(ifr->ifr_cap_nv.length, M_PF, M_WAITOK); in pfsyncioctl()
1870 if ((error = copyin(ifr->ifr_cap_nv.buffer, data, in pfsyncioctl()
1871 ifr->ifr_cap_nv.length)) != 0) { in pfsyncioctl()
1876 if ((nvl = nvlist_unpack(data, ifr->ifr_cap_nv.length, 0)) == NULL) { in pfsyncioctl()
1926 iack->id = st->id; in pfsync_out_iack()
1927 iack->creatorid = st->creatorid; in pfsync_out_iack()
1936 up->id = st->id; in pfsync_out_upd_c()
1937 pf_state_peer_hton(&st->src, &up->src); in pfsync_out_upd_c()
1938 pf_state_peer_hton(&st->dst, &up->dst); in pfsync_out_upd_c()
1939 up->creatorid = st->creatorid; in pfsync_out_upd_c()
1940 up->timeout = st->timeout; in pfsync_out_upd_c()
1948 dp->id = st->id; in pfsync_out_del_c()
1949 dp->creatorid = st->creatorid; in pfsync_out_del_c()
1950 st->state_flags |= PFSTATE_NOSYNC; in pfsync_out_del_c()
1960 b = &sc->sc_buckets[c]; in pfsync_drop_all()
1976 b = &sc->sc_buckets[c]; in pfsync_drop()
1980 if (TAILQ_EMPTY(&b->b_qs[q])) in pfsync_drop()
1983 TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, next) { in pfsync_drop()
1984 KASSERT(st->sync_state == pfsync_qid_sstate[q], in pfsync_drop()
1985 ("%s: st->sync_state %d == q %d", in pfsync_drop()
1986 __func__, st->sync_state, q)); in pfsync_drop()
1987 st->sync_state = PFSYNC_S_NONE; in pfsync_drop()
1990 TAILQ_INIT(&b->b_qs[q]); in pfsync_drop()
1993 while ((ur = TAILQ_FIRST(&b->b_upd_req_list)) != NULL) { in pfsync_drop()
1994 TAILQ_REMOVE(&b->b_upd_req_list, ur, ur_entry); in pfsync_drop()
1998 b->b_len = PFSYNC_MINPKT; in pfsync_drop()
1999 free(b->b_plus, M_PFSYNC); in pfsync_drop()
2000 b->b_plus = NULL; in pfsync_drop()
2001 b->b_pluslen = 0; in pfsync_drop()
2008 struct ifnet *ifp = sc->sc_ifp; in pfsync_sendout()
2014 struct pfsync_bucket *b = &sc->sc_buckets[c]; in pfsync_sendout()
2020 KASSERT(b->b_len > PFSYNC_MINPKT, in pfsync_sendout()
2021 ("%s: sc_len %zu", __func__, b->b_len)); in pfsync_sendout()
2024 if (!bpf_peers_present(ifp->if_bpf) && sc->sc_sync_if == NULL) { in pfsync_sendout()
2029 m = m_get2(max_linkhdr + b->b_len, M_NOWAIT, MT_DATA, M_PKTHDR); in pfsync_sendout()
2031 if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1); in pfsync_sendout()
2035 m->m_data += max_linkhdr; in pfsync_sendout()
2036 bzero(m->m_data, b->b_len); in pfsync_sendout()
2038 len = b->b_len; in pfsync_sendout()
2041 switch (sc->sc_sync_peer.ss_family) { in pfsync_sendout()
2048 bcopy(&sc->sc_template.ipv4, ip, sizeof(*ip)); in pfsync_sendout()
2051 len -= sizeof(union inet_template) - sizeof(struct ip); in pfsync_sendout()
2052 ip->ip_len = htons(len); in pfsync_sendout()
2063 bcopy(&sc->sc_template.ipv6, ip6, sizeof(*ip6)); in pfsync_sendout()
2066 len -= sizeof(union inet_template) - sizeof(struct ip6_hdr); in pfsync_sendout()
2067 ip6->ip6_plen = htons(len); in pfsync_sendout()
2076 m->m_len = m->m_pkthdr.len = len; in pfsync_sendout()
2079 ph = (struct pfsync_header *)(m->m_data + offset); in pfsync_sendout()
2082 ph->version = PFSYNC_VERSION; in pfsync_sendout()
2083 ph->len = htons(len - aflen); in pfsync_sendout()
2084 bcopy(V_pf_status.pf_chksum, ph->pfcksum, PF_MD5_DIGEST_LENGTH); in pfsync_sendout()
2088 if (TAILQ_EMPTY(&b->b_qs[q])) in pfsync_sendout()
2091 subh = (struct pfsync_subheader *)(m->m_data + offset); in pfsync_sendout()
2095 TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, st_next) { in pfsync_sendout()
2096 KASSERT(st->sync_state == pfsync_qid_sstate[q], in pfsync_sendout()
2097 ("%s: st->sync_state == q", in pfsync_sendout()
2103 pfsync_qs[q].write(st, m->m_data + offset); in pfsync_sendout()
2105 st->sync_state = PFSYNC_S_NONE; in pfsync_sendout()
2109 TAILQ_INIT(&b->b_qs[q]); in pfsync_sendout()
2111 subh->action = pfsync_qs[q].action; in pfsync_sendout()
2112 subh->count = htons(count); in pfsync_sendout()
2116 if (!TAILQ_EMPTY(&b->b_upd_req_list)) { in pfsync_sendout()
2117 subh = (struct pfsync_subheader *)(m->m_data + offset); in pfsync_sendout()
2121 while ((ur = TAILQ_FIRST(&b->b_upd_req_list)) != NULL) { in pfsync_sendout()
2122 TAILQ_REMOVE(&b->b_upd_req_list, ur, ur_entry); in pfsync_sendout()
2124 bcopy(&ur->ur_msg, m->m_data + offset, in pfsync_sendout()
2125 sizeof(ur->ur_msg)); in pfsync_sendout()
2126 offset += sizeof(ur->ur_msg); in pfsync_sendout()
2131 subh->action = PFSYNC_ACT_UPD_REQ; in pfsync_sendout()
2132 subh->count = htons(count); in pfsync_sendout()
2137 if (b->b_plus != NULL) { in pfsync_sendout()
2138 bcopy(b->b_plus, m->m_data + offset, b->b_pluslen); in pfsync_sendout()
2139 offset += b->b_pluslen; in pfsync_sendout()
2141 free(b->b_plus, M_PFSYNC); in pfsync_sendout()
2142 b->b_plus = NULL; in pfsync_sendout()
2143 b->b_pluslen = 0; in pfsync_sendout()
2146 subh = (struct pfsync_subheader *)(m->m_data + offset); in pfsync_sendout()
2149 subh->action = PFSYNC_ACT_EOF; in pfsync_sendout()
2150 subh->count = htons(1); in pfsync_sendout()
2154 if (bpf_peers_present(ifp->if_bpf)) { in pfsync_sendout()
2155 m->m_data += aflen; in pfsync_sendout()
2156 m->m_len = m->m_pkthdr.len = len - aflen; in pfsync_sendout()
2157 bpf_mtap(ifp->if_bpf, m); in pfsync_sendout()
2158 m->m_data -= aflen; in pfsync_sendout()
2159 m->m_len = m->m_pkthdr.len = len; in pfsync_sendout()
2162 if (sc->sc_sync_if == NULL) { in pfsync_sendout()
2163 b->b_len = PFSYNC_MINPKT; in pfsync_sendout()
2168 if_inc_counter(sc->sc_ifp, IFCOUNTER_OPACKETS, 1); in pfsync_sendout()
2169 if_inc_counter(sc->sc_ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len); in pfsync_sendout()
2170 b->b_len = PFSYNC_MINPKT; in pfsync_sendout()
2172 if (!_IF_QFULL(&b->b_snd)) in pfsync_sendout()
2173 _IF_ENQUEUE(&b->b_snd, m); in pfsync_sendout()
2176 if_inc_counter(sc->sc_ifp, IFCOUNTER_OQDROPS, 1); in pfsync_sendout()
2188 if (st->state_flags & PFSTATE_NOSYNC) in pfsync_insert_state()
2191 if ((st->rule->rule_flag & PFRULE_NOSYNC) || in pfsync_insert_state()
2192 st->key[PF_SK_WIRE]->proto == IPPROTO_PFSYNC) { in pfsync_insert_state()
2193 st->state_flags |= PFSTATE_NOSYNC; in pfsync_insert_state()
2197 KASSERT(st->sync_state == PFSYNC_S_NONE, in pfsync_insert_state()
2198 ("%s: st->sync_state %u", __func__, st->sync_state)); in pfsync_insert_state()
2201 if (b->b_len == PFSYNC_MINPKT) in pfsync_insert_state()
2202 callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b); in pfsync_insert_state()
2207 st->sync_updates = 0; in pfsync_insert_state()
2214 struct pfsync_deferral *pd; in pfsync_defer() local
2217 if (m->m_flags & (M_BCAST|M_MCAST)) in pfsync_defer()
2227 if (!(sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) || in pfsync_defer()
2228 !(sc->sc_flags & PFSYNCF_DEFER)) { in pfsync_defer()
2236 if (b->b_deferred >= 128) in pfsync_defer()
2237 pfsync_undefer(TAILQ_FIRST(&b->b_deferrals), 0); in pfsync_defer()
2239 pd = malloc(sizeof(*pd), M_PFSYNC, M_NOWAIT); in pfsync_defer()
2240 if (pd == NULL) { in pfsync_defer()
2244 b->b_deferred++; in pfsync_defer()
2246 m->m_flags |= M_SKIP_FIREWALL; in pfsync_defer()
2247 st->state_flags |= PFSTATE_ACK; in pfsync_defer()
2249 pd->pd_sc = sc; in pfsync_defer()
2250 pd->pd_st = st; in pfsync_defer()
2252 pd->pd_m = m; in pfsync_defer()
2254 TAILQ_INSERT_TAIL(&b->b_deferrals, pd, pd_entry); in pfsync_defer()
2255 callout_init_mtx(&pd->pd_tmo, &b->b_mtx, CALLOUT_RETURNUNLOCKED); in pfsync_defer()
2256 callout_reset(&pd->pd_tmo, (V_pfsync_defer_timeout * hz) / 1000, in pfsync_defer()
2257 pfsync_defer_tmo, pd); in pfsync_defer()
2266 pfsync_undefer(struct pfsync_deferral *pd, int drop) in pfsync_undefer() argument
2268 struct pfsync_softc *sc = pd->pd_sc; in pfsync_undefer()
2269 struct mbuf *m = pd->pd_m; in pfsync_undefer()
2270 struct pf_kstate *st = pd->pd_st; in pfsync_undefer()
2275 TAILQ_REMOVE(&b->b_deferrals, pd, pd_entry); in pfsync_undefer()
2276 b->b_deferred--; in pfsync_undefer()
2277 pd->pd_st->state_flags &= ~PFSTATE_ACK; /* XXX: locking! */ in pfsync_undefer()
2278 free(pd, M_PFSYNC); in pfsync_undefer()
2284 _IF_ENQUEUE(&b->b_snd, m); in pfsync_undefer()
2293 struct pfsync_deferral *pd = arg; in pfsync_defer_tmo() local
2294 struct pfsync_softc *sc = pd->pd_sc; in pfsync_defer_tmo()
2295 struct mbuf *m = pd->pd_m; in pfsync_defer_tmo()
2296 struct pf_kstate *st = pd->pd_st; in pfsync_defer_tmo()
2299 CURVNET_SET(sc->sc_ifp->if_vnet); in pfsync_defer_tmo()
2305 TAILQ_REMOVE(&b->b_deferrals, pd, pd_entry); in pfsync_defer_tmo()
2306 b->b_deferred--; in pfsync_defer_tmo()
2307 pd->pd_st->state_flags &= ~PFSTATE_ACK; /* XXX: locking! */ in pfsync_defer_tmo()
2309 free(pd, M_PFSYNC); in pfsync_defer_tmo()
2311 if (sc->sc_sync_if == NULL) { in pfsync_defer_tmo()
2332 struct pfsync_deferral *pd; in pfsync_undefer_state_locked() local
2337 TAILQ_FOREACH(pd, &b->b_deferrals, pd_entry) { in pfsync_undefer_state_locked()
2338 if (pd->pd_st == st) { in pfsync_undefer_state_locked()
2339 if (callout_stop(&pd->pd_tmo) > 0) in pfsync_undefer_state_locked()
2340 pfsync_undefer(pd, drop); in pfsync_undefer_state_locked()
2364 return &sc->sc_buckets[c]; in pfsync_get_bucket()
2377 if (st->state_flags & PFSTATE_ACK) in pfsync_update_state()
2379 if (st->state_flags & PFSTATE_NOSYNC) { in pfsync_update_state()
2380 if (st->sync_state != PFSYNC_S_NONE) in pfsync_update_state()
2386 if (b->b_len == PFSYNC_MINPKT) in pfsync_update_state()
2387 callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b); in pfsync_update_state()
2389 switch (st->sync_state) { in pfsync_update_state()
2395 if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP) { in pfsync_update_state()
2396 st->sync_updates++; in pfsync_update_state()
2397 if (st->sync_updates >= sc->sc_maxupdates) in pfsync_update_state()
2409 st->sync_updates = 0; in pfsync_update_state()
2413 panic("%s: unexpected sync state %d", __func__, st->sync_state); in pfsync_update_state()
2416 if (sync || (time_uptime - st->pfsync_time) < 2) in pfsync_update_state()
2426 struct pfsync_bucket *b = &sc->sc_buckets[0]; in pfsync_request_update()
2437 TAILQ_FOREACH(item, &b->b_upd_req_list, ur_entry) in pfsync_request_update()
2438 if (item->ur_msg.id == id && in pfsync_request_update()
2439 item->ur_msg.creatorid == creatorid) in pfsync_request_update()
2446 item->ur_msg.id = id; in pfsync_request_update()
2447 item->ur_msg.creatorid = creatorid; in pfsync_request_update()
2449 if (TAILQ_EMPTY(&b->b_upd_req_list)) in pfsync_request_update()
2452 if (b->b_len + nlen > sc->sc_ifp->if_mtu) { in pfsync_request_update()
2459 TAILQ_INSERT_TAIL(&b->b_upd_req_list, item, ur_entry); in pfsync_request_update()
2460 b->b_len += nlen; in pfsync_request_update()
2475 if (st->state_flags & PFSTATE_NOSYNC) { in pfsync_update_state_req()
2476 if (st->sync_state != PFSYNC_S_NONE) in pfsync_update_state_req()
2482 switch (st->sync_state) { in pfsync_update_state_req()
2501 panic("%s: unexpected sync state %d", __func__, st->sync_state); in pfsync_update_state_req()
2504 if ((sc->sc_ifp->if_mtu - b->b_len) < sizeof(union pfsync_state_union)) in pfsync_update_state_req()
2520 if (st->state_flags & PFSTATE_ACK) in pfsync_delete_state()
2522 if (st->state_flags & PFSTATE_NOSYNC) { in pfsync_delete_state()
2523 if (st->sync_state != PFSYNC_S_NONE) in pfsync_delete_state()
2529 if (b->b_len == PFSYNC_MINPKT) in pfsync_delete_state()
2530 callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b); in pfsync_delete_state()
2532 switch (st->sync_state) { in pfsync_delete_state()
2550 panic("%s: unexpected sync state %d", __func__, st->sync_state); in pfsync_delete_state()
2583 switch (sc->sc_version) { in pfsync_sstate_to_qid()
2595 switch (sc->sc_version) { in pfsync_sstate_to_qid()
2609 panic("%s: Unsupported st->sync_state 0x%02x", in pfsync_sstate_to_qid()
2614 __func__, sc->sc_version); in pfsync_sstate_to_qid()
2627 KASSERT(st->sync_state == PFSYNC_S_NONE, in pfsync_q_ins()
2628 ("%s: st->sync_state %u", __func__, st->sync_state)); in pfsync_q_ins()
2629 KASSERT(b->b_len >= PFSYNC_MINPKT, ("pfsync pkt len is too low %zu", in pfsync_q_ins()
2630 b->b_len)); in pfsync_q_ins()
2632 if (TAILQ_EMPTY(&b->b_qs[q])) in pfsync_q_ins()
2635 if (b->b_len + nlen > sc->sc_ifp->if_mtu) { in pfsync_q_ins()
2636 pfsync_sendout(1, b->b_id); in pfsync_q_ins()
2641 b->b_len += nlen; in pfsync_q_ins()
2642 st->sync_state = pfsync_qid_sstate[q]; in pfsync_q_ins()
2643 TAILQ_INSERT_TAIL(&b->b_qs[q], st, sync_list); in pfsync_q_ins()
2654 KASSERT(st->sync_state != PFSYNC_S_NONE, in pfsync_q_del()
2655 ("%s: st->sync_state != PFSYNC_S_NONE", __func__)); in pfsync_q_del()
2657 q = pfsync_sstate_to_qid(st->sync_state); in pfsync_q_del()
2658 b->b_len -= pfsync_qs[q].len; in pfsync_q_del()
2659 TAILQ_REMOVE(&b->b_qs[q], st, sync_list); in pfsync_q_del()
2660 st->sync_state = PFSYNC_S_NONE; in pfsync_q_del()
2664 if (TAILQ_EMPTY(&b->b_qs[q])) in pfsync_q_del()
2665 b->b_len -= sizeof(struct pfsync_subheader); in pfsync_q_del()
2678 sc->sc_ureq_received = time_uptime; in pfsync_bulk_start()
2679 sc->sc_bulk_hashid = 0; in pfsync_bulk_start()
2680 sc->sc_bulk_stateid = 0; in pfsync_bulk_start()
2682 callout_reset(&sc->sc_bulk_tmo, 1, pfsync_bulk_update, sc); in pfsync_bulk_start()
2694 CURVNET_SET(sc->sc_ifp->if_vnet); in pfsync_bulk_update()
2701 s = pf_find_state_byid(sc->sc_bulk_stateid, sc->sc_bulk_creatorid); in pfsync_bulk_update()
2706 i = sc->sc_bulk_hashid; in pfsync_bulk_update()
2715 s = LIST_FIRST(&ih->states); in pfsync_bulk_update()
2719 if (s->sync_state == PFSYNC_S_NONE && in pfsync_bulk_update()
2720 s->timeout < PFTM_MAX && in pfsync_bulk_update()
2721 s->pfsync_time <= sc->sc_ureq_received) { in pfsync_bulk_update()
2724 sc->sc_bulk_hashid = i; in pfsync_bulk_update()
2725 sc->sc_bulk_stateid = s->id; in pfsync_bulk_update()
2726 sc->sc_bulk_creatorid = s->creatorid; in pfsync_bulk_update()
2728 callout_reset(&sc->sc_bulk_tmo, 1, in pfsync_bulk_update()
2760 r.bus.endtime = htonl(time_uptime - sc->sc_ureq_received); in pfsync_bulk_status()
2770 struct pfsync_bucket *b = &sc->sc_buckets[0]; in pfsync_bulk_fail()
2772 CURVNET_SET(sc->sc_ifp->if_vnet); in pfsync_bulk_fail()
2776 if (sc->sc_bulk_tries++ < PFSYNC_MAX_BULKTRIES) { in pfsync_bulk_fail()
2778 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, in pfsync_bulk_fail()
2785 sc->sc_ureq_sent = 0; in pfsync_bulk_fail()
2786 sc->sc_bulk_tries = 0; in pfsync_bulk_fail()
2788 if (!(sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) in pfsync_bulk_fail()
2789 (*carp_demote_adj_p)(-V_pfsync_carp_adj, in pfsync_bulk_fail()
2791 sc->sc_flags |= PFSYNCF_OK; in pfsync_bulk_fail()
2804 struct pfsync_bucket *b = &sc->sc_buckets[0]; in pfsync_send_plus()
2809 if (b->b_len + pluslen > sc->sc_ifp->if_mtu) in pfsync_send_plus()
2810 pfsync_sendout(1, b->b_id); in pfsync_send_plus()
2812 newplus = malloc(pluslen + b->b_pluslen, M_PFSYNC, M_NOWAIT); in pfsync_send_plus()
2816 if (b->b_plus != NULL) { in pfsync_send_plus()
2817 memcpy(newplus, b->b_plus, b->b_pluslen); in pfsync_send_plus()
2818 free(b->b_plus, M_PFSYNC); in pfsync_send_plus()
2820 MPASS(b->b_pluslen == 0); in pfsync_send_plus()
2822 memcpy(newplus + b->b_pluslen, plus, pluslen); in pfsync_send_plus()
2824 b->b_plus = newplus; in pfsync_send_plus()
2825 b->b_pluslen += pluslen; in pfsync_send_plus()
2826 b->b_len += pluslen; in pfsync_send_plus()
2828 pfsync_sendout(1, b->b_id); in pfsync_send_plus()
2839 CURVNET_SET(b->b_sc->sc_ifp->if_vnet); in pfsync_timeout()
2852 b->b_flags |= PFSYNCF_BUCKET_PUSH; in pfsync_push()
2863 b = &sc->sc_buckets[c]; in pfsync_push_all()
2878 MPASS(ip->ip_v == IPVERSION || ip->ip_v == (IPV6_VERSION >> 4)); in pfsync_tx()
2880 af = ip->ip_v == IPVERSION ? AF_INET : AF_INET6; in pfsync_tx()
2890 if (m->m_flags & M_SKIP_FIREWALL) { in pfsync_tx()
2895 IP_RAWOUTPUT, &sc->sc_imo, NULL); in pfsync_tx()
2901 if (m->m_flags & M_SKIP_FIREWALL) { in pfsync_tx()
2906 &sc->sc_im6o, NULL, NULL); in pfsync_tx()
2929 CURVNET_SET(sc->sc_ifp->if_vnet); in pfsyncintr()
2932 b = &sc->sc_buckets[c]; in pfsyncintr()
2935 if ((b->b_flags & PFSYNCF_BUCKET_PUSH) && b->b_len > PFSYNC_MINPKT) { in pfsyncintr()
2936 pfsync_sendout(0, b->b_id); in pfsyncintr()
2937 b->b_flags &= ~PFSYNCF_BUCKET_PUSH; in pfsyncintr()
2939 _IF_DEQUEUE_ALL(&b->b_snd, m); in pfsyncintr()
2943 n = m->m_nextpkt; in pfsyncintr()
2944 m->m_nextpkt = NULL; in pfsyncintr()
2958 struct ip_moptions *imo = &sc->sc_imo; in pfsync_multicast_setup()
2961 struct ip6_moptions *im6o = &sc->sc_im6o; in pfsync_multicast_setup()
2965 if (!(ifp->if_flags & IFF_MULTICAST)) in pfsync_multicast_setup()
2968 switch (sc->sc_sync_peer.ss_family) { in pfsync_multicast_setup()
2974 ip_mfilter_init(&imo->imo_head); in pfsync_multicast_setup()
2975 imo->imo_multicast_vif = -1; in pfsync_multicast_setup()
2977 &((struct sockaddr_in *)&sc->sc_sync_peer)->sin_addr, NULL, in pfsync_multicast_setup()
2978 &imf->imf_inm)) != 0) in pfsync_multicast_setup()
2981 ip_mfilter_insert(&imo->imo_head, imf); in pfsync_multicast_setup()
2982 imo->imo_multicast_ifp = ifp; in pfsync_multicast_setup()
2983 imo->imo_multicast_ttl = PFSYNC_DFLTTL; in pfsync_multicast_setup()
2984 imo->imo_multicast_loop = 0; in pfsync_multicast_setup()
2993 syncpeer_sa6 = (struct sockaddr_in6 *)&sc->sc_sync_peer; in pfsync_multicast_setup()
2994 if ((error = in6_setscope(&syncpeer_sa6->sin6_addr, ifp, NULL))) in pfsync_multicast_setup()
2997 ip6_mfilter_init(&im6o->im6o_head); in pfsync_multicast_setup()
2998 if ((error = in6_joingroup(ifp, &syncpeer_sa6->sin6_addr, NULL, in pfsync_multicast_setup()
2999 &(im6f->im6f_in6m), 0)) != 0) in pfsync_multicast_setup()
3002 ip6_mfilter_insert(&im6o->im6o_head, im6f); in pfsync_multicast_setup()
3003 im6o->im6o_multicast_ifp = ifp; in pfsync_multicast_setup()
3004 im6o->im6o_multicast_hlim = PFSYNC_DFLTTL; in pfsync_multicast_setup()
3005 im6o->im6o_multicast_loop = 0; in pfsync_multicast_setup()
3018 struct ip_moptions *imo = &sc->sc_imo; in pfsync_multicast_cleanup()
3021 while ((imf = ip_mfilter_first(&imo->imo_head)) != NULL) { in pfsync_multicast_cleanup()
3022 ip_mfilter_remove(&imo->imo_head, imf); in pfsync_multicast_cleanup()
3023 in_leavegroup(imf->imf_inm, NULL); in pfsync_multicast_cleanup()
3026 imo->imo_multicast_ifp = NULL; in pfsync_multicast_cleanup()
3030 struct ip6_moptions *im6o = &sc->sc_im6o; in pfsync_multicast_cleanup()
3033 while ((im6f = ip6_mfilter_first(&im6o->im6o_head)) != NULL) { in pfsync_multicast_cleanup()
3034 ip6_mfilter_remove(&im6o->im6o_head, im6f); in pfsync_multicast_cleanup()
3035 in6_leavegroup(im6f->im6f_in6m, NULL); in pfsync_multicast_cleanup()
3038 im6o->im6o_multicast_ifp = NULL; in pfsync_multicast_cleanup()
3052 if (sc->sc_sync_if == ifp) { in pfsync_detach_ifnet()
3057 ip_mfilter_init(&sc->sc_imo.imo_head); in pfsync_detach_ifnet()
3058 sc->sc_imo.imo_multicast_ifp = NULL; in pfsync_detach_ifnet()
3059 sc->sc_im6o.im6o_multicast_ifp = NULL; in pfsync_detach_ifnet()
3060 sc->sc_sync_if = NULL; in pfsync_detach_ifnet()
3070 status->maxupdates = pfsyncr->pfsyncr_maxupdates; in pfsync_pfsyncreq_to_kstatus()
3071 status->flags = pfsyncr->pfsyncr_defer; in pfsync_pfsyncreq_to_kstatus()
3073 strlcpy(status->syncdev, pfsyncr->pfsyncr_syncdev, IFNAMSIZ); in pfsync_pfsyncreq_to_kstatus()
3076 if (pfsyncr->pfsyncr_syncpeer.s_addr != 0) { in pfsync_pfsyncreq_to_kstatus()
3078 in->sin_family = AF_INET; in pfsync_pfsyncreq_to_kstatus()
3079 in->sin_len = sizeof(*in); in pfsync_pfsyncreq_to_kstatus()
3080 in->sin_addr.s_addr = pfsyncr->pfsyncr_syncpeer.s_addr; in pfsync_pfsyncreq_to_kstatus()
3082 status->syncpeer = sa; in pfsync_pfsyncreq_to_kstatus()
3096 if ((status->maxupdates < 0) || (status->maxupdates > 255)) in pfsync_kstatus_to_softc()
3099 if (status->syncdev[0] == '\0') in pfsync_kstatus_to_softc()
3101 else if ((sifp = ifunit_ref(status->syncdev)) == NULL) in pfsync_kstatus_to_softc()
3104 switch (status->syncpeer.ss_family) { in pfsync_kstatus_to_softc()
3109 status_sin = (struct sockaddr_in *)&(status->syncpeer); in pfsync_kstatus_to_softc()
3111 if (status_sin->sin_addr.s_addr == 0 || in pfsync_kstatus_to_softc()
3112 status_sin->sin_addr.s_addr == in pfsync_kstatus_to_softc()
3114 status_sin->sin_family = AF_INET; in pfsync_kstatus_to_softc()
3115 status_sin->sin_len = sizeof(*status_sin); in pfsync_kstatus_to_softc()
3116 status_sin->sin_addr.s_addr = in pfsync_kstatus_to_softc()
3120 if (IN_MULTICAST(ntohl(status_sin->sin_addr.s_addr))) { in pfsync_kstatus_to_softc()
3130 status_sin6 = (struct sockaddr_in6*)&(status->syncpeer); in pfsync_kstatus_to_softc()
3132 if (IN6_IS_ADDR_UNSPECIFIED(&status_sin6->sin6_addr) || in pfsync_kstatus_to_softc()
3133 IN6_ARE_ADDR_EQUAL(&status_sin6->sin6_addr, in pfsync_kstatus_to_softc()
3135 status_sin6->sin6_family = AF_INET6; in pfsync_kstatus_to_softc()
3136 status_sin6->sin6_len = sizeof(*status_sin6); in pfsync_kstatus_to_softc()
3137 status_sin6->sin6_addr = in pfsync_kstatus_to_softc()
3141 if (IN6_IS_ADDR_MULTICAST(&status_sin6->sin6_addr)) { in pfsync_kstatus_to_softc()
3152 switch (status->version) { in pfsync_kstatus_to_softc()
3154 sc->sc_version = PFSYNC_MSG_VERSION_DEFAULT; in pfsync_kstatus_to_softc()
3159 sc->sc_version = status->version; in pfsync_kstatus_to_softc()
3166 switch (status->syncpeer.ss_family) { in pfsync_kstatus_to_softc()
3168 struct sockaddr_in *status_sin = (struct sockaddr_in *)&(status->syncpeer); in pfsync_kstatus_to_softc()
3169 struct sockaddr_in *sc_sin = (struct sockaddr_in *)&sc->sc_sync_peer; in pfsync_kstatus_to_softc()
3170 sc_sin->sin_family = AF_INET; in pfsync_kstatus_to_softc()
3171 sc_sin->sin_len = sizeof(*sc_sin); in pfsync_kstatus_to_softc()
3172 if (status_sin->sin_addr.s_addr == 0) { in pfsync_kstatus_to_softc()
3173 sc_sin->sin_addr.s_addr = htonl(INADDR_PFSYNC_GROUP); in pfsync_kstatus_to_softc()
3175 sc_sin->sin_addr.s_addr = status_sin->sin_addr.s_addr; in pfsync_kstatus_to_softc()
3180 struct sockaddr_in6 *status_sin = (struct sockaddr_in6 *)&(status->syncpeer); in pfsync_kstatus_to_softc()
3181 struct sockaddr_in6 *sc_sin = (struct sockaddr_in6 *)&sc->sc_sync_peer; in pfsync_kstatus_to_softc()
3182 sc_sin->sin6_family = AF_INET6; in pfsync_kstatus_to_softc()
3183 sc_sin->sin6_len = sizeof(*sc_sin); in pfsync_kstatus_to_softc()
3184 if(IN6_IS_ADDR_UNSPECIFIED(&status_sin->sin6_addr)) { in pfsync_kstatus_to_softc()
3185 sc_sin->sin6_addr = in6addr_linklocal_pfsync_group; in pfsync_kstatus_to_softc()
3187 sc_sin->sin6_addr = status_sin->sin6_addr; in pfsync_kstatus_to_softc()
3193 sc->sc_maxupdates = status->maxupdates; in pfsync_kstatus_to_softc()
3194 if (status->flags & PFSYNCF_DEFER) { in pfsync_kstatus_to_softc()
3195 sc->sc_flags |= PFSYNCF_DEFER; in pfsync_kstatus_to_softc()
3198 sc->sc_flags &= ~PFSYNCF_DEFER; in pfsync_kstatus_to_softc()
3203 if (sc->sc_sync_if) in pfsync_kstatus_to_softc()
3204 if_rele(sc->sc_sync_if); in pfsync_kstatus_to_softc()
3205 sc->sc_sync_if = NULL; in pfsync_kstatus_to_softc()
3212 PFSYNC_BUCKET_LOCK(&sc->sc_buckets[c]); in pfsync_kstatus_to_softc()
3213 if (sc->sc_buckets[c].b_len > PFSYNC_MINPKT && in pfsync_kstatus_to_softc()
3214 (sifp->if_mtu < sc->sc_ifp->if_mtu || in pfsync_kstatus_to_softc()
3215 (sc->sc_sync_if != NULL && in pfsync_kstatus_to_softc()
3216 sifp->if_mtu < sc->sc_sync_if->if_mtu) || in pfsync_kstatus_to_softc()
3217 sifp->if_mtu < MCLBYTES - sizeof(struct ip))) in pfsync_kstatus_to_softc()
3219 PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[c]); in pfsync_kstatus_to_softc()
3224 if (((sc->sc_sync_peer.ss_family == AF_INET) && in pfsync_kstatus_to_softc()
3226 &sc->sc_sync_peer)->sin_addr.s_addr))) || in pfsync_kstatus_to_softc()
3227 ((sc->sc_sync_peer.ss_family == AF_INET6) && in pfsync_kstatus_to_softc()
3229 &sc->sc_sync_peer)->sin6_addr))) { in pfsync_kstatus_to_softc()
3245 if (sc->sc_sync_if) in pfsync_kstatus_to_softc()
3246 if_rele(sc->sc_sync_if); in pfsync_kstatus_to_softc()
3247 sc->sc_sync_if = sifp; in pfsync_kstatus_to_softc()
3249 switch (sc->sc_sync_peer.ss_family) { in pfsync_kstatus_to_softc()
3253 ip = &sc->sc_template.ipv4; in pfsync_kstatus_to_softc()
3255 ip->ip_v = IPVERSION; in pfsync_kstatus_to_softc()
3256 ip->ip_hl = sizeof(sc->sc_template.ipv4) >> 2; in pfsync_kstatus_to_softc()
3257 ip->ip_tos = IPTOS_LOWDELAY; in pfsync_kstatus_to_softc()
3259 ip->ip_off = htons(IP_DF); in pfsync_kstatus_to_softc()
3260 ip->ip_ttl = PFSYNC_DFLTTL; in pfsync_kstatus_to_softc()
3261 ip->ip_p = IPPROTO_PFSYNC; in pfsync_kstatus_to_softc()
3262 ip->ip_src.s_addr = INADDR_ANY; in pfsync_kstatus_to_softc()
3263 ip->ip_dst = ((struct sockaddr_in *)&sc->sc_sync_peer)->sin_addr; in pfsync_kstatus_to_softc()
3270 ip6 = &sc->sc_template.ipv6; in pfsync_kstatus_to_softc()
3272 ip6->ip6_vfc = IPV6_VERSION; in pfsync_kstatus_to_softc()
3273 ip6->ip6_hlim = PFSYNC_DFLTTL; in pfsync_kstatus_to_softc()
3274 ip6->ip6_nxt = IPPROTO_PFSYNC; in pfsync_kstatus_to_softc()
3275 ip6->ip6_dst = ((struct sockaddr_in6 *)&sc->sc_sync_peer)->sin6_addr; in pfsync_kstatus_to_softc()
3279 in6_selectsrc_addr(if_getfib(sc->sc_sync_if), &ip6->ip6_dst, 0, in pfsync_kstatus_to_softc()
3280 sc->sc_sync_if, &ip6->ip6_src, NULL); in pfsync_kstatus_to_softc()
3288 if ((sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) in pfsync_kstatus_to_softc()
3291 sc->sc_flags &= ~PFSYNCF_OK; in pfsync_kstatus_to_softc()
3295 PFSYNC_BUCKET_LOCK(&sc->sc_buckets[0]); in pfsync_kstatus_to_softc()
3297 PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[0]); in pfsync_kstatus_to_softc()
3299 sc->sc_ureq_sent = time_uptime; in pfsync_kstatus_to_softc()
3300 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, pfsync_bulk_fail, sc); in pfsync_kstatus_to_softc()