1 /*- 2 * SPDX-License-Identifier: (BSD-2-Clause AND ISC) 3 * 4 * Copyright (c) 2002 Michael Shalayeff 5 * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 /*- 31 * Copyright (c) 2009 David Gwynne <dlg@openbsd.org> 32 * 33 * Permission to use, copy, modify, and distribute this software for any 34 * purpose with or without fee is hereby granted, provided that the above 35 * copyright notice and this permission notice appear in all copies. 36 * 37 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 38 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 39 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 40 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 41 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 42 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 43 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 44 */ 45 46 /* 47 * $OpenBSD: if_pfsync.c,v 1.110 2009/02/24 05:39:19 dlg Exp $ 48 * 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 60 */ 61 62 #include <sys/cdefs.h> 63 #include "opt_inet.h" 64 #include "opt_inet6.h" 65 #include "opt_pf.h" 66 67 #include <sys/param.h> 68 #include <sys/bus.h> 69 #include <sys/endian.h> 70 #include <sys/interrupt.h> 71 #include <sys/kernel.h> 72 #include <sys/lock.h> 73 #include <sys/mbuf.h> 74 #include <sys/module.h> 75 #include <sys/mutex.h> 76 #include <sys/nv.h> 77 #include <sys/priv.h> 78 #include <sys/smp.h> 79 #include <sys/socket.h> 80 #include <sys/sockio.h> 81 #include <sys/sysctl.h> 82 #include <sys/syslog.h> 83 84 #include <net/bpf.h> 85 #include <net/if.h> 86 #include <net/if_var.h> 87 #include <net/if_clone.h> 88 #include <net/if_private.h> 89 #include <net/if_types.h> 90 #include <net/vnet.h> 91 #include <net/pfvar.h> 92 #include <net/route.h> 93 #include <net/if_pfsync.h> 94 95 #include <netinet/if_ether.h> 96 #include <netinet/in.h> 97 #include <netinet/in_var.h> 98 #include <netinet6/in6_var.h> 99 #include <netinet/ip.h> 100 #include <netinet/ip6.h> 101 #include <netinet/ip_carp.h> 102 #include <netinet/ip_var.h> 103 #include <netinet/tcp.h> 104 #include <netinet/tcp_fsm.h> 105 #include <netinet/tcp_seq.h> 106 107 #include <netinet/ip6.h> 108 #include <netinet6/ip6_var.h> 109 #include <netinet6/scope6_var.h> 110 111 #include <netpfil/pf/pfsync_nv.h> 112 113 struct pfsync_bucket; 114 struct pfsync_softc; 115 116 union inet_template { 117 struct ip ipv4; 118 struct ip6_hdr ipv6; 119 }; 120 121 #define PFSYNC_MINPKT ( \ 122 sizeof(union inet_template) + \ 123 sizeof(struct pfsync_header) + \ 124 sizeof(struct pfsync_subheader) ) 125 126 static int pfsync_upd_tcp(struct pf_kstate *, struct pfsync_state_peer *, 127 struct pfsync_state_peer *); 128 static int pfsync_in_clr(struct mbuf *, int, int, int, int); 129 static int pfsync_in_ins(struct mbuf *, int, int, int, int); 130 static int pfsync_in_iack(struct mbuf *, int, int, int, int); 131 static int pfsync_in_upd(struct mbuf *, int, int, int, int); 132 static int pfsync_in_upd_c(struct mbuf *, int, int, int, int); 133 static int pfsync_in_ureq(struct mbuf *, int, int, int, int); 134 static int pfsync_in_del_c(struct mbuf *, int, int, int, int); 135 static int pfsync_in_bus(struct mbuf *, int, int, int, int); 136 static int pfsync_in_tdb(struct mbuf *, int, int, int, int); 137 static int pfsync_in_eof(struct mbuf *, int, int, int, int); 138 static int pfsync_in_error(struct mbuf *, int, int, int, int); 139 140 static int (*pfsync_acts[])(struct mbuf *, int, int, int, int) = { 141 pfsync_in_clr, /* PFSYNC_ACT_CLR */ 142 pfsync_in_ins, /* PFSYNC_ACT_INS_1301 */ 143 pfsync_in_iack, /* PFSYNC_ACT_INS_ACK */ 144 pfsync_in_upd, /* PFSYNC_ACT_UPD_1301 */ 145 pfsync_in_upd_c, /* PFSYNC_ACT_UPD_C */ 146 pfsync_in_ureq, /* PFSYNC_ACT_UPD_REQ */ 147 pfsync_in_error, /* PFSYNC_ACT_DEL */ 148 pfsync_in_del_c, /* PFSYNC_ACT_DEL_C */ 149 pfsync_in_error, /* PFSYNC_ACT_INS_F */ 150 pfsync_in_error, /* PFSYNC_ACT_DEL_F */ 151 pfsync_in_bus, /* PFSYNC_ACT_BUS */ 152 pfsync_in_tdb, /* PFSYNC_ACT_TDB */ 153 pfsync_in_eof, /* PFSYNC_ACT_EOF */ 154 pfsync_in_ins, /* PFSYNC_ACT_INS_1400 */ 155 pfsync_in_upd, /* PFSYNC_ACT_UPD_1400 */ 156 }; 157 158 struct pfsync_q { 159 void (*write)(struct pf_kstate *, void *); 160 size_t len; 161 u_int8_t action; 162 }; 163 164 /* We have the following sync queues */ 165 enum pfsync_q_id { 166 PFSYNC_Q_INS_1301, 167 PFSYNC_Q_INS_1400, 168 PFSYNC_Q_IACK, 169 PFSYNC_Q_UPD_1301, 170 PFSYNC_Q_UPD_1400, 171 PFSYNC_Q_UPD_C, 172 PFSYNC_Q_DEL_C, 173 PFSYNC_Q_COUNT, 174 }; 175 176 /* Functions for building messages for given queue */ 177 static void pfsync_out_state_1301(struct pf_kstate *, void *); 178 static void pfsync_out_state_1400(struct pf_kstate *, void *); 179 static void pfsync_out_iack(struct pf_kstate *, void *); 180 static void pfsync_out_upd_c(struct pf_kstate *, void *); 181 static void pfsync_out_del_c(struct pf_kstate *, void *); 182 183 /* Attach those functions to queue */ 184 static struct pfsync_q pfsync_qs[] = { 185 { pfsync_out_state_1301, sizeof(struct pfsync_state_1301), PFSYNC_ACT_INS_1301 }, 186 { pfsync_out_state_1400, sizeof(struct pfsync_state_1400), PFSYNC_ACT_INS_1400 }, 187 { pfsync_out_iack, sizeof(struct pfsync_ins_ack), PFSYNC_ACT_INS_ACK }, 188 { pfsync_out_state_1301, sizeof(struct pfsync_state_1301), PFSYNC_ACT_UPD_1301 }, 189 { pfsync_out_state_1400, sizeof(struct pfsync_state_1400), PFSYNC_ACT_UPD_1400 }, 190 { pfsync_out_upd_c, sizeof(struct pfsync_upd_c), PFSYNC_ACT_UPD_C }, 191 { pfsync_out_del_c, sizeof(struct pfsync_del_c), PFSYNC_ACT_DEL_C } 192 }; 193 194 /* Map queue to pf_kstate->sync_state */ 195 static u_int8_t pfsync_qid_sstate[] = { 196 PFSYNC_S_INS, /* PFSYNC_Q_INS_1301 */ 197 PFSYNC_S_INS, /* PFSYNC_Q_INS_1400 */ 198 PFSYNC_S_IACK, /* PFSYNC_Q_IACK */ 199 PFSYNC_S_UPD, /* PFSYNC_Q_UPD_1301 */ 200 PFSYNC_S_UPD, /* PFSYNC_Q_UPD_1400 */ 201 PFSYNC_S_UPD_C, /* PFSYNC_Q_UPD_C */ 202 PFSYNC_S_DEL_C, /* PFSYNC_Q_DEL_C */ 203 }; 204 205 /* Map pf_kstate->sync_state to queue */ 206 static enum pfsync_q_id pfsync_sstate_to_qid(u_int8_t); 207 208 static void pfsync_q_ins(struct pf_kstate *, int sync_state, bool); 209 static void pfsync_q_del(struct pf_kstate *, bool, struct pfsync_bucket *); 210 211 static void pfsync_update_state(struct pf_kstate *); 212 static void pfsync_tx(struct pfsync_softc *, struct mbuf *); 213 214 struct pfsync_upd_req_item { 215 TAILQ_ENTRY(pfsync_upd_req_item) ur_entry; 216 struct pfsync_upd_req ur_msg; 217 }; 218 219 struct pfsync_deferral { 220 struct pfsync_softc *pd_sc; 221 TAILQ_ENTRY(pfsync_deferral) pd_entry; 222 struct callout pd_tmo; 223 224 struct pf_kstate *pd_st; 225 struct mbuf *pd_m; 226 }; 227 228 struct pfsync_bucket 229 { 230 int b_id; 231 struct pfsync_softc *b_sc; 232 struct mtx b_mtx; 233 struct callout b_tmo; 234 int b_flags; 235 #define PFSYNCF_BUCKET_PUSH 0x00000001 236 237 size_t b_len; 238 TAILQ_HEAD(, pf_kstate) b_qs[PFSYNC_Q_COUNT]; 239 TAILQ_HEAD(, pfsync_upd_req_item) b_upd_req_list; 240 TAILQ_HEAD(, pfsync_deferral) b_deferrals; 241 u_int b_deferred; 242 void *b_plus; 243 size_t b_pluslen; 244 245 struct ifaltq b_snd; 246 }; 247 248 struct pfsync_softc { 249 /* Configuration */ 250 struct ifnet *sc_ifp; 251 struct ifnet *sc_sync_if; 252 struct ip_moptions sc_imo; 253 struct ip6_moptions sc_im6o; 254 struct sockaddr_storage sc_sync_peer; 255 uint32_t sc_flags; 256 uint8_t sc_maxupdates; 257 union inet_template sc_template; 258 struct mtx sc_mtx; 259 uint32_t sc_version; 260 261 /* Queued data */ 262 struct pfsync_bucket *sc_buckets; 263 264 /* Bulk update info */ 265 struct mtx sc_bulk_mtx; 266 uint32_t sc_ureq_sent; 267 int sc_bulk_tries; 268 uint32_t sc_ureq_received; 269 int sc_bulk_hashid; 270 uint64_t sc_bulk_stateid; 271 uint32_t sc_bulk_creatorid; 272 struct callout sc_bulk_tmo; 273 struct callout sc_bulkfail_tmo; 274 }; 275 276 #define PFSYNC_LOCK(sc) mtx_lock(&(sc)->sc_mtx) 277 #define PFSYNC_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) 278 #define PFSYNC_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) 279 280 #define PFSYNC_BUCKET_LOCK(b) mtx_lock(&(b)->b_mtx) 281 #define PFSYNC_BUCKET_UNLOCK(b) mtx_unlock(&(b)->b_mtx) 282 #define PFSYNC_BUCKET_LOCK_ASSERT(b) mtx_assert(&(b)->b_mtx, MA_OWNED) 283 284 #define PFSYNC_BLOCK(sc) mtx_lock(&(sc)->sc_bulk_mtx) 285 #define PFSYNC_BUNLOCK(sc) mtx_unlock(&(sc)->sc_bulk_mtx) 286 #define PFSYNC_BLOCK_ASSERT(sc) mtx_assert(&(sc)->sc_bulk_mtx, MA_OWNED) 287 288 #define PFSYNC_DEFER_TIMEOUT 20 289 290 static const char pfsyncname[] = "pfsync"; 291 static MALLOC_DEFINE(M_PFSYNC, pfsyncname, "pfsync(4) data"); 292 VNET_DEFINE_STATIC(struct pfsync_softc *, pfsyncif) = NULL; 293 #define V_pfsyncif VNET(pfsyncif) 294 VNET_DEFINE_STATIC(void *, pfsync_swi_cookie) = NULL; 295 #define V_pfsync_swi_cookie VNET(pfsync_swi_cookie) 296 VNET_DEFINE_STATIC(struct intr_event *, pfsync_swi_ie); 297 #define V_pfsync_swi_ie VNET(pfsync_swi_ie) 298 VNET_DEFINE_STATIC(struct pfsyncstats, pfsyncstats); 299 #define V_pfsyncstats VNET(pfsyncstats) 300 VNET_DEFINE_STATIC(int, pfsync_carp_adj) = CARP_MAXSKEW; 301 #define V_pfsync_carp_adj VNET(pfsync_carp_adj) 302 VNET_DEFINE_STATIC(unsigned int, pfsync_defer_timeout) = PFSYNC_DEFER_TIMEOUT; 303 #define V_pfsync_defer_timeout VNET(pfsync_defer_timeout) 304 305 static void pfsync_timeout(void *); 306 static void pfsync_push(struct pfsync_bucket *); 307 static void pfsync_push_all(struct pfsync_softc *); 308 static void pfsyncintr(void *); 309 static int pfsync_multicast_setup(struct pfsync_softc *, struct ifnet *, 310 struct in_mfilter *, struct in6_mfilter *); 311 static void pfsync_multicast_cleanup(struct pfsync_softc *); 312 static void pfsync_pointers_init(void); 313 static void pfsync_pointers_uninit(void); 314 static int pfsync_init(void); 315 static void pfsync_uninit(void); 316 317 static unsigned long pfsync_buckets; 318 319 SYSCTL_NODE(_net, OID_AUTO, pfsync, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 320 "PFSYNC"); 321 SYSCTL_STRUCT(_net_pfsync, OID_AUTO, stats, CTLFLAG_VNET | CTLFLAG_RW, 322 &VNET_NAME(pfsyncstats), pfsyncstats, 323 "PFSYNC statistics (struct pfsyncstats, net/if_pfsync.h)"); 324 SYSCTL_INT(_net_pfsync, OID_AUTO, carp_demotion_factor, CTLFLAG_VNET | CTLFLAG_RW, 325 &VNET_NAME(pfsync_carp_adj), 0, "pfsync's CARP demotion factor adjustment"); 326 SYSCTL_ULONG(_net_pfsync, OID_AUTO, pfsync_buckets, CTLFLAG_RDTUN, 327 &pfsync_buckets, 0, "Number of pfsync hash buckets"); 328 SYSCTL_UINT(_net_pfsync, OID_AUTO, defer_delay, CTLFLAG_VNET | CTLFLAG_RW, 329 &VNET_NAME(pfsync_defer_timeout), 0, "Deferred packet timeout (in ms)"); 330 331 static int pfsync_clone_create(struct if_clone *, int, caddr_t); 332 static void pfsync_clone_destroy(struct ifnet *); 333 static int pfsync_alloc_scrub_memory(struct pfsync_state_peer *, 334 struct pf_state_peer *); 335 static int pfsyncoutput(struct ifnet *, struct mbuf *, 336 const struct sockaddr *, struct route *); 337 static int pfsyncioctl(struct ifnet *, u_long, caddr_t); 338 339 static int pfsync_defer(struct pf_kstate *, struct mbuf *); 340 static void pfsync_undefer(struct pfsync_deferral *, int); 341 static void pfsync_undefer_state_locked(struct pf_kstate *, int); 342 static void pfsync_undefer_state(struct pf_kstate *, int); 343 static void pfsync_defer_tmo(void *); 344 345 static void pfsync_request_update(u_int32_t, u_int64_t); 346 static bool pfsync_update_state_req(struct pf_kstate *); 347 348 static void pfsync_drop(struct pfsync_softc *); 349 static void pfsync_sendout(int, int); 350 static void pfsync_send_plus(void *, size_t); 351 352 static void pfsync_bulk_start(void); 353 static void pfsync_bulk_status(u_int8_t); 354 static void pfsync_bulk_update(void *); 355 static void pfsync_bulk_fail(void *); 356 357 static void pfsync_detach_ifnet(struct ifnet *); 358 359 static int pfsync_pfsyncreq_to_kstatus(struct pfsyncreq *, 360 struct pfsync_kstatus *); 361 static int pfsync_kstatus_to_softc(struct pfsync_kstatus *, 362 struct pfsync_softc *); 363 364 #ifdef IPSEC 365 static void pfsync_update_net_tdb(struct pfsync_tdb *); 366 #endif 367 static struct pfsync_bucket *pfsync_get_bucket(struct pfsync_softc *, 368 struct pf_kstate *); 369 370 #define PFSYNC_MAX_BULKTRIES 12 371 372 VNET_DEFINE(struct if_clone *, pfsync_cloner); 373 #define V_pfsync_cloner VNET(pfsync_cloner) 374 375 const struct in6_addr in6addr_linklocal_pfsync_group = 376 {{{ 0xff, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0 }}}; 378 static int 379 pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t param) 380 { 381 struct pfsync_softc *sc; 382 struct ifnet *ifp; 383 struct pfsync_bucket *b; 384 int c; 385 enum pfsync_q_id q; 386 387 if (unit != 0) 388 return (EINVAL); 389 390 if (! pfsync_buckets) 391 pfsync_buckets = mp_ncpus * 2; 392 393 sc = malloc(sizeof(struct pfsync_softc), M_PFSYNC, M_WAITOK | M_ZERO); 394 sc->sc_flags |= PFSYNCF_OK; 395 sc->sc_maxupdates = 128; 396 sc->sc_version = PFSYNC_MSG_VERSION_DEFAULT; 397 398 ifp = sc->sc_ifp = if_alloc(IFT_PFSYNC); 399 if (ifp == NULL) { 400 free(sc, M_PFSYNC); 401 return (ENOSPC); 402 } 403 if_initname(ifp, pfsyncname, unit); 404 ifp->if_softc = sc; 405 ifp->if_ioctl = pfsyncioctl; 406 ifp->if_output = pfsyncoutput; 407 ifp->if_type = IFT_PFSYNC; 408 ifp->if_hdrlen = sizeof(struct pfsync_header); 409 ifp->if_mtu = ETHERMTU; 410 mtx_init(&sc->sc_mtx, pfsyncname, NULL, MTX_DEF); 411 mtx_init(&sc->sc_bulk_mtx, "pfsync bulk", NULL, MTX_DEF); 412 callout_init_mtx(&sc->sc_bulk_tmo, &sc->sc_bulk_mtx, 0); 413 callout_init_mtx(&sc->sc_bulkfail_tmo, &sc->sc_bulk_mtx, 0); 414 415 if_attach(ifp); 416 417 bpfattach(ifp, DLT_PFSYNC, PFSYNC_HDRLEN); 418 419 sc->sc_buckets = mallocarray(pfsync_buckets, sizeof(*sc->sc_buckets), 420 M_PFSYNC, M_ZERO | M_WAITOK); 421 for (c = 0; c < pfsync_buckets; c++) { 422 b = &sc->sc_buckets[c]; 423 mtx_init(&b->b_mtx, "pfsync bucket", NULL, MTX_DEF); 424 425 b->b_id = c; 426 b->b_sc = sc; 427 b->b_len = PFSYNC_MINPKT; 428 429 for (q = 0; q < PFSYNC_Q_COUNT; q++) 430 TAILQ_INIT(&b->b_qs[q]); 431 432 TAILQ_INIT(&b->b_upd_req_list); 433 TAILQ_INIT(&b->b_deferrals); 434 435 callout_init(&b->b_tmo, 1); 436 437 b->b_snd.ifq_maxlen = ifqmaxlen; 438 } 439 440 V_pfsyncif = sc; 441 442 return (0); 443 } 444 445 static void 446 pfsync_clone_destroy(struct ifnet *ifp) 447 { 448 struct pfsync_softc *sc = ifp->if_softc; 449 struct pfsync_bucket *b; 450 int c, ret; 451 452 for (c = 0; c < pfsync_buckets; c++) { 453 b = &sc->sc_buckets[c]; 454 /* 455 * At this stage, everything should have already been 456 * cleared by pfsync_uninit(), and we have only to 457 * drain callouts. 458 */ 459 PFSYNC_BUCKET_LOCK(b); 460 while (b->b_deferred > 0) { 461 struct pfsync_deferral *pd = 462 TAILQ_FIRST(&b->b_deferrals); 463 464 ret = callout_stop(&pd->pd_tmo); 465 PFSYNC_BUCKET_UNLOCK(b); 466 if (ret > 0) { 467 pfsync_undefer(pd, 1); 468 } else { 469 callout_drain(&pd->pd_tmo); 470 } 471 PFSYNC_BUCKET_LOCK(b); 472 } 473 MPASS(b->b_deferred == 0); 474 MPASS(TAILQ_EMPTY(&b->b_deferrals)); 475 PFSYNC_BUCKET_UNLOCK(b); 476 477 callout_drain(&b->b_tmo); 478 } 479 480 callout_drain(&sc->sc_bulkfail_tmo); 481 callout_drain(&sc->sc_bulk_tmo); 482 483 if (!(sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) 484 (*carp_demote_adj_p)(-V_pfsync_carp_adj, "pfsync destroy"); 485 bpfdetach(ifp); 486 if_detach(ifp); 487 488 pfsync_drop(sc); 489 490 if_free(ifp); 491 pfsync_multicast_cleanup(sc); 492 mtx_destroy(&sc->sc_mtx); 493 mtx_destroy(&sc->sc_bulk_mtx); 494 495 free(sc->sc_buckets, M_PFSYNC); 496 free(sc, M_PFSYNC); 497 498 V_pfsyncif = NULL; 499 } 500 501 static int 502 pfsync_alloc_scrub_memory(struct pfsync_state_peer *s, 503 struct pf_state_peer *d) 504 { 505 if (s->scrub.scrub_flag && d->scrub == NULL) { 506 d->scrub = uma_zalloc(V_pf_state_scrub_z, M_NOWAIT | M_ZERO); 507 if (d->scrub == NULL) 508 return (ENOMEM); 509 } 510 511 return (0); 512 } 513 514 static int 515 pfsync_state_import(union pfsync_state_union *sp, int flags, int msg_version) 516 { 517 struct pfsync_softc *sc = V_pfsyncif; 518 #ifndef __NO_STRICT_ALIGNMENT 519 struct pfsync_state_key key[2]; 520 #endif 521 struct pfsync_state_key *kw, *ks; 522 struct pf_kstate *st = NULL; 523 struct pf_state_key *skw = NULL, *sks = NULL; 524 struct pf_krule *r = NULL; 525 struct pfi_kkif *kif; 526 int error; 527 528 PF_RULES_RASSERT(); 529 530 if (sp->pfs_1301.creatorid == 0) { 531 if (V_pf_status.debug >= PF_DEBUG_MISC) 532 printf("%s: invalid creator id: %08x\n", __func__, 533 ntohl(sp->pfs_1301.creatorid)); 534 return (EINVAL); 535 } 536 537 if ((kif = pfi_kkif_find(sp->pfs_1301.ifname)) == NULL) { 538 if (V_pf_status.debug >= PF_DEBUG_MISC) 539 printf("%s: unknown interface: %s\n", __func__, 540 sp->pfs_1301.ifname); 541 if (flags & PFSYNC_SI_IOCTL) 542 return (EINVAL); 543 return (0); /* skip this state */ 544 } 545 546 /* 547 * If the ruleset checksums match or the state is coming from the ioctl, 548 * it's safe to associate the state with the rule of that number. 549 */ 550 if (sp->pfs_1301.rule != htonl(-1) && sp->pfs_1301.anchor == htonl(-1) && 551 (flags & (PFSYNC_SI_IOCTL | PFSYNC_SI_CKSUM)) && ntohl(sp->pfs_1301.rule) < 552 pf_main_ruleset.rules[PF_RULESET_FILTER].active.rcount) 553 r = pf_main_ruleset.rules[ 554 PF_RULESET_FILTER].active.ptr_array[ntohl(sp->pfs_1301.rule)]; 555 else 556 r = &V_pf_default_rule; 557 558 if ((r->max_states && 559 counter_u64_fetch(r->states_cur) >= r->max_states)) 560 goto cleanup; 561 562 /* 563 * XXXGL: consider M_WAITOK in ioctl path after. 564 */ 565 st = pf_alloc_state(M_NOWAIT); 566 if (__predict_false(st == NULL)) 567 goto cleanup; 568 569 if ((skw = uma_zalloc(V_pf_state_key_z, M_NOWAIT)) == NULL) 570 goto cleanup; 571 572 #ifndef __NO_STRICT_ALIGNMENT 573 bcopy(&sp->pfs_1301.key, key, sizeof(struct pfsync_state_key) * 2); 574 kw = &key[PF_SK_WIRE]; 575 ks = &key[PF_SK_STACK]; 576 #else 577 kw = &sp->pfs_1301.key[PF_SK_WIRE]; 578 ks = &sp->pfs_1301.key[PF_SK_STACK]; 579 #endif 580 581 if (PF_ANEQ(&kw->addr[0], &ks->addr[0], sp->pfs_1301.af) || 582 PF_ANEQ(&kw->addr[1], &ks->addr[1], sp->pfs_1301.af) || 583 kw->port[0] != ks->port[0] || 584 kw->port[1] != ks->port[1]) { 585 sks = uma_zalloc(V_pf_state_key_z, M_NOWAIT); 586 if (sks == NULL) 587 goto cleanup; 588 } else 589 sks = skw; 590 591 /* allocate memory for scrub info */ 592 if (pfsync_alloc_scrub_memory(&sp->pfs_1301.src, &st->src) || 593 pfsync_alloc_scrub_memory(&sp->pfs_1301.dst, &st->dst)) 594 goto cleanup; 595 596 /* Copy to state key(s). */ 597 skw->addr[0] = kw->addr[0]; 598 skw->addr[1] = kw->addr[1]; 599 skw->port[0] = kw->port[0]; 600 skw->port[1] = kw->port[1]; 601 skw->proto = sp->pfs_1301.proto; 602 skw->af = sp->pfs_1301.af; 603 if (sks != skw) { 604 sks->addr[0] = ks->addr[0]; 605 sks->addr[1] = ks->addr[1]; 606 sks->port[0] = ks->port[0]; 607 sks->port[1] = ks->port[1]; 608 sks->proto = sp->pfs_1301.proto; 609 sks->af = sp->pfs_1301.af; 610 } 611 612 /* copy to state */ 613 bcopy(&sp->pfs_1301.rt_addr, &st->rt_addr, sizeof(st->rt_addr)); 614 st->creation = time_uptime - ntohl(sp->pfs_1301.creation); 615 st->expire = time_uptime; 616 if (sp->pfs_1301.expire) { 617 uint32_t timeout; 618 619 timeout = r->timeout[sp->pfs_1301.timeout]; 620 if (!timeout) 621 timeout = V_pf_default_rule.timeout[sp->pfs_1301.timeout]; 622 623 /* sp->expire may have been adaptively scaled by export. */ 624 st->expire -= timeout - ntohl(sp->pfs_1301.expire); 625 } 626 627 st->direction = sp->pfs_1301.direction; 628 st->act.log = sp->pfs_1301.log; 629 st->timeout = sp->pfs_1301.timeout; 630 631 switch (msg_version) { 632 case PFSYNC_MSG_VERSION_1301: 633 st->state_flags = sp->pfs_1301.state_flags; 634 /* 635 * In FreeBSD 13 pfsync lacks many attributes. Copy them 636 * from the rule if possible. If rule can't be matched 637 * clear any set options as we can't recover their 638 * parameters. 639 */ 640 if (r == &V_pf_default_rule) { 641 st->state_flags &= ~PFSTATE_SETMASK; 642 } else { 643 /* 644 * Similar to pf_rule_to_actions(). This code 645 * won't set the actions properly if they come 646 * from multiple "match" rules as only rule 647 * creating the state is send over pfsync. 648 */ 649 st->act.qid = r->qid; 650 st->act.pqid = r->pqid; 651 st->act.rtableid = r->rtableid; 652 if (r->scrub_flags & PFSTATE_SETTOS) 653 st->act.set_tos = r->set_tos; 654 st->act.min_ttl = r->min_ttl; 655 st->act.max_mss = r->max_mss; 656 st->state_flags |= (r->scrub_flags & 657 (PFSTATE_NODF|PFSTATE_RANDOMID| 658 PFSTATE_SETTOS|PFSTATE_SCRUB_TCP| 659 PFSTATE_SETPRIO)); 660 if (r->dnpipe || r->dnrpipe) { 661 if (r->free_flags & PFRULE_DN_IS_PIPE) 662 st->state_flags |= PFSTATE_DN_IS_PIPE; 663 else 664 st->state_flags &= ~PFSTATE_DN_IS_PIPE; 665 } 666 st->act.dnpipe = r->dnpipe; 667 st->act.dnrpipe = r->dnrpipe; 668 } 669 break; 670 case PFSYNC_MSG_VERSION_1400: 671 st->state_flags = ntohs(sp->pfs_1400.state_flags); 672 st->act.qid = ntohs(sp->pfs_1400.qid); 673 st->act.pqid = ntohs(sp->pfs_1400.pqid); 674 st->act.dnpipe = ntohs(sp->pfs_1400.dnpipe); 675 st->act.dnrpipe = ntohs(sp->pfs_1400.dnrpipe); 676 st->act.rtableid = ntohl(sp->pfs_1400.rtableid); 677 st->act.min_ttl = sp->pfs_1400.min_ttl; 678 st->act.set_tos = sp->pfs_1400.set_tos; 679 st->act.max_mss = ntohs(sp->pfs_1400.max_mss); 680 st->act.set_prio[0] = sp->pfs_1400.set_prio[0]; 681 st->act.set_prio[1] = sp->pfs_1400.set_prio[1]; 682 st->rt = sp->pfs_1400.rt; 683 if (st->rt && (st->rt_kif = pfi_kkif_find(sp->pfs_1400.rt_ifname)) == NULL) { 684 if (V_pf_status.debug >= PF_DEBUG_MISC) 685 printf("%s: unknown route interface: %s\n", 686 __func__, sp->pfs_1400.rt_ifname); 687 if (flags & PFSYNC_SI_IOCTL) 688 return (EINVAL); 689 return (0); /* skip this state */ 690 } 691 break; 692 default: 693 panic("%s: Unsupported pfsync_msg_version %d", 694 __func__, msg_version); 695 } 696 697 st->id = sp->pfs_1301.id; 698 st->creatorid = sp->pfs_1301.creatorid; 699 pf_state_peer_ntoh(&sp->pfs_1301.src, &st->src); 700 pf_state_peer_ntoh(&sp->pfs_1301.dst, &st->dst); 701 702 st->rule.ptr = r; 703 st->nat_rule.ptr = NULL; 704 st->anchor.ptr = NULL; 705 706 st->pfsync_time = time_uptime; 707 st->sync_state = PFSYNC_S_NONE; 708 709 if (!(flags & PFSYNC_SI_IOCTL)) 710 st->state_flags |= PFSTATE_NOSYNC; 711 712 if ((error = pf_state_insert(kif, kif, skw, sks, st)) != 0) 713 goto cleanup_state; 714 715 /* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */ 716 counter_u64_add(r->states_cur, 1); 717 counter_u64_add(r->states_tot, 1); 718 719 if (!(flags & PFSYNC_SI_IOCTL)) { 720 st->state_flags &= ~PFSTATE_NOSYNC; 721 if (st->state_flags & PFSTATE_ACK) { 722 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 723 PFSYNC_BUCKET_LOCK(b); 724 pfsync_q_ins(st, PFSYNC_S_IACK, true); 725 PFSYNC_BUCKET_UNLOCK(b); 726 727 pfsync_push_all(sc); 728 } 729 } 730 st->state_flags &= ~PFSTATE_ACK; 731 PF_STATE_UNLOCK(st); 732 733 return (0); 734 735 cleanup: 736 error = ENOMEM; 737 if (skw == sks) 738 sks = NULL; 739 uma_zfree(V_pf_state_key_z, skw); 740 uma_zfree(V_pf_state_key_z, sks); 741 742 cleanup_state: /* pf_state_insert() frees the state keys. */ 743 if (st) { 744 st->timeout = PFTM_UNLINKED; /* appease an assert */ 745 pf_free_state(st); 746 } 747 return (error); 748 } 749 750 #ifdef INET 751 static int 752 pfsync_input(struct mbuf **mp, int *offp __unused, int proto __unused) 753 { 754 struct pfsync_softc *sc = V_pfsyncif; 755 struct mbuf *m = *mp; 756 struct ip *ip = mtod(m, struct ip *); 757 struct pfsync_header *ph; 758 struct pfsync_subheader subh; 759 760 int offset, len, flags = 0; 761 int rv; 762 uint16_t count; 763 764 PF_RULES_RLOCK_TRACKER; 765 766 *mp = NULL; 767 V_pfsyncstats.pfsyncs_ipackets++; 768 769 /* Verify that we have a sync interface configured. */ 770 if (!sc || !sc->sc_sync_if || !V_pf_status.running || 771 (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 772 goto done; 773 774 /* verify that the packet came in on the right interface */ 775 if (sc->sc_sync_if != m->m_pkthdr.rcvif) { 776 V_pfsyncstats.pfsyncs_badif++; 777 goto done; 778 } 779 780 if_inc_counter(sc->sc_ifp, IFCOUNTER_IPACKETS, 1); 781 if_inc_counter(sc->sc_ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); 782 /* verify that the IP TTL is 255. */ 783 if (ip->ip_ttl != PFSYNC_DFLTTL) { 784 V_pfsyncstats.pfsyncs_badttl++; 785 goto done; 786 } 787 788 offset = ip->ip_hl << 2; 789 if (m->m_pkthdr.len < offset + sizeof(*ph)) { 790 V_pfsyncstats.pfsyncs_hdrops++; 791 goto done; 792 } 793 794 if (offset + sizeof(*ph) > m->m_len) { 795 if (m_pullup(m, offset + sizeof(*ph)) == NULL) { 796 V_pfsyncstats.pfsyncs_hdrops++; 797 return (IPPROTO_DONE); 798 } 799 ip = mtod(m, struct ip *); 800 } 801 ph = (struct pfsync_header *)((char *)ip + offset); 802 803 /* verify the version */ 804 if (ph->version != PFSYNC_VERSION) { 805 V_pfsyncstats.pfsyncs_badver++; 806 goto done; 807 } 808 809 len = ntohs(ph->len) + offset; 810 if (m->m_pkthdr.len < len) { 811 V_pfsyncstats.pfsyncs_badlen++; 812 goto done; 813 } 814 815 /* 816 * Trusting pf_chksum during packet processing, as well as seeking 817 * in interface name tree, require holding PF_RULES_RLOCK(). 818 */ 819 PF_RULES_RLOCK(); 820 if (!bcmp(&ph->pfcksum, &V_pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH)) 821 flags = PFSYNC_SI_CKSUM; 822 823 offset += sizeof(*ph); 824 while (offset <= len - sizeof(subh)) { 825 m_copydata(m, offset, sizeof(subh), (caddr_t)&subh); 826 offset += sizeof(subh); 827 828 if (subh.action >= PFSYNC_ACT_MAX) { 829 V_pfsyncstats.pfsyncs_badact++; 830 PF_RULES_RUNLOCK(); 831 goto done; 832 } 833 834 count = ntohs(subh.count); 835 V_pfsyncstats.pfsyncs_iacts[subh.action] += count; 836 rv = (*pfsync_acts[subh.action])(m, offset, count, flags, subh.action); 837 if (rv == -1) { 838 PF_RULES_RUNLOCK(); 839 return (IPPROTO_DONE); 840 } 841 842 offset += rv; 843 } 844 PF_RULES_RUNLOCK(); 845 846 done: 847 m_freem(m); 848 return (IPPROTO_DONE); 849 } 850 #endif 851 852 #ifdef INET6 853 static int 854 pfsync6_input(struct mbuf **mp, int *offp __unused, int proto __unused) 855 { 856 struct pfsync_softc *sc = V_pfsyncif; 857 struct mbuf *m = *mp; 858 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 859 struct pfsync_header *ph; 860 struct pfsync_subheader subh; 861 862 int offset, len, flags = 0; 863 int rv; 864 uint16_t count; 865 866 PF_RULES_RLOCK_TRACKER; 867 868 *mp = NULL; 869 V_pfsyncstats.pfsyncs_ipackets++; 870 871 /* Verify that we have a sync interface configured. */ 872 if (!sc || !sc->sc_sync_if || !V_pf_status.running || 873 (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 874 goto done; 875 876 /* verify that the packet came in on the right interface */ 877 if (sc->sc_sync_if != m->m_pkthdr.rcvif) { 878 V_pfsyncstats.pfsyncs_badif++; 879 goto done; 880 } 881 882 if_inc_counter(sc->sc_ifp, IFCOUNTER_IPACKETS, 1); 883 if_inc_counter(sc->sc_ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); 884 /* verify that the IP TTL is 255. */ 885 if (ip6->ip6_hlim != PFSYNC_DFLTTL) { 886 V_pfsyncstats.pfsyncs_badttl++; 887 goto done; 888 } 889 890 891 offset = sizeof(*ip6); 892 if (m->m_pkthdr.len < offset + sizeof(*ph)) { 893 V_pfsyncstats.pfsyncs_hdrops++; 894 goto done; 895 } 896 897 if (offset + sizeof(*ph) > m->m_len) { 898 if (m_pullup(m, offset + sizeof(*ph)) == NULL) { 899 V_pfsyncstats.pfsyncs_hdrops++; 900 return (IPPROTO_DONE); 901 } 902 ip6 = mtod(m, struct ip6_hdr *); 903 } 904 ph = (struct pfsync_header *)((char *)ip6 + offset); 905 906 /* verify the version */ 907 if (ph->version != PFSYNC_VERSION) { 908 V_pfsyncstats.pfsyncs_badver++; 909 goto done; 910 } 911 912 len = ntohs(ph->len) + offset; 913 if (m->m_pkthdr.len < len) { 914 V_pfsyncstats.pfsyncs_badlen++; 915 goto done; 916 } 917 918 /* 919 * Trusting pf_chksum during packet processing, as well as seeking 920 * in interface name tree, require holding PF_RULES_RLOCK(). 921 */ 922 PF_RULES_RLOCK(); 923 if (!bcmp(&ph->pfcksum, &V_pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH)) 924 flags = PFSYNC_SI_CKSUM; 925 926 offset += sizeof(*ph); 927 while (offset <= len - sizeof(subh)) { 928 m_copydata(m, offset, sizeof(subh), (caddr_t)&subh); 929 offset += sizeof(subh); 930 931 if (subh.action >= PFSYNC_ACT_MAX) { 932 V_pfsyncstats.pfsyncs_badact++; 933 PF_RULES_RUNLOCK(); 934 goto done; 935 } 936 937 count = ntohs(subh.count); 938 V_pfsyncstats.pfsyncs_iacts[subh.action] += count; 939 rv = (*pfsync_acts[subh.action])(m, offset, count, flags, subh.action); 940 if (rv == -1) { 941 PF_RULES_RUNLOCK(); 942 return (IPPROTO_DONE); 943 } 944 945 offset += rv; 946 } 947 PF_RULES_RUNLOCK(); 948 949 done: 950 m_freem(m); 951 return (IPPROTO_DONE); 952 } 953 #endif 954 955 static int 956 pfsync_in_clr(struct mbuf *m, int offset, int count, int flags, int action) 957 { 958 struct pfsync_clr *clr; 959 struct mbuf *mp; 960 int len = sizeof(*clr) * count; 961 int i, offp; 962 u_int32_t creatorid; 963 964 mp = m_pulldown(m, offset, len, &offp); 965 if (mp == NULL) { 966 V_pfsyncstats.pfsyncs_badlen++; 967 return (-1); 968 } 969 clr = (struct pfsync_clr *)(mp->m_data + offp); 970 971 for (i = 0; i < count; i++) { 972 creatorid = clr[i].creatorid; 973 974 if (clr[i].ifname[0] != '\0' && 975 pfi_kkif_find(clr[i].ifname) == NULL) 976 continue; 977 978 for (int i = 0; i <= pf_hashmask; i++) { 979 struct pf_idhash *ih = &V_pf_idhash[i]; 980 struct pf_kstate *s; 981 relock: 982 PF_HASHROW_LOCK(ih); 983 LIST_FOREACH(s, &ih->states, entry) { 984 if (s->creatorid == creatorid) { 985 s->state_flags |= PFSTATE_NOSYNC; 986 pf_unlink_state(s); 987 goto relock; 988 } 989 } 990 PF_HASHROW_UNLOCK(ih); 991 } 992 } 993 994 return (len); 995 } 996 997 static int 998 pfsync_in_ins(struct mbuf *m, int offset, int count, int flags, int action) 999 { 1000 struct mbuf *mp; 1001 union pfsync_state_union *sa, *sp; 1002 int i, offp, len, msg_version; 1003 1004 switch (action) { 1005 case PFSYNC_ACT_INS_1301: 1006 len = sizeof(struct pfsync_state_1301) * count; 1007 msg_version = PFSYNC_MSG_VERSION_1301; 1008 break; 1009 case PFSYNC_ACT_INS_1400: 1010 len = sizeof(struct pfsync_state_1400) * count; 1011 msg_version = PFSYNC_MSG_VERSION_1400; 1012 break; 1013 default: 1014 V_pfsyncstats.pfsyncs_badact++; 1015 return (-1); 1016 } 1017 1018 mp = m_pulldown(m, offset, len, &offp); 1019 if (mp == NULL) { 1020 V_pfsyncstats.pfsyncs_badlen++; 1021 return (-1); 1022 } 1023 sa = (union pfsync_state_union *)(mp->m_data + offp); 1024 1025 for (i = 0; i < count; i++) { 1026 sp = &sa[i]; 1027 1028 /* Check for invalid values. */ 1029 if (sp->pfs_1301.timeout >= PFTM_MAX || 1030 sp->pfs_1301.src.state > PF_TCPS_PROXY_DST || 1031 sp->pfs_1301.dst.state > PF_TCPS_PROXY_DST || 1032 sp->pfs_1301.direction > PF_OUT || 1033 (sp->pfs_1301.af != AF_INET && 1034 sp->pfs_1301.af != AF_INET6)) { 1035 if (V_pf_status.debug >= PF_DEBUG_MISC) 1036 printf("%s: invalid value\n", __func__); 1037 V_pfsyncstats.pfsyncs_badval++; 1038 continue; 1039 } 1040 1041 if (pfsync_state_import(sp, flags, msg_version) == ENOMEM) 1042 /* Drop out, but process the rest of the actions. */ 1043 break; 1044 } 1045 1046 return (len); 1047 } 1048 1049 static int 1050 pfsync_in_iack(struct mbuf *m, int offset, int count, int flags, int action) 1051 { 1052 struct pfsync_ins_ack *ia, *iaa; 1053 struct pf_kstate *st; 1054 1055 struct mbuf *mp; 1056 int len = count * sizeof(*ia); 1057 int offp, i; 1058 1059 mp = m_pulldown(m, offset, len, &offp); 1060 if (mp == NULL) { 1061 V_pfsyncstats.pfsyncs_badlen++; 1062 return (-1); 1063 } 1064 iaa = (struct pfsync_ins_ack *)(mp->m_data + offp); 1065 1066 for (i = 0; i < count; i++) { 1067 ia = &iaa[i]; 1068 1069 st = pf_find_state_byid(ia->id, ia->creatorid); 1070 if (st == NULL) 1071 continue; 1072 1073 if (st->state_flags & PFSTATE_ACK) { 1074 pfsync_undefer_state(st, 0); 1075 } 1076 PF_STATE_UNLOCK(st); 1077 } 1078 /* 1079 * XXX this is not yet implemented, but we know the size of the 1080 * message so we can skip it. 1081 */ 1082 1083 return (count * sizeof(struct pfsync_ins_ack)); 1084 } 1085 1086 static int 1087 pfsync_upd_tcp(struct pf_kstate *st, struct pfsync_state_peer *src, 1088 struct pfsync_state_peer *dst) 1089 { 1090 int sync = 0; 1091 1092 PF_STATE_LOCK_ASSERT(st); 1093 1094 /* 1095 * The state should never go backwards except 1096 * for syn-proxy states. Neither should the 1097 * sequence window slide backwards. 1098 */ 1099 if ((st->src.state > src->state && 1100 (st->src.state < PF_TCPS_PROXY_SRC || 1101 src->state >= PF_TCPS_PROXY_SRC)) || 1102 1103 (st->src.state == src->state && 1104 SEQ_GT(st->src.seqlo, ntohl(src->seqlo)))) 1105 sync++; 1106 else 1107 pf_state_peer_ntoh(src, &st->src); 1108 1109 if ((st->dst.state > dst->state) || 1110 1111 (st->dst.state >= TCPS_SYN_SENT && 1112 SEQ_GT(st->dst.seqlo, ntohl(dst->seqlo)))) 1113 sync++; 1114 else 1115 pf_state_peer_ntoh(dst, &st->dst); 1116 1117 return (sync); 1118 } 1119 1120 static int 1121 pfsync_in_upd(struct mbuf *m, int offset, int count, int flags, int action) 1122 { 1123 struct pfsync_softc *sc = V_pfsyncif; 1124 union pfsync_state_union *sa, *sp; 1125 struct pf_kstate *st; 1126 struct mbuf *mp; 1127 int sync, offp, i, len, msg_version; 1128 1129 switch (action) { 1130 case PFSYNC_ACT_UPD_1301: 1131 len = sizeof(struct pfsync_state_1301) * count; 1132 msg_version = PFSYNC_MSG_VERSION_1301; 1133 break; 1134 case PFSYNC_ACT_UPD_1400: 1135 len = sizeof(struct pfsync_state_1400) * count; 1136 msg_version = PFSYNC_MSG_VERSION_1400; 1137 break; 1138 default: 1139 V_pfsyncstats.pfsyncs_badact++; 1140 return (-1); 1141 } 1142 1143 mp = m_pulldown(m, offset, len, &offp); 1144 if (mp == NULL) { 1145 V_pfsyncstats.pfsyncs_badlen++; 1146 return (-1); 1147 } 1148 sa = (union pfsync_state_union *)(mp->m_data + offp); 1149 1150 for (i = 0; i < count; i++) { 1151 sp = &sa[i]; 1152 1153 /* check for invalid values */ 1154 if (sp->pfs_1301.timeout >= PFTM_MAX || 1155 sp->pfs_1301.src.state > PF_TCPS_PROXY_DST || 1156 sp->pfs_1301.dst.state > PF_TCPS_PROXY_DST) { 1157 if (V_pf_status.debug >= PF_DEBUG_MISC) { 1158 printf("pfsync_input: PFSYNC_ACT_UPD: " 1159 "invalid value\n"); 1160 } 1161 V_pfsyncstats.pfsyncs_badval++; 1162 continue; 1163 } 1164 1165 st = pf_find_state_byid(sp->pfs_1301.id, sp->pfs_1301.creatorid); 1166 if (st == NULL) { 1167 /* insert the update */ 1168 if (pfsync_state_import(sp, flags, msg_version)) 1169 V_pfsyncstats.pfsyncs_badstate++; 1170 continue; 1171 } 1172 1173 if (st->state_flags & PFSTATE_ACK) { 1174 pfsync_undefer_state(st, 1); 1175 } 1176 1177 if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP) 1178 sync = pfsync_upd_tcp(st, &sp->pfs_1301.src, &sp->pfs_1301.dst); 1179 else { 1180 sync = 0; 1181 1182 /* 1183 * Non-TCP protocol state machine always go 1184 * forwards 1185 */ 1186 if (st->src.state > sp->pfs_1301.src.state) 1187 sync++; 1188 else 1189 pf_state_peer_ntoh(&sp->pfs_1301.src, &st->src); 1190 if (st->dst.state > sp->pfs_1301.dst.state) 1191 sync++; 1192 else 1193 pf_state_peer_ntoh(&sp->pfs_1301.dst, &st->dst); 1194 } 1195 if (sync < 2) { 1196 pfsync_alloc_scrub_memory(&sp->pfs_1301.dst, &st->dst); 1197 pf_state_peer_ntoh(&sp->pfs_1301.dst, &st->dst); 1198 st->expire = time_uptime; 1199 st->timeout = sp->pfs_1301.timeout; 1200 } 1201 st->pfsync_time = time_uptime; 1202 1203 if (sync) { 1204 V_pfsyncstats.pfsyncs_stale++; 1205 1206 pfsync_update_state(st); 1207 PF_STATE_UNLOCK(st); 1208 pfsync_push_all(sc); 1209 continue; 1210 } 1211 PF_STATE_UNLOCK(st); 1212 } 1213 1214 return (len); 1215 } 1216 1217 static int 1218 pfsync_in_upd_c(struct mbuf *m, int offset, int count, int flags, int action) 1219 { 1220 struct pfsync_softc *sc = V_pfsyncif; 1221 struct pfsync_upd_c *ua, *up; 1222 struct pf_kstate *st; 1223 int len = count * sizeof(*up); 1224 int sync; 1225 struct mbuf *mp; 1226 int offp, i; 1227 1228 mp = m_pulldown(m, offset, len, &offp); 1229 if (mp == NULL) { 1230 V_pfsyncstats.pfsyncs_badlen++; 1231 return (-1); 1232 } 1233 ua = (struct pfsync_upd_c *)(mp->m_data + offp); 1234 1235 for (i = 0; i < count; i++) { 1236 up = &ua[i]; 1237 1238 /* check for invalid values */ 1239 if (up->timeout >= PFTM_MAX || 1240 up->src.state > PF_TCPS_PROXY_DST || 1241 up->dst.state > PF_TCPS_PROXY_DST) { 1242 if (V_pf_status.debug >= PF_DEBUG_MISC) { 1243 printf("pfsync_input: " 1244 "PFSYNC_ACT_UPD_C: " 1245 "invalid value\n"); 1246 } 1247 V_pfsyncstats.pfsyncs_badval++; 1248 continue; 1249 } 1250 1251 st = pf_find_state_byid(up->id, up->creatorid); 1252 if (st == NULL) { 1253 /* We don't have this state. Ask for it. */ 1254 PFSYNC_BUCKET_LOCK(&sc->sc_buckets[0]); 1255 pfsync_request_update(up->creatorid, up->id); 1256 PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[0]); 1257 continue; 1258 } 1259 1260 if (st->state_flags & PFSTATE_ACK) { 1261 pfsync_undefer_state(st, 1); 1262 } 1263 1264 if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP) 1265 sync = pfsync_upd_tcp(st, &up->src, &up->dst); 1266 else { 1267 sync = 0; 1268 1269 /* 1270 * Non-TCP protocol state machine always go 1271 * forwards 1272 */ 1273 if (st->src.state > up->src.state) 1274 sync++; 1275 else 1276 pf_state_peer_ntoh(&up->src, &st->src); 1277 if (st->dst.state > up->dst.state) 1278 sync++; 1279 else 1280 pf_state_peer_ntoh(&up->dst, &st->dst); 1281 } 1282 if (sync < 2) { 1283 pfsync_alloc_scrub_memory(&up->dst, &st->dst); 1284 pf_state_peer_ntoh(&up->dst, &st->dst); 1285 st->expire = time_uptime; 1286 st->timeout = up->timeout; 1287 } 1288 st->pfsync_time = time_uptime; 1289 1290 if (sync) { 1291 V_pfsyncstats.pfsyncs_stale++; 1292 1293 pfsync_update_state(st); 1294 PF_STATE_UNLOCK(st); 1295 pfsync_push_all(sc); 1296 continue; 1297 } 1298 PF_STATE_UNLOCK(st); 1299 } 1300 1301 return (len); 1302 } 1303 1304 static int 1305 pfsync_in_ureq(struct mbuf *m, int offset, int count, int flags, int action) 1306 { 1307 struct pfsync_upd_req *ur, *ura; 1308 struct mbuf *mp; 1309 int len = count * sizeof(*ur); 1310 int i, offp; 1311 1312 struct pf_kstate *st; 1313 1314 mp = m_pulldown(m, offset, len, &offp); 1315 if (mp == NULL) { 1316 V_pfsyncstats.pfsyncs_badlen++; 1317 return (-1); 1318 } 1319 ura = (struct pfsync_upd_req *)(mp->m_data + offp); 1320 1321 for (i = 0; i < count; i++) { 1322 ur = &ura[i]; 1323 1324 if (ur->id == 0 && ur->creatorid == 0) 1325 pfsync_bulk_start(); 1326 else { 1327 st = pf_find_state_byid(ur->id, ur->creatorid); 1328 if (st == NULL) { 1329 V_pfsyncstats.pfsyncs_badstate++; 1330 continue; 1331 } 1332 if (st->state_flags & PFSTATE_NOSYNC) { 1333 PF_STATE_UNLOCK(st); 1334 continue; 1335 } 1336 1337 pfsync_update_state_req(st); 1338 PF_STATE_UNLOCK(st); 1339 } 1340 } 1341 1342 return (len); 1343 } 1344 1345 static int 1346 pfsync_in_del_c(struct mbuf *m, int offset, int count, int flags, int action) 1347 { 1348 struct mbuf *mp; 1349 struct pfsync_del_c *sa, *sp; 1350 struct pf_kstate *st; 1351 int len = count * sizeof(*sp); 1352 int offp, i; 1353 1354 mp = m_pulldown(m, offset, len, &offp); 1355 if (mp == NULL) { 1356 V_pfsyncstats.pfsyncs_badlen++; 1357 return (-1); 1358 } 1359 sa = (struct pfsync_del_c *)(mp->m_data + offp); 1360 1361 for (i = 0; i < count; i++) { 1362 sp = &sa[i]; 1363 1364 st = pf_find_state_byid(sp->id, sp->creatorid); 1365 if (st == NULL) { 1366 V_pfsyncstats.pfsyncs_badstate++; 1367 continue; 1368 } 1369 1370 st->state_flags |= PFSTATE_NOSYNC; 1371 pf_unlink_state(st); 1372 } 1373 1374 return (len); 1375 } 1376 1377 static int 1378 pfsync_in_bus(struct mbuf *m, int offset, int count, int flags, int action) 1379 { 1380 struct pfsync_softc *sc = V_pfsyncif; 1381 struct pfsync_bus *bus; 1382 struct mbuf *mp; 1383 int len = count * sizeof(*bus); 1384 int offp; 1385 1386 PFSYNC_BLOCK(sc); 1387 1388 /* If we're not waiting for a bulk update, who cares. */ 1389 if (sc->sc_ureq_sent == 0) { 1390 PFSYNC_BUNLOCK(sc); 1391 return (len); 1392 } 1393 1394 mp = m_pulldown(m, offset, len, &offp); 1395 if (mp == NULL) { 1396 PFSYNC_BUNLOCK(sc); 1397 V_pfsyncstats.pfsyncs_badlen++; 1398 return (-1); 1399 } 1400 bus = (struct pfsync_bus *)(mp->m_data + offp); 1401 1402 switch (bus->status) { 1403 case PFSYNC_BUS_START: 1404 callout_reset(&sc->sc_bulkfail_tmo, 4 * hz + 1405 V_pf_limits[PF_LIMIT_STATES].limit / 1406 ((sc->sc_ifp->if_mtu - PFSYNC_MINPKT) / 1407 sizeof(union pfsync_state_union)), 1408 pfsync_bulk_fail, sc); 1409 if (V_pf_status.debug >= PF_DEBUG_MISC) 1410 printf("pfsync: received bulk update start\n"); 1411 break; 1412 1413 case PFSYNC_BUS_END: 1414 if (time_uptime - ntohl(bus->endtime) >= 1415 sc->sc_ureq_sent) { 1416 /* that's it, we're happy */ 1417 sc->sc_ureq_sent = 0; 1418 sc->sc_bulk_tries = 0; 1419 callout_stop(&sc->sc_bulkfail_tmo); 1420 if (!(sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) 1421 (*carp_demote_adj_p)(-V_pfsync_carp_adj, 1422 "pfsync bulk done"); 1423 sc->sc_flags |= PFSYNCF_OK; 1424 if (V_pf_status.debug >= PF_DEBUG_MISC) 1425 printf("pfsync: received valid " 1426 "bulk update end\n"); 1427 } else { 1428 if (V_pf_status.debug >= PF_DEBUG_MISC) 1429 printf("pfsync: received invalid " 1430 "bulk update end: bad timestamp\n"); 1431 } 1432 break; 1433 } 1434 PFSYNC_BUNLOCK(sc); 1435 1436 return (len); 1437 } 1438 1439 static int 1440 pfsync_in_tdb(struct mbuf *m, int offset, int count, int flags, int action) 1441 { 1442 int len = count * sizeof(struct pfsync_tdb); 1443 1444 #if defined(IPSEC) 1445 struct pfsync_tdb *tp; 1446 struct mbuf *mp; 1447 int offp; 1448 int i; 1449 int s; 1450 1451 mp = m_pulldown(m, offset, len, &offp); 1452 if (mp == NULL) { 1453 V_pfsyncstats.pfsyncs_badlen++; 1454 return (-1); 1455 } 1456 tp = (struct pfsync_tdb *)(mp->m_data + offp); 1457 1458 for (i = 0; i < count; i++) 1459 pfsync_update_net_tdb(&tp[i]); 1460 #endif 1461 1462 return (len); 1463 } 1464 1465 #if defined(IPSEC) 1466 /* Update an in-kernel tdb. Silently fail if no tdb is found. */ 1467 static void 1468 pfsync_update_net_tdb(struct pfsync_tdb *pt) 1469 { 1470 struct tdb *tdb; 1471 int s; 1472 1473 /* check for invalid values */ 1474 if (ntohl(pt->spi) <= SPI_RESERVED_MAX || 1475 (pt->dst.sa.sa_family != AF_INET && 1476 pt->dst.sa.sa_family != AF_INET6)) 1477 goto bad; 1478 1479 tdb = gettdb(pt->spi, &pt->dst, pt->sproto); 1480 if (tdb) { 1481 pt->rpl = ntohl(pt->rpl); 1482 pt->cur_bytes = (unsigned long long)be64toh(pt->cur_bytes); 1483 1484 /* Neither replay nor byte counter should ever decrease. */ 1485 if (pt->rpl < tdb->tdb_rpl || 1486 pt->cur_bytes < tdb->tdb_cur_bytes) { 1487 goto bad; 1488 } 1489 1490 tdb->tdb_rpl = pt->rpl; 1491 tdb->tdb_cur_bytes = pt->cur_bytes; 1492 } 1493 return; 1494 1495 bad: 1496 if (V_pf_status.debug >= PF_DEBUG_MISC) 1497 printf("pfsync_insert: PFSYNC_ACT_TDB_UPD: " 1498 "invalid value\n"); 1499 V_pfsyncstats.pfsyncs_badstate++; 1500 return; 1501 } 1502 #endif 1503 1504 static int 1505 pfsync_in_eof(struct mbuf *m, int offset, int count, int flags, int action) 1506 { 1507 /* check if we are at the right place in the packet */ 1508 if (offset != m->m_pkthdr.len) 1509 V_pfsyncstats.pfsyncs_badlen++; 1510 1511 /* we're done. free and let the caller return */ 1512 m_freem(m); 1513 return (-1); 1514 } 1515 1516 static int 1517 pfsync_in_error(struct mbuf *m, int offset, int count, int flags, int action) 1518 { 1519 V_pfsyncstats.pfsyncs_badact++; 1520 1521 m_freem(m); 1522 return (-1); 1523 } 1524 1525 static int 1526 pfsyncoutput(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 1527 struct route *rt) 1528 { 1529 m_freem(m); 1530 return (0); 1531 } 1532 1533 /* ARGSUSED */ 1534 static int 1535 pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1536 { 1537 struct pfsync_softc *sc = ifp->if_softc; 1538 struct ifreq *ifr = (struct ifreq *)data; 1539 struct pfsyncreq pfsyncr; 1540 size_t nvbuflen; 1541 int error; 1542 int c; 1543 1544 switch (cmd) { 1545 case SIOCSIFFLAGS: 1546 PFSYNC_LOCK(sc); 1547 if (ifp->if_flags & IFF_UP) { 1548 ifp->if_drv_flags |= IFF_DRV_RUNNING; 1549 PFSYNC_UNLOCK(sc); 1550 pfsync_pointers_init(); 1551 } else { 1552 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 1553 PFSYNC_UNLOCK(sc); 1554 pfsync_pointers_uninit(); 1555 } 1556 break; 1557 case SIOCSIFMTU: 1558 if (!sc->sc_sync_if || 1559 ifr->ifr_mtu <= PFSYNC_MINPKT || 1560 ifr->ifr_mtu > sc->sc_sync_if->if_mtu) 1561 return (EINVAL); 1562 if (ifr->ifr_mtu < ifp->if_mtu) { 1563 for (c = 0; c < pfsync_buckets; c++) { 1564 PFSYNC_BUCKET_LOCK(&sc->sc_buckets[c]); 1565 if (sc->sc_buckets[c].b_len > PFSYNC_MINPKT) 1566 pfsync_sendout(1, c); 1567 PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[c]); 1568 } 1569 } 1570 ifp->if_mtu = ifr->ifr_mtu; 1571 break; 1572 case SIOCGETPFSYNC: 1573 bzero(&pfsyncr, sizeof(pfsyncr)); 1574 PFSYNC_LOCK(sc); 1575 if (sc->sc_sync_if) { 1576 strlcpy(pfsyncr.pfsyncr_syncdev, 1577 sc->sc_sync_if->if_xname, IFNAMSIZ); 1578 } 1579 pfsyncr.pfsyncr_syncpeer = ((struct sockaddr_in *)&sc->sc_sync_peer)->sin_addr; 1580 pfsyncr.pfsyncr_maxupdates = sc->sc_maxupdates; 1581 pfsyncr.pfsyncr_defer = sc->sc_flags; 1582 PFSYNC_UNLOCK(sc); 1583 return (copyout(&pfsyncr, ifr_data_get_ptr(ifr), 1584 sizeof(pfsyncr))); 1585 1586 case SIOCGETPFSYNCNV: 1587 { 1588 nvlist_t *nvl_syncpeer; 1589 nvlist_t *nvl = nvlist_create(0); 1590 1591 if (nvl == NULL) 1592 return (ENOMEM); 1593 1594 if (sc->sc_sync_if) 1595 nvlist_add_string(nvl, "syncdev", sc->sc_sync_if->if_xname); 1596 nvlist_add_number(nvl, "maxupdates", sc->sc_maxupdates); 1597 nvlist_add_number(nvl, "flags", sc->sc_flags); 1598 nvlist_add_number(nvl, "version", sc->sc_version); 1599 if ((nvl_syncpeer = pfsync_sockaddr_to_syncpeer_nvlist(&sc->sc_sync_peer)) != NULL) 1600 nvlist_add_nvlist(nvl, "syncpeer", nvl_syncpeer); 1601 1602 void *packed = NULL; 1603 packed = nvlist_pack(nvl, &nvbuflen); 1604 if (packed == NULL) { 1605 free(packed, M_NVLIST); 1606 nvlist_destroy(nvl); 1607 return (ENOMEM); 1608 } 1609 1610 if (nvbuflen > ifr->ifr_cap_nv.buf_length) { 1611 ifr->ifr_cap_nv.length = nvbuflen; 1612 ifr->ifr_cap_nv.buffer = NULL; 1613 free(packed, M_NVLIST); 1614 nvlist_destroy(nvl); 1615 return (EFBIG); 1616 } 1617 1618 ifr->ifr_cap_nv.length = nvbuflen; 1619 error = copyout(packed, ifr->ifr_cap_nv.buffer, nvbuflen); 1620 1621 nvlist_destroy(nvl); 1622 nvlist_destroy(nvl_syncpeer); 1623 free(packed, M_NVLIST); 1624 break; 1625 } 1626 1627 case SIOCSETPFSYNC: 1628 { 1629 struct pfsync_kstatus status; 1630 1631 if ((error = priv_check(curthread, PRIV_NETINET_PF)) != 0) 1632 return (error); 1633 if ((error = copyin(ifr_data_get_ptr(ifr), &pfsyncr, 1634 sizeof(pfsyncr)))) 1635 return (error); 1636 1637 memset((char *)&status, 0, sizeof(struct pfsync_kstatus)); 1638 pfsync_pfsyncreq_to_kstatus(&pfsyncr, &status); 1639 1640 error = pfsync_kstatus_to_softc(&status, sc); 1641 return (error); 1642 } 1643 case SIOCSETPFSYNCNV: 1644 { 1645 struct pfsync_kstatus status; 1646 void *data; 1647 nvlist_t *nvl; 1648 1649 if ((error = priv_check(curthread, PRIV_NETINET_PF)) != 0) 1650 return (error); 1651 if (ifr->ifr_cap_nv.length > IFR_CAP_NV_MAXBUFSIZE) 1652 return (EINVAL); 1653 1654 data = malloc(ifr->ifr_cap_nv.length, M_TEMP, M_WAITOK); 1655 1656 if ((error = copyin(ifr->ifr_cap_nv.buffer, data, 1657 ifr->ifr_cap_nv.length)) != 0) { 1658 free(data, M_TEMP); 1659 return (error); 1660 } 1661 1662 if ((nvl = nvlist_unpack(data, ifr->ifr_cap_nv.length, 0)) == NULL) { 1663 free(data, M_TEMP); 1664 return (EINVAL); 1665 } 1666 1667 memset((char *)&status, 0, sizeof(struct pfsync_kstatus)); 1668 pfsync_nvstatus_to_kstatus(nvl, &status); 1669 1670 nvlist_destroy(nvl); 1671 free(data, M_TEMP); 1672 1673 error = pfsync_kstatus_to_softc(&status, sc); 1674 return (error); 1675 } 1676 default: 1677 return (ENOTTY); 1678 } 1679 1680 return (0); 1681 } 1682 1683 static void 1684 pfsync_out_state_1301(struct pf_kstate *st, void *buf) 1685 { 1686 union pfsync_state_union *sp = buf; 1687 1688 pfsync_state_export(sp, st, PFSYNC_MSG_VERSION_1301); 1689 } 1690 1691 static void 1692 pfsync_out_state_1400(struct pf_kstate *st, void *buf) 1693 { 1694 union pfsync_state_union *sp = buf; 1695 1696 pfsync_state_export(sp, st, PFSYNC_MSG_VERSION_1400); 1697 } 1698 1699 static void 1700 pfsync_out_iack(struct pf_kstate *st, void *buf) 1701 { 1702 struct pfsync_ins_ack *iack = buf; 1703 1704 iack->id = st->id; 1705 iack->creatorid = st->creatorid; 1706 } 1707 1708 static void 1709 pfsync_out_upd_c(struct pf_kstate *st, void *buf) 1710 { 1711 struct pfsync_upd_c *up = buf; 1712 1713 bzero(up, sizeof(*up)); 1714 up->id = st->id; 1715 pf_state_peer_hton(&st->src, &up->src); 1716 pf_state_peer_hton(&st->dst, &up->dst); 1717 up->creatorid = st->creatorid; 1718 up->timeout = st->timeout; 1719 } 1720 1721 static void 1722 pfsync_out_del_c(struct pf_kstate *st, void *buf) 1723 { 1724 struct pfsync_del_c *dp = buf; 1725 1726 dp->id = st->id; 1727 dp->creatorid = st->creatorid; 1728 st->state_flags |= PFSTATE_NOSYNC; 1729 } 1730 1731 static void 1732 pfsync_drop(struct pfsync_softc *sc) 1733 { 1734 struct pf_kstate *st, *next; 1735 struct pfsync_upd_req_item *ur; 1736 struct pfsync_bucket *b; 1737 int c; 1738 enum pfsync_q_id q; 1739 1740 for (c = 0; c < pfsync_buckets; c++) { 1741 b = &sc->sc_buckets[c]; 1742 for (q = 0; q < PFSYNC_Q_COUNT; q++) { 1743 if (TAILQ_EMPTY(&b->b_qs[q])) 1744 continue; 1745 1746 TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, next) { 1747 KASSERT(st->sync_state == pfsync_qid_sstate[q], 1748 ("%s: st->sync_state == q", 1749 __func__)); 1750 st->sync_state = PFSYNC_S_NONE; 1751 pf_release_state(st); 1752 } 1753 TAILQ_INIT(&b->b_qs[q]); 1754 } 1755 1756 while ((ur = TAILQ_FIRST(&b->b_upd_req_list)) != NULL) { 1757 TAILQ_REMOVE(&b->b_upd_req_list, ur, ur_entry); 1758 free(ur, M_PFSYNC); 1759 } 1760 1761 b->b_len = PFSYNC_MINPKT; 1762 b->b_plus = NULL; 1763 } 1764 } 1765 1766 static void 1767 pfsync_sendout(int schedswi, int c) 1768 { 1769 struct pfsync_softc *sc = V_pfsyncif; 1770 struct ifnet *ifp = sc->sc_ifp; 1771 struct mbuf *m; 1772 struct pfsync_header *ph; 1773 struct pfsync_subheader *subh; 1774 struct pf_kstate *st, *st_next; 1775 struct pfsync_upd_req_item *ur; 1776 struct pfsync_bucket *b = &sc->sc_buckets[c]; 1777 int aflen, offset, count = 0; 1778 enum pfsync_q_id q; 1779 1780 KASSERT(sc != NULL, ("%s: null sc", __func__)); 1781 KASSERT(b->b_len > PFSYNC_MINPKT, 1782 ("%s: sc_len %zu", __func__, b->b_len)); 1783 PFSYNC_BUCKET_LOCK_ASSERT(b); 1784 1785 if (ifp->if_bpf == NULL && sc->sc_sync_if == NULL) { 1786 pfsync_drop(sc); 1787 return; 1788 } 1789 1790 m = m_get2(max_linkhdr + b->b_len, M_NOWAIT, MT_DATA, M_PKTHDR); 1791 if (m == NULL) { 1792 if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1); 1793 V_pfsyncstats.pfsyncs_onomem++; 1794 return; 1795 } 1796 m->m_data += max_linkhdr; 1797 m->m_len = m->m_pkthdr.len = b->b_len; 1798 1799 /* build the ip header */ 1800 switch (sc->sc_sync_peer.ss_family) { 1801 #ifdef INET 1802 case AF_INET: 1803 { 1804 struct ip *ip; 1805 1806 ip = mtod(m, struct ip *); 1807 bcopy(&sc->sc_template.ipv4, ip, sizeof(*ip)); 1808 aflen = offset = sizeof(*ip); 1809 1810 ip->ip_len = htons(m->m_pkthdr.len); 1811 ip_fillid(ip); 1812 break; 1813 } 1814 #endif 1815 #ifdef INET6 1816 case AF_INET6: 1817 { 1818 struct ip6_hdr *ip6; 1819 1820 ip6 = mtod(m, struct ip6_hdr *); 1821 bcopy(&sc->sc_template.ipv6, ip6, sizeof(*ip6)); 1822 aflen = offset = sizeof(*ip6); 1823 1824 ip6->ip6_plen = htons(m->m_pkthdr.len); 1825 break; 1826 } 1827 #endif 1828 default: 1829 m_freem(m); 1830 return; 1831 } 1832 1833 /* build the pfsync header */ 1834 ph = (struct pfsync_header *)(m->m_data + offset); 1835 bzero(ph, sizeof(*ph)); 1836 offset += sizeof(*ph); 1837 1838 ph->version = PFSYNC_VERSION; 1839 ph->len = htons(b->b_len - aflen); 1840 bcopy(V_pf_status.pf_chksum, ph->pfcksum, PF_MD5_DIGEST_LENGTH); 1841 1842 /* walk the queues */ 1843 for (q = 0; q < PFSYNC_Q_COUNT; q++) { 1844 if (TAILQ_EMPTY(&b->b_qs[q])) 1845 continue; 1846 1847 subh = (struct pfsync_subheader *)(m->m_data + offset); 1848 offset += sizeof(*subh); 1849 1850 count = 0; 1851 TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, st_next) { 1852 KASSERT(st->sync_state == pfsync_qid_sstate[q], 1853 ("%s: st->sync_state == q", 1854 __func__)); 1855 /* 1856 * XXXGL: some of write methods do unlocked reads 1857 * of state data :( 1858 */ 1859 pfsync_qs[q].write(st, m->m_data + offset); 1860 offset += pfsync_qs[q].len; 1861 st->sync_state = PFSYNC_S_NONE; 1862 pf_release_state(st); 1863 count++; 1864 } 1865 TAILQ_INIT(&b->b_qs[q]); 1866 1867 bzero(subh, sizeof(*subh)); 1868 subh->action = pfsync_qs[q].action; 1869 subh->count = htons(count); 1870 V_pfsyncstats.pfsyncs_oacts[pfsync_qs[q].action] += count; 1871 } 1872 1873 if (!TAILQ_EMPTY(&b->b_upd_req_list)) { 1874 subh = (struct pfsync_subheader *)(m->m_data + offset); 1875 offset += sizeof(*subh); 1876 1877 count = 0; 1878 while ((ur = TAILQ_FIRST(&b->b_upd_req_list)) != NULL) { 1879 TAILQ_REMOVE(&b->b_upd_req_list, ur, ur_entry); 1880 1881 bcopy(&ur->ur_msg, m->m_data + offset, 1882 sizeof(ur->ur_msg)); 1883 offset += sizeof(ur->ur_msg); 1884 free(ur, M_PFSYNC); 1885 count++; 1886 } 1887 1888 bzero(subh, sizeof(*subh)); 1889 subh->action = PFSYNC_ACT_UPD_REQ; 1890 subh->count = htons(count); 1891 V_pfsyncstats.pfsyncs_oacts[PFSYNC_ACT_UPD_REQ] += count; 1892 } 1893 1894 /* has someone built a custom region for us to add? */ 1895 if (b->b_plus != NULL) { 1896 bcopy(b->b_plus, m->m_data + offset, b->b_pluslen); 1897 offset += b->b_pluslen; 1898 1899 b->b_plus = NULL; 1900 } 1901 1902 subh = (struct pfsync_subheader *)(m->m_data + offset); 1903 offset += sizeof(*subh); 1904 1905 bzero(subh, sizeof(*subh)); 1906 subh->action = PFSYNC_ACT_EOF; 1907 subh->count = htons(1); 1908 V_pfsyncstats.pfsyncs_oacts[PFSYNC_ACT_EOF]++; 1909 1910 /* we're done, let's put it on the wire */ 1911 if (ifp->if_bpf) { 1912 m->m_data += aflen; 1913 m->m_len = m->m_pkthdr.len = b->b_len - aflen; 1914 BPF_MTAP(ifp, m); 1915 m->m_data -= aflen; 1916 m->m_len = m->m_pkthdr.len = b->b_len; 1917 } 1918 1919 if (sc->sc_sync_if == NULL) { 1920 b->b_len = PFSYNC_MINPKT; 1921 m_freem(m); 1922 return; 1923 } 1924 1925 if_inc_counter(sc->sc_ifp, IFCOUNTER_OPACKETS, 1); 1926 if_inc_counter(sc->sc_ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len); 1927 b->b_len = PFSYNC_MINPKT; 1928 1929 if (!_IF_QFULL(&b->b_snd)) 1930 _IF_ENQUEUE(&b->b_snd, m); 1931 else { 1932 m_freem(m); 1933 if_inc_counter(sc->sc_ifp, IFCOUNTER_OQDROPS, 1); 1934 } 1935 if (schedswi) 1936 swi_sched(V_pfsync_swi_cookie, 0); 1937 } 1938 1939 static void 1940 pfsync_insert_state(struct pf_kstate *st) 1941 { 1942 struct pfsync_softc *sc = V_pfsyncif; 1943 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 1944 1945 if (st->state_flags & PFSTATE_NOSYNC) 1946 return; 1947 1948 if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) || 1949 st->key[PF_SK_WIRE]->proto == IPPROTO_PFSYNC) { 1950 st->state_flags |= PFSTATE_NOSYNC; 1951 return; 1952 } 1953 1954 KASSERT(st->sync_state == PFSYNC_S_NONE, 1955 ("%s: st->sync_state %u", __func__, st->sync_state)); 1956 1957 PFSYNC_BUCKET_LOCK(b); 1958 if (b->b_len == PFSYNC_MINPKT) 1959 callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b); 1960 1961 pfsync_q_ins(st, PFSYNC_S_INS, true); 1962 PFSYNC_BUCKET_UNLOCK(b); 1963 1964 st->sync_updates = 0; 1965 } 1966 1967 static int 1968 pfsync_defer(struct pf_kstate *st, struct mbuf *m) 1969 { 1970 struct pfsync_softc *sc = V_pfsyncif; 1971 struct pfsync_deferral *pd; 1972 struct pfsync_bucket *b; 1973 1974 if (m->m_flags & (M_BCAST|M_MCAST)) 1975 return (0); 1976 1977 if (sc == NULL) 1978 return (0); 1979 1980 b = pfsync_get_bucket(sc, st); 1981 1982 PFSYNC_LOCK(sc); 1983 1984 if (!(sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) || 1985 !(sc->sc_flags & PFSYNCF_DEFER)) { 1986 PFSYNC_UNLOCK(sc); 1987 return (0); 1988 } 1989 1990 PFSYNC_BUCKET_LOCK(b); 1991 PFSYNC_UNLOCK(sc); 1992 1993 if (b->b_deferred >= 128) 1994 pfsync_undefer(TAILQ_FIRST(&b->b_deferrals), 0); 1995 1996 pd = malloc(sizeof(*pd), M_PFSYNC, M_NOWAIT); 1997 if (pd == NULL) { 1998 PFSYNC_BUCKET_UNLOCK(b); 1999 return (0); 2000 } 2001 b->b_deferred++; 2002 2003 m->m_flags |= M_SKIP_FIREWALL; 2004 st->state_flags |= PFSTATE_ACK; 2005 2006 pd->pd_sc = sc; 2007 pd->pd_st = st; 2008 pf_ref_state(st); 2009 pd->pd_m = m; 2010 2011 TAILQ_INSERT_TAIL(&b->b_deferrals, pd, pd_entry); 2012 callout_init_mtx(&pd->pd_tmo, &b->b_mtx, CALLOUT_RETURNUNLOCKED); 2013 callout_reset(&pd->pd_tmo, (V_pfsync_defer_timeout * hz) / 1000, 2014 pfsync_defer_tmo, pd); 2015 2016 pfsync_push(b); 2017 PFSYNC_BUCKET_UNLOCK(b); 2018 2019 return (1); 2020 } 2021 2022 static void 2023 pfsync_undefer(struct pfsync_deferral *pd, int drop) 2024 { 2025 struct pfsync_softc *sc = pd->pd_sc; 2026 struct mbuf *m = pd->pd_m; 2027 struct pf_kstate *st = pd->pd_st; 2028 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 2029 2030 PFSYNC_BUCKET_LOCK_ASSERT(b); 2031 2032 TAILQ_REMOVE(&b->b_deferrals, pd, pd_entry); 2033 b->b_deferred--; 2034 pd->pd_st->state_flags &= ~PFSTATE_ACK; /* XXX: locking! */ 2035 free(pd, M_PFSYNC); 2036 pf_release_state(st); 2037 2038 if (drop) 2039 m_freem(m); 2040 else { 2041 _IF_ENQUEUE(&b->b_snd, m); 2042 pfsync_push(b); 2043 } 2044 } 2045 2046 static void 2047 pfsync_defer_tmo(void *arg) 2048 { 2049 struct epoch_tracker et; 2050 struct pfsync_deferral *pd = arg; 2051 struct pfsync_softc *sc = pd->pd_sc; 2052 struct mbuf *m = pd->pd_m; 2053 struct pf_kstate *st = pd->pd_st; 2054 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 2055 2056 PFSYNC_BUCKET_LOCK_ASSERT(b); 2057 2058 TAILQ_REMOVE(&b->b_deferrals, pd, pd_entry); 2059 b->b_deferred--; 2060 pd->pd_st->state_flags &= ~PFSTATE_ACK; /* XXX: locking! */ 2061 PFSYNC_BUCKET_UNLOCK(b); 2062 free(pd, M_PFSYNC); 2063 2064 if (sc->sc_sync_if == NULL) { 2065 pf_release_state(st); 2066 m_freem(m); 2067 return; 2068 } 2069 2070 NET_EPOCH_ENTER(et); 2071 CURVNET_SET(sc->sc_sync_if->if_vnet); 2072 2073 pfsync_tx(sc, m); 2074 2075 pf_release_state(st); 2076 2077 CURVNET_RESTORE(); 2078 NET_EPOCH_EXIT(et); 2079 } 2080 2081 static void 2082 pfsync_undefer_state_locked(struct pf_kstate *st, int drop) 2083 { 2084 struct pfsync_softc *sc = V_pfsyncif; 2085 struct pfsync_deferral *pd; 2086 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 2087 2088 PFSYNC_BUCKET_LOCK_ASSERT(b); 2089 2090 TAILQ_FOREACH(pd, &b->b_deferrals, pd_entry) { 2091 if (pd->pd_st == st) { 2092 if (callout_stop(&pd->pd_tmo) > 0) 2093 pfsync_undefer(pd, drop); 2094 2095 return; 2096 } 2097 } 2098 2099 panic("%s: unable to find deferred state", __func__); 2100 } 2101 2102 static void 2103 pfsync_undefer_state(struct pf_kstate *st, int drop) 2104 { 2105 struct pfsync_softc *sc = V_pfsyncif; 2106 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 2107 2108 PFSYNC_BUCKET_LOCK(b); 2109 pfsync_undefer_state_locked(st, drop); 2110 PFSYNC_BUCKET_UNLOCK(b); 2111 } 2112 2113 static struct pfsync_bucket* 2114 pfsync_get_bucket(struct pfsync_softc *sc, struct pf_kstate *st) 2115 { 2116 int c = PF_IDHASH(st) % pfsync_buckets; 2117 return &sc->sc_buckets[c]; 2118 } 2119 2120 static void 2121 pfsync_update_state(struct pf_kstate *st) 2122 { 2123 struct pfsync_softc *sc = V_pfsyncif; 2124 bool sync = false, ref = true; 2125 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 2126 2127 PF_STATE_LOCK_ASSERT(st); 2128 PFSYNC_BUCKET_LOCK(b); 2129 2130 if (st->state_flags & PFSTATE_ACK) 2131 pfsync_undefer_state_locked(st, 0); 2132 if (st->state_flags & PFSTATE_NOSYNC) { 2133 if (st->sync_state != PFSYNC_S_NONE) 2134 pfsync_q_del(st, true, b); 2135 PFSYNC_BUCKET_UNLOCK(b); 2136 return; 2137 } 2138 2139 if (b->b_len == PFSYNC_MINPKT) 2140 callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b); 2141 2142 switch (st->sync_state) { 2143 case PFSYNC_S_UPD_C: 2144 case PFSYNC_S_UPD: 2145 case PFSYNC_S_INS: 2146 /* we're already handling it */ 2147 2148 if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP) { 2149 st->sync_updates++; 2150 if (st->sync_updates >= sc->sc_maxupdates) 2151 sync = true; 2152 } 2153 break; 2154 2155 case PFSYNC_S_IACK: 2156 pfsync_q_del(st, false, b); 2157 ref = false; 2158 /* FALLTHROUGH */ 2159 2160 case PFSYNC_S_NONE: 2161 pfsync_q_ins(st, PFSYNC_S_UPD_C, ref); 2162 st->sync_updates = 0; 2163 break; 2164 2165 default: 2166 panic("%s: unexpected sync state %d", __func__, st->sync_state); 2167 } 2168 2169 if (sync || (time_uptime - st->pfsync_time) < 2) 2170 pfsync_push(b); 2171 2172 PFSYNC_BUCKET_UNLOCK(b); 2173 } 2174 2175 static void 2176 pfsync_request_update(u_int32_t creatorid, u_int64_t id) 2177 { 2178 struct pfsync_softc *sc = V_pfsyncif; 2179 struct pfsync_bucket *b = &sc->sc_buckets[0]; 2180 struct pfsync_upd_req_item *item; 2181 size_t nlen = sizeof(struct pfsync_upd_req); 2182 2183 PFSYNC_BUCKET_LOCK_ASSERT(b); 2184 2185 /* 2186 * This code does a bit to prevent multiple update requests for the 2187 * same state being generated. It searches current subheader queue, 2188 * but it doesn't lookup into queue of already packed datagrams. 2189 */ 2190 TAILQ_FOREACH(item, &b->b_upd_req_list, ur_entry) 2191 if (item->ur_msg.id == id && 2192 item->ur_msg.creatorid == creatorid) 2193 return; 2194 2195 item = malloc(sizeof(*item), M_PFSYNC, M_NOWAIT); 2196 if (item == NULL) 2197 return; /* XXX stats */ 2198 2199 item->ur_msg.id = id; 2200 item->ur_msg.creatorid = creatorid; 2201 2202 if (TAILQ_EMPTY(&b->b_upd_req_list)) 2203 nlen += sizeof(struct pfsync_subheader); 2204 2205 if (b->b_len + nlen > sc->sc_ifp->if_mtu) { 2206 pfsync_sendout(0, 0); 2207 2208 nlen = sizeof(struct pfsync_subheader) + 2209 sizeof(struct pfsync_upd_req); 2210 } 2211 2212 TAILQ_INSERT_TAIL(&b->b_upd_req_list, item, ur_entry); 2213 b->b_len += nlen; 2214 2215 pfsync_push(b); 2216 } 2217 2218 static bool 2219 pfsync_update_state_req(struct pf_kstate *st) 2220 { 2221 struct pfsync_softc *sc = V_pfsyncif; 2222 bool ref = true, full = false; 2223 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 2224 2225 PF_STATE_LOCK_ASSERT(st); 2226 PFSYNC_BUCKET_LOCK(b); 2227 2228 if (st->state_flags & PFSTATE_NOSYNC) { 2229 if (st->sync_state != PFSYNC_S_NONE) 2230 pfsync_q_del(st, true, b); 2231 PFSYNC_BUCKET_UNLOCK(b); 2232 return (full); 2233 } 2234 2235 switch (st->sync_state) { 2236 case PFSYNC_S_UPD_C: 2237 case PFSYNC_S_IACK: 2238 pfsync_q_del(st, false, b); 2239 ref = false; 2240 /* FALLTHROUGH */ 2241 2242 case PFSYNC_S_NONE: 2243 pfsync_q_ins(st, PFSYNC_S_UPD, ref); 2244 pfsync_push(b); 2245 break; 2246 2247 case PFSYNC_S_INS: 2248 case PFSYNC_S_UPD: 2249 case PFSYNC_S_DEL_C: 2250 /* we're already handling it */ 2251 break; 2252 2253 default: 2254 panic("%s: unexpected sync state %d", __func__, st->sync_state); 2255 } 2256 2257 if ((sc->sc_ifp->if_mtu - b->b_len) < sizeof(union pfsync_state_union)) 2258 full = true; 2259 2260 PFSYNC_BUCKET_UNLOCK(b); 2261 2262 return (full); 2263 } 2264 2265 static void 2266 pfsync_delete_state(struct pf_kstate *st) 2267 { 2268 struct pfsync_softc *sc = V_pfsyncif; 2269 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 2270 bool ref = true; 2271 2272 PFSYNC_BUCKET_LOCK(b); 2273 if (st->state_flags & PFSTATE_ACK) 2274 pfsync_undefer_state_locked(st, 1); 2275 if (st->state_flags & PFSTATE_NOSYNC) { 2276 if (st->sync_state != PFSYNC_S_NONE) 2277 pfsync_q_del(st, true, b); 2278 PFSYNC_BUCKET_UNLOCK(b); 2279 return; 2280 } 2281 2282 if (b->b_len == PFSYNC_MINPKT) 2283 callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b); 2284 2285 switch (st->sync_state) { 2286 case PFSYNC_S_INS: 2287 /* We never got to tell the world so just forget about it. */ 2288 pfsync_q_del(st, true, b); 2289 break; 2290 2291 case PFSYNC_S_UPD_C: 2292 case PFSYNC_S_UPD: 2293 case PFSYNC_S_IACK: 2294 pfsync_q_del(st, false, b); 2295 ref = false; 2296 /* FALLTHROUGH */ 2297 2298 case PFSYNC_S_NONE: 2299 pfsync_q_ins(st, PFSYNC_S_DEL_C, ref); 2300 break; 2301 2302 default: 2303 panic("%s: unexpected sync state %d", __func__, st->sync_state); 2304 } 2305 2306 PFSYNC_BUCKET_UNLOCK(b); 2307 } 2308 2309 static void 2310 pfsync_clear_states(u_int32_t creatorid, const char *ifname) 2311 { 2312 struct { 2313 struct pfsync_subheader subh; 2314 struct pfsync_clr clr; 2315 } __packed r; 2316 2317 bzero(&r, sizeof(r)); 2318 2319 r.subh.action = PFSYNC_ACT_CLR; 2320 r.subh.count = htons(1); 2321 V_pfsyncstats.pfsyncs_oacts[PFSYNC_ACT_CLR]++; 2322 2323 strlcpy(r.clr.ifname, ifname, sizeof(r.clr.ifname)); 2324 r.clr.creatorid = creatorid; 2325 2326 pfsync_send_plus(&r, sizeof(r)); 2327 } 2328 2329 static enum pfsync_q_id 2330 pfsync_sstate_to_qid(u_int8_t sync_state) 2331 { 2332 struct pfsync_softc *sc = V_pfsyncif; 2333 2334 switch (sync_state) { 2335 case PFSYNC_S_INS: 2336 switch (sc->sc_version) { 2337 case PFSYNC_MSG_VERSION_1301: 2338 return PFSYNC_Q_INS_1301; 2339 case PFSYNC_MSG_VERSION_1400: 2340 return PFSYNC_Q_INS_1400; 2341 } 2342 break; 2343 case PFSYNC_S_IACK: 2344 return PFSYNC_Q_IACK; 2345 case PFSYNC_S_UPD: 2346 switch (sc->sc_version) { 2347 case PFSYNC_MSG_VERSION_1301: 2348 return PFSYNC_Q_UPD_1301; 2349 case PFSYNC_MSG_VERSION_1400: 2350 return PFSYNC_Q_UPD_1400; 2351 } 2352 break; 2353 case PFSYNC_S_UPD_C: 2354 return PFSYNC_Q_UPD_C; 2355 case PFSYNC_S_DEL_C: 2356 return PFSYNC_Q_DEL_C; 2357 default: 2358 panic("%s: Unsupported st->sync_state 0x%02x", 2359 __func__, sync_state); 2360 } 2361 2362 panic("%s: Unsupported pfsync_msg_version %d", 2363 __func__, sc->sc_version); 2364 } 2365 2366 static void 2367 pfsync_q_ins(struct pf_kstate *st, int sync_state, bool ref) 2368 { 2369 enum pfsync_q_id q = pfsync_sstate_to_qid(sync_state); 2370 struct pfsync_softc *sc = V_pfsyncif; 2371 size_t nlen = pfsync_qs[q].len; 2372 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 2373 2374 PFSYNC_BUCKET_LOCK_ASSERT(b); 2375 2376 KASSERT(st->sync_state == PFSYNC_S_NONE, 2377 ("%s: st->sync_state %u", __func__, st->sync_state)); 2378 KASSERT(b->b_len >= PFSYNC_MINPKT, ("pfsync pkt len is too low %zu", 2379 b->b_len)); 2380 2381 if (TAILQ_EMPTY(&b->b_qs[q])) 2382 nlen += sizeof(struct pfsync_subheader); 2383 2384 if (b->b_len + nlen > sc->sc_ifp->if_mtu) { 2385 pfsync_sendout(1, b->b_id); 2386 2387 nlen = sizeof(struct pfsync_subheader) + pfsync_qs[q].len; 2388 } 2389 2390 b->b_len += nlen; 2391 TAILQ_INSERT_TAIL(&b->b_qs[q], st, sync_list); 2392 st->sync_state = pfsync_qid_sstate[q]; 2393 if (ref) 2394 pf_ref_state(st); 2395 } 2396 2397 static void 2398 pfsync_q_del(struct pf_kstate *st, bool unref, struct pfsync_bucket *b) 2399 { 2400 enum pfsync_q_id q; 2401 2402 PFSYNC_BUCKET_LOCK_ASSERT(b); 2403 KASSERT(st->sync_state != PFSYNC_S_NONE, 2404 ("%s: st->sync_state != PFSYNC_S_NONE", __func__)); 2405 2406 q = pfsync_sstate_to_qid(st->sync_state); 2407 b->b_len -= pfsync_qs[q].len; 2408 TAILQ_REMOVE(&b->b_qs[q], st, sync_list); 2409 st->sync_state = PFSYNC_S_NONE; 2410 if (unref) 2411 pf_release_state(st); 2412 2413 if (TAILQ_EMPTY(&b->b_qs[q])) 2414 b->b_len -= sizeof(struct pfsync_subheader); 2415 } 2416 2417 static void 2418 pfsync_bulk_start(void) 2419 { 2420 struct pfsync_softc *sc = V_pfsyncif; 2421 2422 if (V_pf_status.debug >= PF_DEBUG_MISC) 2423 printf("pfsync: received bulk update request\n"); 2424 2425 PFSYNC_BLOCK(sc); 2426 2427 sc->sc_ureq_received = time_uptime; 2428 sc->sc_bulk_hashid = 0; 2429 sc->sc_bulk_stateid = 0; 2430 pfsync_bulk_status(PFSYNC_BUS_START); 2431 callout_reset(&sc->sc_bulk_tmo, 1, pfsync_bulk_update, sc); 2432 PFSYNC_BUNLOCK(sc); 2433 } 2434 2435 static void 2436 pfsync_bulk_update(void *arg) 2437 { 2438 struct pfsync_softc *sc = arg; 2439 struct pf_kstate *s; 2440 int i; 2441 2442 PFSYNC_BLOCK_ASSERT(sc); 2443 CURVNET_SET(sc->sc_ifp->if_vnet); 2444 2445 /* 2446 * Start with last state from previous invocation. 2447 * It may had gone, in this case start from the 2448 * hash slot. 2449 */ 2450 s = pf_find_state_byid(sc->sc_bulk_stateid, sc->sc_bulk_creatorid); 2451 2452 if (s != NULL) 2453 i = PF_IDHASH(s); 2454 else 2455 i = sc->sc_bulk_hashid; 2456 2457 for (; i <= pf_hashmask; i++) { 2458 struct pf_idhash *ih = &V_pf_idhash[i]; 2459 2460 if (s != NULL) 2461 PF_HASHROW_ASSERT(ih); 2462 else { 2463 PF_HASHROW_LOCK(ih); 2464 s = LIST_FIRST(&ih->states); 2465 } 2466 2467 for (; s; s = LIST_NEXT(s, entry)) { 2468 if (s->sync_state == PFSYNC_S_NONE && 2469 s->timeout < PFTM_MAX && 2470 s->pfsync_time <= sc->sc_ureq_received) { 2471 if (pfsync_update_state_req(s)) { 2472 /* We've filled a packet. */ 2473 sc->sc_bulk_hashid = i; 2474 sc->sc_bulk_stateid = s->id; 2475 sc->sc_bulk_creatorid = s->creatorid; 2476 PF_HASHROW_UNLOCK(ih); 2477 callout_reset(&sc->sc_bulk_tmo, 1, 2478 pfsync_bulk_update, sc); 2479 goto full; 2480 } 2481 } 2482 } 2483 PF_HASHROW_UNLOCK(ih); 2484 } 2485 2486 /* We're done. */ 2487 pfsync_bulk_status(PFSYNC_BUS_END); 2488 full: 2489 CURVNET_RESTORE(); 2490 } 2491 2492 static void 2493 pfsync_bulk_status(u_int8_t status) 2494 { 2495 struct { 2496 struct pfsync_subheader subh; 2497 struct pfsync_bus bus; 2498 } __packed r; 2499 2500 struct pfsync_softc *sc = V_pfsyncif; 2501 2502 bzero(&r, sizeof(r)); 2503 2504 r.subh.action = PFSYNC_ACT_BUS; 2505 r.subh.count = htons(1); 2506 V_pfsyncstats.pfsyncs_oacts[PFSYNC_ACT_BUS]++; 2507 2508 r.bus.creatorid = V_pf_status.hostid; 2509 r.bus.endtime = htonl(time_uptime - sc->sc_ureq_received); 2510 r.bus.status = status; 2511 2512 pfsync_send_plus(&r, sizeof(r)); 2513 } 2514 2515 static void 2516 pfsync_bulk_fail(void *arg) 2517 { 2518 struct pfsync_softc *sc = arg; 2519 struct pfsync_bucket *b = &sc->sc_buckets[0]; 2520 2521 CURVNET_SET(sc->sc_ifp->if_vnet); 2522 2523 PFSYNC_BLOCK_ASSERT(sc); 2524 2525 if (sc->sc_bulk_tries++ < PFSYNC_MAX_BULKTRIES) { 2526 /* Try again */ 2527 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, 2528 pfsync_bulk_fail, V_pfsyncif); 2529 PFSYNC_BUCKET_LOCK(b); 2530 pfsync_request_update(0, 0); 2531 PFSYNC_BUCKET_UNLOCK(b); 2532 } else { 2533 /* Pretend like the transfer was ok. */ 2534 sc->sc_ureq_sent = 0; 2535 sc->sc_bulk_tries = 0; 2536 PFSYNC_LOCK(sc); 2537 if (!(sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) 2538 (*carp_demote_adj_p)(-V_pfsync_carp_adj, 2539 "pfsync bulk fail"); 2540 sc->sc_flags |= PFSYNCF_OK; 2541 PFSYNC_UNLOCK(sc); 2542 if (V_pf_status.debug >= PF_DEBUG_MISC) 2543 printf("pfsync: failed to receive bulk update\n"); 2544 } 2545 2546 CURVNET_RESTORE(); 2547 } 2548 2549 static void 2550 pfsync_send_plus(void *plus, size_t pluslen) 2551 { 2552 struct pfsync_softc *sc = V_pfsyncif; 2553 struct pfsync_bucket *b = &sc->sc_buckets[0]; 2554 2555 PFSYNC_BUCKET_LOCK(b); 2556 2557 if (b->b_len + pluslen > sc->sc_ifp->if_mtu) 2558 pfsync_sendout(1, b->b_id); 2559 2560 b->b_plus = plus; 2561 b->b_len += (b->b_pluslen = pluslen); 2562 2563 pfsync_sendout(1, b->b_id); 2564 PFSYNC_BUCKET_UNLOCK(b); 2565 } 2566 2567 static void 2568 pfsync_timeout(void *arg) 2569 { 2570 struct pfsync_bucket *b = arg; 2571 2572 CURVNET_SET(b->b_sc->sc_ifp->if_vnet); 2573 PFSYNC_BUCKET_LOCK(b); 2574 pfsync_push(b); 2575 PFSYNC_BUCKET_UNLOCK(b); 2576 CURVNET_RESTORE(); 2577 } 2578 2579 static void 2580 pfsync_push(struct pfsync_bucket *b) 2581 { 2582 2583 PFSYNC_BUCKET_LOCK_ASSERT(b); 2584 2585 b->b_flags |= PFSYNCF_BUCKET_PUSH; 2586 swi_sched(V_pfsync_swi_cookie, 0); 2587 } 2588 2589 static void 2590 pfsync_push_all(struct pfsync_softc *sc) 2591 { 2592 int c; 2593 struct pfsync_bucket *b; 2594 2595 for (c = 0; c < pfsync_buckets; c++) { 2596 b = &sc->sc_buckets[c]; 2597 2598 PFSYNC_BUCKET_LOCK(b); 2599 pfsync_push(b); 2600 PFSYNC_BUCKET_UNLOCK(b); 2601 } 2602 } 2603 2604 static void 2605 pfsync_tx(struct pfsync_softc *sc, struct mbuf *m) 2606 { 2607 struct ip *ip; 2608 int af, error = 0; 2609 2610 ip = mtod(m, struct ip *); 2611 MPASS(ip->ip_v == IPVERSION || ip->ip_v == (IPV6_VERSION >> 4)); 2612 2613 af = ip->ip_v == IPVERSION ? AF_INET : AF_INET6; 2614 2615 /* 2616 * We distinguish between a deferral packet and our 2617 * own pfsync packet based on M_SKIP_FIREWALL 2618 * flag. This is XXX. 2619 */ 2620 switch (af) { 2621 #ifdef INET 2622 case AF_INET: 2623 if (m->m_flags & M_SKIP_FIREWALL) { 2624 error = ip_output(m, NULL, NULL, 0, 2625 NULL, NULL); 2626 } else { 2627 error = ip_output(m, NULL, NULL, 2628 IP_RAWOUTPUT, &sc->sc_imo, NULL); 2629 } 2630 break; 2631 #endif 2632 #ifdef INET6 2633 case AF_INET6: 2634 if (m->m_flags & M_SKIP_FIREWALL) { 2635 error = ip6_output(m, NULL, NULL, 0, 2636 NULL, NULL, NULL); 2637 } else { 2638 error = ip6_output(m, NULL, NULL, 0, 2639 &sc->sc_im6o, NULL, NULL); 2640 } 2641 break; 2642 #endif 2643 } 2644 2645 if (error == 0) 2646 V_pfsyncstats.pfsyncs_opackets++; 2647 else 2648 V_pfsyncstats.pfsyncs_oerrors++; 2649 2650 } 2651 2652 static void 2653 pfsyncintr(void *arg) 2654 { 2655 struct epoch_tracker et; 2656 struct pfsync_softc *sc = arg; 2657 struct pfsync_bucket *b; 2658 struct mbuf *m, *n; 2659 int c; 2660 2661 NET_EPOCH_ENTER(et); 2662 CURVNET_SET(sc->sc_ifp->if_vnet); 2663 2664 for (c = 0; c < pfsync_buckets; c++) { 2665 b = &sc->sc_buckets[c]; 2666 2667 PFSYNC_BUCKET_LOCK(b); 2668 if ((b->b_flags & PFSYNCF_BUCKET_PUSH) && b->b_len > PFSYNC_MINPKT) { 2669 pfsync_sendout(0, b->b_id); 2670 b->b_flags &= ~PFSYNCF_BUCKET_PUSH; 2671 } 2672 _IF_DEQUEUE_ALL(&b->b_snd, m); 2673 PFSYNC_BUCKET_UNLOCK(b); 2674 2675 for (; m != NULL; m = n) { 2676 n = m->m_nextpkt; 2677 m->m_nextpkt = NULL; 2678 2679 pfsync_tx(sc, m); 2680 } 2681 } 2682 CURVNET_RESTORE(); 2683 NET_EPOCH_EXIT(et); 2684 } 2685 2686 static int 2687 pfsync_multicast_setup(struct pfsync_softc *sc, struct ifnet *ifp, 2688 struct in_mfilter* imf, struct in6_mfilter* im6f) 2689 { 2690 #ifdef INET 2691 struct ip_moptions *imo = &sc->sc_imo; 2692 #endif 2693 #ifdef INET6 2694 struct ip6_moptions *im6o = &sc->sc_im6o; 2695 struct sockaddr_in6 *syncpeer_sa6 = NULL; 2696 #endif 2697 2698 if (!(ifp->if_flags & IFF_MULTICAST)) 2699 return (EADDRNOTAVAIL); 2700 2701 switch (sc->sc_sync_peer.ss_family) { 2702 #ifdef INET 2703 case AF_INET: 2704 { 2705 int error; 2706 2707 ip_mfilter_init(&imo->imo_head); 2708 imo->imo_multicast_vif = -1; 2709 if ((error = in_joingroup(ifp, 2710 &((struct sockaddr_in *)&sc->sc_sync_peer)->sin_addr, NULL, 2711 &imf->imf_inm)) != 0) 2712 return (error); 2713 2714 ip_mfilter_insert(&imo->imo_head, imf); 2715 imo->imo_multicast_ifp = ifp; 2716 imo->imo_multicast_ttl = PFSYNC_DFLTTL; 2717 imo->imo_multicast_loop = 0; 2718 break; 2719 } 2720 #endif 2721 #ifdef INET6 2722 case AF_INET6: 2723 { 2724 int error; 2725 2726 syncpeer_sa6 = (struct sockaddr_in6 *)&sc->sc_sync_peer; 2727 if ((error = in6_setscope(&syncpeer_sa6->sin6_addr, ifp, NULL))) 2728 return (error); 2729 2730 ip6_mfilter_init(&im6o->im6o_head); 2731 if ((error = in6_joingroup(ifp, &syncpeer_sa6->sin6_addr, NULL, 2732 &(im6f->im6f_in6m), 0)) != 0) 2733 return (error); 2734 2735 ip6_mfilter_insert(&im6o->im6o_head, im6f); 2736 im6o->im6o_multicast_ifp = ifp; 2737 im6o->im6o_multicast_hlim = PFSYNC_DFLTTL; 2738 im6o->im6o_multicast_loop = 0; 2739 break; 2740 } 2741 #endif 2742 } 2743 2744 return (0); 2745 } 2746 2747 static void 2748 pfsync_multicast_cleanup(struct pfsync_softc *sc) 2749 { 2750 #ifdef INET 2751 struct ip_moptions *imo = &sc->sc_imo; 2752 struct in_mfilter *imf; 2753 2754 while ((imf = ip_mfilter_first(&imo->imo_head)) != NULL) { 2755 ip_mfilter_remove(&imo->imo_head, imf); 2756 in_leavegroup(imf->imf_inm, NULL); 2757 ip_mfilter_free(imf); 2758 } 2759 imo->imo_multicast_ifp = NULL; 2760 #endif 2761 2762 #ifdef INET6 2763 struct ip6_moptions *im6o = &sc->sc_im6o; 2764 struct in6_mfilter *im6f; 2765 2766 while ((im6f = ip6_mfilter_first(&im6o->im6o_head)) != NULL) { 2767 ip6_mfilter_remove(&im6o->im6o_head, im6f); 2768 in6_leavegroup(im6f->im6f_in6m, NULL); 2769 ip6_mfilter_free(im6f); 2770 } 2771 im6o->im6o_multicast_ifp = NULL; 2772 #endif 2773 } 2774 2775 void 2776 pfsync_detach_ifnet(struct ifnet *ifp) 2777 { 2778 struct pfsync_softc *sc = V_pfsyncif; 2779 2780 if (sc == NULL) 2781 return; 2782 2783 PFSYNC_LOCK(sc); 2784 2785 if (sc->sc_sync_if == ifp) { 2786 /* We don't need mutlicast cleanup here, because the interface 2787 * is going away. We do need to ensure we don't try to do 2788 * cleanup later. 2789 */ 2790 ip_mfilter_init(&sc->sc_imo.imo_head); 2791 sc->sc_imo.imo_multicast_ifp = NULL; 2792 sc->sc_im6o.im6o_multicast_ifp = NULL; 2793 sc->sc_sync_if = NULL; 2794 } 2795 2796 PFSYNC_UNLOCK(sc); 2797 } 2798 2799 static int 2800 pfsync_pfsyncreq_to_kstatus(struct pfsyncreq *pfsyncr, struct pfsync_kstatus *status) 2801 { 2802 struct sockaddr_storage sa; 2803 status->maxupdates = pfsyncr->pfsyncr_maxupdates; 2804 status->flags = pfsyncr->pfsyncr_defer; 2805 2806 strlcpy(status->syncdev, pfsyncr->pfsyncr_syncdev, IFNAMSIZ); 2807 2808 memset(&sa, 0, sizeof(sa)); 2809 if (pfsyncr->pfsyncr_syncpeer.s_addr != 0) { 2810 struct sockaddr_in *in = (struct sockaddr_in *)&sa; 2811 in->sin_family = AF_INET; 2812 in->sin_len = sizeof(*in); 2813 in->sin_addr.s_addr = pfsyncr->pfsyncr_syncpeer.s_addr; 2814 } 2815 status->syncpeer = sa; 2816 2817 return 0; 2818 } 2819 2820 static int 2821 pfsync_kstatus_to_softc(struct pfsync_kstatus *status, struct pfsync_softc *sc) 2822 { 2823 struct ifnet *sifp; 2824 struct in_mfilter *imf = NULL; 2825 struct in6_mfilter *im6f = NULL; 2826 int error; 2827 int c; 2828 2829 if ((status->maxupdates < 0) || (status->maxupdates > 255)) 2830 return (EINVAL); 2831 2832 if (status->syncdev[0] == '\0') 2833 sifp = NULL; 2834 else if ((sifp = ifunit_ref(status->syncdev)) == NULL) 2835 return (EINVAL); 2836 2837 switch (status->syncpeer.ss_family) { 2838 #ifdef INET 2839 case AF_UNSPEC: 2840 case AF_INET: { 2841 struct sockaddr_in *status_sin; 2842 status_sin = (struct sockaddr_in *)&(status->syncpeer); 2843 if (sifp != NULL) { 2844 if (status_sin->sin_addr.s_addr == 0 || 2845 status_sin->sin_addr.s_addr == 2846 htonl(INADDR_PFSYNC_GROUP)) { 2847 status_sin->sin_family = AF_INET; 2848 status_sin->sin_len = sizeof(*status_sin); 2849 status_sin->sin_addr.s_addr = 2850 htonl(INADDR_PFSYNC_GROUP); 2851 } 2852 2853 if (IN_MULTICAST(ntohl(status_sin->sin_addr.s_addr))) { 2854 imf = ip_mfilter_alloc(M_WAITOK, 0, 0); 2855 } 2856 } 2857 break; 2858 } 2859 #endif 2860 #ifdef INET6 2861 case AF_INET6: { 2862 struct sockaddr_in6 *status_sin6; 2863 status_sin6 = (struct sockaddr_in6*)&(status->syncpeer); 2864 if (sifp != NULL) { 2865 if (IN6_IS_ADDR_UNSPECIFIED(&status_sin6->sin6_addr) || 2866 IN6_ARE_ADDR_EQUAL(&status_sin6->sin6_addr, 2867 &in6addr_linklocal_pfsync_group)) { 2868 status_sin6->sin6_family = AF_INET6; 2869 status_sin6->sin6_len = sizeof(*status_sin6); 2870 status_sin6->sin6_addr = 2871 in6addr_linklocal_pfsync_group; 2872 } 2873 2874 if (IN6_IS_ADDR_MULTICAST(&status_sin6->sin6_addr)) { 2875 im6f = ip6_mfilter_alloc(M_WAITOK, 0, 0); 2876 } 2877 } 2878 break; 2879 } 2880 #endif 2881 } 2882 2883 PFSYNC_LOCK(sc); 2884 2885 switch (status->version) { 2886 case PFSYNC_MSG_VERSION_UNSPECIFIED: 2887 sc->sc_version = PFSYNC_MSG_VERSION_DEFAULT; 2888 break; 2889 case PFSYNC_MSG_VERSION_1301: 2890 case PFSYNC_MSG_VERSION_1400: 2891 sc->sc_version = status->version; 2892 break; 2893 default: 2894 PFSYNC_UNLOCK(sc); 2895 return (EINVAL); 2896 } 2897 2898 switch (status->syncpeer.ss_family) { 2899 case AF_INET: { 2900 struct sockaddr_in *status_sin = (struct sockaddr_in *)&(status->syncpeer); 2901 struct sockaddr_in *sc_sin = (struct sockaddr_in *)&sc->sc_sync_peer; 2902 sc_sin->sin_family = AF_INET; 2903 sc_sin->sin_len = sizeof(*sc_sin); 2904 if (status_sin->sin_addr.s_addr == 0) { 2905 sc_sin->sin_addr.s_addr = htonl(INADDR_PFSYNC_GROUP); 2906 } else { 2907 sc_sin->sin_addr.s_addr = status_sin->sin_addr.s_addr; 2908 } 2909 break; 2910 } 2911 case AF_INET6: { 2912 struct sockaddr_in6 *status_sin = (struct sockaddr_in6 *)&(status->syncpeer); 2913 struct sockaddr_in6 *sc_sin = (struct sockaddr_in6 *)&sc->sc_sync_peer; 2914 sc_sin->sin6_family = AF_INET6; 2915 sc_sin->sin6_len = sizeof(*sc_sin); 2916 if(IN6_IS_ADDR_UNSPECIFIED(&status_sin->sin6_addr)) { 2917 sc_sin->sin6_addr = in6addr_linklocal_pfsync_group; 2918 } else { 2919 sc_sin->sin6_addr = status_sin->sin6_addr; 2920 } 2921 break; 2922 } 2923 } 2924 2925 sc->sc_maxupdates = status->maxupdates; 2926 if (status->flags & PFSYNCF_DEFER) { 2927 sc->sc_flags |= PFSYNCF_DEFER; 2928 V_pfsync_defer_ptr = pfsync_defer; 2929 } else { 2930 sc->sc_flags &= ~PFSYNCF_DEFER; 2931 V_pfsync_defer_ptr = NULL; 2932 } 2933 2934 if (sifp == NULL) { 2935 if (sc->sc_sync_if) 2936 if_rele(sc->sc_sync_if); 2937 sc->sc_sync_if = NULL; 2938 pfsync_multicast_cleanup(sc); 2939 PFSYNC_UNLOCK(sc); 2940 return (0); 2941 } 2942 2943 for (c = 0; c < pfsync_buckets; c++) { 2944 PFSYNC_BUCKET_LOCK(&sc->sc_buckets[c]); 2945 if (sc->sc_buckets[c].b_len > PFSYNC_MINPKT && 2946 (sifp->if_mtu < sc->sc_ifp->if_mtu || 2947 (sc->sc_sync_if != NULL && 2948 sifp->if_mtu < sc->sc_sync_if->if_mtu) || 2949 sifp->if_mtu < MCLBYTES - sizeof(struct ip))) 2950 pfsync_sendout(1, c); 2951 PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[c]); 2952 } 2953 2954 pfsync_multicast_cleanup(sc); 2955 2956 if (((sc->sc_sync_peer.ss_family == AF_INET) && 2957 IN_MULTICAST(ntohl(((struct sockaddr_in *) 2958 &sc->sc_sync_peer)->sin_addr.s_addr))) || 2959 ((sc->sc_sync_peer.ss_family == AF_INET6) && 2960 IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*) 2961 &sc->sc_sync_peer)->sin6_addr))) { 2962 error = pfsync_multicast_setup(sc, sifp, imf, im6f); 2963 if (error) { 2964 if_rele(sifp); 2965 PFSYNC_UNLOCK(sc); 2966 #ifdef INET 2967 if (imf != NULL) 2968 ip_mfilter_free(imf); 2969 #endif 2970 #ifdef INET6 2971 if (im6f != NULL) 2972 ip6_mfilter_free(im6f); 2973 #endif 2974 return (error); 2975 } 2976 } 2977 if (sc->sc_sync_if) 2978 if_rele(sc->sc_sync_if); 2979 sc->sc_sync_if = sifp; 2980 2981 switch (sc->sc_sync_peer.ss_family) { 2982 #ifdef INET 2983 case AF_INET: { 2984 struct ip *ip; 2985 ip = &sc->sc_template.ipv4; 2986 bzero(ip, sizeof(*ip)); 2987 ip->ip_v = IPVERSION; 2988 ip->ip_hl = sizeof(sc->sc_template.ipv4) >> 2; 2989 ip->ip_tos = IPTOS_LOWDELAY; 2990 /* len and id are set later. */ 2991 ip->ip_off = htons(IP_DF); 2992 ip->ip_ttl = PFSYNC_DFLTTL; 2993 ip->ip_p = IPPROTO_PFSYNC; 2994 ip->ip_src.s_addr = INADDR_ANY; 2995 ip->ip_dst = ((struct sockaddr_in *)&sc->sc_sync_peer)->sin_addr; 2996 break; 2997 } 2998 #endif 2999 #ifdef INET6 3000 case AF_INET6: { 3001 struct ip6_hdr *ip6; 3002 ip6 = &sc->sc_template.ipv6; 3003 bzero(ip6, sizeof(*ip6)); 3004 ip6->ip6_vfc = IPV6_VERSION; 3005 ip6->ip6_hlim = PFSYNC_DFLTTL; 3006 ip6->ip6_nxt = IPPROTO_PFSYNC; 3007 ip6->ip6_dst = ((struct sockaddr_in6 *)&sc->sc_sync_peer)->sin6_addr; 3008 3009 struct epoch_tracker et; 3010 NET_EPOCH_ENTER(et); 3011 in6_selectsrc_addr(if_getfib(sc->sc_sync_if), &ip6->ip6_dst, 0, 3012 sc->sc_sync_if, &ip6->ip6_src, NULL); 3013 NET_EPOCH_EXIT(et); 3014 break; 3015 } 3016 #endif 3017 } 3018 3019 /* Request a full state table update. */ 3020 if ((sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) 3021 (*carp_demote_adj_p)(V_pfsync_carp_adj, 3022 "pfsync bulk start"); 3023 sc->sc_flags &= ~PFSYNCF_OK; 3024 if (V_pf_status.debug >= PF_DEBUG_MISC) 3025 printf("pfsync: requesting bulk update\n"); 3026 PFSYNC_UNLOCK(sc); 3027 PFSYNC_BUCKET_LOCK(&sc->sc_buckets[0]); 3028 pfsync_request_update(0, 0); 3029 PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[0]); 3030 PFSYNC_BLOCK(sc); 3031 sc->sc_ureq_sent = time_uptime; 3032 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, pfsync_bulk_fail, sc); 3033 PFSYNC_BUNLOCK(sc); 3034 return (0); 3035 } 3036 3037 static void 3038 pfsync_pointers_init(void) 3039 { 3040 3041 PF_RULES_WLOCK(); 3042 V_pfsync_state_import_ptr = pfsync_state_import; 3043 V_pfsync_insert_state_ptr = pfsync_insert_state; 3044 V_pfsync_update_state_ptr = pfsync_update_state; 3045 V_pfsync_delete_state_ptr = pfsync_delete_state; 3046 V_pfsync_clear_states_ptr = pfsync_clear_states; 3047 V_pfsync_defer_ptr = pfsync_defer; 3048 PF_RULES_WUNLOCK(); 3049 } 3050 3051 static void 3052 pfsync_pointers_uninit(void) 3053 { 3054 3055 PF_RULES_WLOCK(); 3056 V_pfsync_state_import_ptr = NULL; 3057 V_pfsync_insert_state_ptr = NULL; 3058 V_pfsync_update_state_ptr = NULL; 3059 V_pfsync_delete_state_ptr = NULL; 3060 V_pfsync_clear_states_ptr = NULL; 3061 V_pfsync_defer_ptr = NULL; 3062 PF_RULES_WUNLOCK(); 3063 } 3064 3065 static void 3066 vnet_pfsync_init(const void *unused __unused) 3067 { 3068 int error; 3069 3070 V_pfsync_cloner = if_clone_simple(pfsyncname, 3071 pfsync_clone_create, pfsync_clone_destroy, 1); 3072 error = swi_add(&V_pfsync_swi_ie, pfsyncname, pfsyncintr, V_pfsyncif, 3073 SWI_NET, INTR_MPSAFE, &V_pfsync_swi_cookie); 3074 if (error) { 3075 if_clone_detach(V_pfsync_cloner); 3076 log(LOG_INFO, "swi_add() failed in %s\n", __func__); 3077 } 3078 3079 pfsync_pointers_init(); 3080 } 3081 VNET_SYSINIT(vnet_pfsync_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY, 3082 vnet_pfsync_init, NULL); 3083 3084 static void 3085 vnet_pfsync_uninit(const void *unused __unused) 3086 { 3087 int ret __diagused; 3088 3089 pfsync_pointers_uninit(); 3090 3091 if_clone_detach(V_pfsync_cloner); 3092 ret = swi_remove(V_pfsync_swi_cookie); 3093 MPASS(ret == 0); 3094 ret = intr_event_destroy(V_pfsync_swi_ie); 3095 MPASS(ret == 0); 3096 } 3097 3098 VNET_SYSUNINIT(vnet_pfsync_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_FOURTH, 3099 vnet_pfsync_uninit, NULL); 3100 3101 static int 3102 pfsync_init(void) 3103 { 3104 int error; 3105 3106 pfsync_detach_ifnet_ptr = pfsync_detach_ifnet; 3107 3108 #ifdef INET 3109 error = ipproto_register(IPPROTO_PFSYNC, pfsync_input, NULL); 3110 if (error) 3111 return (error); 3112 #endif 3113 #ifdef INET6 3114 error = ip6proto_register(IPPROTO_PFSYNC, pfsync6_input, NULL); 3115 if (error) { 3116 ipproto_unregister(IPPROTO_PFSYNC); 3117 return (error); 3118 } 3119 #endif 3120 3121 return (0); 3122 } 3123 3124 static void 3125 pfsync_uninit(void) 3126 { 3127 pfsync_detach_ifnet_ptr = NULL; 3128 3129 #ifdef INET 3130 ipproto_unregister(IPPROTO_PFSYNC); 3131 #endif 3132 #ifdef INET6 3133 ip6proto_unregister(IPPROTO_PFSYNC); 3134 #endif 3135 } 3136 3137 static int 3138 pfsync_modevent(module_t mod, int type, void *data) 3139 { 3140 int error = 0; 3141 3142 switch (type) { 3143 case MOD_LOAD: 3144 error = pfsync_init(); 3145 break; 3146 case MOD_UNLOAD: 3147 pfsync_uninit(); 3148 break; 3149 default: 3150 error = EINVAL; 3151 break; 3152 } 3153 3154 return (error); 3155 } 3156 3157 static moduledata_t pfsync_mod = { 3158 pfsyncname, 3159 pfsync_modevent, 3160 0 3161 }; 3162 3163 #define PFSYNC_MODVER 1 3164 3165 /* Stay on FIREWALL as we depend on pf being initialized and on inetdomain. */ 3166 DECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY); 3167 MODULE_VERSION(pfsync, PFSYNC_MODVER); 3168 MODULE_DEPEND(pfsync, pf, PF_MODVER, PF_MODVER, PF_MODVER); 3169