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