Lines Matching +full:scaled +full:- +full:sync
1 /*-
2 * SPDX-License-Identifier: (BSD-2-Clause AND ISC)
30 /*-
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
166 /* We have the following sync queues */
196 /* Map queue to pf_kstate->sync_state */
207 /* Map pf_kstate->sync_state to queue */
278 #define PFSYNC_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
279 #define PFSYNC_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
280 #define PFSYNC_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
282 #define PFSYNC_BUCKET_LOCK(b) mtx_lock(&(b)->b_mtx)
283 #define PFSYNC_BUCKET_UNLOCK(b) mtx_unlock(&(b)->b_mtx)
284 #define PFSYNC_BUCKET_LOCK_ASSERT(b) mtx_assert(&(b)->b_mtx, MA_OWNED)
286 #define PFSYNC_BLOCK(sc) mtx_lock(&(sc)->sc_bulk_mtx)
287 #define PFSYNC_BUNLOCK(sc) mtx_unlock(&(sc)->sc_bulk_mtx)
288 #define PFSYNC_BLOCK_ASSERT(sc) mtx_assert(&(sc)->sc_bulk_mtx, MA_OWNED)
397 sc->sc_flags |= PFSYNCF_OK; in pfsync_clone_create()
398 sc->sc_maxupdates = 128; in pfsync_clone_create()
399 sc->sc_version = PFSYNC_MSG_VERSION_DEFAULT; in pfsync_clone_create()
401 ifp = sc->sc_ifp = if_alloc(IFT_PFSYNC); in pfsync_clone_create()
403 ifp->if_softc = sc; in pfsync_clone_create()
404 ifp->if_ioctl = pfsyncioctl; in pfsync_clone_create()
405 ifp->if_output = pfsyncoutput; in pfsync_clone_create()
406 ifp->if_type = IFT_PFSYNC; in pfsync_clone_create()
407 ifp->if_hdrlen = sizeof(struct pfsync_header); in pfsync_clone_create()
408 ifp->if_mtu = ETHERMTU; in pfsync_clone_create()
409 mtx_init(&sc->sc_mtx, pfsyncname, NULL, MTX_DEF); in pfsync_clone_create()
410 mtx_init(&sc->sc_bulk_mtx, "pfsync bulk", NULL, MTX_DEF); in pfsync_clone_create()
411 callout_init_mtx(&sc->sc_bulk_tmo, &sc->sc_bulk_mtx, 0); in pfsync_clone_create()
412 callout_init_mtx(&sc->sc_bulkfail_tmo, &sc->sc_bulk_mtx, 0); in pfsync_clone_create()
418 sc->sc_buckets = mallocarray(pfsync_buckets, sizeof(*sc->sc_buckets), in pfsync_clone_create()
421 b = &sc->sc_buckets[c]; in pfsync_clone_create()
422 mtx_init(&b->b_mtx, "pfsync bucket", NULL, MTX_DEF); in pfsync_clone_create()
424 b->b_id = c; in pfsync_clone_create()
425 b->b_sc = sc; in pfsync_clone_create()
426 b->b_len = PFSYNC_MINPKT; in pfsync_clone_create()
429 TAILQ_INIT(&b->b_qs[q]); in pfsync_clone_create()
431 TAILQ_INIT(&b->b_upd_req_list); in pfsync_clone_create()
432 TAILQ_INIT(&b->b_deferrals); in pfsync_clone_create()
434 callout_init(&b->b_tmo, 1); in pfsync_clone_create()
436 b->b_snd.ifq_maxlen = ifqmaxlen; in pfsync_clone_create()
447 struct pfsync_softc *sc = ifp->if_softc; in pfsync_clone_destroy()
452 b = &sc->sc_buckets[c]; in pfsync_clone_destroy()
459 while (b->b_deferred > 0) { in pfsync_clone_destroy()
461 TAILQ_FIRST(&b->b_deferrals); in pfsync_clone_destroy()
463 ret = callout_stop(&pd->pd_tmo); in pfsync_clone_destroy()
468 callout_drain(&pd->pd_tmo); in pfsync_clone_destroy()
472 MPASS(b->b_deferred == 0); in pfsync_clone_destroy()
473 MPASS(TAILQ_EMPTY(&b->b_deferrals)); in pfsync_clone_destroy()
476 free(b->b_plus, M_PFSYNC); in pfsync_clone_destroy()
477 b->b_plus = NULL; in pfsync_clone_destroy()
478 b->b_pluslen = 0; in pfsync_clone_destroy()
480 callout_drain(&b->b_tmo); in pfsync_clone_destroy()
483 callout_drain(&sc->sc_bulkfail_tmo); in pfsync_clone_destroy()
484 callout_drain(&sc->sc_bulk_tmo); in pfsync_clone_destroy()
486 if (!(sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) in pfsync_clone_destroy()
487 (*carp_demote_adj_p)(-V_pfsync_carp_adj, "pfsync destroy"); in pfsync_clone_destroy()
495 mtx_destroy(&sc->sc_mtx); in pfsync_clone_destroy()
496 mtx_destroy(&sc->sc_bulk_mtx); in pfsync_clone_destroy()
498 free(sc->sc_buckets, M_PFSYNC); in pfsync_clone_destroy()
508 if (s->scrub.scrub_flag && d->scrub == NULL) { in pfsync_alloc_scrub_memory()
509 d->scrub = uma_zalloc(V_pf_state_scrub_z, M_NOWAIT | M_ZERO); in pfsync_alloc_scrub_memory()
510 if (d->scrub == NULL) in pfsync_alloc_scrub_memory()
536 if (sp->pfs_1301.creatorid == 0) { in pfsync_state_import()
539 ntohl(sp->pfs_1301.creatorid)); in pfsync_state_import()
543 if ((kif = pfi_kkif_find(sp->pfs_1301.ifname)) == NULL) { in pfsync_state_import()
546 sp->pfs_1301.ifname); in pfsync_state_import()
556 if (sp->pfs_1301.rule != htonl(-1) && sp->pfs_1301.anchor == htonl(-1) && in pfsync_state_import()
557 (flags & (PFSYNC_SI_IOCTL | PFSYNC_SI_CKSUM)) && ntohl(sp->pfs_1301.rule) < in pfsync_state_import()
560 PF_RULESET_FILTER].active.ptr_array[ntohl(sp->pfs_1301.rule)]; in pfsync_state_import()
577 struct pf_kpool *pool = &r->route; in pfsync_state_import()
580 if (TAILQ_EMPTY(&pool->list)) in pfsync_state_import()
581 pool = &r->rdr; in pfsync_state_import()
591 rpool_first = TAILQ_FIRST(&(pool->list)); in pfsync_state_import()
600 rt = r->rt; in pfsync_state_import()
601 rt_kif = rpool_first->kif; in pfsync_state_import()
602 } else if (!PF_AZERO(&sp->pfs_1301.rt_addr, sp->pfs_1301.af)) { in pfsync_state_import()
618 if (sp->pfs_1400.rt) { in pfsync_state_import()
619 rt_kif = pfi_kkif_find(sp->pfs_1400.rt_ifname); in pfsync_state_import()
623 __func__, sp->pfs_1400.rt_ifname)); in pfsync_state_import()
626 rt = sp->pfs_1400.rt; in pfsync_state_import()
631 if ((r->max_states && in pfsync_state_import()
632 counter_u64_fetch(r->states_cur) >= r->max_states)) in pfsync_state_import()
646 bcopy(&sp->pfs_1301.key, key, sizeof(struct pfsync_state_key) * 2); in pfsync_state_import()
650 kw = &sp->pfs_1301.key[PF_SK_WIRE]; in pfsync_state_import()
651 ks = &sp->pfs_1301.key[PF_SK_STACK]; in pfsync_state_import()
654 if (PF_ANEQ(&kw->addr[0], &ks->addr[0], sp->pfs_1301.af) || in pfsync_state_import()
655 PF_ANEQ(&kw->addr[1], &ks->addr[1], sp->pfs_1301.af) || in pfsync_state_import()
656 kw->port[0] != ks->port[0] || in pfsync_state_import()
657 kw->port[1] != ks->port[1]) { in pfsync_state_import()
665 if (pfsync_alloc_scrub_memory(&sp->pfs_1301.src, &st->src) || in pfsync_state_import()
666 pfsync_alloc_scrub_memory(&sp->pfs_1301.dst, &st->dst)) in pfsync_state_import()
670 skw->addr[0] = kw->addr[0]; in pfsync_state_import()
671 skw->addr[1] = kw->addr[1]; in pfsync_state_import()
672 skw->port[0] = kw->port[0]; in pfsync_state_import()
673 skw->port[1] = kw->port[1]; in pfsync_state_import()
674 skw->proto = sp->pfs_1301.proto; in pfsync_state_import()
675 skw->af = sp->pfs_1301.af; in pfsync_state_import()
677 sks->addr[0] = ks->addr[0]; in pfsync_state_import()
678 sks->addr[1] = ks->addr[1]; in pfsync_state_import()
679 sks->port[0] = ks->port[0]; in pfsync_state_import()
680 sks->port[1] = ks->port[1]; in pfsync_state_import()
681 sks->proto = sp->pfs_1301.proto; in pfsync_state_import()
682 sks->af = sp->pfs_1301.af; in pfsync_state_import()
686 bcopy(&sp->pfs_1301.rt_addr, &st->act.rt_addr, sizeof(st->act.rt_addr)); in pfsync_state_import()
687 st->creation = (time_uptime - ntohl(sp->pfs_1301.creation)) * 1000; in pfsync_state_import()
688 st->expire = pf_get_uptime(); in pfsync_state_import()
689 if (sp->pfs_1301.expire) { in pfsync_state_import()
692 timeout = r->timeout[sp->pfs_1301.timeout]; in pfsync_state_import()
694 timeout = V_pf_default_rule.timeout[sp->pfs_1301.timeout]; in pfsync_state_import()
696 /* sp->expire may have been adaptively scaled by export. */ in pfsync_state_import()
697 st->expire -= (timeout - ntohl(sp->pfs_1301.expire)) * 1000; in pfsync_state_import()
700 st->direction = sp->pfs_1301.direction; in pfsync_state_import()
701 st->act.log = sp->pfs_1301.log; in pfsync_state_import()
702 st->timeout = sp->pfs_1301.timeout; in pfsync_state_import()
704 st->act.rt = rt; in pfsync_state_import()
705 st->act.rt_kif = rt_kif; in pfsync_state_import()
709 st->state_flags = sp->pfs_1301.state_flags; in pfsync_state_import()
717 st->state_flags &= ~PFSTATE_SETMASK; in pfsync_state_import()
725 st->act.qid = r->qid; in pfsync_state_import()
726 st->act.pqid = r->pqid; in pfsync_state_import()
727 st->act.rtableid = r->rtableid; in pfsync_state_import()
728 if (r->scrub_flags & PFSTATE_SETTOS) in pfsync_state_import()
729 st->act.set_tos = r->set_tos; in pfsync_state_import()
730 st->act.min_ttl = r->min_ttl; in pfsync_state_import()
731 st->act.max_mss = r->max_mss; in pfsync_state_import()
732 st->state_flags |= (r->scrub_flags & in pfsync_state_import()
736 if (r->dnpipe || r->dnrpipe) { in pfsync_state_import()
737 if (r->free_flags & PFRULE_DN_IS_PIPE) in pfsync_state_import()
738 st->state_flags |= PFSTATE_DN_IS_PIPE; in pfsync_state_import()
740 st->state_flags &= ~PFSTATE_DN_IS_PIPE; in pfsync_state_import()
742 st->act.dnpipe = r->dnpipe; in pfsync_state_import()
743 st->act.dnrpipe = r->dnrpipe; in pfsync_state_import()
747 st->state_flags = ntohs(sp->pfs_1400.state_flags); in pfsync_state_import()
748 st->act.qid = ntohs(sp->pfs_1400.qid); in pfsync_state_import()
749 st->act.pqid = ntohs(sp->pfs_1400.pqid); in pfsync_state_import()
750 st->act.dnpipe = ntohs(sp->pfs_1400.dnpipe); in pfsync_state_import()
751 st->act.dnrpipe = ntohs(sp->pfs_1400.dnrpipe); in pfsync_state_import()
752 st->act.rtableid = ntohl(sp->pfs_1400.rtableid); in pfsync_state_import()
753 st->act.min_ttl = sp->pfs_1400.min_ttl; in pfsync_state_import()
754 st->act.set_tos = sp->pfs_1400.set_tos; in pfsync_state_import()
755 st->act.max_mss = ntohs(sp->pfs_1400.max_mss); in pfsync_state_import()
756 st->act.set_prio[0] = sp->pfs_1400.set_prio[0]; in pfsync_state_import()
757 st->act.set_prio[1] = sp->pfs_1400.set_prio[1]; in pfsync_state_import()
764 st->id = sp->pfs_1301.id; in pfsync_state_import()
765 st->creatorid = sp->pfs_1301.creatorid; in pfsync_state_import()
766 pf_state_peer_ntoh(&sp->pfs_1301.src, &st->src); in pfsync_state_import()
767 pf_state_peer_ntoh(&sp->pfs_1301.dst, &st->dst); in pfsync_state_import()
769 st->rule = r; in pfsync_state_import()
770 st->nat_rule = NULL; in pfsync_state_import()
771 st->anchor = NULL; in pfsync_state_import()
773 st->pfsync_time = time_uptime; in pfsync_state_import()
774 st->sync_state = PFSYNC_S_NONE; in pfsync_state_import()
777 st->state_flags |= PFSTATE_NOSYNC; in pfsync_state_import()
783 counter_u64_add(r->states_cur, 1); in pfsync_state_import()
784 counter_u64_add(r->states_tot, 1); in pfsync_state_import()
787 st->state_flags &= ~PFSTATE_NOSYNC; in pfsync_state_import()
788 if (st->state_flags & PFSTATE_ACK) { in pfsync_state_import()
797 st->state_flags &= ~PFSTATE_ACK; in pfsync_state_import()
812 st->timeout = PFTM_UNLINKED; /* appease an assert */ in pfsync_state_import()
837 /* Verify that we have a sync interface configured. */ in pfsync_input()
838 if (!sc || !sc->sc_sync_if || !V_pf_status.running || in pfsync_input()
839 (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) in pfsync_input()
843 if (sc->sc_sync_if != m->m_pkthdr.rcvif) { in pfsync_input()
848 if_inc_counter(sc->sc_ifp, IFCOUNTER_IPACKETS, 1); in pfsync_input()
849 if_inc_counter(sc->sc_ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); in pfsync_input()
851 if (ip->ip_ttl != PFSYNC_DFLTTL) { in pfsync_input()
856 offset = ip->ip_hl << 2; in pfsync_input()
857 if (m->m_pkthdr.len < offset + sizeof(*ph)) { in pfsync_input()
862 if (offset + sizeof(*ph) > m->m_len) { in pfsync_input()
872 if (ph->version != PFSYNC_VERSION) { in pfsync_input()
877 len = ntohs(ph->len) + offset; in pfsync_input()
878 if (m->m_pkthdr.len < len) { in pfsync_input()
888 if (!bcmp(&ph->pfcksum, &V_pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH)) in pfsync_input()
892 while (offset <= len - sizeof(subh)) { in pfsync_input()
905 if (rv == -1) { in pfsync_input()
939 /* Verify that we have a sync interface configured. */ in pfsync6_input()
940 if (!sc || !sc->sc_sync_if || !V_pf_status.running || in pfsync6_input()
941 (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) in pfsync6_input()
945 if (sc->sc_sync_if != m->m_pkthdr.rcvif) { in pfsync6_input()
950 if_inc_counter(sc->sc_ifp, IFCOUNTER_IPACKETS, 1); in pfsync6_input()
951 if_inc_counter(sc->sc_ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); in pfsync6_input()
953 if (ip6->ip6_hlim != PFSYNC_DFLTTL) { in pfsync6_input()
960 if (m->m_pkthdr.len < offset + sizeof(*ph)) { in pfsync6_input()
965 if (offset + sizeof(*ph) > m->m_len) { in pfsync6_input()
975 if (ph->version != PFSYNC_VERSION) { in pfsync6_input()
980 len = ntohs(ph->len) + offset; in pfsync6_input()
981 if (m->m_pkthdr.len < len) { in pfsync6_input()
991 if (!bcmp(&ph->pfcksum, &V_pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH)) in pfsync6_input()
995 while (offset <= len - sizeof(subh)) { in pfsync6_input()
1008 if (rv == -1) { in pfsync6_input()
1035 return (-1); in pfsync_in_clr()
1037 clr = (struct pfsync_clr *)(mp->m_data + offp); in pfsync_in_clr()
1051 LIST_FOREACH(s, &ih->states, entry) { in pfsync_in_clr()
1052 if (s->creatorid == creatorid) { in pfsync_in_clr()
1053 s->state_flags |= PFSTATE_NOSYNC; in pfsync_in_clr()
1085 return (-1); in pfsync_in_ins()
1091 return (-1); in pfsync_in_ins()
1093 sa = (union pfsync_state_union *)(mp->m_data + offp); in pfsync_in_ins()
1099 if (sp->pfs_1301.timeout >= PFTM_MAX || in pfsync_in_ins()
1100 sp->pfs_1301.src.state > PF_TCPS_PROXY_DST || in pfsync_in_ins()
1101 sp->pfs_1301.dst.state > PF_TCPS_PROXY_DST || in pfsync_in_ins()
1102 sp->pfs_1301.direction > PF_OUT || in pfsync_in_ins()
1103 (sp->pfs_1301.af != AF_INET && in pfsync_in_ins()
1104 sp->pfs_1301.af != AF_INET6)) { in pfsync_in_ins()
1132 return (-1); in pfsync_in_iack()
1134 iaa = (struct pfsync_ins_ack *)(mp->m_data + offp); in pfsync_in_iack()
1139 st = pf_find_state_byid(ia->id, ia->creatorid); in pfsync_in_iack()
1143 if (st->state_flags & PFSTATE_ACK) { in pfsync_in_iack()
1160 int sync = 0; in pfsync_upd_tcp() local
1166 * for syn-proxy states. Neither should the in pfsync_upd_tcp()
1169 if ((st->src.state > src->state && in pfsync_upd_tcp()
1170 (st->src.state < PF_TCPS_PROXY_SRC || in pfsync_upd_tcp()
1171 src->state >= PF_TCPS_PROXY_SRC)) || in pfsync_upd_tcp()
1173 (st->src.state == src->state && in pfsync_upd_tcp()
1174 SEQ_GT(st->src.seqlo, ntohl(src->seqlo)))) in pfsync_upd_tcp()
1175 sync++; in pfsync_upd_tcp()
1177 pf_state_peer_ntoh(src, &st->src); in pfsync_upd_tcp()
1179 if ((st->dst.state > dst->state) || in pfsync_upd_tcp()
1181 (st->dst.state >= TCPS_SYN_SENT && in pfsync_upd_tcp()
1182 SEQ_GT(st->dst.seqlo, ntohl(dst->seqlo)))) in pfsync_upd_tcp()
1183 sync++; in pfsync_upd_tcp()
1185 pf_state_peer_ntoh(dst, &st->dst); in pfsync_upd_tcp()
1187 return (sync); in pfsync_upd_tcp()
1197 int sync, offp, i, total_len, msg_len, msg_version; in pfsync_in_upd() local
1212 return (-1); in pfsync_in_upd()
1218 return (-1); in pfsync_in_upd()
1220 sa = (union pfsync_state_union *)(mp->m_data + offp); in pfsync_in_upd()
1226 if (sp->pfs_1301.timeout >= PFTM_MAX || in pfsync_in_upd()
1227 sp->pfs_1301.src.state > PF_TCPS_PROXY_DST || in pfsync_in_upd()
1228 sp->pfs_1301.dst.state > PF_TCPS_PROXY_DST) { in pfsync_in_upd()
1237 st = pf_find_state_byid(sp->pfs_1301.id, sp->pfs_1301.creatorid); in pfsync_in_upd()
1245 if (st->state_flags & PFSTATE_ACK) { in pfsync_in_upd()
1249 if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP) in pfsync_in_upd()
1250 sync = pfsync_upd_tcp(st, &sp->pfs_1301.src, &sp->pfs_1301.dst); in pfsync_in_upd()
1252 sync = 0; in pfsync_in_upd()
1255 * Non-TCP protocol state machine always go in pfsync_in_upd()
1258 if (st->src.state > sp->pfs_1301.src.state) in pfsync_in_upd()
1259 sync++; in pfsync_in_upd()
1261 pf_state_peer_ntoh(&sp->pfs_1301.src, &st->src); in pfsync_in_upd()
1262 if (st->dst.state > sp->pfs_1301.dst.state) in pfsync_in_upd()
1263 sync++; in pfsync_in_upd()
1265 pf_state_peer_ntoh(&sp->pfs_1301.dst, &st->dst); in pfsync_in_upd()
1267 if (sync < 2) { in pfsync_in_upd()
1268 pfsync_alloc_scrub_memory(&sp->pfs_1301.dst, &st->dst); in pfsync_in_upd()
1269 pf_state_peer_ntoh(&sp->pfs_1301.dst, &st->dst); in pfsync_in_upd()
1270 st->expire = pf_get_uptime(); in pfsync_in_upd()
1271 st->timeout = sp->pfs_1301.timeout; in pfsync_in_upd()
1273 st->pfsync_time = time_uptime; in pfsync_in_upd()
1275 if (sync) { in pfsync_in_upd()
1296 int sync; in pfsync_in_upd_c() local
1303 return (-1); in pfsync_in_upd_c()
1305 ua = (struct pfsync_upd_c *)(mp->m_data + offp); in pfsync_in_upd_c()
1311 if (up->timeout >= PFTM_MAX || in pfsync_in_upd_c()
1312 up->src.state > PF_TCPS_PROXY_DST || in pfsync_in_upd_c()
1313 up->dst.state > PF_TCPS_PROXY_DST) { in pfsync_in_upd_c()
1323 st = pf_find_state_byid(up->id, up->creatorid); in pfsync_in_upd_c()
1326 PFSYNC_BUCKET_LOCK(&sc->sc_buckets[0]); in pfsync_in_upd_c()
1327 pfsync_request_update(up->creatorid, up->id); in pfsync_in_upd_c()
1328 PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[0]); in pfsync_in_upd_c()
1332 if (st->state_flags & PFSTATE_ACK) { in pfsync_in_upd_c()
1336 if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP) in pfsync_in_upd_c()
1337 sync = pfsync_upd_tcp(st, &up->src, &up->dst); in pfsync_in_upd_c()
1339 sync = 0; in pfsync_in_upd_c()
1342 * Non-TCP protocol state machine always go in pfsync_in_upd_c()
1345 if (st->src.state > up->src.state) in pfsync_in_upd_c()
1346 sync++; in pfsync_in_upd_c()
1348 pf_state_peer_ntoh(&up->src, &st->src); in pfsync_in_upd_c()
1349 if (st->dst.state > up->dst.state) in pfsync_in_upd_c()
1350 sync++; in pfsync_in_upd_c()
1352 pf_state_peer_ntoh(&up->dst, &st->dst); in pfsync_in_upd_c()
1354 if (sync < 2) { in pfsync_in_upd_c()
1355 pfsync_alloc_scrub_memory(&up->dst, &st->dst); in pfsync_in_upd_c()
1356 pf_state_peer_ntoh(&up->dst, &st->dst); in pfsync_in_upd_c()
1357 st->expire = pf_get_uptime(); in pfsync_in_upd_c()
1358 st->timeout = up->timeout; in pfsync_in_upd_c()
1360 st->pfsync_time = time_uptime; in pfsync_in_upd_c()
1362 if (sync) { in pfsync_in_upd_c()
1389 return (-1); in pfsync_in_ureq()
1391 ura = (struct pfsync_upd_req *)(mp->m_data + offp); in pfsync_in_ureq()
1396 if (ur->id == 0 && ur->creatorid == 0) in pfsync_in_ureq()
1399 st = pf_find_state_byid(ur->id, ur->creatorid); in pfsync_in_ureq()
1404 if (st->state_flags & PFSTATE_NOSYNC) { in pfsync_in_ureq()
1429 return (-1); in pfsync_in_del_c()
1431 sa = (struct pfsync_del_c *)(mp->m_data + offp); in pfsync_in_del_c()
1436 st = pf_find_state_byid(sp->id, sp->creatorid); in pfsync_in_del_c()
1442 st->state_flags |= PFSTATE_NOSYNC; in pfsync_in_del_c()
1461 if (sc->sc_ureq_sent == 0) { in pfsync_in_bus()
1470 return (-1); in pfsync_in_bus()
1472 bus = (struct pfsync_bus *)(mp->m_data + offp); in pfsync_in_bus()
1474 switch (bus->status) { in pfsync_in_bus()
1476 callout_reset(&sc->sc_bulkfail_tmo, 4 * hz + in pfsync_in_bus()
1478 ((sc->sc_ifp->if_mtu - PFSYNC_MINPKT) / in pfsync_in_bus()
1486 if (time_uptime - ntohl(bus->endtime) >= in pfsync_in_bus()
1487 sc->sc_ureq_sent) { in pfsync_in_bus()
1489 sc->sc_ureq_sent = 0; in pfsync_in_bus()
1490 sc->sc_bulk_tries = 0; in pfsync_in_bus()
1491 callout_stop(&sc->sc_bulkfail_tmo); in pfsync_in_bus()
1492 if (!(sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) in pfsync_in_bus()
1493 (*carp_demote_adj_p)(-V_pfsync_carp_adj, in pfsync_in_bus()
1495 sc->sc_flags |= PFSYNCF_OK; in pfsync_in_bus()
1526 return (-1); in pfsync_in_tdb()
1528 tp = (struct pfsync_tdb *)(mp->m_data + offp); in pfsync_in_tdb()
1538 /* Update an in-kernel tdb. Silently fail if no tdb is found. */
1546 if (ntohl(pt->spi) <= SPI_RESERVED_MAX || in pfsync_update_net_tdb()
1547 (pt->dst.sa.sa_family != AF_INET && in pfsync_update_net_tdb()
1548 pt->dst.sa.sa_family != AF_INET6)) in pfsync_update_net_tdb()
1551 tdb = gettdb(pt->spi, &pt->dst, pt->sproto); in pfsync_update_net_tdb()
1553 pt->rpl = ntohl(pt->rpl); in pfsync_update_net_tdb()
1554 pt->cur_bytes = (unsigned long long)be64toh(pt->cur_bytes); in pfsync_update_net_tdb()
1557 if (pt->rpl < tdb->tdb_rpl || in pfsync_update_net_tdb()
1558 pt->cur_bytes < tdb->tdb_cur_bytes) { in pfsync_update_net_tdb()
1562 tdb->tdb_rpl = pt->rpl; in pfsync_update_net_tdb()
1563 tdb->tdb_cur_bytes = pt->cur_bytes; in pfsync_update_net_tdb()
1580 if (offset != m->m_pkthdr.len) in pfsync_in_eof()
1585 return (-1); in pfsync_in_eof()
1594 return (-1); in pfsync_in_error()
1609 struct pfsync_softc *sc = ifp->if_softc; in pfsyncioctl()
1619 if (ifp->if_flags & IFF_UP) { in pfsyncioctl()
1620 ifp->if_drv_flags |= IFF_DRV_RUNNING; in pfsyncioctl()
1624 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; in pfsyncioctl()
1630 if (!sc->sc_sync_if || in pfsyncioctl()
1631 ifr->ifr_mtu <= PFSYNC_MINPKT || in pfsyncioctl()
1632 ifr->ifr_mtu > sc->sc_sync_if->if_mtu) in pfsyncioctl()
1634 if (ifr->ifr_mtu < ifp->if_mtu) { in pfsyncioctl()
1636 PFSYNC_BUCKET_LOCK(&sc->sc_buckets[c]); in pfsyncioctl()
1637 if (sc->sc_buckets[c].b_len > PFSYNC_MINPKT) in pfsyncioctl()
1639 PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[c]); in pfsyncioctl()
1642 ifp->if_mtu = ifr->ifr_mtu; in pfsyncioctl()
1647 if (sc->sc_sync_if) { in pfsyncioctl()
1649 sc->sc_sync_if->if_xname, IFNAMSIZ); in pfsyncioctl()
1651 pfsyncr.pfsyncr_syncpeer = ((struct sockaddr_in *)&sc->sc_sync_peer)->sin_addr; in pfsyncioctl()
1652 pfsyncr.pfsyncr_maxupdates = sc->sc_maxupdates; in pfsyncioctl()
1653 pfsyncr.pfsyncr_defer = sc->sc_flags; in pfsyncioctl()
1666 if (sc->sc_sync_if) in pfsyncioctl()
1667 nvlist_add_string(nvl, "syncdev", sc->sc_sync_if->if_xname); in pfsyncioctl()
1668 nvlist_add_number(nvl, "maxupdates", sc->sc_maxupdates); in pfsyncioctl()
1669 nvlist_add_number(nvl, "flags", sc->sc_flags); in pfsyncioctl()
1670 nvlist_add_number(nvl, "version", sc->sc_version); in pfsyncioctl()
1671 if ((nvl_syncpeer = pfsync_sockaddr_to_syncpeer_nvlist(&sc->sc_sync_peer)) != NULL) in pfsyncioctl()
1682 if (nvbuflen > ifr->ifr_cap_nv.buf_length) { in pfsyncioctl()
1683 ifr->ifr_cap_nv.length = nvbuflen; in pfsyncioctl()
1684 ifr->ifr_cap_nv.buffer = NULL; in pfsyncioctl()
1690 ifr->ifr_cap_nv.length = nvbuflen; in pfsyncioctl()
1691 error = copyout(packed, ifr->ifr_cap_nv.buffer, nvbuflen); in pfsyncioctl()
1723 if (ifr->ifr_cap_nv.length > IFR_CAP_NV_MAXBUFSIZE) in pfsyncioctl()
1726 data = malloc(ifr->ifr_cap_nv.length, M_TEMP, M_WAITOK); in pfsyncioctl()
1728 if ((error = copyin(ifr->ifr_cap_nv.buffer, data, in pfsyncioctl()
1729 ifr->ifr_cap_nv.length)) != 0) { in pfsyncioctl()
1734 if ((nvl = nvlist_unpack(data, ifr->ifr_cap_nv.length, 0)) == NULL) { in pfsyncioctl()
1776 iack->id = st->id; in pfsync_out_iack()
1777 iack->creatorid = st->creatorid; in pfsync_out_iack()
1786 up->id = st->id; in pfsync_out_upd_c()
1787 pf_state_peer_hton(&st->src, &up->src); in pfsync_out_upd_c()
1788 pf_state_peer_hton(&st->dst, &up->dst); in pfsync_out_upd_c()
1789 up->creatorid = st->creatorid; in pfsync_out_upd_c()
1790 up->timeout = st->timeout; in pfsync_out_upd_c()
1798 dp->id = st->id; in pfsync_out_del_c()
1799 dp->creatorid = st->creatorid; in pfsync_out_del_c()
1800 st->state_flags |= PFSTATE_NOSYNC; in pfsync_out_del_c()
1810 b = &sc->sc_buckets[c]; in pfsync_drop_all()
1826 b = &sc->sc_buckets[c]; in pfsync_drop()
1830 if (TAILQ_EMPTY(&b->b_qs[q])) in pfsync_drop()
1833 TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, next) { in pfsync_drop()
1834 KASSERT(st->sync_state == pfsync_qid_sstate[q], in pfsync_drop()
1835 ("%s: st->sync_state %d == q %d", in pfsync_drop()
1836 __func__, st->sync_state, q)); in pfsync_drop()
1837 st->sync_state = PFSYNC_S_NONE; in pfsync_drop()
1840 TAILQ_INIT(&b->b_qs[q]); in pfsync_drop()
1843 while ((ur = TAILQ_FIRST(&b->b_upd_req_list)) != NULL) { in pfsync_drop()
1844 TAILQ_REMOVE(&b->b_upd_req_list, ur, ur_entry); in pfsync_drop()
1848 b->b_len = PFSYNC_MINPKT; in pfsync_drop()
1849 free(b->b_plus, M_PFSYNC); in pfsync_drop()
1850 b->b_plus = NULL; in pfsync_drop()
1851 b->b_pluslen = 0; in pfsync_drop()
1858 struct ifnet *ifp = sc->sc_ifp; in pfsync_sendout()
1864 struct pfsync_bucket *b = &sc->sc_buckets[c]; in pfsync_sendout()
1870 KASSERT(b->b_len > PFSYNC_MINPKT, in pfsync_sendout()
1871 ("%s: sc_len %zu", __func__, b->b_len)); in pfsync_sendout()
1874 if (!bpf_peers_present(ifp->if_bpf) && sc->sc_sync_if == NULL) { in pfsync_sendout()
1879 m = m_get2(max_linkhdr + b->b_len, M_NOWAIT, MT_DATA, M_PKTHDR); in pfsync_sendout()
1881 if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1); in pfsync_sendout()
1885 m->m_data += max_linkhdr; in pfsync_sendout()
1886 bzero(m->m_data, b->b_len); in pfsync_sendout()
1888 len = b->b_len; in pfsync_sendout()
1891 switch (sc->sc_sync_peer.ss_family) { in pfsync_sendout()
1898 bcopy(&sc->sc_template.ipv4, ip, sizeof(*ip)); in pfsync_sendout()
1901 len -= sizeof(union inet_template) - sizeof(struct ip); in pfsync_sendout()
1902 ip->ip_len = htons(len); in pfsync_sendout()
1913 bcopy(&sc->sc_template.ipv6, ip6, sizeof(*ip6)); in pfsync_sendout()
1916 len -= sizeof(union inet_template) - sizeof(struct ip6_hdr); in pfsync_sendout()
1917 ip6->ip6_plen = htons(len); in pfsync_sendout()
1926 m->m_len = m->m_pkthdr.len = len; in pfsync_sendout()
1929 ph = (struct pfsync_header *)(m->m_data + offset); in pfsync_sendout()
1932 ph->version = PFSYNC_VERSION; in pfsync_sendout()
1933 ph->len = htons(len - aflen); in pfsync_sendout()
1934 bcopy(V_pf_status.pf_chksum, ph->pfcksum, PF_MD5_DIGEST_LENGTH); in pfsync_sendout()
1938 if (TAILQ_EMPTY(&b->b_qs[q])) in pfsync_sendout()
1941 subh = (struct pfsync_subheader *)(m->m_data + offset); in pfsync_sendout()
1945 TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, st_next) { in pfsync_sendout()
1946 KASSERT(st->sync_state == pfsync_qid_sstate[q], in pfsync_sendout()
1947 ("%s: st->sync_state == q", in pfsync_sendout()
1953 pfsync_qs[q].write(st, m->m_data + offset); in pfsync_sendout()
1955 st->sync_state = PFSYNC_S_NONE; in pfsync_sendout()
1959 TAILQ_INIT(&b->b_qs[q]); in pfsync_sendout()
1961 subh->action = pfsync_qs[q].action; in pfsync_sendout()
1962 subh->count = htons(count); in pfsync_sendout()
1966 if (!TAILQ_EMPTY(&b->b_upd_req_list)) { in pfsync_sendout()
1967 subh = (struct pfsync_subheader *)(m->m_data + offset); in pfsync_sendout()
1971 while ((ur = TAILQ_FIRST(&b->b_upd_req_list)) != NULL) { in pfsync_sendout()
1972 TAILQ_REMOVE(&b->b_upd_req_list, ur, ur_entry); in pfsync_sendout()
1974 bcopy(&ur->ur_msg, m->m_data + offset, in pfsync_sendout()
1975 sizeof(ur->ur_msg)); in pfsync_sendout()
1976 offset += sizeof(ur->ur_msg); in pfsync_sendout()
1981 subh->action = PFSYNC_ACT_UPD_REQ; in pfsync_sendout()
1982 subh->count = htons(count); in pfsync_sendout()
1987 if (b->b_plus != NULL) { in pfsync_sendout()
1988 bcopy(b->b_plus, m->m_data + offset, b->b_pluslen); in pfsync_sendout()
1989 offset += b->b_pluslen; in pfsync_sendout()
1991 free(b->b_plus, M_PFSYNC); in pfsync_sendout()
1992 b->b_plus = NULL; in pfsync_sendout()
1993 b->b_pluslen = 0; in pfsync_sendout()
1996 subh = (struct pfsync_subheader *)(m->m_data + offset); in pfsync_sendout()
1999 subh->action = PFSYNC_ACT_EOF; in pfsync_sendout()
2000 subh->count = htons(1); in pfsync_sendout()
2004 if (bpf_peers_present(ifp->if_bpf)) { in pfsync_sendout()
2005 m->m_data += aflen; in pfsync_sendout()
2006 m->m_len = m->m_pkthdr.len = len - aflen; in pfsync_sendout()
2007 bpf_mtap(ifp->if_bpf, m); in pfsync_sendout()
2008 m->m_data -= aflen; in pfsync_sendout()
2009 m->m_len = m->m_pkthdr.len = len; in pfsync_sendout()
2012 if (sc->sc_sync_if == NULL) { in pfsync_sendout()
2013 b->b_len = PFSYNC_MINPKT; in pfsync_sendout()
2018 if_inc_counter(sc->sc_ifp, IFCOUNTER_OPACKETS, 1); in pfsync_sendout()
2019 if_inc_counter(sc->sc_ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len); in pfsync_sendout()
2020 b->b_len = PFSYNC_MINPKT; in pfsync_sendout()
2022 if (!_IF_QFULL(&b->b_snd)) in pfsync_sendout()
2023 _IF_ENQUEUE(&b->b_snd, m); in pfsync_sendout()
2026 if_inc_counter(sc->sc_ifp, IFCOUNTER_OQDROPS, 1); in pfsync_sendout()
2038 if (st->state_flags & PFSTATE_NOSYNC) in pfsync_insert_state()
2041 if ((st->rule->rule_flag & PFRULE_NOSYNC) || in pfsync_insert_state()
2042 st->key[PF_SK_WIRE]->proto == IPPROTO_PFSYNC) { in pfsync_insert_state()
2043 st->state_flags |= PFSTATE_NOSYNC; in pfsync_insert_state()
2047 KASSERT(st->sync_state == PFSYNC_S_NONE, in pfsync_insert_state()
2048 ("%s: st->sync_state %u", __func__, st->sync_state)); in pfsync_insert_state()
2051 if (b->b_len == PFSYNC_MINPKT) in pfsync_insert_state()
2052 callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b); in pfsync_insert_state()
2057 st->sync_updates = 0; in pfsync_insert_state()
2067 if (m->m_flags & (M_BCAST|M_MCAST)) in pfsync_defer()
2077 if (!(sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) || in pfsync_defer()
2078 !(sc->sc_flags & PFSYNCF_DEFER)) { in pfsync_defer()
2086 if (b->b_deferred >= 128) in pfsync_defer()
2087 pfsync_undefer(TAILQ_FIRST(&b->b_deferrals), 0); in pfsync_defer()
2094 b->b_deferred++; in pfsync_defer()
2096 m->m_flags |= M_SKIP_FIREWALL; in pfsync_defer()
2097 st->state_flags |= PFSTATE_ACK; in pfsync_defer()
2099 pd->pd_sc = sc; in pfsync_defer()
2100 pd->pd_st = st; in pfsync_defer()
2102 pd->pd_m = m; in pfsync_defer()
2104 TAILQ_INSERT_TAIL(&b->b_deferrals, pd, pd_entry); in pfsync_defer()
2105 callout_init_mtx(&pd->pd_tmo, &b->b_mtx, CALLOUT_RETURNUNLOCKED); in pfsync_defer()
2106 callout_reset(&pd->pd_tmo, (V_pfsync_defer_timeout * hz) / 1000, in pfsync_defer()
2118 struct pfsync_softc *sc = pd->pd_sc; in pfsync_undefer()
2119 struct mbuf *m = pd->pd_m; in pfsync_undefer()
2120 struct pf_kstate *st = pd->pd_st; in pfsync_undefer()
2125 TAILQ_REMOVE(&b->b_deferrals, pd, pd_entry); in pfsync_undefer()
2126 b->b_deferred--; in pfsync_undefer()
2127 pd->pd_st->state_flags &= ~PFSTATE_ACK; /* XXX: locking! */ in pfsync_undefer()
2134 _IF_ENQUEUE(&b->b_snd, m); in pfsync_undefer()
2144 struct pfsync_softc *sc = pd->pd_sc; in pfsync_defer_tmo()
2145 struct mbuf *m = pd->pd_m; in pfsync_defer_tmo()
2146 struct pf_kstate *st = pd->pd_st; in pfsync_defer_tmo()
2149 CURVNET_SET(sc->sc_ifp->if_vnet); in pfsync_defer_tmo()
2155 TAILQ_REMOVE(&b->b_deferrals, pd, pd_entry); in pfsync_defer_tmo()
2156 b->b_deferred--; in pfsync_defer_tmo()
2157 pd->pd_st->state_flags &= ~PFSTATE_ACK; /* XXX: locking! */ in pfsync_defer_tmo()
2161 if (sc->sc_sync_if == NULL) { in pfsync_defer_tmo()
2187 TAILQ_FOREACH(pd, &b->b_deferrals, pd_entry) { in pfsync_undefer_state_locked()
2188 if (pd->pd_st == st) { in pfsync_undefer_state_locked()
2189 if (callout_stop(&pd->pd_tmo) > 0) in pfsync_undefer_state_locked()
2214 return &sc->sc_buckets[c]; in pfsync_get_bucket()
2221 bool sync = false, ref = true; in pfsync_update_state() local
2227 if (st->state_flags & PFSTATE_ACK) in pfsync_update_state()
2229 if (st->state_flags & PFSTATE_NOSYNC) { in pfsync_update_state()
2230 if (st->sync_state != PFSYNC_S_NONE) in pfsync_update_state()
2236 if (b->b_len == PFSYNC_MINPKT) in pfsync_update_state()
2237 callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b); in pfsync_update_state()
2239 switch (st->sync_state) { in pfsync_update_state()
2245 if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP) { in pfsync_update_state()
2246 st->sync_updates++; in pfsync_update_state()
2247 if (st->sync_updates >= sc->sc_maxupdates) in pfsync_update_state()
2248 sync = true; in pfsync_update_state()
2259 st->sync_updates = 0; in pfsync_update_state()
2263 panic("%s: unexpected sync state %d", __func__, st->sync_state); in pfsync_update_state()
2266 if (sync || (time_uptime - st->pfsync_time) < 2) in pfsync_update_state()
2276 struct pfsync_bucket *b = &sc->sc_buckets[0]; in pfsync_request_update()
2287 TAILQ_FOREACH(item, &b->b_upd_req_list, ur_entry) in pfsync_request_update()
2288 if (item->ur_msg.id == id && in pfsync_request_update()
2289 item->ur_msg.creatorid == creatorid) in pfsync_request_update()
2296 item->ur_msg.id = id; in pfsync_request_update()
2297 item->ur_msg.creatorid = creatorid; in pfsync_request_update()
2299 if (TAILQ_EMPTY(&b->b_upd_req_list)) in pfsync_request_update()
2302 if (b->b_len + nlen > sc->sc_ifp->if_mtu) { in pfsync_request_update()
2309 TAILQ_INSERT_TAIL(&b->b_upd_req_list, item, ur_entry); in pfsync_request_update()
2310 b->b_len += nlen; in pfsync_request_update()
2325 if (st->state_flags & PFSTATE_NOSYNC) { in pfsync_update_state_req()
2326 if (st->sync_state != PFSYNC_S_NONE) in pfsync_update_state_req()
2332 switch (st->sync_state) { in pfsync_update_state_req()
2351 panic("%s: unexpected sync state %d", __func__, st->sync_state); in pfsync_update_state_req()
2354 if ((sc->sc_ifp->if_mtu - b->b_len) < sizeof(union pfsync_state_union)) in pfsync_update_state_req()
2370 if (st->state_flags & PFSTATE_ACK) in pfsync_delete_state()
2372 if (st->state_flags & PFSTATE_NOSYNC) { in pfsync_delete_state()
2373 if (st->sync_state != PFSYNC_S_NONE) in pfsync_delete_state()
2379 if (b->b_len == PFSYNC_MINPKT) in pfsync_delete_state()
2380 callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b); in pfsync_delete_state()
2382 switch (st->sync_state) { in pfsync_delete_state()
2400 panic("%s: unexpected sync state %d", __func__, st->sync_state); in pfsync_delete_state()
2433 switch (sc->sc_version) { in pfsync_sstate_to_qid()
2443 switch (sc->sc_version) { in pfsync_sstate_to_qid()
2455 panic("%s: Unsupported st->sync_state 0x%02x", in pfsync_sstate_to_qid()
2460 __func__, sc->sc_version); in pfsync_sstate_to_qid()
2473 KASSERT(st->sync_state == PFSYNC_S_NONE, in pfsync_q_ins()
2474 ("%s: st->sync_state %u", __func__, st->sync_state)); in pfsync_q_ins()
2475 KASSERT(b->b_len >= PFSYNC_MINPKT, ("pfsync pkt len is too low %zu", in pfsync_q_ins()
2476 b->b_len)); in pfsync_q_ins()
2478 if (TAILQ_EMPTY(&b->b_qs[q])) in pfsync_q_ins()
2481 if (b->b_len + nlen > sc->sc_ifp->if_mtu) { in pfsync_q_ins()
2482 pfsync_sendout(1, b->b_id); in pfsync_q_ins()
2487 b->b_len += nlen; in pfsync_q_ins()
2488 st->sync_state = pfsync_qid_sstate[q]; in pfsync_q_ins()
2489 TAILQ_INSERT_TAIL(&b->b_qs[q], st, sync_list); in pfsync_q_ins()
2500 KASSERT(st->sync_state != PFSYNC_S_NONE, in pfsync_q_del()
2501 ("%s: st->sync_state != PFSYNC_S_NONE", __func__)); in pfsync_q_del()
2503 q = pfsync_sstate_to_qid(st->sync_state); in pfsync_q_del()
2504 b->b_len -= pfsync_qs[q].len; in pfsync_q_del()
2505 TAILQ_REMOVE(&b->b_qs[q], st, sync_list); in pfsync_q_del()
2506 st->sync_state = PFSYNC_S_NONE; in pfsync_q_del()
2510 if (TAILQ_EMPTY(&b->b_qs[q])) in pfsync_q_del()
2511 b->b_len -= sizeof(struct pfsync_subheader); in pfsync_q_del()
2524 sc->sc_ureq_received = time_uptime; in pfsync_bulk_start()
2525 sc->sc_bulk_hashid = 0; in pfsync_bulk_start()
2526 sc->sc_bulk_stateid = 0; in pfsync_bulk_start()
2528 callout_reset(&sc->sc_bulk_tmo, 1, pfsync_bulk_update, sc); in pfsync_bulk_start()
2540 CURVNET_SET(sc->sc_ifp->if_vnet); in pfsync_bulk_update()
2547 s = pf_find_state_byid(sc->sc_bulk_stateid, sc->sc_bulk_creatorid); in pfsync_bulk_update()
2552 i = sc->sc_bulk_hashid; in pfsync_bulk_update()
2561 s = LIST_FIRST(&ih->states); in pfsync_bulk_update()
2565 if (s->sync_state == PFSYNC_S_NONE && in pfsync_bulk_update()
2566 s->timeout < PFTM_MAX && in pfsync_bulk_update()
2567 s->pfsync_time <= sc->sc_ureq_received) { in pfsync_bulk_update()
2570 sc->sc_bulk_hashid = i; in pfsync_bulk_update()
2571 sc->sc_bulk_stateid = s->id; in pfsync_bulk_update()
2572 sc->sc_bulk_creatorid = s->creatorid; in pfsync_bulk_update()
2574 callout_reset(&sc->sc_bulk_tmo, 1, in pfsync_bulk_update()
2606 r.bus.endtime = htonl(time_uptime - sc->sc_ureq_received); in pfsync_bulk_status()
2616 struct pfsync_bucket *b = &sc->sc_buckets[0]; in pfsync_bulk_fail()
2618 CURVNET_SET(sc->sc_ifp->if_vnet); in pfsync_bulk_fail()
2622 if (sc->sc_bulk_tries++ < PFSYNC_MAX_BULKTRIES) { in pfsync_bulk_fail()
2624 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, in pfsync_bulk_fail()
2631 sc->sc_ureq_sent = 0; in pfsync_bulk_fail()
2632 sc->sc_bulk_tries = 0; in pfsync_bulk_fail()
2634 if (!(sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) in pfsync_bulk_fail()
2635 (*carp_demote_adj_p)(-V_pfsync_carp_adj, in pfsync_bulk_fail()
2637 sc->sc_flags |= PFSYNCF_OK; in pfsync_bulk_fail()
2650 struct pfsync_bucket *b = &sc->sc_buckets[0]; in pfsync_send_plus()
2655 if (b->b_len + pluslen > sc->sc_ifp->if_mtu) in pfsync_send_plus()
2656 pfsync_sendout(1, b->b_id); in pfsync_send_plus()
2658 newplus = malloc(pluslen + b->b_pluslen, M_PFSYNC, M_NOWAIT); in pfsync_send_plus()
2662 if (b->b_plus != NULL) { in pfsync_send_plus()
2663 memcpy(newplus, b->b_plus, b->b_pluslen); in pfsync_send_plus()
2664 free(b->b_plus, M_PFSYNC); in pfsync_send_plus()
2666 MPASS(b->b_pluslen == 0); in pfsync_send_plus()
2668 memcpy(newplus + b->b_pluslen, plus, pluslen); in pfsync_send_plus()
2670 b->b_plus = newplus; in pfsync_send_plus()
2671 b->b_pluslen += pluslen; in pfsync_send_plus()
2672 b->b_len += pluslen; in pfsync_send_plus()
2674 pfsync_sendout(1, b->b_id); in pfsync_send_plus()
2685 CURVNET_SET(b->b_sc->sc_ifp->if_vnet); in pfsync_timeout()
2698 b->b_flags |= PFSYNCF_BUCKET_PUSH; in pfsync_push()
2709 b = &sc->sc_buckets[c]; in pfsync_push_all()
2724 MPASS(ip->ip_v == IPVERSION || ip->ip_v == (IPV6_VERSION >> 4)); in pfsync_tx()
2726 af = ip->ip_v == IPVERSION ? AF_INET : AF_INET6; in pfsync_tx()
2736 if (m->m_flags & M_SKIP_FIREWALL) { in pfsync_tx()
2741 IP_RAWOUTPUT, &sc->sc_imo, NULL); in pfsync_tx()
2747 if (m->m_flags & M_SKIP_FIREWALL) { in pfsync_tx()
2752 &sc->sc_im6o, NULL, NULL); in pfsync_tx()
2775 CURVNET_SET(sc->sc_ifp->if_vnet); in pfsyncintr()
2778 b = &sc->sc_buckets[c]; in pfsyncintr()
2781 if ((b->b_flags & PFSYNCF_BUCKET_PUSH) && b->b_len > PFSYNC_MINPKT) { in pfsyncintr()
2782 pfsync_sendout(0, b->b_id); in pfsyncintr()
2783 b->b_flags &= ~PFSYNCF_BUCKET_PUSH; in pfsyncintr()
2785 _IF_DEQUEUE_ALL(&b->b_snd, m); in pfsyncintr()
2789 n = m->m_nextpkt; in pfsyncintr()
2790 m->m_nextpkt = NULL; in pfsyncintr()
2804 struct ip_moptions *imo = &sc->sc_imo; in pfsync_multicast_setup()
2807 struct ip6_moptions *im6o = &sc->sc_im6o; in pfsync_multicast_setup()
2811 if (!(ifp->if_flags & IFF_MULTICAST)) in pfsync_multicast_setup()
2814 switch (sc->sc_sync_peer.ss_family) { in pfsync_multicast_setup()
2820 ip_mfilter_init(&imo->imo_head); in pfsync_multicast_setup()
2821 imo->imo_multicast_vif = -1; in pfsync_multicast_setup()
2823 &((struct sockaddr_in *)&sc->sc_sync_peer)->sin_addr, NULL, in pfsync_multicast_setup()
2824 &imf->imf_inm)) != 0) in pfsync_multicast_setup()
2827 ip_mfilter_insert(&imo->imo_head, imf); in pfsync_multicast_setup()
2828 imo->imo_multicast_ifp = ifp; in pfsync_multicast_setup()
2829 imo->imo_multicast_ttl = PFSYNC_DFLTTL; in pfsync_multicast_setup()
2830 imo->imo_multicast_loop = 0; in pfsync_multicast_setup()
2839 syncpeer_sa6 = (struct sockaddr_in6 *)&sc->sc_sync_peer; in pfsync_multicast_setup()
2840 if ((error = in6_setscope(&syncpeer_sa6->sin6_addr, ifp, NULL))) in pfsync_multicast_setup()
2843 ip6_mfilter_init(&im6o->im6o_head); in pfsync_multicast_setup()
2844 if ((error = in6_joingroup(ifp, &syncpeer_sa6->sin6_addr, NULL, in pfsync_multicast_setup()
2845 &(im6f->im6f_in6m), 0)) != 0) in pfsync_multicast_setup()
2848 ip6_mfilter_insert(&im6o->im6o_head, im6f); in pfsync_multicast_setup()
2849 im6o->im6o_multicast_ifp = ifp; in pfsync_multicast_setup()
2850 im6o->im6o_multicast_hlim = PFSYNC_DFLTTL; in pfsync_multicast_setup()
2851 im6o->im6o_multicast_loop = 0; in pfsync_multicast_setup()
2864 struct ip_moptions *imo = &sc->sc_imo; in pfsync_multicast_cleanup()
2867 while ((imf = ip_mfilter_first(&imo->imo_head)) != NULL) { in pfsync_multicast_cleanup()
2868 ip_mfilter_remove(&imo->imo_head, imf); in pfsync_multicast_cleanup()
2869 in_leavegroup(imf->imf_inm, NULL); in pfsync_multicast_cleanup()
2872 imo->imo_multicast_ifp = NULL; in pfsync_multicast_cleanup()
2876 struct ip6_moptions *im6o = &sc->sc_im6o; in pfsync_multicast_cleanup()
2879 while ((im6f = ip6_mfilter_first(&im6o->im6o_head)) != NULL) { in pfsync_multicast_cleanup()
2880 ip6_mfilter_remove(&im6o->im6o_head, im6f); in pfsync_multicast_cleanup()
2881 in6_leavegroup(im6f->im6f_in6m, NULL); in pfsync_multicast_cleanup()
2884 im6o->im6o_multicast_ifp = NULL; in pfsync_multicast_cleanup()
2898 if (sc->sc_sync_if == ifp) { in pfsync_detach_ifnet()
2903 ip_mfilter_init(&sc->sc_imo.imo_head); in pfsync_detach_ifnet()
2904 sc->sc_imo.imo_multicast_ifp = NULL; in pfsync_detach_ifnet()
2905 sc->sc_im6o.im6o_multicast_ifp = NULL; in pfsync_detach_ifnet()
2906 sc->sc_sync_if = NULL; in pfsync_detach_ifnet()
2916 status->maxupdates = pfsyncr->pfsyncr_maxupdates; in pfsync_pfsyncreq_to_kstatus()
2917 status->flags = pfsyncr->pfsyncr_defer; in pfsync_pfsyncreq_to_kstatus()
2919 strlcpy(status->syncdev, pfsyncr->pfsyncr_syncdev, IFNAMSIZ); in pfsync_pfsyncreq_to_kstatus()
2922 if (pfsyncr->pfsyncr_syncpeer.s_addr != 0) { in pfsync_pfsyncreq_to_kstatus()
2924 in->sin_family = AF_INET; in pfsync_pfsyncreq_to_kstatus()
2925 in->sin_len = sizeof(*in); in pfsync_pfsyncreq_to_kstatus()
2926 in->sin_addr.s_addr = pfsyncr->pfsyncr_syncpeer.s_addr; in pfsync_pfsyncreq_to_kstatus()
2928 status->syncpeer = sa; in pfsync_pfsyncreq_to_kstatus()
2942 if ((status->maxupdates < 0) || (status->maxupdates > 255)) in pfsync_kstatus_to_softc()
2945 if (status->syncdev[0] == '\0') in pfsync_kstatus_to_softc()
2947 else if ((sifp = ifunit_ref(status->syncdev)) == NULL) in pfsync_kstatus_to_softc()
2950 switch (status->syncpeer.ss_family) { in pfsync_kstatus_to_softc()
2955 status_sin = (struct sockaddr_in *)&(status->syncpeer); in pfsync_kstatus_to_softc()
2957 if (status_sin->sin_addr.s_addr == 0 || in pfsync_kstatus_to_softc()
2958 status_sin->sin_addr.s_addr == in pfsync_kstatus_to_softc()
2960 status_sin->sin_family = AF_INET; in pfsync_kstatus_to_softc()
2961 status_sin->sin_len = sizeof(*status_sin); in pfsync_kstatus_to_softc()
2962 status_sin->sin_addr.s_addr = in pfsync_kstatus_to_softc()
2966 if (IN_MULTICAST(ntohl(status_sin->sin_addr.s_addr))) { in pfsync_kstatus_to_softc()
2976 status_sin6 = (struct sockaddr_in6*)&(status->syncpeer); in pfsync_kstatus_to_softc()
2978 if (IN6_IS_ADDR_UNSPECIFIED(&status_sin6->sin6_addr) || in pfsync_kstatus_to_softc()
2979 IN6_ARE_ADDR_EQUAL(&status_sin6->sin6_addr, in pfsync_kstatus_to_softc()
2981 status_sin6->sin6_family = AF_INET6; in pfsync_kstatus_to_softc()
2982 status_sin6->sin6_len = sizeof(*status_sin6); in pfsync_kstatus_to_softc()
2983 status_sin6->sin6_addr = in pfsync_kstatus_to_softc()
2987 if (IN6_IS_ADDR_MULTICAST(&status_sin6->sin6_addr)) { in pfsync_kstatus_to_softc()
2998 switch (status->version) { in pfsync_kstatus_to_softc()
3000 sc->sc_version = PFSYNC_MSG_VERSION_DEFAULT; in pfsync_kstatus_to_softc()
3004 sc->sc_version = status->version; in pfsync_kstatus_to_softc()
3011 switch (status->syncpeer.ss_family) { in pfsync_kstatus_to_softc()
3013 struct sockaddr_in *status_sin = (struct sockaddr_in *)&(status->syncpeer); in pfsync_kstatus_to_softc()
3014 struct sockaddr_in *sc_sin = (struct sockaddr_in *)&sc->sc_sync_peer; in pfsync_kstatus_to_softc()
3015 sc_sin->sin_family = AF_INET; in pfsync_kstatus_to_softc()
3016 sc_sin->sin_len = sizeof(*sc_sin); in pfsync_kstatus_to_softc()
3017 if (status_sin->sin_addr.s_addr == 0) { in pfsync_kstatus_to_softc()
3018 sc_sin->sin_addr.s_addr = htonl(INADDR_PFSYNC_GROUP); in pfsync_kstatus_to_softc()
3020 sc_sin->sin_addr.s_addr = status_sin->sin_addr.s_addr; in pfsync_kstatus_to_softc()
3025 struct sockaddr_in6 *status_sin = (struct sockaddr_in6 *)&(status->syncpeer); in pfsync_kstatus_to_softc()
3026 struct sockaddr_in6 *sc_sin = (struct sockaddr_in6 *)&sc->sc_sync_peer; in pfsync_kstatus_to_softc()
3027 sc_sin->sin6_family = AF_INET6; in pfsync_kstatus_to_softc()
3028 sc_sin->sin6_len = sizeof(*sc_sin); in pfsync_kstatus_to_softc()
3029 if(IN6_IS_ADDR_UNSPECIFIED(&status_sin->sin6_addr)) { in pfsync_kstatus_to_softc()
3030 sc_sin->sin6_addr = in6addr_linklocal_pfsync_group; in pfsync_kstatus_to_softc()
3032 sc_sin->sin6_addr = status_sin->sin6_addr; in pfsync_kstatus_to_softc()
3038 sc->sc_maxupdates = status->maxupdates; in pfsync_kstatus_to_softc()
3039 if (status->flags & PFSYNCF_DEFER) { in pfsync_kstatus_to_softc()
3040 sc->sc_flags |= PFSYNCF_DEFER; in pfsync_kstatus_to_softc()
3043 sc->sc_flags &= ~PFSYNCF_DEFER; in pfsync_kstatus_to_softc()
3048 if (sc->sc_sync_if) in pfsync_kstatus_to_softc()
3049 if_rele(sc->sc_sync_if); in pfsync_kstatus_to_softc()
3050 sc->sc_sync_if = NULL; in pfsync_kstatus_to_softc()
3057 PFSYNC_BUCKET_LOCK(&sc->sc_buckets[c]); in pfsync_kstatus_to_softc()
3058 if (sc->sc_buckets[c].b_len > PFSYNC_MINPKT && in pfsync_kstatus_to_softc()
3059 (sifp->if_mtu < sc->sc_ifp->if_mtu || in pfsync_kstatus_to_softc()
3060 (sc->sc_sync_if != NULL && in pfsync_kstatus_to_softc()
3061 sifp->if_mtu < sc->sc_sync_if->if_mtu) || in pfsync_kstatus_to_softc()
3062 sifp->if_mtu < MCLBYTES - sizeof(struct ip))) in pfsync_kstatus_to_softc()
3064 PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[c]); in pfsync_kstatus_to_softc()
3069 if (((sc->sc_sync_peer.ss_family == AF_INET) && in pfsync_kstatus_to_softc()
3071 &sc->sc_sync_peer)->sin_addr.s_addr))) || in pfsync_kstatus_to_softc()
3072 ((sc->sc_sync_peer.ss_family == AF_INET6) && in pfsync_kstatus_to_softc()
3074 &sc->sc_sync_peer)->sin6_addr))) { in pfsync_kstatus_to_softc()
3090 if (sc->sc_sync_if) in pfsync_kstatus_to_softc()
3091 if_rele(sc->sc_sync_if); in pfsync_kstatus_to_softc()
3092 sc->sc_sync_if = sifp; in pfsync_kstatus_to_softc()
3094 switch (sc->sc_sync_peer.ss_family) { in pfsync_kstatus_to_softc()
3098 ip = &sc->sc_template.ipv4; in pfsync_kstatus_to_softc()
3100 ip->ip_v = IPVERSION; in pfsync_kstatus_to_softc()
3101 ip->ip_hl = sizeof(sc->sc_template.ipv4) >> 2; in pfsync_kstatus_to_softc()
3102 ip->ip_tos = IPTOS_LOWDELAY; in pfsync_kstatus_to_softc()
3104 ip->ip_off = htons(IP_DF); in pfsync_kstatus_to_softc()
3105 ip->ip_ttl = PFSYNC_DFLTTL; in pfsync_kstatus_to_softc()
3106 ip->ip_p = IPPROTO_PFSYNC; in pfsync_kstatus_to_softc()
3107 ip->ip_src.s_addr = INADDR_ANY; in pfsync_kstatus_to_softc()
3108 ip->ip_dst = ((struct sockaddr_in *)&sc->sc_sync_peer)->sin_addr; in pfsync_kstatus_to_softc()
3115 ip6 = &sc->sc_template.ipv6; in pfsync_kstatus_to_softc()
3117 ip6->ip6_vfc = IPV6_VERSION; in pfsync_kstatus_to_softc()
3118 ip6->ip6_hlim = PFSYNC_DFLTTL; in pfsync_kstatus_to_softc()
3119 ip6->ip6_nxt = IPPROTO_PFSYNC; in pfsync_kstatus_to_softc()
3120 ip6->ip6_dst = ((struct sockaddr_in6 *)&sc->sc_sync_peer)->sin6_addr; in pfsync_kstatus_to_softc()
3124 in6_selectsrc_addr(if_getfib(sc->sc_sync_if), &ip6->ip6_dst, 0, in pfsync_kstatus_to_softc()
3125 sc->sc_sync_if, &ip6->ip6_src, NULL); in pfsync_kstatus_to_softc()
3133 if ((sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) in pfsync_kstatus_to_softc()
3136 sc->sc_flags &= ~PFSYNCF_OK; in pfsync_kstatus_to_softc()
3140 PFSYNC_BUCKET_LOCK(&sc->sc_buckets[0]); in pfsync_kstatus_to_softc()
3142 PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[0]); in pfsync_kstatus_to_softc()
3144 sc->sc_ureq_sent = time_uptime; in pfsync_kstatus_to_softc()
3145 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, pfsync_bulk_fail, sc); in pfsync_kstatus_to_softc()