1 /*- 2 * SPDX-License-Identifier: (BSD-2-Clause-FreeBSD 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 __FBSDID("$FreeBSD$"); 64 65 #include "opt_inet.h" 66 #include "opt_inet6.h" 67 #include "opt_pf.h" 68 69 #include <sys/param.h> 70 #include <sys/bus.h> 71 #include <sys/endian.h> 72 #include <sys/interrupt.h> 73 #include <sys/kernel.h> 74 #include <sys/lock.h> 75 #include <sys/mbuf.h> 76 #include <sys/module.h> 77 #include <sys/mutex.h> 78 #include <sys/priv.h> 79 #include <sys/protosw.h> 80 #include <sys/smp.h> 81 #include <sys/socket.h> 82 #include <sys/sockio.h> 83 #include <sys/sysctl.h> 84 #include <sys/syslog.h> 85 86 #include <net/bpf.h> 87 #include <net/if.h> 88 #include <net/if_var.h> 89 #include <net/if_clone.h> 90 #include <net/if_types.h> 91 #include <net/vnet.h> 92 #include <net/pfvar.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 <netinet/ip.h> 99 #include <netinet/ip_carp.h> 100 #include <netinet/ip_var.h> 101 #include <netinet/tcp.h> 102 #include <netinet/tcp_fsm.h> 103 #include <netinet/tcp_seq.h> 104 105 #define PFSYNC_MINPKT ( \ 106 sizeof(struct ip) + \ 107 sizeof(struct pfsync_header) + \ 108 sizeof(struct pfsync_subheader) ) 109 110 struct pfsync_bucket; 111 112 struct pfsync_pkt { 113 struct ip *ip; 114 struct in_addr src; 115 u_int8_t flags; 116 }; 117 118 static int pfsync_upd_tcp(struct pf_kstate *, struct pfsync_state_peer *, 119 struct pfsync_state_peer *); 120 static int pfsync_in_clr(struct pfsync_pkt *, struct mbuf *, int, int); 121 static int pfsync_in_ins(struct pfsync_pkt *, struct mbuf *, int, int); 122 static int pfsync_in_iack(struct pfsync_pkt *, struct mbuf *, int, int); 123 static int pfsync_in_upd(struct pfsync_pkt *, struct mbuf *, int, int); 124 static int pfsync_in_upd_c(struct pfsync_pkt *, struct mbuf *, int, int); 125 static int pfsync_in_ureq(struct pfsync_pkt *, struct mbuf *, int, int); 126 static int pfsync_in_del(struct pfsync_pkt *, struct mbuf *, int, int); 127 static int pfsync_in_del_c(struct pfsync_pkt *, struct mbuf *, int, int); 128 static int pfsync_in_bus(struct pfsync_pkt *, struct mbuf *, int, int); 129 static int pfsync_in_tdb(struct pfsync_pkt *, struct mbuf *, int, int); 130 static int pfsync_in_eof(struct pfsync_pkt *, struct mbuf *, int, int); 131 static int pfsync_in_error(struct pfsync_pkt *, struct mbuf *, int, int); 132 133 static int (*pfsync_acts[])(struct pfsync_pkt *, struct mbuf *, int, int) = { 134 pfsync_in_clr, /* PFSYNC_ACT_CLR */ 135 pfsync_in_ins, /* PFSYNC_ACT_INS */ 136 pfsync_in_iack, /* PFSYNC_ACT_INS_ACK */ 137 pfsync_in_upd, /* PFSYNC_ACT_UPD */ 138 pfsync_in_upd_c, /* PFSYNC_ACT_UPD_C */ 139 pfsync_in_ureq, /* PFSYNC_ACT_UPD_REQ */ 140 pfsync_in_del, /* PFSYNC_ACT_DEL */ 141 pfsync_in_del_c, /* PFSYNC_ACT_DEL_C */ 142 pfsync_in_error, /* PFSYNC_ACT_INS_F */ 143 pfsync_in_error, /* PFSYNC_ACT_DEL_F */ 144 pfsync_in_bus, /* PFSYNC_ACT_BUS */ 145 pfsync_in_tdb, /* PFSYNC_ACT_TDB */ 146 pfsync_in_eof /* PFSYNC_ACT_EOF */ 147 }; 148 149 struct pfsync_q { 150 void (*write)(struct pf_kstate *, void *); 151 size_t len; 152 u_int8_t action; 153 }; 154 155 /* we have one of these for every PFSYNC_S_ */ 156 static void pfsync_out_state(struct pf_kstate *, void *); 157 static void pfsync_out_iack(struct pf_kstate *, void *); 158 static void pfsync_out_upd_c(struct pf_kstate *, void *); 159 static void pfsync_out_del(struct pf_kstate *, void *); 160 161 static struct pfsync_q pfsync_qs[] = { 162 { pfsync_out_state, sizeof(struct pfsync_state), PFSYNC_ACT_INS }, 163 { pfsync_out_iack, sizeof(struct pfsync_ins_ack), PFSYNC_ACT_INS_ACK }, 164 { pfsync_out_state, sizeof(struct pfsync_state), PFSYNC_ACT_UPD }, 165 { pfsync_out_upd_c, sizeof(struct pfsync_upd_c), PFSYNC_ACT_UPD_C }, 166 { pfsync_out_del, sizeof(struct pfsync_del_c), PFSYNC_ACT_DEL_C } 167 }; 168 169 static void pfsync_q_ins(struct pf_kstate *, int, bool); 170 static void pfsync_q_del(struct pf_kstate *, bool, struct pfsync_bucket *); 171 172 static void pfsync_update_state(struct pf_kstate *); 173 174 struct pfsync_upd_req_item { 175 TAILQ_ENTRY(pfsync_upd_req_item) ur_entry; 176 struct pfsync_upd_req ur_msg; 177 }; 178 179 struct pfsync_deferral { 180 struct pfsync_softc *pd_sc; 181 TAILQ_ENTRY(pfsync_deferral) pd_entry; 182 u_int pd_refs; 183 struct callout pd_tmo; 184 185 struct pf_kstate *pd_st; 186 struct mbuf *pd_m; 187 }; 188 189 struct pfsync_sofct; 190 191 struct pfsync_bucket 192 { 193 int b_id; 194 struct pfsync_softc *b_sc; 195 struct mtx b_mtx; 196 struct callout b_tmo; 197 int b_flags; 198 #define PFSYNCF_BUCKET_PUSH 0x00000001 199 200 size_t b_len; 201 TAILQ_HEAD(, pf_kstate) b_qs[PFSYNC_S_COUNT]; 202 TAILQ_HEAD(, pfsync_upd_req_item) b_upd_req_list; 203 TAILQ_HEAD(, pfsync_deferral) b_deferrals; 204 u_int b_deferred; 205 void *b_plus; 206 size_t b_pluslen; 207 208 struct ifaltq b_snd; 209 }; 210 211 struct pfsync_softc { 212 /* Configuration */ 213 struct ifnet *sc_ifp; 214 struct ifnet *sc_sync_if; 215 struct ip_moptions sc_imo; 216 struct in_addr sc_sync_peer; 217 uint32_t sc_flags; 218 uint8_t sc_maxupdates; 219 struct ip sc_template; 220 struct mtx sc_mtx; 221 222 /* Queued data */ 223 struct pfsync_bucket *sc_buckets; 224 225 /* Bulk update info */ 226 struct mtx sc_bulk_mtx; 227 uint32_t sc_ureq_sent; 228 int sc_bulk_tries; 229 uint32_t sc_ureq_received; 230 int sc_bulk_hashid; 231 uint64_t sc_bulk_stateid; 232 uint32_t sc_bulk_creatorid; 233 struct callout sc_bulk_tmo; 234 struct callout sc_bulkfail_tmo; 235 }; 236 237 #define PFSYNC_LOCK(sc) mtx_lock(&(sc)->sc_mtx) 238 #define PFSYNC_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) 239 #define PFSYNC_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) 240 241 #define PFSYNC_BUCKET_LOCK(b) mtx_lock(&(b)->b_mtx) 242 #define PFSYNC_BUCKET_UNLOCK(b) mtx_unlock(&(b)->b_mtx) 243 #define PFSYNC_BUCKET_LOCK_ASSERT(b) mtx_assert(&(b)->b_mtx, MA_OWNED) 244 245 #define PFSYNC_BLOCK(sc) mtx_lock(&(sc)->sc_bulk_mtx) 246 #define PFSYNC_BUNLOCK(sc) mtx_unlock(&(sc)->sc_bulk_mtx) 247 #define PFSYNC_BLOCK_ASSERT(sc) mtx_assert(&(sc)->sc_bulk_mtx, MA_OWNED) 248 249 static const char pfsyncname[] = "pfsync"; 250 static MALLOC_DEFINE(M_PFSYNC, pfsyncname, "pfsync(4) data"); 251 VNET_DEFINE_STATIC(struct pfsync_softc *, pfsyncif) = NULL; 252 #define V_pfsyncif VNET(pfsyncif) 253 VNET_DEFINE_STATIC(void *, pfsync_swi_cookie) = NULL; 254 #define V_pfsync_swi_cookie VNET(pfsync_swi_cookie) 255 VNET_DEFINE_STATIC(struct intr_event *, pfsync_swi_ie); 256 #define V_pfsync_swi_ie VNET(pfsync_swi_ie) 257 VNET_DEFINE_STATIC(struct pfsyncstats, pfsyncstats); 258 #define V_pfsyncstats VNET(pfsyncstats) 259 VNET_DEFINE_STATIC(int, pfsync_carp_adj) = CARP_MAXSKEW; 260 #define V_pfsync_carp_adj VNET(pfsync_carp_adj) 261 262 static void pfsync_timeout(void *); 263 static void pfsync_push(struct pfsync_bucket *); 264 static void pfsync_push_all(struct pfsync_softc *); 265 static void pfsyncintr(void *); 266 static int pfsync_multicast_setup(struct pfsync_softc *, struct ifnet *, 267 struct in_mfilter *imf); 268 static void pfsync_multicast_cleanup(struct pfsync_softc *); 269 static void pfsync_pointers_init(void); 270 static void pfsync_pointers_uninit(void); 271 static int pfsync_init(void); 272 static void pfsync_uninit(void); 273 274 static unsigned long pfsync_buckets; 275 276 SYSCTL_NODE(_net, OID_AUTO, pfsync, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 277 "PFSYNC"); 278 SYSCTL_STRUCT(_net_pfsync, OID_AUTO, stats, CTLFLAG_VNET | CTLFLAG_RW, 279 &VNET_NAME(pfsyncstats), pfsyncstats, 280 "PFSYNC statistics (struct pfsyncstats, net/if_pfsync.h)"); 281 SYSCTL_INT(_net_pfsync, OID_AUTO, carp_demotion_factor, CTLFLAG_RW, 282 &VNET_NAME(pfsync_carp_adj), 0, "pfsync's CARP demotion factor adjustment"); 283 SYSCTL_ULONG(_net_pfsync, OID_AUTO, pfsync_buckets, CTLFLAG_RDTUN, 284 &pfsync_buckets, 0, "Number of pfsync hash buckets"); 285 286 static int pfsync_clone_create(struct if_clone *, int, caddr_t); 287 static void pfsync_clone_destroy(struct ifnet *); 288 static int pfsync_alloc_scrub_memory(struct pfsync_state_peer *, 289 struct pf_state_peer *); 290 static int pfsyncoutput(struct ifnet *, struct mbuf *, 291 const struct sockaddr *, struct route *); 292 static int pfsyncioctl(struct ifnet *, u_long, caddr_t); 293 294 static int pfsync_defer(struct pf_kstate *, struct mbuf *); 295 static void pfsync_undefer(struct pfsync_deferral *, int); 296 static void pfsync_undefer_state(struct pf_kstate *, int); 297 static void pfsync_defer_tmo(void *); 298 299 static void pfsync_request_update(u_int32_t, u_int64_t); 300 static bool pfsync_update_state_req(struct pf_kstate *); 301 302 static void pfsync_drop(struct pfsync_softc *); 303 static void pfsync_sendout(int, int); 304 static void pfsync_send_plus(void *, size_t); 305 306 static void pfsync_bulk_start(void); 307 static void pfsync_bulk_status(u_int8_t); 308 static void pfsync_bulk_update(void *); 309 static void pfsync_bulk_fail(void *); 310 311 static void pfsync_detach_ifnet(struct ifnet *); 312 #ifdef IPSEC 313 static void pfsync_update_net_tdb(struct pfsync_tdb *); 314 #endif 315 static struct pfsync_bucket *pfsync_get_bucket(struct pfsync_softc *, 316 struct pf_kstate *); 317 318 #define PFSYNC_MAX_BULKTRIES 12 319 320 VNET_DEFINE(struct if_clone *, pfsync_cloner); 321 #define V_pfsync_cloner VNET(pfsync_cloner) 322 323 static int 324 pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t param) 325 { 326 struct pfsync_softc *sc; 327 struct ifnet *ifp; 328 struct pfsync_bucket *b; 329 int c, q; 330 331 if (unit != 0) 332 return (EINVAL); 333 334 if (! pfsync_buckets) 335 pfsync_buckets = mp_ncpus * 2; 336 337 sc = malloc(sizeof(struct pfsync_softc), M_PFSYNC, M_WAITOK | M_ZERO); 338 sc->sc_flags |= PFSYNCF_OK; 339 sc->sc_maxupdates = 128; 340 341 ifp = sc->sc_ifp = if_alloc(IFT_PFSYNC); 342 if (ifp == NULL) { 343 free(sc, M_PFSYNC); 344 return (ENOSPC); 345 } 346 if_initname(ifp, pfsyncname, unit); 347 ifp->if_softc = sc; 348 ifp->if_ioctl = pfsyncioctl; 349 ifp->if_output = pfsyncoutput; 350 ifp->if_type = IFT_PFSYNC; 351 ifp->if_hdrlen = sizeof(struct pfsync_header); 352 ifp->if_mtu = ETHERMTU; 353 mtx_init(&sc->sc_mtx, pfsyncname, NULL, MTX_DEF); 354 mtx_init(&sc->sc_bulk_mtx, "pfsync bulk", NULL, MTX_DEF); 355 callout_init_mtx(&sc->sc_bulk_tmo, &sc->sc_bulk_mtx, 0); 356 callout_init_mtx(&sc->sc_bulkfail_tmo, &sc->sc_bulk_mtx, 0); 357 358 if_attach(ifp); 359 360 bpfattach(ifp, DLT_PFSYNC, PFSYNC_HDRLEN); 361 362 sc->sc_buckets = mallocarray(pfsync_buckets, sizeof(*sc->sc_buckets), 363 M_PFSYNC, M_ZERO | M_WAITOK); 364 for (c = 0; c < pfsync_buckets; c++) { 365 b = &sc->sc_buckets[c]; 366 mtx_init(&b->b_mtx, "pfsync bucket", NULL, MTX_DEF); 367 368 b->b_id = c; 369 b->b_sc = sc; 370 b->b_len = PFSYNC_MINPKT; 371 372 for (q = 0; q < PFSYNC_S_COUNT; q++) 373 TAILQ_INIT(&b->b_qs[q]); 374 375 TAILQ_INIT(&b->b_upd_req_list); 376 TAILQ_INIT(&b->b_deferrals); 377 378 callout_init(&b->b_tmo, 1); 379 380 b->b_snd.ifq_maxlen = ifqmaxlen; 381 } 382 383 V_pfsyncif = sc; 384 385 return (0); 386 } 387 388 static void 389 pfsync_clone_destroy(struct ifnet *ifp) 390 { 391 struct pfsync_softc *sc = ifp->if_softc; 392 struct pfsync_bucket *b; 393 int c; 394 395 for (c = 0; c < pfsync_buckets; c++) { 396 b = &sc->sc_buckets[c]; 397 /* 398 * At this stage, everything should have already been 399 * cleared by pfsync_uninit(), and we have only to 400 * drain callouts. 401 */ 402 while (b->b_deferred > 0) { 403 struct pfsync_deferral *pd = 404 TAILQ_FIRST(&b->b_deferrals); 405 406 TAILQ_REMOVE(&b->b_deferrals, pd, pd_entry); 407 b->b_deferred--; 408 if (callout_stop(&pd->pd_tmo) > 0) { 409 pf_release_state(pd->pd_st); 410 m_freem(pd->pd_m); 411 free(pd, M_PFSYNC); 412 } else { 413 pd->pd_refs++; 414 callout_drain(&pd->pd_tmo); 415 free(pd, M_PFSYNC); 416 } 417 } 418 419 callout_drain(&b->b_tmo); 420 } 421 422 callout_drain(&sc->sc_bulkfail_tmo); 423 callout_drain(&sc->sc_bulk_tmo); 424 425 if (!(sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) 426 (*carp_demote_adj_p)(-V_pfsync_carp_adj, "pfsync destroy"); 427 bpfdetach(ifp); 428 if_detach(ifp); 429 430 pfsync_drop(sc); 431 432 if_free(ifp); 433 pfsync_multicast_cleanup(sc); 434 mtx_destroy(&sc->sc_mtx); 435 mtx_destroy(&sc->sc_bulk_mtx); 436 437 free(sc->sc_buckets, M_PFSYNC); 438 free(sc, M_PFSYNC); 439 440 V_pfsyncif = NULL; 441 } 442 443 static int 444 pfsync_alloc_scrub_memory(struct pfsync_state_peer *s, 445 struct pf_state_peer *d) 446 { 447 if (s->scrub.scrub_flag && d->scrub == NULL) { 448 d->scrub = uma_zalloc(V_pf_state_scrub_z, M_NOWAIT | M_ZERO); 449 if (d->scrub == NULL) 450 return (ENOMEM); 451 } 452 453 return (0); 454 } 455 456 static int 457 pfsync_state_import(struct pfsync_state *sp, u_int8_t flags) 458 { 459 struct pfsync_softc *sc = V_pfsyncif; 460 #ifndef __NO_STRICT_ALIGNMENT 461 struct pfsync_state_key key[2]; 462 #endif 463 struct pfsync_state_key *kw, *ks; 464 struct pf_kstate *st = NULL; 465 struct pf_state_key *skw = NULL, *sks = NULL; 466 struct pf_krule *r = NULL; 467 struct pfi_kkif *kif; 468 int error; 469 470 PF_RULES_RASSERT(); 471 472 if (sp->creatorid == 0) { 473 if (V_pf_status.debug >= PF_DEBUG_MISC) 474 printf("%s: invalid creator id: %08x\n", __func__, 475 ntohl(sp->creatorid)); 476 return (EINVAL); 477 } 478 479 if ((kif = pfi_kkif_find(sp->ifname)) == NULL) { 480 if (V_pf_status.debug >= PF_DEBUG_MISC) 481 printf("%s: unknown interface: %s\n", __func__, 482 sp->ifname); 483 if (flags & PFSYNC_SI_IOCTL) 484 return (EINVAL); 485 return (0); /* skip this state */ 486 } 487 488 /* 489 * If the ruleset checksums match or the state is coming from the ioctl, 490 * it's safe to associate the state with the rule of that number. 491 */ 492 if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) && 493 (flags & (PFSYNC_SI_IOCTL | PFSYNC_SI_CKSUM)) && ntohl(sp->rule) < 494 pf_main_ruleset.rules[PF_RULESET_FILTER].active.rcount) 495 r = pf_main_ruleset.rules[ 496 PF_RULESET_FILTER].active.ptr_array[ntohl(sp->rule)]; 497 else 498 r = &V_pf_default_rule; 499 500 if ((r->max_states && 501 counter_u64_fetch(r->states_cur) >= r->max_states)) 502 goto cleanup; 503 504 /* 505 * XXXGL: consider M_WAITOK in ioctl path after. 506 */ 507 st = pf_alloc_state(M_NOWAIT); 508 if (__predict_false(st == NULL)) 509 goto cleanup; 510 511 if ((skw = uma_zalloc(V_pf_state_key_z, M_NOWAIT)) == NULL) 512 goto cleanup; 513 514 #ifndef __NO_STRICT_ALIGNMENT 515 bcopy(&sp->key, key, sizeof(struct pfsync_state_key) * 2); 516 kw = &key[PF_SK_WIRE]; 517 ks = &key[PF_SK_STACK]; 518 #else 519 kw = &sp->key[PF_SK_WIRE]; 520 ks = &sp->key[PF_SK_STACK]; 521 #endif 522 523 if (PF_ANEQ(&kw->addr[0], &ks->addr[0], sp->af) || 524 PF_ANEQ(&kw->addr[1], &ks->addr[1], sp->af) || 525 kw->port[0] != ks->port[0] || 526 kw->port[1] != ks->port[1]) { 527 sks = uma_zalloc(V_pf_state_key_z, M_NOWAIT); 528 if (sks == NULL) 529 goto cleanup; 530 } else 531 sks = skw; 532 533 /* allocate memory for scrub info */ 534 if (pfsync_alloc_scrub_memory(&sp->src, &st->src) || 535 pfsync_alloc_scrub_memory(&sp->dst, &st->dst)) 536 goto cleanup; 537 538 /* Copy to state key(s). */ 539 skw->addr[0] = kw->addr[0]; 540 skw->addr[1] = kw->addr[1]; 541 skw->port[0] = kw->port[0]; 542 skw->port[1] = kw->port[1]; 543 skw->proto = sp->proto; 544 skw->af = sp->af; 545 if (sks != skw) { 546 sks->addr[0] = ks->addr[0]; 547 sks->addr[1] = ks->addr[1]; 548 sks->port[0] = ks->port[0]; 549 sks->port[1] = ks->port[1]; 550 sks->proto = sp->proto; 551 sks->af = sp->af; 552 } 553 554 /* copy to state */ 555 bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr)); 556 st->creation = time_uptime - ntohl(sp->creation); 557 st->expire = time_uptime; 558 if (sp->expire) { 559 uint32_t timeout; 560 561 timeout = r->timeout[sp->timeout]; 562 if (!timeout) 563 timeout = V_pf_default_rule.timeout[sp->timeout]; 564 565 /* sp->expire may have been adaptively scaled by export. */ 566 st->expire -= timeout - ntohl(sp->expire); 567 } 568 569 st->direction = sp->direction; 570 st->log = sp->log; 571 st->timeout = sp->timeout; 572 st->state_flags = sp->state_flags; 573 574 st->id = sp->id; 575 st->creatorid = sp->creatorid; 576 pf_state_peer_ntoh(&sp->src, &st->src); 577 pf_state_peer_ntoh(&sp->dst, &st->dst); 578 579 st->rule.ptr = r; 580 st->nat_rule.ptr = NULL; 581 st->anchor.ptr = NULL; 582 st->rt_kif = NULL; 583 584 st->pfsync_time = time_uptime; 585 st->sync_state = PFSYNC_S_NONE; 586 587 if (!(flags & PFSYNC_SI_IOCTL)) 588 st->state_flags |= PFSTATE_NOSYNC; 589 590 if ((error = pf_state_insert(kif, kif, skw, sks, st)) != 0) 591 goto cleanup_state; 592 593 /* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */ 594 counter_u64_add(r->states_cur, 1); 595 counter_u64_add(r->states_tot, 1); 596 597 if (!(flags & PFSYNC_SI_IOCTL)) { 598 st->state_flags &= ~PFSTATE_NOSYNC; 599 if (st->state_flags & PFSTATE_ACK) { 600 pfsync_q_ins(st, PFSYNC_S_IACK, true); 601 pfsync_push_all(sc); 602 } 603 } 604 st->state_flags &= ~PFSTATE_ACK; 605 PF_STATE_UNLOCK(st); 606 607 return (0); 608 609 cleanup: 610 error = ENOMEM; 611 if (skw == sks) 612 sks = NULL; 613 if (skw != NULL) 614 uma_zfree(V_pf_state_key_z, skw); 615 if (sks != NULL) 616 uma_zfree(V_pf_state_key_z, sks); 617 618 cleanup_state: /* pf_state_insert() frees the state keys. */ 619 if (st) { 620 pf_free_state(st); 621 } 622 return (error); 623 } 624 625 static int 626 pfsync_input(struct mbuf **mp, int *offp __unused, int proto __unused) 627 { 628 struct pfsync_softc *sc = V_pfsyncif; 629 struct pfsync_pkt pkt; 630 struct mbuf *m = *mp; 631 struct ip *ip = mtod(m, struct ip *); 632 struct pfsync_header *ph; 633 struct pfsync_subheader subh; 634 635 int offset, len; 636 int rv; 637 uint16_t count; 638 639 PF_RULES_RLOCK_TRACKER; 640 641 *mp = NULL; 642 V_pfsyncstats.pfsyncs_ipackets++; 643 644 /* Verify that we have a sync interface configured. */ 645 if (!sc || !sc->sc_sync_if || !V_pf_status.running || 646 (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 647 goto done; 648 649 /* verify that the packet came in on the right interface */ 650 if (sc->sc_sync_if != m->m_pkthdr.rcvif) { 651 V_pfsyncstats.pfsyncs_badif++; 652 goto done; 653 } 654 655 if_inc_counter(sc->sc_ifp, IFCOUNTER_IPACKETS, 1); 656 if_inc_counter(sc->sc_ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); 657 /* verify that the IP TTL is 255. */ 658 if (ip->ip_ttl != PFSYNC_DFLTTL) { 659 V_pfsyncstats.pfsyncs_badttl++; 660 goto done; 661 } 662 663 offset = ip->ip_hl << 2; 664 if (m->m_pkthdr.len < offset + sizeof(*ph)) { 665 V_pfsyncstats.pfsyncs_hdrops++; 666 goto done; 667 } 668 669 if (offset + sizeof(*ph) > m->m_len) { 670 if (m_pullup(m, offset + sizeof(*ph)) == NULL) { 671 V_pfsyncstats.pfsyncs_hdrops++; 672 return (IPPROTO_DONE); 673 } 674 ip = mtod(m, struct ip *); 675 } 676 ph = (struct pfsync_header *)((char *)ip + offset); 677 678 /* verify the version */ 679 if (ph->version != PFSYNC_VERSION) { 680 V_pfsyncstats.pfsyncs_badver++; 681 goto done; 682 } 683 684 len = ntohs(ph->len) + offset; 685 if (m->m_pkthdr.len < len) { 686 V_pfsyncstats.pfsyncs_badlen++; 687 goto done; 688 } 689 690 /* Cheaper to grab this now than having to mess with mbufs later */ 691 pkt.ip = ip; 692 pkt.src = ip->ip_src; 693 pkt.flags = 0; 694 695 /* 696 * Trusting pf_chksum during packet processing, as well as seeking 697 * in interface name tree, require holding PF_RULES_RLOCK(). 698 */ 699 PF_RULES_RLOCK(); 700 if (!bcmp(&ph->pfcksum, &V_pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH)) 701 pkt.flags |= PFSYNC_SI_CKSUM; 702 703 offset += sizeof(*ph); 704 while (offset <= len - sizeof(subh)) { 705 m_copydata(m, offset, sizeof(subh), (caddr_t)&subh); 706 offset += sizeof(subh); 707 708 if (subh.action >= PFSYNC_ACT_MAX) { 709 V_pfsyncstats.pfsyncs_badact++; 710 PF_RULES_RUNLOCK(); 711 goto done; 712 } 713 714 count = ntohs(subh.count); 715 V_pfsyncstats.pfsyncs_iacts[subh.action] += count; 716 rv = (*pfsync_acts[subh.action])(&pkt, m, offset, count); 717 if (rv == -1) { 718 PF_RULES_RUNLOCK(); 719 return (IPPROTO_DONE); 720 } 721 722 offset += rv; 723 } 724 PF_RULES_RUNLOCK(); 725 726 done: 727 m_freem(m); 728 return (IPPROTO_DONE); 729 } 730 731 static int 732 pfsync_in_clr(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count) 733 { 734 struct pfsync_clr *clr; 735 struct mbuf *mp; 736 int len = sizeof(*clr) * count; 737 int i, offp; 738 u_int32_t creatorid; 739 740 mp = m_pulldown(m, offset, len, &offp); 741 if (mp == NULL) { 742 V_pfsyncstats.pfsyncs_badlen++; 743 return (-1); 744 } 745 clr = (struct pfsync_clr *)(mp->m_data + offp); 746 747 for (i = 0; i < count; i++) { 748 creatorid = clr[i].creatorid; 749 750 if (clr[i].ifname[0] != '\0' && 751 pfi_kkif_find(clr[i].ifname) == NULL) 752 continue; 753 754 for (int i = 0; i <= pf_hashmask; i++) { 755 struct pf_idhash *ih = &V_pf_idhash[i]; 756 struct pf_kstate *s; 757 relock: 758 PF_HASHROW_LOCK(ih); 759 LIST_FOREACH(s, &ih->states, entry) { 760 if (s->creatorid == creatorid) { 761 s->state_flags |= PFSTATE_NOSYNC; 762 pf_unlink_state(s, PF_ENTER_LOCKED); 763 goto relock; 764 } 765 } 766 PF_HASHROW_UNLOCK(ih); 767 } 768 } 769 770 return (len); 771 } 772 773 static int 774 pfsync_in_ins(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count) 775 { 776 struct mbuf *mp; 777 struct pfsync_state *sa, *sp; 778 int len = sizeof(*sp) * count; 779 int i, offp; 780 781 mp = m_pulldown(m, offset, len, &offp); 782 if (mp == NULL) { 783 V_pfsyncstats.pfsyncs_badlen++; 784 return (-1); 785 } 786 sa = (struct pfsync_state *)(mp->m_data + offp); 787 788 for (i = 0; i < count; i++) { 789 sp = &sa[i]; 790 791 /* Check for invalid values. */ 792 if (sp->timeout >= PFTM_MAX || 793 sp->src.state > PF_TCPS_PROXY_DST || 794 sp->dst.state > PF_TCPS_PROXY_DST || 795 sp->direction > PF_OUT || 796 (sp->af != AF_INET && sp->af != AF_INET6)) { 797 if (V_pf_status.debug >= PF_DEBUG_MISC) 798 printf("%s: invalid value\n", __func__); 799 V_pfsyncstats.pfsyncs_badval++; 800 continue; 801 } 802 803 if (pfsync_state_import(sp, pkt->flags) == ENOMEM) 804 /* Drop out, but process the rest of the actions. */ 805 break; 806 } 807 808 return (len); 809 } 810 811 static int 812 pfsync_in_iack(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count) 813 { 814 struct pfsync_ins_ack *ia, *iaa; 815 struct pf_kstate *st; 816 817 struct mbuf *mp; 818 int len = count * sizeof(*ia); 819 int offp, i; 820 821 mp = m_pulldown(m, offset, len, &offp); 822 if (mp == NULL) { 823 V_pfsyncstats.pfsyncs_badlen++; 824 return (-1); 825 } 826 iaa = (struct pfsync_ins_ack *)(mp->m_data + offp); 827 828 for (i = 0; i < count; i++) { 829 ia = &iaa[i]; 830 831 st = pf_find_state_byid(ia->id, ia->creatorid); 832 if (st == NULL) 833 continue; 834 835 if (st->state_flags & PFSTATE_ACK) { 836 pfsync_undefer_state(st, 0); 837 } 838 PF_STATE_UNLOCK(st); 839 } 840 /* 841 * XXX this is not yet implemented, but we know the size of the 842 * message so we can skip it. 843 */ 844 845 return (count * sizeof(struct pfsync_ins_ack)); 846 } 847 848 static int 849 pfsync_upd_tcp(struct pf_kstate *st, struct pfsync_state_peer *src, 850 struct pfsync_state_peer *dst) 851 { 852 int sync = 0; 853 854 PF_STATE_LOCK_ASSERT(st); 855 856 /* 857 * The state should never go backwards except 858 * for syn-proxy states. Neither should the 859 * sequence window slide backwards. 860 */ 861 if ((st->src.state > src->state && 862 (st->src.state < PF_TCPS_PROXY_SRC || 863 src->state >= PF_TCPS_PROXY_SRC)) || 864 865 (st->src.state == src->state && 866 SEQ_GT(st->src.seqlo, ntohl(src->seqlo)))) 867 sync++; 868 else 869 pf_state_peer_ntoh(src, &st->src); 870 871 if ((st->dst.state > dst->state) || 872 873 (st->dst.state >= TCPS_SYN_SENT && 874 SEQ_GT(st->dst.seqlo, ntohl(dst->seqlo)))) 875 sync++; 876 else 877 pf_state_peer_ntoh(dst, &st->dst); 878 879 return (sync); 880 } 881 882 static int 883 pfsync_in_upd(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count) 884 { 885 struct pfsync_softc *sc = V_pfsyncif; 886 struct pfsync_state *sa, *sp; 887 struct pf_kstate *st; 888 int sync; 889 890 struct mbuf *mp; 891 int len = count * sizeof(*sp); 892 int offp, i; 893 894 mp = m_pulldown(m, offset, len, &offp); 895 if (mp == NULL) { 896 V_pfsyncstats.pfsyncs_badlen++; 897 return (-1); 898 } 899 sa = (struct pfsync_state *)(mp->m_data + offp); 900 901 for (i = 0; i < count; i++) { 902 sp = &sa[i]; 903 904 /* check for invalid values */ 905 if (sp->timeout >= PFTM_MAX || 906 sp->src.state > PF_TCPS_PROXY_DST || 907 sp->dst.state > PF_TCPS_PROXY_DST) { 908 if (V_pf_status.debug >= PF_DEBUG_MISC) { 909 printf("pfsync_input: PFSYNC_ACT_UPD: " 910 "invalid value\n"); 911 } 912 V_pfsyncstats.pfsyncs_badval++; 913 continue; 914 } 915 916 st = pf_find_state_byid(sp->id, sp->creatorid); 917 if (st == NULL) { 918 /* insert the update */ 919 if (pfsync_state_import(sp, pkt->flags)) 920 V_pfsyncstats.pfsyncs_badstate++; 921 continue; 922 } 923 924 if (st->state_flags & PFSTATE_ACK) { 925 pfsync_undefer_state(st, 1); 926 } 927 928 if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP) 929 sync = pfsync_upd_tcp(st, &sp->src, &sp->dst); 930 else { 931 sync = 0; 932 933 /* 934 * Non-TCP protocol state machine always go 935 * forwards 936 */ 937 if (st->src.state > sp->src.state) 938 sync++; 939 else 940 pf_state_peer_ntoh(&sp->src, &st->src); 941 if (st->dst.state > sp->dst.state) 942 sync++; 943 else 944 pf_state_peer_ntoh(&sp->dst, &st->dst); 945 } 946 if (sync < 2) { 947 pfsync_alloc_scrub_memory(&sp->dst, &st->dst); 948 pf_state_peer_ntoh(&sp->dst, &st->dst); 949 st->expire = time_uptime; 950 st->timeout = sp->timeout; 951 } 952 st->pfsync_time = time_uptime; 953 954 if (sync) { 955 V_pfsyncstats.pfsyncs_stale++; 956 957 pfsync_update_state(st); 958 PF_STATE_UNLOCK(st); 959 pfsync_push_all(sc); 960 continue; 961 } 962 PF_STATE_UNLOCK(st); 963 } 964 965 return (len); 966 } 967 968 static int 969 pfsync_in_upd_c(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count) 970 { 971 struct pfsync_softc *sc = V_pfsyncif; 972 struct pfsync_upd_c *ua, *up; 973 struct pf_kstate *st; 974 int len = count * sizeof(*up); 975 int sync; 976 struct mbuf *mp; 977 int offp, i; 978 979 mp = m_pulldown(m, offset, len, &offp); 980 if (mp == NULL) { 981 V_pfsyncstats.pfsyncs_badlen++; 982 return (-1); 983 } 984 ua = (struct pfsync_upd_c *)(mp->m_data + offp); 985 986 for (i = 0; i < count; i++) { 987 up = &ua[i]; 988 989 /* check for invalid values */ 990 if (up->timeout >= PFTM_MAX || 991 up->src.state > PF_TCPS_PROXY_DST || 992 up->dst.state > PF_TCPS_PROXY_DST) { 993 if (V_pf_status.debug >= PF_DEBUG_MISC) { 994 printf("pfsync_input: " 995 "PFSYNC_ACT_UPD_C: " 996 "invalid value\n"); 997 } 998 V_pfsyncstats.pfsyncs_badval++; 999 continue; 1000 } 1001 1002 st = pf_find_state_byid(up->id, up->creatorid); 1003 if (st == NULL) { 1004 /* We don't have this state. Ask for it. */ 1005 PFSYNC_BUCKET_LOCK(&sc->sc_buckets[0]); 1006 pfsync_request_update(up->creatorid, up->id); 1007 PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[0]); 1008 continue; 1009 } 1010 1011 if (st->state_flags & PFSTATE_ACK) { 1012 pfsync_undefer_state(st, 1); 1013 } 1014 1015 if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP) 1016 sync = pfsync_upd_tcp(st, &up->src, &up->dst); 1017 else { 1018 sync = 0; 1019 1020 /* 1021 * Non-TCP protocol state machine always go 1022 * forwards 1023 */ 1024 if (st->src.state > up->src.state) 1025 sync++; 1026 else 1027 pf_state_peer_ntoh(&up->src, &st->src); 1028 if (st->dst.state > up->dst.state) 1029 sync++; 1030 else 1031 pf_state_peer_ntoh(&up->dst, &st->dst); 1032 } 1033 if (sync < 2) { 1034 pfsync_alloc_scrub_memory(&up->dst, &st->dst); 1035 pf_state_peer_ntoh(&up->dst, &st->dst); 1036 st->expire = time_uptime; 1037 st->timeout = up->timeout; 1038 } 1039 st->pfsync_time = time_uptime; 1040 1041 if (sync) { 1042 V_pfsyncstats.pfsyncs_stale++; 1043 1044 pfsync_update_state(st); 1045 PF_STATE_UNLOCK(st); 1046 pfsync_push_all(sc); 1047 continue; 1048 } 1049 PF_STATE_UNLOCK(st); 1050 } 1051 1052 return (len); 1053 } 1054 1055 static int 1056 pfsync_in_ureq(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count) 1057 { 1058 struct pfsync_upd_req *ur, *ura; 1059 struct mbuf *mp; 1060 int len = count * sizeof(*ur); 1061 int i, offp; 1062 1063 struct pf_kstate *st; 1064 1065 mp = m_pulldown(m, offset, len, &offp); 1066 if (mp == NULL) { 1067 V_pfsyncstats.pfsyncs_badlen++; 1068 return (-1); 1069 } 1070 ura = (struct pfsync_upd_req *)(mp->m_data + offp); 1071 1072 for (i = 0; i < count; i++) { 1073 ur = &ura[i]; 1074 1075 if (ur->id == 0 && ur->creatorid == 0) 1076 pfsync_bulk_start(); 1077 else { 1078 st = pf_find_state_byid(ur->id, ur->creatorid); 1079 if (st == NULL) { 1080 V_pfsyncstats.pfsyncs_badstate++; 1081 continue; 1082 } 1083 if (st->state_flags & PFSTATE_NOSYNC) { 1084 PF_STATE_UNLOCK(st); 1085 continue; 1086 } 1087 1088 pfsync_update_state_req(st); 1089 PF_STATE_UNLOCK(st); 1090 } 1091 } 1092 1093 return (len); 1094 } 1095 1096 static int 1097 pfsync_in_del(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count) 1098 { 1099 struct mbuf *mp; 1100 struct pfsync_state *sa, *sp; 1101 struct pf_kstate *st; 1102 int len = count * sizeof(*sp); 1103 int offp, i; 1104 1105 mp = m_pulldown(m, offset, len, &offp); 1106 if (mp == NULL) { 1107 V_pfsyncstats.pfsyncs_badlen++; 1108 return (-1); 1109 } 1110 sa = (struct pfsync_state *)(mp->m_data + offp); 1111 1112 for (i = 0; i < count; i++) { 1113 sp = &sa[i]; 1114 1115 st = pf_find_state_byid(sp->id, sp->creatorid); 1116 if (st == NULL) { 1117 V_pfsyncstats.pfsyncs_badstate++; 1118 continue; 1119 } 1120 st->state_flags |= PFSTATE_NOSYNC; 1121 pf_unlink_state(st, PF_ENTER_LOCKED); 1122 } 1123 1124 return (len); 1125 } 1126 1127 static int 1128 pfsync_in_del_c(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count) 1129 { 1130 struct mbuf *mp; 1131 struct pfsync_del_c *sa, *sp; 1132 struct pf_kstate *st; 1133 int len = count * sizeof(*sp); 1134 int offp, i; 1135 1136 mp = m_pulldown(m, offset, len, &offp); 1137 if (mp == NULL) { 1138 V_pfsyncstats.pfsyncs_badlen++; 1139 return (-1); 1140 } 1141 sa = (struct pfsync_del_c *)(mp->m_data + offp); 1142 1143 for (i = 0; i < count; i++) { 1144 sp = &sa[i]; 1145 1146 st = pf_find_state_byid(sp->id, sp->creatorid); 1147 if (st == NULL) { 1148 V_pfsyncstats.pfsyncs_badstate++; 1149 continue; 1150 } 1151 1152 st->state_flags |= PFSTATE_NOSYNC; 1153 pf_unlink_state(st, PF_ENTER_LOCKED); 1154 } 1155 1156 return (len); 1157 } 1158 1159 static int 1160 pfsync_in_bus(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count) 1161 { 1162 struct pfsync_softc *sc = V_pfsyncif; 1163 struct pfsync_bus *bus; 1164 struct mbuf *mp; 1165 int len = count * sizeof(*bus); 1166 int offp; 1167 1168 PFSYNC_BLOCK(sc); 1169 1170 /* If we're not waiting for a bulk update, who cares. */ 1171 if (sc->sc_ureq_sent == 0) { 1172 PFSYNC_BUNLOCK(sc); 1173 return (len); 1174 } 1175 1176 mp = m_pulldown(m, offset, len, &offp); 1177 if (mp == NULL) { 1178 PFSYNC_BUNLOCK(sc); 1179 V_pfsyncstats.pfsyncs_badlen++; 1180 return (-1); 1181 } 1182 bus = (struct pfsync_bus *)(mp->m_data + offp); 1183 1184 switch (bus->status) { 1185 case PFSYNC_BUS_START: 1186 callout_reset(&sc->sc_bulkfail_tmo, 4 * hz + 1187 V_pf_limits[PF_LIMIT_STATES].limit / 1188 ((sc->sc_ifp->if_mtu - PFSYNC_MINPKT) / 1189 sizeof(struct pfsync_state)), 1190 pfsync_bulk_fail, sc); 1191 if (V_pf_status.debug >= PF_DEBUG_MISC) 1192 printf("pfsync: received bulk update start\n"); 1193 break; 1194 1195 case PFSYNC_BUS_END: 1196 if (time_uptime - ntohl(bus->endtime) >= 1197 sc->sc_ureq_sent) { 1198 /* that's it, we're happy */ 1199 sc->sc_ureq_sent = 0; 1200 sc->sc_bulk_tries = 0; 1201 callout_stop(&sc->sc_bulkfail_tmo); 1202 if (!(sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) 1203 (*carp_demote_adj_p)(-V_pfsync_carp_adj, 1204 "pfsync bulk done"); 1205 sc->sc_flags |= PFSYNCF_OK; 1206 if (V_pf_status.debug >= PF_DEBUG_MISC) 1207 printf("pfsync: received valid " 1208 "bulk update end\n"); 1209 } else { 1210 if (V_pf_status.debug >= PF_DEBUG_MISC) 1211 printf("pfsync: received invalid " 1212 "bulk update end: bad timestamp\n"); 1213 } 1214 break; 1215 } 1216 PFSYNC_BUNLOCK(sc); 1217 1218 return (len); 1219 } 1220 1221 static int 1222 pfsync_in_tdb(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count) 1223 { 1224 int len = count * sizeof(struct pfsync_tdb); 1225 1226 #if defined(IPSEC) 1227 struct pfsync_tdb *tp; 1228 struct mbuf *mp; 1229 int offp; 1230 int i; 1231 int s; 1232 1233 mp = m_pulldown(m, offset, len, &offp); 1234 if (mp == NULL) { 1235 V_pfsyncstats.pfsyncs_badlen++; 1236 return (-1); 1237 } 1238 tp = (struct pfsync_tdb *)(mp->m_data + offp); 1239 1240 for (i = 0; i < count; i++) 1241 pfsync_update_net_tdb(&tp[i]); 1242 #endif 1243 1244 return (len); 1245 } 1246 1247 #if defined(IPSEC) 1248 /* Update an in-kernel tdb. Silently fail if no tdb is found. */ 1249 static void 1250 pfsync_update_net_tdb(struct pfsync_tdb *pt) 1251 { 1252 struct tdb *tdb; 1253 int s; 1254 1255 /* check for invalid values */ 1256 if (ntohl(pt->spi) <= SPI_RESERVED_MAX || 1257 (pt->dst.sa.sa_family != AF_INET && 1258 pt->dst.sa.sa_family != AF_INET6)) 1259 goto bad; 1260 1261 tdb = gettdb(pt->spi, &pt->dst, pt->sproto); 1262 if (tdb) { 1263 pt->rpl = ntohl(pt->rpl); 1264 pt->cur_bytes = (unsigned long long)be64toh(pt->cur_bytes); 1265 1266 /* Neither replay nor byte counter should ever decrease. */ 1267 if (pt->rpl < tdb->tdb_rpl || 1268 pt->cur_bytes < tdb->tdb_cur_bytes) { 1269 goto bad; 1270 } 1271 1272 tdb->tdb_rpl = pt->rpl; 1273 tdb->tdb_cur_bytes = pt->cur_bytes; 1274 } 1275 return; 1276 1277 bad: 1278 if (V_pf_status.debug >= PF_DEBUG_MISC) 1279 printf("pfsync_insert: PFSYNC_ACT_TDB_UPD: " 1280 "invalid value\n"); 1281 V_pfsyncstats.pfsyncs_badstate++; 1282 return; 1283 } 1284 #endif 1285 1286 static int 1287 pfsync_in_eof(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count) 1288 { 1289 /* check if we are at the right place in the packet */ 1290 if (offset != m->m_pkthdr.len) 1291 V_pfsyncstats.pfsyncs_badlen++; 1292 1293 /* we're done. free and let the caller return */ 1294 m_freem(m); 1295 return (-1); 1296 } 1297 1298 static int 1299 pfsync_in_error(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count) 1300 { 1301 V_pfsyncstats.pfsyncs_badact++; 1302 1303 m_freem(m); 1304 return (-1); 1305 } 1306 1307 static int 1308 pfsyncoutput(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 1309 struct route *rt) 1310 { 1311 m_freem(m); 1312 return (0); 1313 } 1314 1315 /* ARGSUSED */ 1316 static int 1317 pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1318 { 1319 struct pfsync_softc *sc = ifp->if_softc; 1320 struct ifreq *ifr = (struct ifreq *)data; 1321 struct pfsyncreq pfsyncr; 1322 int error; 1323 int c; 1324 1325 switch (cmd) { 1326 case SIOCSIFFLAGS: 1327 PFSYNC_LOCK(sc); 1328 if (ifp->if_flags & IFF_UP) { 1329 ifp->if_drv_flags |= IFF_DRV_RUNNING; 1330 PFSYNC_UNLOCK(sc); 1331 pfsync_pointers_init(); 1332 } else { 1333 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 1334 PFSYNC_UNLOCK(sc); 1335 pfsync_pointers_uninit(); 1336 } 1337 break; 1338 case SIOCSIFMTU: 1339 if (!sc->sc_sync_if || 1340 ifr->ifr_mtu <= PFSYNC_MINPKT || 1341 ifr->ifr_mtu > sc->sc_sync_if->if_mtu) 1342 return (EINVAL); 1343 if (ifr->ifr_mtu < ifp->if_mtu) { 1344 for (c = 0; c < pfsync_buckets; c++) { 1345 PFSYNC_BUCKET_LOCK(&sc->sc_buckets[c]); 1346 if (sc->sc_buckets[c].b_len > PFSYNC_MINPKT) 1347 pfsync_sendout(1, c); 1348 PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[c]); 1349 } 1350 } 1351 ifp->if_mtu = ifr->ifr_mtu; 1352 break; 1353 case SIOCGETPFSYNC: 1354 bzero(&pfsyncr, sizeof(pfsyncr)); 1355 PFSYNC_LOCK(sc); 1356 if (sc->sc_sync_if) { 1357 strlcpy(pfsyncr.pfsyncr_syncdev, 1358 sc->sc_sync_if->if_xname, IFNAMSIZ); 1359 } 1360 pfsyncr.pfsyncr_syncpeer = sc->sc_sync_peer; 1361 pfsyncr.pfsyncr_maxupdates = sc->sc_maxupdates; 1362 pfsyncr.pfsyncr_defer = sc->sc_flags; 1363 PFSYNC_UNLOCK(sc); 1364 return (copyout(&pfsyncr, ifr_data_get_ptr(ifr), 1365 sizeof(pfsyncr))); 1366 1367 case SIOCSETPFSYNC: 1368 { 1369 struct in_mfilter *imf = NULL; 1370 struct ifnet *sifp; 1371 struct ip *ip; 1372 1373 if ((error = priv_check(curthread, PRIV_NETINET_PF)) != 0) 1374 return (error); 1375 if ((error = copyin(ifr_data_get_ptr(ifr), &pfsyncr, 1376 sizeof(pfsyncr)))) 1377 return (error); 1378 1379 if (pfsyncr.pfsyncr_maxupdates > 255) 1380 return (EINVAL); 1381 1382 if (pfsyncr.pfsyncr_syncdev[0] == 0) 1383 sifp = NULL; 1384 else if ((sifp = ifunit_ref(pfsyncr.pfsyncr_syncdev)) == NULL) 1385 return (EINVAL); 1386 1387 if (sifp != NULL && ( 1388 pfsyncr.pfsyncr_syncpeer.s_addr == 0 || 1389 pfsyncr.pfsyncr_syncpeer.s_addr == 1390 htonl(INADDR_PFSYNC_GROUP))) 1391 imf = ip_mfilter_alloc(M_WAITOK, 0, 0); 1392 1393 PFSYNC_LOCK(sc); 1394 if (pfsyncr.pfsyncr_syncpeer.s_addr == 0) 1395 sc->sc_sync_peer.s_addr = htonl(INADDR_PFSYNC_GROUP); 1396 else 1397 sc->sc_sync_peer.s_addr = 1398 pfsyncr.pfsyncr_syncpeer.s_addr; 1399 1400 sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates; 1401 if (pfsyncr.pfsyncr_defer) { 1402 sc->sc_flags |= PFSYNCF_DEFER; 1403 V_pfsync_defer_ptr = pfsync_defer; 1404 } else { 1405 sc->sc_flags &= ~PFSYNCF_DEFER; 1406 V_pfsync_defer_ptr = NULL; 1407 } 1408 1409 if (sifp == NULL) { 1410 if (sc->sc_sync_if) 1411 if_rele(sc->sc_sync_if); 1412 sc->sc_sync_if = NULL; 1413 pfsync_multicast_cleanup(sc); 1414 PFSYNC_UNLOCK(sc); 1415 break; 1416 } 1417 1418 for (c = 0; c < pfsync_buckets; c++) { 1419 PFSYNC_BUCKET_LOCK(&sc->sc_buckets[c]); 1420 if (sc->sc_buckets[c].b_len > PFSYNC_MINPKT && 1421 (sifp->if_mtu < sc->sc_ifp->if_mtu || 1422 (sc->sc_sync_if != NULL && 1423 sifp->if_mtu < sc->sc_sync_if->if_mtu) || 1424 sifp->if_mtu < MCLBYTES - sizeof(struct ip))) 1425 pfsync_sendout(1, c); 1426 PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[c]); 1427 } 1428 1429 pfsync_multicast_cleanup(sc); 1430 1431 if (sc->sc_sync_peer.s_addr == htonl(INADDR_PFSYNC_GROUP)) { 1432 error = pfsync_multicast_setup(sc, sifp, imf); 1433 if (error) { 1434 if_rele(sifp); 1435 ip_mfilter_free(imf); 1436 PFSYNC_UNLOCK(sc); 1437 return (error); 1438 } 1439 } 1440 if (sc->sc_sync_if) 1441 if_rele(sc->sc_sync_if); 1442 sc->sc_sync_if = sifp; 1443 1444 ip = &sc->sc_template; 1445 bzero(ip, sizeof(*ip)); 1446 ip->ip_v = IPVERSION; 1447 ip->ip_hl = sizeof(sc->sc_template) >> 2; 1448 ip->ip_tos = IPTOS_LOWDELAY; 1449 /* len and id are set later. */ 1450 ip->ip_off = htons(IP_DF); 1451 ip->ip_ttl = PFSYNC_DFLTTL; 1452 ip->ip_p = IPPROTO_PFSYNC; 1453 ip->ip_src.s_addr = INADDR_ANY; 1454 ip->ip_dst.s_addr = sc->sc_sync_peer.s_addr; 1455 1456 /* Request a full state table update. */ 1457 if ((sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) 1458 (*carp_demote_adj_p)(V_pfsync_carp_adj, 1459 "pfsync bulk start"); 1460 sc->sc_flags &= ~PFSYNCF_OK; 1461 if (V_pf_status.debug >= PF_DEBUG_MISC) 1462 printf("pfsync: requesting bulk update\n"); 1463 PFSYNC_UNLOCK(sc); 1464 PFSYNC_BUCKET_LOCK(&sc->sc_buckets[0]); 1465 pfsync_request_update(0, 0); 1466 PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[0]); 1467 PFSYNC_BLOCK(sc); 1468 sc->sc_ureq_sent = time_uptime; 1469 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, pfsync_bulk_fail, 1470 sc); 1471 PFSYNC_BUNLOCK(sc); 1472 1473 break; 1474 } 1475 default: 1476 return (ENOTTY); 1477 } 1478 1479 return (0); 1480 } 1481 1482 static void 1483 pfsync_out_state(struct pf_kstate *st, void *buf) 1484 { 1485 struct pfsync_state *sp = buf; 1486 1487 pfsync_state_export(sp, st); 1488 } 1489 1490 static void 1491 pfsync_out_iack(struct pf_kstate *st, void *buf) 1492 { 1493 struct pfsync_ins_ack *iack = buf; 1494 1495 iack->id = st->id; 1496 iack->creatorid = st->creatorid; 1497 } 1498 1499 static void 1500 pfsync_out_upd_c(struct pf_kstate *st, void *buf) 1501 { 1502 struct pfsync_upd_c *up = buf; 1503 1504 bzero(up, sizeof(*up)); 1505 up->id = st->id; 1506 pf_state_peer_hton(&st->src, &up->src); 1507 pf_state_peer_hton(&st->dst, &up->dst); 1508 up->creatorid = st->creatorid; 1509 up->timeout = st->timeout; 1510 } 1511 1512 static void 1513 pfsync_out_del(struct pf_kstate *st, void *buf) 1514 { 1515 struct pfsync_del_c *dp = buf; 1516 1517 dp->id = st->id; 1518 dp->creatorid = st->creatorid; 1519 st->state_flags |= PFSTATE_NOSYNC; 1520 } 1521 1522 static void 1523 pfsync_drop(struct pfsync_softc *sc) 1524 { 1525 struct pf_kstate *st, *next; 1526 struct pfsync_upd_req_item *ur; 1527 struct pfsync_bucket *b; 1528 int c, q; 1529 1530 for (c = 0; c < pfsync_buckets; c++) { 1531 b = &sc->sc_buckets[c]; 1532 for (q = 0; q < PFSYNC_S_COUNT; q++) { 1533 if (TAILQ_EMPTY(&b->b_qs[q])) 1534 continue; 1535 1536 TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, next) { 1537 KASSERT(st->sync_state == q, 1538 ("%s: st->sync_state == q", 1539 __func__)); 1540 st->sync_state = PFSYNC_S_NONE; 1541 pf_release_state(st); 1542 } 1543 TAILQ_INIT(&b->b_qs[q]); 1544 } 1545 1546 while ((ur = TAILQ_FIRST(&b->b_upd_req_list)) != NULL) { 1547 TAILQ_REMOVE(&b->b_upd_req_list, ur, ur_entry); 1548 free(ur, M_PFSYNC); 1549 } 1550 1551 b->b_len = PFSYNC_MINPKT; 1552 b->b_plus = NULL; 1553 } 1554 } 1555 1556 static void 1557 pfsync_sendout(int schedswi, int c) 1558 { 1559 struct pfsync_softc *sc = V_pfsyncif; 1560 struct ifnet *ifp = sc->sc_ifp; 1561 struct mbuf *m; 1562 struct ip *ip; 1563 struct pfsync_header *ph; 1564 struct pfsync_subheader *subh; 1565 struct pf_kstate *st, *st_next; 1566 struct pfsync_upd_req_item *ur; 1567 struct pfsync_bucket *b = &sc->sc_buckets[c]; 1568 int offset; 1569 int q, count = 0; 1570 1571 KASSERT(sc != NULL, ("%s: null sc", __func__)); 1572 KASSERT(b->b_len > PFSYNC_MINPKT, 1573 ("%s: sc_len %zu", __func__, b->b_len)); 1574 PFSYNC_BUCKET_LOCK_ASSERT(b); 1575 1576 if (ifp->if_bpf == NULL && sc->sc_sync_if == NULL) { 1577 pfsync_drop(sc); 1578 return; 1579 } 1580 1581 m = m_get2(max_linkhdr + b->b_len, M_NOWAIT, MT_DATA, M_PKTHDR); 1582 if (m == NULL) { 1583 if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1); 1584 V_pfsyncstats.pfsyncs_onomem++; 1585 return; 1586 } 1587 m->m_data += max_linkhdr; 1588 m->m_len = m->m_pkthdr.len = b->b_len; 1589 1590 /* build the ip header */ 1591 ip = (struct ip *)m->m_data; 1592 bcopy(&sc->sc_template, ip, sizeof(*ip)); 1593 offset = sizeof(*ip); 1594 1595 ip->ip_len = htons(m->m_pkthdr.len); 1596 ip_fillid(ip); 1597 1598 /* build the pfsync header */ 1599 ph = (struct pfsync_header *)(m->m_data + offset); 1600 bzero(ph, sizeof(*ph)); 1601 offset += sizeof(*ph); 1602 1603 ph->version = PFSYNC_VERSION; 1604 ph->len = htons(b->b_len - sizeof(*ip)); 1605 bcopy(V_pf_status.pf_chksum, ph->pfcksum, PF_MD5_DIGEST_LENGTH); 1606 1607 /* walk the queues */ 1608 for (q = 0; q < PFSYNC_S_COUNT; q++) { 1609 if (TAILQ_EMPTY(&b->b_qs[q])) 1610 continue; 1611 1612 subh = (struct pfsync_subheader *)(m->m_data + offset); 1613 offset += sizeof(*subh); 1614 1615 count = 0; 1616 TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, st_next) { 1617 KASSERT(st->sync_state == q, 1618 ("%s: st->sync_state == q", 1619 __func__)); 1620 /* 1621 * XXXGL: some of write methods do unlocked reads 1622 * of state data :( 1623 */ 1624 pfsync_qs[q].write(st, m->m_data + offset); 1625 offset += pfsync_qs[q].len; 1626 st->sync_state = PFSYNC_S_NONE; 1627 pf_release_state(st); 1628 count++; 1629 } 1630 TAILQ_INIT(&b->b_qs[q]); 1631 1632 bzero(subh, sizeof(*subh)); 1633 subh->action = pfsync_qs[q].action; 1634 subh->count = htons(count); 1635 V_pfsyncstats.pfsyncs_oacts[pfsync_qs[q].action] += count; 1636 } 1637 1638 if (!TAILQ_EMPTY(&b->b_upd_req_list)) { 1639 subh = (struct pfsync_subheader *)(m->m_data + offset); 1640 offset += sizeof(*subh); 1641 1642 count = 0; 1643 while ((ur = TAILQ_FIRST(&b->b_upd_req_list)) != NULL) { 1644 TAILQ_REMOVE(&b->b_upd_req_list, ur, ur_entry); 1645 1646 bcopy(&ur->ur_msg, m->m_data + offset, 1647 sizeof(ur->ur_msg)); 1648 offset += sizeof(ur->ur_msg); 1649 free(ur, M_PFSYNC); 1650 count++; 1651 } 1652 1653 bzero(subh, sizeof(*subh)); 1654 subh->action = PFSYNC_ACT_UPD_REQ; 1655 subh->count = htons(count); 1656 V_pfsyncstats.pfsyncs_oacts[PFSYNC_ACT_UPD_REQ] += count; 1657 } 1658 1659 /* has someone built a custom region for us to add? */ 1660 if (b->b_plus != NULL) { 1661 bcopy(b->b_plus, m->m_data + offset, b->b_pluslen); 1662 offset += b->b_pluslen; 1663 1664 b->b_plus = NULL; 1665 } 1666 1667 subh = (struct pfsync_subheader *)(m->m_data + offset); 1668 offset += sizeof(*subh); 1669 1670 bzero(subh, sizeof(*subh)); 1671 subh->action = PFSYNC_ACT_EOF; 1672 subh->count = htons(1); 1673 V_pfsyncstats.pfsyncs_oacts[PFSYNC_ACT_EOF]++; 1674 1675 /* we're done, let's put it on the wire */ 1676 if (ifp->if_bpf) { 1677 m->m_data += sizeof(*ip); 1678 m->m_len = m->m_pkthdr.len = b->b_len - sizeof(*ip); 1679 BPF_MTAP(ifp, m); 1680 m->m_data -= sizeof(*ip); 1681 m->m_len = m->m_pkthdr.len = b->b_len; 1682 } 1683 1684 if (sc->sc_sync_if == NULL) { 1685 b->b_len = PFSYNC_MINPKT; 1686 m_freem(m); 1687 return; 1688 } 1689 1690 if_inc_counter(sc->sc_ifp, IFCOUNTER_OPACKETS, 1); 1691 if_inc_counter(sc->sc_ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len); 1692 b->b_len = PFSYNC_MINPKT; 1693 1694 if (!_IF_QFULL(&b->b_snd)) 1695 _IF_ENQUEUE(&b->b_snd, m); 1696 else { 1697 m_freem(m); 1698 if_inc_counter(sc->sc_ifp, IFCOUNTER_OQDROPS, 1); 1699 } 1700 if (schedswi) 1701 swi_sched(V_pfsync_swi_cookie, 0); 1702 } 1703 1704 static void 1705 pfsync_insert_state(struct pf_kstate *st) 1706 { 1707 struct pfsync_softc *sc = V_pfsyncif; 1708 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 1709 1710 if (st->state_flags & PFSTATE_NOSYNC) 1711 return; 1712 1713 if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) || 1714 st->key[PF_SK_WIRE]->proto == IPPROTO_PFSYNC) { 1715 st->state_flags |= PFSTATE_NOSYNC; 1716 return; 1717 } 1718 1719 KASSERT(st->sync_state == PFSYNC_S_NONE, 1720 ("%s: st->sync_state %u", __func__, st->sync_state)); 1721 1722 PFSYNC_BUCKET_LOCK(b); 1723 if (b->b_len == PFSYNC_MINPKT) 1724 callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b); 1725 1726 pfsync_q_ins(st, PFSYNC_S_INS, true); 1727 PFSYNC_BUCKET_UNLOCK(b); 1728 1729 st->sync_updates = 0; 1730 } 1731 1732 static int 1733 pfsync_defer(struct pf_kstate *st, struct mbuf *m) 1734 { 1735 struct pfsync_softc *sc = V_pfsyncif; 1736 struct pfsync_deferral *pd; 1737 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 1738 1739 if (m->m_flags & (M_BCAST|M_MCAST)) 1740 return (0); 1741 1742 PFSYNC_LOCK(sc); 1743 1744 if (sc == NULL || !(sc->sc_ifp->if_flags & IFF_DRV_RUNNING) || 1745 !(sc->sc_flags & PFSYNCF_DEFER)) { 1746 PFSYNC_UNLOCK(sc); 1747 return (0); 1748 } 1749 1750 if (b->b_deferred >= 128) 1751 pfsync_undefer(TAILQ_FIRST(&b->b_deferrals), 0); 1752 1753 pd = malloc(sizeof(*pd), M_PFSYNC, M_NOWAIT); 1754 if (pd == NULL) 1755 return (0); 1756 b->b_deferred++; 1757 1758 m->m_flags |= M_SKIP_FIREWALL; 1759 st->state_flags |= PFSTATE_ACK; 1760 1761 pd->pd_sc = sc; 1762 pd->pd_refs = 0; 1763 pd->pd_st = st; 1764 pf_ref_state(st); 1765 pd->pd_m = m; 1766 1767 TAILQ_INSERT_TAIL(&b->b_deferrals, pd, pd_entry); 1768 callout_init_mtx(&pd->pd_tmo, &b->b_mtx, CALLOUT_RETURNUNLOCKED); 1769 callout_reset(&pd->pd_tmo, 10, pfsync_defer_tmo, pd); 1770 1771 pfsync_push(b); 1772 1773 return (1); 1774 } 1775 1776 static void 1777 pfsync_undefer(struct pfsync_deferral *pd, int drop) 1778 { 1779 struct pfsync_softc *sc = pd->pd_sc; 1780 struct mbuf *m = pd->pd_m; 1781 struct pf_kstate *st = pd->pd_st; 1782 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 1783 1784 PFSYNC_BUCKET_LOCK_ASSERT(b); 1785 1786 TAILQ_REMOVE(&b->b_deferrals, pd, pd_entry); 1787 b->b_deferred--; 1788 pd->pd_st->state_flags &= ~PFSTATE_ACK; /* XXX: locking! */ 1789 free(pd, M_PFSYNC); 1790 pf_release_state(st); 1791 1792 if (drop) 1793 m_freem(m); 1794 else { 1795 _IF_ENQUEUE(&b->b_snd, m); 1796 pfsync_push(b); 1797 } 1798 } 1799 1800 static void 1801 pfsync_defer_tmo(void *arg) 1802 { 1803 struct epoch_tracker et; 1804 struct pfsync_deferral *pd = arg; 1805 struct pfsync_softc *sc = pd->pd_sc; 1806 struct mbuf *m = pd->pd_m; 1807 struct pf_kstate *st = pd->pd_st; 1808 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 1809 1810 PFSYNC_BUCKET_LOCK_ASSERT(b); 1811 1812 NET_EPOCH_ENTER(et); 1813 CURVNET_SET(m->m_pkthdr.rcvif->if_vnet); 1814 1815 TAILQ_REMOVE(&b->b_deferrals, pd, pd_entry); 1816 b->b_deferred--; 1817 pd->pd_st->state_flags &= ~PFSTATE_ACK; /* XXX: locking! */ 1818 if (pd->pd_refs == 0) 1819 free(pd, M_PFSYNC); 1820 PFSYNC_UNLOCK(sc); 1821 1822 ip_output(m, NULL, NULL, 0, NULL, NULL); 1823 1824 pf_release_state(st); 1825 1826 CURVNET_RESTORE(); 1827 NET_EPOCH_EXIT(et); 1828 } 1829 1830 static void 1831 pfsync_undefer_state(struct pf_kstate *st, int drop) 1832 { 1833 struct pfsync_softc *sc = V_pfsyncif; 1834 struct pfsync_deferral *pd; 1835 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 1836 1837 PFSYNC_BUCKET_LOCK(b); 1838 1839 TAILQ_FOREACH(pd, &b->b_deferrals, pd_entry) { 1840 if (pd->pd_st == st) { 1841 if (callout_stop(&pd->pd_tmo) > 0) 1842 pfsync_undefer(pd, drop); 1843 1844 PFSYNC_BUCKET_UNLOCK(b); 1845 return; 1846 } 1847 } 1848 PFSYNC_BUCKET_UNLOCK(b); 1849 1850 panic("%s: unable to find deferred state", __func__); 1851 } 1852 1853 static struct pfsync_bucket* 1854 pfsync_get_bucket(struct pfsync_softc *sc, struct pf_kstate *st) 1855 { 1856 int c = PF_IDHASH(st) % pfsync_buckets; 1857 return &sc->sc_buckets[c]; 1858 } 1859 1860 static void 1861 pfsync_update_state(struct pf_kstate *st) 1862 { 1863 struct pfsync_softc *sc = V_pfsyncif; 1864 bool sync = false, ref = true; 1865 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 1866 1867 PF_STATE_LOCK_ASSERT(st); 1868 PFSYNC_BUCKET_LOCK(b); 1869 1870 if (st->state_flags & PFSTATE_ACK) 1871 pfsync_undefer_state(st, 0); 1872 if (st->state_flags & PFSTATE_NOSYNC) { 1873 if (st->sync_state != PFSYNC_S_NONE) 1874 pfsync_q_del(st, true, b); 1875 PFSYNC_BUCKET_UNLOCK(b); 1876 return; 1877 } 1878 1879 if (b->b_len == PFSYNC_MINPKT) 1880 callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b); 1881 1882 switch (st->sync_state) { 1883 case PFSYNC_S_UPD_C: 1884 case PFSYNC_S_UPD: 1885 case PFSYNC_S_INS: 1886 /* we're already handling it */ 1887 1888 if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP) { 1889 st->sync_updates++; 1890 if (st->sync_updates >= sc->sc_maxupdates) 1891 sync = true; 1892 } 1893 break; 1894 1895 case PFSYNC_S_IACK: 1896 pfsync_q_del(st, false, b); 1897 ref = false; 1898 /* FALLTHROUGH */ 1899 1900 case PFSYNC_S_NONE: 1901 pfsync_q_ins(st, PFSYNC_S_UPD_C, ref); 1902 st->sync_updates = 0; 1903 break; 1904 1905 default: 1906 panic("%s: unexpected sync state %d", __func__, st->sync_state); 1907 } 1908 1909 if (sync || (time_uptime - st->pfsync_time) < 2) 1910 pfsync_push(b); 1911 1912 PFSYNC_BUCKET_UNLOCK(b); 1913 } 1914 1915 static void 1916 pfsync_request_update(u_int32_t creatorid, u_int64_t id) 1917 { 1918 struct pfsync_softc *sc = V_pfsyncif; 1919 struct pfsync_bucket *b = &sc->sc_buckets[0]; 1920 struct pfsync_upd_req_item *item; 1921 size_t nlen = sizeof(struct pfsync_upd_req); 1922 1923 PFSYNC_BUCKET_LOCK_ASSERT(b); 1924 1925 /* 1926 * This code does a bit to prevent multiple update requests for the 1927 * same state being generated. It searches current subheader queue, 1928 * but it doesn't lookup into queue of already packed datagrams. 1929 */ 1930 TAILQ_FOREACH(item, &b->b_upd_req_list, ur_entry) 1931 if (item->ur_msg.id == id && 1932 item->ur_msg.creatorid == creatorid) 1933 return; 1934 1935 item = malloc(sizeof(*item), M_PFSYNC, M_NOWAIT); 1936 if (item == NULL) 1937 return; /* XXX stats */ 1938 1939 item->ur_msg.id = id; 1940 item->ur_msg.creatorid = creatorid; 1941 1942 if (TAILQ_EMPTY(&b->b_upd_req_list)) 1943 nlen += sizeof(struct pfsync_subheader); 1944 1945 if (b->b_len + nlen > sc->sc_ifp->if_mtu) { 1946 pfsync_sendout(0, 0); 1947 1948 nlen = sizeof(struct pfsync_subheader) + 1949 sizeof(struct pfsync_upd_req); 1950 } 1951 1952 TAILQ_INSERT_TAIL(&b->b_upd_req_list, item, ur_entry); 1953 b->b_len += nlen; 1954 1955 pfsync_push(b); 1956 } 1957 1958 static bool 1959 pfsync_update_state_req(struct pf_kstate *st) 1960 { 1961 struct pfsync_softc *sc = V_pfsyncif; 1962 bool ref = true, full = false; 1963 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 1964 1965 PF_STATE_LOCK_ASSERT(st); 1966 PFSYNC_BUCKET_LOCK(b); 1967 1968 if (st->state_flags & PFSTATE_NOSYNC) { 1969 if (st->sync_state != PFSYNC_S_NONE) 1970 pfsync_q_del(st, true, b); 1971 PFSYNC_BUCKET_UNLOCK(b); 1972 return (full); 1973 } 1974 1975 switch (st->sync_state) { 1976 case PFSYNC_S_UPD_C: 1977 case PFSYNC_S_IACK: 1978 pfsync_q_del(st, false, b); 1979 ref = false; 1980 /* FALLTHROUGH */ 1981 1982 case PFSYNC_S_NONE: 1983 pfsync_q_ins(st, PFSYNC_S_UPD, ref); 1984 pfsync_push(b); 1985 break; 1986 1987 case PFSYNC_S_INS: 1988 case PFSYNC_S_UPD: 1989 case PFSYNC_S_DEL: 1990 /* we're already handling it */ 1991 break; 1992 1993 default: 1994 panic("%s: unexpected sync state %d", __func__, st->sync_state); 1995 } 1996 1997 if ((sc->sc_ifp->if_mtu - b->b_len) < sizeof(struct pfsync_state)) 1998 full = true; 1999 2000 PFSYNC_BUCKET_UNLOCK(b); 2001 2002 return (full); 2003 } 2004 2005 static void 2006 pfsync_delete_state(struct pf_kstate *st) 2007 { 2008 struct pfsync_softc *sc = V_pfsyncif; 2009 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 2010 bool ref = true; 2011 2012 PFSYNC_BUCKET_LOCK(b); 2013 if (st->state_flags & PFSTATE_ACK) 2014 pfsync_undefer_state(st, 1); 2015 if (st->state_flags & PFSTATE_NOSYNC) { 2016 if (st->sync_state != PFSYNC_S_NONE) 2017 pfsync_q_del(st, true, b); 2018 PFSYNC_BUCKET_UNLOCK(b); 2019 return; 2020 } 2021 2022 if (b->b_len == PFSYNC_MINPKT) 2023 callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b); 2024 2025 switch (st->sync_state) { 2026 case PFSYNC_S_INS: 2027 /* We never got to tell the world so just forget about it. */ 2028 pfsync_q_del(st, true, b); 2029 break; 2030 2031 case PFSYNC_S_UPD_C: 2032 case PFSYNC_S_UPD: 2033 case PFSYNC_S_IACK: 2034 pfsync_q_del(st, false, b); 2035 ref = false; 2036 /* FALLTHROUGH */ 2037 2038 case PFSYNC_S_NONE: 2039 pfsync_q_ins(st, PFSYNC_S_DEL, ref); 2040 break; 2041 2042 default: 2043 panic("%s: unexpected sync state %d", __func__, st->sync_state); 2044 } 2045 2046 PFSYNC_BUCKET_UNLOCK(b); 2047 } 2048 2049 static void 2050 pfsync_clear_states(u_int32_t creatorid, const char *ifname) 2051 { 2052 struct { 2053 struct pfsync_subheader subh; 2054 struct pfsync_clr clr; 2055 } __packed r; 2056 2057 bzero(&r, sizeof(r)); 2058 2059 r.subh.action = PFSYNC_ACT_CLR; 2060 r.subh.count = htons(1); 2061 V_pfsyncstats.pfsyncs_oacts[PFSYNC_ACT_CLR]++; 2062 2063 strlcpy(r.clr.ifname, ifname, sizeof(r.clr.ifname)); 2064 r.clr.creatorid = creatorid; 2065 2066 pfsync_send_plus(&r, sizeof(r)); 2067 } 2068 2069 static void 2070 pfsync_q_ins(struct pf_kstate *st, int q, bool ref) 2071 { 2072 struct pfsync_softc *sc = V_pfsyncif; 2073 size_t nlen = pfsync_qs[q].len; 2074 struct pfsync_bucket *b = pfsync_get_bucket(sc, st); 2075 2076 PFSYNC_BUCKET_LOCK_ASSERT(b); 2077 2078 KASSERT(st->sync_state == PFSYNC_S_NONE, 2079 ("%s: st->sync_state %u", __func__, st->sync_state)); 2080 KASSERT(b->b_len >= PFSYNC_MINPKT, ("pfsync pkt len is too low %zu", 2081 b->b_len)); 2082 2083 if (TAILQ_EMPTY(&b->b_qs[q])) 2084 nlen += sizeof(struct pfsync_subheader); 2085 2086 if (b->b_len + nlen > sc->sc_ifp->if_mtu) { 2087 pfsync_sendout(1, b->b_id); 2088 2089 nlen = sizeof(struct pfsync_subheader) + pfsync_qs[q].len; 2090 } 2091 2092 b->b_len += nlen; 2093 TAILQ_INSERT_TAIL(&b->b_qs[q], st, sync_list); 2094 st->sync_state = q; 2095 if (ref) 2096 pf_ref_state(st); 2097 } 2098 2099 static void 2100 pfsync_q_del(struct pf_kstate *st, bool unref, struct pfsync_bucket *b) 2101 { 2102 int q = st->sync_state; 2103 2104 PFSYNC_BUCKET_LOCK_ASSERT(b); 2105 KASSERT(st->sync_state != PFSYNC_S_NONE, 2106 ("%s: st->sync_state != PFSYNC_S_NONE", __func__)); 2107 2108 b->b_len -= pfsync_qs[q].len; 2109 TAILQ_REMOVE(&b->b_qs[q], st, sync_list); 2110 st->sync_state = PFSYNC_S_NONE; 2111 if (unref) 2112 pf_release_state(st); 2113 2114 if (TAILQ_EMPTY(&b->b_qs[q])) 2115 b->b_len -= sizeof(struct pfsync_subheader); 2116 } 2117 2118 static void 2119 pfsync_bulk_start(void) 2120 { 2121 struct pfsync_softc *sc = V_pfsyncif; 2122 2123 if (V_pf_status.debug >= PF_DEBUG_MISC) 2124 printf("pfsync: received bulk update request\n"); 2125 2126 PFSYNC_BLOCK(sc); 2127 2128 sc->sc_ureq_received = time_uptime; 2129 sc->sc_bulk_hashid = 0; 2130 sc->sc_bulk_stateid = 0; 2131 pfsync_bulk_status(PFSYNC_BUS_START); 2132 callout_reset(&sc->sc_bulk_tmo, 1, pfsync_bulk_update, sc); 2133 PFSYNC_BUNLOCK(sc); 2134 } 2135 2136 static void 2137 pfsync_bulk_update(void *arg) 2138 { 2139 struct pfsync_softc *sc = arg; 2140 struct pf_kstate *s; 2141 int i, sent = 0; 2142 2143 PFSYNC_BLOCK_ASSERT(sc); 2144 CURVNET_SET(sc->sc_ifp->if_vnet); 2145 2146 /* 2147 * Start with last state from previous invocation. 2148 * It may had gone, in this case start from the 2149 * hash slot. 2150 */ 2151 s = pf_find_state_byid(sc->sc_bulk_stateid, sc->sc_bulk_creatorid); 2152 2153 if (s != NULL) 2154 i = PF_IDHASH(s); 2155 else 2156 i = sc->sc_bulk_hashid; 2157 2158 for (; i <= pf_hashmask; i++) { 2159 struct pf_idhash *ih = &V_pf_idhash[i]; 2160 2161 if (s != NULL) 2162 PF_HASHROW_ASSERT(ih); 2163 else { 2164 PF_HASHROW_LOCK(ih); 2165 s = LIST_FIRST(&ih->states); 2166 } 2167 2168 for (; s; s = LIST_NEXT(s, entry)) { 2169 if (s->sync_state == PFSYNC_S_NONE && 2170 s->timeout < PFTM_MAX && 2171 s->pfsync_time <= sc->sc_ureq_received) { 2172 if (pfsync_update_state_req(s)) { 2173 /* We've filled a packet. */ 2174 sc->sc_bulk_hashid = i; 2175 sc->sc_bulk_stateid = s->id; 2176 sc->sc_bulk_creatorid = s->creatorid; 2177 PF_HASHROW_UNLOCK(ih); 2178 callout_reset(&sc->sc_bulk_tmo, 1, 2179 pfsync_bulk_update, sc); 2180 goto full; 2181 } 2182 sent++; 2183 } 2184 } 2185 PF_HASHROW_UNLOCK(ih); 2186 } 2187 2188 /* We're done. */ 2189 pfsync_bulk_status(PFSYNC_BUS_END); 2190 full: 2191 CURVNET_RESTORE(); 2192 } 2193 2194 static void 2195 pfsync_bulk_status(u_int8_t status) 2196 { 2197 struct { 2198 struct pfsync_subheader subh; 2199 struct pfsync_bus bus; 2200 } __packed r; 2201 2202 struct pfsync_softc *sc = V_pfsyncif; 2203 2204 bzero(&r, sizeof(r)); 2205 2206 r.subh.action = PFSYNC_ACT_BUS; 2207 r.subh.count = htons(1); 2208 V_pfsyncstats.pfsyncs_oacts[PFSYNC_ACT_BUS]++; 2209 2210 r.bus.creatorid = V_pf_status.hostid; 2211 r.bus.endtime = htonl(time_uptime - sc->sc_ureq_received); 2212 r.bus.status = status; 2213 2214 pfsync_send_plus(&r, sizeof(r)); 2215 } 2216 2217 static void 2218 pfsync_bulk_fail(void *arg) 2219 { 2220 struct pfsync_softc *sc = arg; 2221 struct pfsync_bucket *b = &sc->sc_buckets[0]; 2222 2223 CURVNET_SET(sc->sc_ifp->if_vnet); 2224 2225 PFSYNC_BLOCK_ASSERT(sc); 2226 2227 if (sc->sc_bulk_tries++ < PFSYNC_MAX_BULKTRIES) { 2228 /* Try again */ 2229 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, 2230 pfsync_bulk_fail, V_pfsyncif); 2231 PFSYNC_BUCKET_LOCK(b); 2232 pfsync_request_update(0, 0); 2233 PFSYNC_BUCKET_UNLOCK(b); 2234 } else { 2235 /* Pretend like the transfer was ok. */ 2236 sc->sc_ureq_sent = 0; 2237 sc->sc_bulk_tries = 0; 2238 PFSYNC_LOCK(sc); 2239 if (!(sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) 2240 (*carp_demote_adj_p)(-V_pfsync_carp_adj, 2241 "pfsync bulk fail"); 2242 sc->sc_flags |= PFSYNCF_OK; 2243 PFSYNC_UNLOCK(sc); 2244 if (V_pf_status.debug >= PF_DEBUG_MISC) 2245 printf("pfsync: failed to receive bulk update\n"); 2246 } 2247 2248 CURVNET_RESTORE(); 2249 } 2250 2251 static void 2252 pfsync_send_plus(void *plus, size_t pluslen) 2253 { 2254 struct pfsync_softc *sc = V_pfsyncif; 2255 struct pfsync_bucket *b = &sc->sc_buckets[0]; 2256 2257 PFSYNC_BUCKET_LOCK(b); 2258 2259 if (b->b_len + pluslen > sc->sc_ifp->if_mtu) 2260 pfsync_sendout(1, b->b_id); 2261 2262 b->b_plus = plus; 2263 b->b_len += (b->b_pluslen = pluslen); 2264 2265 pfsync_sendout(1, b->b_id); 2266 PFSYNC_BUCKET_UNLOCK(b); 2267 } 2268 2269 static void 2270 pfsync_timeout(void *arg) 2271 { 2272 struct pfsync_bucket *b = arg; 2273 2274 CURVNET_SET(b->b_sc->sc_ifp->if_vnet); 2275 PFSYNC_BUCKET_LOCK(b); 2276 pfsync_push(b); 2277 PFSYNC_BUCKET_UNLOCK(b); 2278 CURVNET_RESTORE(); 2279 } 2280 2281 static void 2282 pfsync_push(struct pfsync_bucket *b) 2283 { 2284 2285 PFSYNC_BUCKET_LOCK_ASSERT(b); 2286 2287 b->b_flags |= PFSYNCF_BUCKET_PUSH; 2288 swi_sched(V_pfsync_swi_cookie, 0); 2289 } 2290 2291 static void 2292 pfsync_push_all(struct pfsync_softc *sc) 2293 { 2294 int c; 2295 struct pfsync_bucket *b; 2296 2297 for (c = 0; c < pfsync_buckets; c++) { 2298 b = &sc->sc_buckets[c]; 2299 2300 PFSYNC_BUCKET_LOCK(b); 2301 pfsync_push(b); 2302 PFSYNC_BUCKET_UNLOCK(b); 2303 } 2304 } 2305 2306 static void 2307 pfsyncintr(void *arg) 2308 { 2309 struct epoch_tracker et; 2310 struct pfsync_softc *sc = arg; 2311 struct pfsync_bucket *b; 2312 struct mbuf *m, *n; 2313 int c; 2314 2315 NET_EPOCH_ENTER(et); 2316 CURVNET_SET(sc->sc_ifp->if_vnet); 2317 2318 for (c = 0; c < pfsync_buckets; c++) { 2319 b = &sc->sc_buckets[c]; 2320 2321 PFSYNC_BUCKET_LOCK(b); 2322 if ((b->b_flags & PFSYNCF_BUCKET_PUSH) && b->b_len > PFSYNC_MINPKT) { 2323 pfsync_sendout(0, b->b_id); 2324 b->b_flags &= ~PFSYNCF_BUCKET_PUSH; 2325 } 2326 _IF_DEQUEUE_ALL(&b->b_snd, m); 2327 PFSYNC_BUCKET_UNLOCK(b); 2328 2329 for (; m != NULL; m = n) { 2330 n = m->m_nextpkt; 2331 m->m_nextpkt = NULL; 2332 2333 /* 2334 * We distinguish between a deferral packet and our 2335 * own pfsync packet based on M_SKIP_FIREWALL 2336 * flag. This is XXX. 2337 */ 2338 if (m->m_flags & M_SKIP_FIREWALL) 2339 ip_output(m, NULL, NULL, 0, NULL, NULL); 2340 else if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, 2341 NULL) == 0) 2342 V_pfsyncstats.pfsyncs_opackets++; 2343 else 2344 V_pfsyncstats.pfsyncs_oerrors++; 2345 } 2346 } 2347 CURVNET_RESTORE(); 2348 NET_EPOCH_EXIT(et); 2349 } 2350 2351 static int 2352 pfsync_multicast_setup(struct pfsync_softc *sc, struct ifnet *ifp, 2353 struct in_mfilter *imf) 2354 { 2355 struct ip_moptions *imo = &sc->sc_imo; 2356 int error; 2357 2358 if (!(ifp->if_flags & IFF_MULTICAST)) 2359 return (EADDRNOTAVAIL); 2360 2361 imo->imo_multicast_vif = -1; 2362 2363 if ((error = in_joingroup(ifp, &sc->sc_sync_peer, NULL, 2364 &imf->imf_inm)) != 0) 2365 return (error); 2366 2367 ip_mfilter_init(&imo->imo_head); 2368 ip_mfilter_insert(&imo->imo_head, imf); 2369 imo->imo_multicast_ifp = ifp; 2370 imo->imo_multicast_ttl = PFSYNC_DFLTTL; 2371 imo->imo_multicast_loop = 0; 2372 2373 return (0); 2374 } 2375 2376 static void 2377 pfsync_multicast_cleanup(struct pfsync_softc *sc) 2378 { 2379 struct ip_moptions *imo = &sc->sc_imo; 2380 struct in_mfilter *imf; 2381 2382 while ((imf = ip_mfilter_first(&imo->imo_head)) != NULL) { 2383 ip_mfilter_remove(&imo->imo_head, imf); 2384 in_leavegroup(imf->imf_inm, NULL); 2385 ip_mfilter_free(imf); 2386 } 2387 imo->imo_multicast_ifp = NULL; 2388 } 2389 2390 void 2391 pfsync_detach_ifnet(struct ifnet *ifp) 2392 { 2393 struct pfsync_softc *sc = V_pfsyncif; 2394 2395 if (sc == NULL) 2396 return; 2397 2398 PFSYNC_LOCK(sc); 2399 2400 if (sc->sc_sync_if == ifp) { 2401 /* We don't need mutlicast cleanup here, because the interface 2402 * is going away. We do need to ensure we don't try to do 2403 * cleanup later. 2404 */ 2405 ip_mfilter_init(&sc->sc_imo.imo_head); 2406 sc->sc_imo.imo_multicast_ifp = NULL; 2407 sc->sc_sync_if = NULL; 2408 } 2409 2410 PFSYNC_UNLOCK(sc); 2411 } 2412 2413 #ifdef INET 2414 extern struct domain inetdomain; 2415 static struct protosw in_pfsync_protosw = { 2416 .pr_type = SOCK_RAW, 2417 .pr_domain = &inetdomain, 2418 .pr_protocol = IPPROTO_PFSYNC, 2419 .pr_flags = PR_ATOMIC|PR_ADDR, 2420 .pr_input = pfsync_input, 2421 .pr_output = rip_output, 2422 .pr_ctloutput = rip_ctloutput, 2423 .pr_usrreqs = &rip_usrreqs 2424 }; 2425 #endif 2426 2427 static void 2428 pfsync_pointers_init() 2429 { 2430 2431 PF_RULES_WLOCK(); 2432 V_pfsync_state_import_ptr = pfsync_state_import; 2433 V_pfsync_insert_state_ptr = pfsync_insert_state; 2434 V_pfsync_update_state_ptr = pfsync_update_state; 2435 V_pfsync_delete_state_ptr = pfsync_delete_state; 2436 V_pfsync_clear_states_ptr = pfsync_clear_states; 2437 V_pfsync_defer_ptr = pfsync_defer; 2438 PF_RULES_WUNLOCK(); 2439 } 2440 2441 static void 2442 pfsync_pointers_uninit() 2443 { 2444 2445 PF_RULES_WLOCK(); 2446 V_pfsync_state_import_ptr = NULL; 2447 V_pfsync_insert_state_ptr = NULL; 2448 V_pfsync_update_state_ptr = NULL; 2449 V_pfsync_delete_state_ptr = NULL; 2450 V_pfsync_clear_states_ptr = NULL; 2451 V_pfsync_defer_ptr = NULL; 2452 PF_RULES_WUNLOCK(); 2453 } 2454 2455 static void 2456 vnet_pfsync_init(const void *unused __unused) 2457 { 2458 int error; 2459 2460 V_pfsync_cloner = if_clone_simple(pfsyncname, 2461 pfsync_clone_create, pfsync_clone_destroy, 1); 2462 error = swi_add(&V_pfsync_swi_ie, pfsyncname, pfsyncintr, V_pfsyncif, 2463 SWI_NET, INTR_MPSAFE, &V_pfsync_swi_cookie); 2464 if (error) { 2465 if_clone_detach(V_pfsync_cloner); 2466 log(LOG_INFO, "swi_add() failed in %s\n", __func__); 2467 } 2468 2469 pfsync_pointers_init(); 2470 } 2471 VNET_SYSINIT(vnet_pfsync_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY, 2472 vnet_pfsync_init, NULL); 2473 2474 static void 2475 vnet_pfsync_uninit(const void *unused __unused) 2476 { 2477 int ret; 2478 2479 pfsync_pointers_uninit(); 2480 2481 if_clone_detach(V_pfsync_cloner); 2482 ret = swi_remove(V_pfsync_swi_cookie); 2483 MPASS(ret == 0); 2484 ret = intr_event_destroy(V_pfsync_swi_ie); 2485 MPASS(ret == 0); 2486 } 2487 2488 VNET_SYSUNINIT(vnet_pfsync_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_FOURTH, 2489 vnet_pfsync_uninit, NULL); 2490 2491 static int 2492 pfsync_init() 2493 { 2494 #ifdef INET 2495 int error; 2496 2497 pfsync_detach_ifnet_ptr = pfsync_detach_ifnet; 2498 2499 error = pf_proto_register(PF_INET, &in_pfsync_protosw); 2500 if (error) 2501 return (error); 2502 error = ipproto_register(IPPROTO_PFSYNC); 2503 if (error) { 2504 pf_proto_unregister(PF_INET, IPPROTO_PFSYNC, SOCK_RAW); 2505 return (error); 2506 } 2507 #endif 2508 2509 return (0); 2510 } 2511 2512 static void 2513 pfsync_uninit() 2514 { 2515 pfsync_detach_ifnet_ptr = NULL; 2516 2517 #ifdef INET 2518 ipproto_unregister(IPPROTO_PFSYNC); 2519 pf_proto_unregister(PF_INET, IPPROTO_PFSYNC, SOCK_RAW); 2520 #endif 2521 } 2522 2523 static int 2524 pfsync_modevent(module_t mod, int type, void *data) 2525 { 2526 int error = 0; 2527 2528 switch (type) { 2529 case MOD_LOAD: 2530 error = pfsync_init(); 2531 break; 2532 case MOD_UNLOAD: 2533 pfsync_uninit(); 2534 break; 2535 default: 2536 error = EINVAL; 2537 break; 2538 } 2539 2540 return (error); 2541 } 2542 2543 static moduledata_t pfsync_mod = { 2544 pfsyncname, 2545 pfsync_modevent, 2546 0 2547 }; 2548 2549 #define PFSYNC_MODVER 1 2550 2551 /* Stay on FIREWALL as we depend on pf being initialized and on inetdomain. */ 2552 DECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY); 2553 MODULE_VERSION(pfsync, PFSYNC_MODVER); 2554 MODULE_DEPEND(pfsync, pf, PF_MODVER, PF_MODVER, PF_MODVER); 2555