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