if_pfsync.c revision 191148
1/* $OpenBSD: if_pfsync.c,v 1.73 2006/11/16 13:13:38 henning Exp $ */ 2 3/* 4 * Copyright (c) 2002 Michael Shalayeff 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26 * THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#ifdef __FreeBSD__ 30#include "opt_inet.h" 31#include "opt_inet6.h" 32#include "opt_carp.h" 33#include "opt_bpf.h" 34#include "opt_pf.h" 35 36#include <sys/cdefs.h> 37__FBSDID("$FreeBSD: head/sys/contrib/pf/net/if_pfsync.c 191148 2009-04-16 20:30:28Z kmacy $"); 38 39#ifdef DEV_BPF 40#define NBPFILTER DEV_BPF 41#else 42#define NBPFILTER 0 43#endif 44 45#ifdef DEV_PFSYNC 46#define NPFSYNC DEV_PFSYNC 47#else 48#define NPFSYNC 0 49#endif 50 51#ifdef DEV_CARP 52#define NCARP DEV_CARP 53#else 54#define NCARP 0 55#endif 56#endif /* __FreeBSD__ */ 57 58#include <sys/param.h> 59#ifdef __FreeBSD__ 60#include <sys/priv.h> 61#endif 62#include <sys/proc.h> 63#include <sys/systm.h> 64#include <sys/time.h> 65#include <sys/mbuf.h> 66#include <sys/socket.h> 67#ifdef __FreeBSD__ 68#include <sys/endian.h> 69#include <sys/malloc.h> 70#include <sys/module.h> 71#include <sys/sockio.h> 72#include <sys/taskqueue.h> 73#include <sys/lock.h> 74#include <sys/mutex.h> 75#include <sys/sysctl.h> 76#else 77#include <sys/ioctl.h> 78#include <sys/timeout.h> 79#endif 80#include <sys/kernel.h> 81 82#include <net/if.h> 83#ifdef __FreeBSD__ 84#include <net/if_clone.h> 85#endif 86#include <net/if_types.h> 87#include <net/route.h> 88#include <net/bpf.h> 89#include <netinet/in.h> 90#include <netinet/if_ether.h> 91#include <netinet/tcp.h> 92#include <netinet/tcp_seq.h> 93 94#ifdef INET 95#include <netinet/in_systm.h> 96#include <netinet/in_var.h> 97#include <netinet/ip.h> 98#include <netinet/ip_var.h> 99#endif 100 101#ifdef INET6 102#include <netinet6/nd6.h> 103#endif /* INET6 */ 104 105#ifndef __FreeBSD__ 106#include "carp.h" 107#endif 108#if NCARP > 0 109#include <netinet/ip_carp.h> 110#endif 111 112#include <net/pfvar.h> 113#include <net/if_pfsync.h> 114 115#ifndef __FreeBSD__ 116#include "bpfilter.h" 117#include "pfsync.h" 118#endif 119 120#define PFSYNC_MINMTU \ 121 (sizeof(struct pfsync_header) + sizeof(struct pf_state)) 122 123#ifdef PFSYNCDEBUG 124#define DPRINTF(x) do { if (pfsyncdebug) printf x ; } while (0) 125int pfsyncdebug; 126#else 127#define DPRINTF(x) 128#endif 129 130struct pfsync_softc *pfsyncif = NULL; 131struct pfsyncstats pfsyncstats; 132#ifdef __FreeBSD__ 133SYSCTL_DECL(_net_inet_pfsync); 134SYSCTL_STRUCT(_net_inet_pfsync, 0, stats, CTLFLAG_RW, 135 &pfsyncstats, pfsyncstats, 136 "PFSYNC statistics (struct pfsyncstats, net/if_pfsync.h)"); 137#endif 138 139void pfsyncattach(int); 140#ifdef __FreeBSD__ 141int pfsync_clone_create(struct if_clone *, int, caddr_t); 142void pfsync_clone_destroy(struct ifnet *); 143#else 144int pfsync_clone_create(struct if_clone *, int); 145int pfsync_clone_destroy(struct ifnet *); 146#endif 147void pfsync_setmtu(struct pfsync_softc *, int); 148int pfsync_alloc_scrub_memory(struct pfsync_state_peer *, 149 struct pf_state_peer *); 150int pfsync_insert_net_state(struct pfsync_state *, u_int8_t); 151#ifdef PFSYNC_TDB 152void pfsync_update_net_tdb(struct pfsync_tdb *); 153#endif 154int pfsyncoutput(struct ifnet *, struct mbuf *, struct sockaddr *, 155 struct route *); 156int pfsyncioctl(struct ifnet *, u_long, caddr_t); 157void pfsyncstart(struct ifnet *); 158 159struct mbuf *pfsync_get_mbuf(struct pfsync_softc *, u_int8_t, void **); 160int pfsync_request_update(struct pfsync_state_upd *, struct in_addr *); 161int pfsync_sendout(struct pfsync_softc *); 162#ifdef PFSYNC_TDB 163int pfsync_tdb_sendout(struct pfsync_softc *); 164#endif 165int pfsync_sendout_mbuf(struct pfsync_softc *, struct mbuf *); 166void pfsync_timeout(void *); 167#ifdef PFSYNC_TDB 168void pfsync_tdb_timeout(void *); 169#endif 170void pfsync_send_bus(struct pfsync_softc *, u_int8_t); 171void pfsync_bulk_update(void *); 172void pfsync_bulkfail(void *); 173 174#ifdef __FreeBSD__ 175void pfsync_ifdetach(void *, struct ifnet *); 176void pfsync_senddef(void *, int); 177 178/* XXX: ugly */ 179#define betoh64 (unsigned long long)be64toh 180#define timeout_del callout_stop 181#endif 182 183int pfsync_sync_ok; 184#ifndef __FreeBSD__ 185extern int ifqmaxlen; 186#endif 187 188#ifdef __FreeBSD__ 189IFC_SIMPLE_DECLARE(pfsync, 1); 190#else 191struct if_clone pfsync_cloner = 192 IF_CLONE_INITIALIZER("pfsync", pfsync_clone_create, pfsync_clone_destroy); 193#endif 194 195void 196pfsyncattach(int npfsync) 197{ 198 if_clone_attach(&pfsync_cloner); 199} 200 201int 202#ifdef __FreeBSD__ 203pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t param) 204#else 205pfsync_clone_create(struct if_clone *ifc, int unit) 206#endif 207{ 208 struct ifnet *ifp; 209 210 if (unit != 0) 211 return (EINVAL); 212 213 pfsync_sync_ok = 1; 214 if ((pfsyncif = malloc(sizeof(*pfsyncif), M_DEVBUF, M_NOWAIT)) == NULL) 215 return (ENOMEM); 216 bzero(pfsyncif, sizeof(*pfsyncif)); 217#ifdef __FreeBSD__ 218 if ((pfsyncif->sc_imo.imo_membership = (struct in_multi **)malloc( 219 (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_DEVBUF, 220 M_NOWAIT)) == NULL) { 221 free(pfsyncif, M_DEVBUF); 222 return (ENOSPC); 223 } 224 pfsyncif->sc_imo.imo_mfilters = NULL; 225 pfsyncif->sc_imo.imo_max_memberships = IP_MIN_MEMBERSHIPS; 226 pfsyncif->sc_imo.imo_multicast_vif = -1; 227 228 ifp = pfsyncif->sc_ifp = if_alloc(IFT_PFSYNC); 229 if (ifp == NULL) { 230 free(pfsyncif->sc_imo.imo_membership, M_DEVBUF); 231 free(pfsyncif, M_DEVBUF); 232 return (ENOSPC); 233 } 234 if_initname(ifp, ifc->ifc_name, unit); 235 236 pfsyncif->sc_detachtag = EVENTHANDLER_REGISTER(ifnet_departure_event, 237 pfsync_ifdetach, pfsyncif, EVENTHANDLER_PRI_ANY); 238 if (pfsyncif->sc_detachtag == NULL) { 239 if_free(ifp); 240 free(pfsyncif->sc_imo.imo_membership, M_DEVBUF); 241 free(pfsyncif, M_DEVBUF); 242 return (ENOSPC); 243 } 244 245 pfsyncif->sc_ifq.ifq_maxlen = ifqmaxlen; 246 mtx_init(&pfsyncif->sc_ifq.ifq_mtx, ifp->if_xname, 247 "pfsync send queue", MTX_DEF); 248 TASK_INIT(&pfsyncif->sc_send_task, 0, pfsync_senddef, pfsyncif); 249#endif 250 pfsyncif->sc_mbuf = NULL; 251 pfsyncif->sc_mbuf_net = NULL; 252#ifdef PFSYNC_TDB 253 pfsyncif->sc_mbuf_tdb = NULL; 254#endif 255 pfsyncif->sc_statep.s = NULL; 256 pfsyncif->sc_statep_net.s = NULL; 257#ifdef PFSYNC_TDB 258 pfsyncif->sc_statep_tdb.t = NULL; 259#endif 260 pfsyncif->sc_maxupdates = 128; 261#ifdef __FreeBSD__ 262 pfsyncif->sc_sync_peer.s_addr = htonl(INADDR_PFSYNC_GROUP); 263 pfsyncif->sc_sendaddr.s_addr = htonl(INADDR_PFSYNC_GROUP); 264#else 265 pfsyncif->sc_sync_peer.s_addr = INADDR_PFSYNC_GROUP; 266 pfsyncif->sc_sendaddr.s_addr = INADDR_PFSYNC_GROUP; 267#endif 268 pfsyncif->sc_ureq_received = 0; 269 pfsyncif->sc_ureq_sent = 0; 270 pfsyncif->sc_bulk_send_next = NULL; 271 pfsyncif->sc_bulk_terminator = NULL; 272#ifndef __FreeBSD__ 273 ifp = &pfsyncif->sc_if; 274 snprintf(ifp->if_xname, sizeof ifp->if_xname, "pfsync%d", unit); 275#endif 276 ifp->if_softc = pfsyncif; 277 ifp->if_ioctl = pfsyncioctl; 278 ifp->if_output = pfsyncoutput; 279 ifp->if_start = pfsyncstart; 280 ifp->if_type = IFT_PFSYNC; 281 ifp->if_snd.ifq_maxlen = ifqmaxlen; 282 ifp->if_hdrlen = PFSYNC_HDRLEN; 283 pfsync_setmtu(pfsyncif, ETHERMTU); 284#ifdef __FreeBSD__ 285 callout_init(&pfsyncif->sc_tmo, CALLOUT_MPSAFE); 286#ifdef PFSYNC_TDB 287 callout_init(&pfsyncif->sc_tdb_tmo, CALLOUT_MPSAFE); 288#endif 289 callout_init(&pfsyncif->sc_bulk_tmo, CALLOUT_MPSAFE); 290 callout_init(&pfsyncif->sc_bulkfail_tmo, CALLOUT_MPSAFE); 291#else 292 timeout_set(&pfsyncif->sc_tmo, pfsync_timeout, pfsyncif); 293 timeout_set(&pfsyncif->sc_tdb_tmo, pfsync_tdb_timeout, pfsyncif); 294 timeout_set(&pfsyncif->sc_bulk_tmo, pfsync_bulk_update, pfsyncif); 295 timeout_set(&pfsyncif->sc_bulkfail_tmo, pfsync_bulkfail, pfsyncif); 296#endif 297 if_attach(ifp); 298#ifndef __FreeBSD__ 299 if_alloc_sadl(ifp); 300#endif 301 302#if NCARP > 0 303 if_addgroup(ifp, "carp"); 304#endif 305 306#if NBPFILTER > 0 307#ifdef __FreeBSD__ 308 bpfattach(ifp, DLT_PFSYNC, PFSYNC_HDRLEN); 309#else 310 bpfattach(&pfsyncif->sc_if.if_bpf, ifp, DLT_PFSYNC, PFSYNC_HDRLEN); 311#endif 312#endif 313 314 return (0); 315} 316 317#ifdef __FreeBSD__ 318void 319#else 320int 321#endif 322pfsync_clone_destroy(struct ifnet *ifp) 323{ 324#ifdef __FreeBSD__ 325 EVENTHANDLER_DEREGISTER(ifnet_departure_event, pfsyncif->sc_detachtag); 326 callout_stop(&pfsyncif->sc_tmo); 327#ifdef PFSYNC_TDB 328 callout_stop(&pfsyncif->sc_tdb_tmo); 329#endif 330 callout_stop(&pfsyncif->sc_bulk_tmo); 331 callout_stop(&pfsyncif->sc_bulkfail_tmo); 332 /* XXX: more? */ 333#endif 334 335#if NBPFILTER > 0 336 bpfdetach(ifp); 337#endif 338 if_detach(ifp); 339#ifdef __FreeBSD__ 340 if_free(ifp); 341 free(pfsyncif->sc_imo.imo_membership, M_DEVBUF); 342#endif 343 free(pfsyncif, M_DEVBUF); 344 pfsyncif = NULL; 345#ifndef __FreeBSD__ 346 return (0); 347#endif 348} 349 350/* 351 * Start output on the pfsync interface. 352 */ 353void 354pfsyncstart(struct ifnet *ifp) 355{ 356 struct mbuf *m; 357#ifndef __FreeBSD__ 358 int s; 359#endif 360 361 for (;;) { 362#ifdef __FreeBSD__ 363 IF_LOCK(&ifp->if_snd); 364 _IF_DROP(&ifp->if_snd); 365 _IF_DEQUEUE(&ifp->if_snd, m); 366 IF_UNLOCK(&ifp->if_snd); 367#else 368 s = splnet(); 369 IF_DROP(&ifp->if_snd); 370 IF_DEQUEUE(&ifp->if_snd, m); 371 splx(s); 372#endif 373 374 if (m == NULL) 375 return; 376 else 377 m_freem(m); 378 } 379} 380 381int 382pfsync_alloc_scrub_memory(struct pfsync_state_peer *s, 383 struct pf_state_peer *d) 384{ 385 if (s->scrub.scrub_flag && d->scrub == NULL) { 386 d->scrub = pool_get(&pf_state_scrub_pl, PR_NOWAIT); 387 if (d->scrub == NULL) 388 return (ENOMEM); 389 bzero(d->scrub, sizeof(*d->scrub)); 390 } 391 392 return (0); 393} 394 395int 396pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag) 397{ 398 struct pf_state *st = NULL; 399 struct pf_rule *r = NULL; 400 struct pfi_kif *kif; 401 402 if (sp->creatorid == 0 && pf_status.debug >= PF_DEBUG_MISC) { 403 printf("pfsync_insert_net_state: invalid creator id:" 404 " %08x\n", ntohl(sp->creatorid)); 405 return (EINVAL); 406 } 407 408 kif = pfi_kif_get(sp->ifname); 409 if (kif == NULL) { 410 if (pf_status.debug >= PF_DEBUG_MISC) 411 printf("pfsync_insert_net_state: " 412 "unknown interface: %s\n", sp->ifname); 413 /* skip this state */ 414 return (0); 415 } 416 417 /* 418 * If the ruleset checksums match, it's safe to associate the state 419 * with the rule of that number. 420 */ 421 if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) && chksum_flag) 422 r = pf_main_ruleset.rules[ 423 PF_RULESET_FILTER].active.ptr_array[ntohl(sp->rule)]; 424 else 425 r = &pf_default_rule; 426 427 if (!r->max_states || r->states < r->max_states) 428 st = pool_get(&pf_state_pl, PR_NOWAIT); 429 if (st == NULL) { 430 pfi_kif_unref(kif, PFI_KIF_REF_NONE); 431 return (ENOMEM); 432 } 433 bzero(st, sizeof(*st)); 434 435 /* allocate memory for scrub info */ 436 if (pfsync_alloc_scrub_memory(&sp->src, &st->src) || 437 pfsync_alloc_scrub_memory(&sp->dst, &st->dst)) { 438 pfi_kif_unref(kif, PFI_KIF_REF_NONE); 439 if (st->src.scrub) 440 pool_put(&pf_state_scrub_pl, st->src.scrub); 441 pool_put(&pf_state_pl, st); 442 return (ENOMEM); 443 } 444 445 st->rule.ptr = r; 446 /* XXX get pointers to nat_rule and anchor */ 447 448 /* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */ 449 r->states++; 450 451 /* fill in the rest of the state entry */ 452 pf_state_host_ntoh(&sp->lan, &st->lan); 453 pf_state_host_ntoh(&sp->gwy, &st->gwy); 454 pf_state_host_ntoh(&sp->ext, &st->ext); 455 456 pf_state_peer_ntoh(&sp->src, &st->src); 457 pf_state_peer_ntoh(&sp->dst, &st->dst); 458 459 bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr)); 460 st->creation = time_second - ntohl(sp->creation); 461 st->expire = ntohl(sp->expire) + time_second; 462 463 st->af = sp->af; 464 st->proto = sp->proto; 465 st->direction = sp->direction; 466 st->log = sp->log; 467 st->timeout = sp->timeout; 468 st->allow_opts = sp->allow_opts; 469 470 bcopy(sp->id, &st->id, sizeof(st->id)); 471 st->creatorid = sp->creatorid; 472 st->sync_flags = PFSTATE_FROMSYNC; 473 474 if (pf_insert_state(kif, st)) { 475 pfi_kif_unref(kif, PFI_KIF_REF_NONE); 476 /* XXX when we have nat_rule/anchors, use STATE_DEC_COUNTERS */ 477 r->states--; 478 if (st->dst.scrub) 479 pool_put(&pf_state_scrub_pl, st->dst.scrub); 480 if (st->src.scrub) 481 pool_put(&pf_state_scrub_pl, st->src.scrub); 482 pool_put(&pf_state_pl, st); 483 return (EINVAL); 484 } 485 486 return (0); 487} 488 489void 490#ifdef __FreeBSD__ 491pfsync_input(struct mbuf *m, __unused int off) 492#else 493pfsync_input(struct mbuf *m, ...) 494#endif 495{ 496 struct ip *ip = mtod(m, struct ip *); 497 struct pfsync_header *ph; 498 struct pfsync_softc *sc = pfsyncif; 499 struct pf_state *st; 500 struct pf_state_cmp key; 501 struct pfsync_state *sp; 502 struct pfsync_state_upd *up; 503 struct pfsync_state_del *dp; 504 struct pfsync_state_clr *cp; 505 struct pfsync_state_upd_req *rup; 506 struct pfsync_state_bus *bus; 507#ifdef PFSYNC_TDB 508 struct pfsync_tdb *pt; 509#endif 510 struct in_addr src; 511 struct mbuf *mp; 512 int iplen, action, error, i, s, count, offp, sfail, stale = 0; 513 u_int8_t chksum_flag = 0; 514 515 pfsyncstats.pfsyncs_ipackets++; 516 517 /* verify that we have a sync interface configured */ 518 if (!sc || !sc->sc_sync_ifp || !pf_status.running) 519 goto done; 520 521 /* verify that the packet came in on the right interface */ 522 if (sc->sc_sync_ifp != m->m_pkthdr.rcvif) { 523 pfsyncstats.pfsyncs_badif++; 524 goto done; 525 } 526 527 /* verify that the IP TTL is 255. */ 528 if (ip->ip_ttl != PFSYNC_DFLTTL) { 529 pfsyncstats.pfsyncs_badttl++; 530 goto done; 531 } 532 533 iplen = ip->ip_hl << 2; 534 535 if (m->m_pkthdr.len < iplen + sizeof(*ph)) { 536 pfsyncstats.pfsyncs_hdrops++; 537 goto done; 538 } 539 540 if (iplen + sizeof(*ph) > m->m_len) { 541 if ((m = m_pullup(m, iplen + sizeof(*ph))) == NULL) { 542 pfsyncstats.pfsyncs_hdrops++; 543 goto done; 544 } 545 ip = mtod(m, struct ip *); 546 } 547 ph = (struct pfsync_header *)((char *)ip + iplen); 548 549 /* verify the version */ 550 if (ph->version != PFSYNC_VERSION) { 551 pfsyncstats.pfsyncs_badver++; 552 goto done; 553 } 554 555 action = ph->action; 556 count = ph->count; 557 558 /* make sure it's a valid action code */ 559 if (action >= PFSYNC_ACT_MAX) { 560 pfsyncstats.pfsyncs_badact++; 561 goto done; 562 } 563 564 /* Cheaper to grab this now than having to mess with mbufs later */ 565 src = ip->ip_src; 566 567 if (!bcmp(&ph->pf_chksum, &pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH)) 568 chksum_flag++; 569 570 switch (action) { 571 case PFSYNC_ACT_CLR: { 572 struct pf_state *nexts; 573 struct pfi_kif *kif; 574 u_int32_t creatorid; 575 if ((mp = m_pulldown(m, iplen + sizeof(*ph), 576 sizeof(*cp), &offp)) == NULL) { 577 pfsyncstats.pfsyncs_badlen++; 578 return; 579 } 580 cp = (struct pfsync_state_clr *)(mp->m_data + offp); 581 creatorid = cp->creatorid; 582 583 s = splsoftnet(); 584#ifdef __FreeBSD__ 585 PF_LOCK(); 586#endif 587 if (cp->ifname[0] == '\0') { 588 for (st = RB_MIN(pf_state_tree_id, &tree_id); 589 st; st = nexts) { 590 nexts = RB_NEXT(pf_state_tree_id, &tree_id, st); 591 if (st->creatorid == creatorid) { 592 st->sync_flags |= PFSTATE_FROMSYNC; 593 pf_unlink_state(st); 594 } 595 } 596 } else { 597 if ((kif = pfi_kif_get(cp->ifname)) == NULL) { 598#ifdef __FreeBSD__ 599 PF_UNLOCK(); 600#endif 601 splx(s); 602 return; 603 } 604 for (st = RB_MIN(pf_state_tree_lan_ext, 605 &kif->pfik_lan_ext); st; st = nexts) { 606 nexts = RB_NEXT(pf_state_tree_lan_ext, 607 &kif->pfik_lan_ext, st); 608 if (st->creatorid == creatorid) { 609 st->sync_flags |= PFSTATE_FROMSYNC; 610 pf_unlink_state(st); 611 } 612 } 613 } 614#ifdef __FreeBSD__ 615 PF_UNLOCK(); 616#endif 617 splx(s); 618 619 break; 620 } 621 case PFSYNC_ACT_INS: 622 if ((mp = m_pulldown(m, iplen + sizeof(*ph), 623 count * sizeof(*sp), &offp)) == NULL) { 624 pfsyncstats.pfsyncs_badlen++; 625 return; 626 } 627 628 s = splsoftnet(); 629#ifdef __FreeBSD__ 630 PF_LOCK(); 631#endif 632 for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp); 633 i < count; i++, sp++) { 634 /* check for invalid values */ 635 if (sp->timeout >= PFTM_MAX || 636 sp->src.state > PF_TCPS_PROXY_DST || 637 sp->dst.state > PF_TCPS_PROXY_DST || 638 sp->direction > PF_OUT || 639 (sp->af != AF_INET && sp->af != AF_INET6)) { 640 if (pf_status.debug >= PF_DEBUG_MISC) 641 printf("pfsync_insert: PFSYNC_ACT_INS: " 642 "invalid value\n"); 643 pfsyncstats.pfsyncs_badstate++; 644 continue; 645 } 646 647 if ((error = pfsync_insert_net_state(sp, 648 chksum_flag))) { 649 if (error == ENOMEM) { 650#ifdef __FreeBSD__ 651 PF_UNLOCK(); 652#endif 653 splx(s); 654 goto done; 655 } 656 continue; 657 } 658 } 659#ifdef __FreeBSD__ 660 PF_UNLOCK(); 661#endif 662 splx(s); 663 break; 664 case PFSYNC_ACT_UPD: 665 if ((mp = m_pulldown(m, iplen + sizeof(*ph), 666 count * sizeof(*sp), &offp)) == NULL) { 667 pfsyncstats.pfsyncs_badlen++; 668 return; 669 } 670 671 s = splsoftnet(); 672#ifdef __FreeBSD__ 673 PF_LOCK(); 674#endif 675 for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp); 676 i < count; i++, sp++) { 677 int flags = PFSYNC_FLAG_STALE; 678 679 /* check for invalid values */ 680 if (sp->timeout >= PFTM_MAX || 681 sp->src.state > PF_TCPS_PROXY_DST || 682 sp->dst.state > PF_TCPS_PROXY_DST) { 683 if (pf_status.debug >= PF_DEBUG_MISC) 684 printf("pfsync_insert: PFSYNC_ACT_UPD: " 685 "invalid value\n"); 686 pfsyncstats.pfsyncs_badstate++; 687 continue; 688 } 689 690 bcopy(sp->id, &key.id, sizeof(key.id)); 691 key.creatorid = sp->creatorid; 692 693 st = pf_find_state_byid(&key); 694 if (st == NULL) { 695 /* insert the update */ 696 if (pfsync_insert_net_state(sp, chksum_flag)) 697 pfsyncstats.pfsyncs_badstate++; 698 continue; 699 } 700 sfail = 0; 701 if (st->proto == IPPROTO_TCP) { 702 /* 703 * The state should never go backwards except 704 * for syn-proxy states. Neither should the 705 * sequence window slide backwards. 706 */ 707 if (st->src.state > sp->src.state && 708 (st->src.state < PF_TCPS_PROXY_SRC || 709 sp->src.state >= PF_TCPS_PROXY_SRC)) 710 sfail = 1; 711 else if (SEQ_GT(st->src.seqlo, 712 ntohl(sp->src.seqlo))) 713 sfail = 3; 714 else if (st->dst.state > sp->dst.state) { 715 /* There might still be useful 716 * information about the src state here, 717 * so import that part of the update, 718 * then "fail" so we send the updated 719 * state back to the peer who is missing 720 * our what we know. */ 721 pf_state_peer_ntoh(&sp->src, &st->src); 722 /* XXX do anything with timeouts? */ 723 sfail = 7; 724 flags = 0; 725 } else if (st->dst.state >= TCPS_SYN_SENT && 726 SEQ_GT(st->dst.seqlo, ntohl(sp->dst.seqlo))) 727 sfail = 4; 728 } else { 729 /* 730 * Non-TCP protocol state machine always go 731 * forwards 732 */ 733 if (st->src.state > sp->src.state) 734 sfail = 5; 735 else if (st->dst.state > sp->dst.state) 736 sfail = 6; 737 } 738 if (sfail) { 739 if (pf_status.debug >= PF_DEBUG_MISC) 740 printf("pfsync: %s stale update " 741 "(%d) id: %016llx " 742 "creatorid: %08x\n", 743 (sfail < 7 ? "ignoring" 744 : "partial"), sfail, 745 betoh64(st->id), 746 ntohl(st->creatorid)); 747 pfsyncstats.pfsyncs_badstate++; 748 749 if (!(sp->sync_flags & PFSTATE_STALE)) { 750 /* we have a better state, send it */ 751 if (sc->sc_mbuf != NULL && !stale) 752 pfsync_sendout(sc); 753 stale++; 754 if (!st->sync_flags) 755 pfsync_pack_state( 756 PFSYNC_ACT_UPD, st, flags); 757 } 758 continue; 759 } 760 pfsync_alloc_scrub_memory(&sp->dst, &st->dst); 761 pf_state_peer_ntoh(&sp->src, &st->src); 762 pf_state_peer_ntoh(&sp->dst, &st->dst); 763 st->expire = ntohl(sp->expire) + time_second; 764 st->timeout = sp->timeout; 765 } 766 if (stale && sc->sc_mbuf != NULL) 767 pfsync_sendout(sc); 768#ifdef __FreeBSD__ 769 PF_UNLOCK(); 770#endif 771 splx(s); 772 break; 773 /* 774 * It's not strictly necessary for us to support the "uncompressed" 775 * delete action, but it's relatively simple and maintains consistency. 776 */ 777 case PFSYNC_ACT_DEL: 778 if ((mp = m_pulldown(m, iplen + sizeof(*ph), 779 count * sizeof(*sp), &offp)) == NULL) { 780 pfsyncstats.pfsyncs_badlen++; 781 return; 782 } 783 784 s = splsoftnet(); 785#ifdef __FreeBSD__ 786 PF_LOCK(); 787#endif 788 for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp); 789 i < count; i++, sp++) { 790 bcopy(sp->id, &key.id, sizeof(key.id)); 791 key.creatorid = sp->creatorid; 792 793 st = pf_find_state_byid(&key); 794 if (st == NULL) { 795 pfsyncstats.pfsyncs_badstate++; 796 continue; 797 } 798 st->sync_flags |= PFSTATE_FROMSYNC; 799 pf_unlink_state(st); 800 } 801#ifdef __FreeBSD__ 802 PF_UNLOCK(); 803#endif 804 splx(s); 805 break; 806 case PFSYNC_ACT_UPD_C: { 807 int update_requested = 0; 808 809 if ((mp = m_pulldown(m, iplen + sizeof(*ph), 810 count * sizeof(*up), &offp)) == NULL) { 811 pfsyncstats.pfsyncs_badlen++; 812 return; 813 } 814 815 s = splsoftnet(); 816#ifdef __FreeBSD__ 817 PF_LOCK(); 818#endif 819 for (i = 0, up = (struct pfsync_state_upd *)(mp->m_data + offp); 820 i < count; i++, up++) { 821 /* check for invalid values */ 822 if (up->timeout >= PFTM_MAX || 823 up->src.state > PF_TCPS_PROXY_DST || 824 up->dst.state > PF_TCPS_PROXY_DST) { 825 if (pf_status.debug >= PF_DEBUG_MISC) 826 printf("pfsync_insert: " 827 "PFSYNC_ACT_UPD_C: " 828 "invalid value\n"); 829 pfsyncstats.pfsyncs_badstate++; 830 continue; 831 } 832 833 bcopy(up->id, &key.id, sizeof(key.id)); 834 key.creatorid = up->creatorid; 835 836 st = pf_find_state_byid(&key); 837 if (st == NULL) { 838 /* We don't have this state. Ask for it. */ 839 error = pfsync_request_update(up, &src); 840 if (error == ENOMEM) { 841#ifdef __FreeBSD__ 842 PF_UNLOCK(); 843#endif 844 splx(s); 845 goto done; 846 } 847 update_requested = 1; 848 pfsyncstats.pfsyncs_badstate++; 849 continue; 850 } 851 sfail = 0; 852 if (st->proto == IPPROTO_TCP) { 853 /* 854 * The state should never go backwards except 855 * for syn-proxy states. Neither should the 856 * sequence window slide backwards. 857 */ 858 if (st->src.state > up->src.state && 859 (st->src.state < PF_TCPS_PROXY_SRC || 860 up->src.state >= PF_TCPS_PROXY_SRC)) 861 sfail = 1; 862 else if (st->dst.state > up->dst.state) 863 sfail = 2; 864 else if (SEQ_GT(st->src.seqlo, 865 ntohl(up->src.seqlo))) 866 sfail = 3; 867 else if (st->dst.state >= TCPS_SYN_SENT && 868 SEQ_GT(st->dst.seqlo, ntohl(up->dst.seqlo))) 869 sfail = 4; 870 } else { 871 /* 872 * Non-TCP protocol state machine always go 873 * forwards 874 */ 875 if (st->src.state > up->src.state) 876 sfail = 5; 877 else if (st->dst.state > up->dst.state) 878 sfail = 6; 879 } 880 if (sfail) { 881 if (pf_status.debug >= PF_DEBUG_MISC) 882 printf("pfsync: ignoring stale update " 883 "(%d) id: %016llx " 884 "creatorid: %08x\n", sfail, 885 betoh64(st->id), 886 ntohl(st->creatorid)); 887 pfsyncstats.pfsyncs_badstate++; 888 889 /* we have a better state, send it out */ 890 if ((!stale || update_requested) && 891 sc->sc_mbuf != NULL) { 892 pfsync_sendout(sc); 893 update_requested = 0; 894 } 895 stale++; 896 if (!st->sync_flags) 897 pfsync_pack_state(PFSYNC_ACT_UPD, st, 898 PFSYNC_FLAG_STALE); 899 continue; 900 } 901 pfsync_alloc_scrub_memory(&up->dst, &st->dst); 902 pf_state_peer_ntoh(&up->src, &st->src); 903 pf_state_peer_ntoh(&up->dst, &st->dst); 904 st->expire = ntohl(up->expire) + time_second; 905 st->timeout = up->timeout; 906 } 907 if ((update_requested || stale) && sc->sc_mbuf) 908 pfsync_sendout(sc); 909#ifdef __FreeBSD__ 910 PF_UNLOCK(); 911#endif 912 splx(s); 913 break; 914 } 915 case PFSYNC_ACT_DEL_C: 916 if ((mp = m_pulldown(m, iplen + sizeof(*ph), 917 count * sizeof(*dp), &offp)) == NULL) { 918 pfsyncstats.pfsyncs_badlen++; 919 return; 920 } 921 922 s = splsoftnet(); 923#ifdef __FreeBSD__ 924 PF_LOCK(); 925#endif 926 for (i = 0, dp = (struct pfsync_state_del *)(mp->m_data + offp); 927 i < count; i++, dp++) { 928 bcopy(dp->id, &key.id, sizeof(key.id)); 929 key.creatorid = dp->creatorid; 930 931 st = pf_find_state_byid(&key); 932 if (st == NULL) { 933 pfsyncstats.pfsyncs_badstate++; 934 continue; 935 } 936 st->sync_flags |= PFSTATE_FROMSYNC; 937 pf_unlink_state(st); 938 } 939#ifdef __FreeBSD__ 940 PF_UNLOCK(); 941#endif 942 splx(s); 943 break; 944 case PFSYNC_ACT_INS_F: 945 case PFSYNC_ACT_DEL_F: 946 /* not implemented */ 947 break; 948 case PFSYNC_ACT_UREQ: 949 if ((mp = m_pulldown(m, iplen + sizeof(*ph), 950 count * sizeof(*rup), &offp)) == NULL) { 951 pfsyncstats.pfsyncs_badlen++; 952 return; 953 } 954 955 s = splsoftnet(); 956#ifdef __FreeBSD__ 957 PF_LOCK(); 958#endif 959 if (sc->sc_mbuf != NULL) 960 pfsync_sendout(sc); 961 for (i = 0, 962 rup = (struct pfsync_state_upd_req *)(mp->m_data + offp); 963 i < count; i++, rup++) { 964 bcopy(rup->id, &key.id, sizeof(key.id)); 965 key.creatorid = rup->creatorid; 966 967 if (key.id == 0 && key.creatorid == 0) { 968 sc->sc_ureq_received = time_uptime; 969 if (sc->sc_bulk_send_next == NULL) 970 sc->sc_bulk_send_next = 971 TAILQ_FIRST(&state_list); 972 sc->sc_bulk_terminator = sc->sc_bulk_send_next; 973 if (pf_status.debug >= PF_DEBUG_MISC) 974 printf("pfsync: received " 975 "bulk update request\n"); 976 pfsync_send_bus(sc, PFSYNC_BUS_START); 977#ifdef __FreeBSD__ 978 callout_reset(&sc->sc_bulk_tmo, 1 * hz, 979 pfsync_bulk_update, pfsyncif); 980#else 981 timeout_add(&sc->sc_bulk_tmo, 1 * hz); 982#endif 983 } else { 984 st = pf_find_state_byid(&key); 985 if (st == NULL) { 986 pfsyncstats.pfsyncs_badstate++; 987 continue; 988 } 989 if (!st->sync_flags) 990 pfsync_pack_state(PFSYNC_ACT_UPD, 991 st, 0); 992 } 993 } 994 if (sc->sc_mbuf != NULL) 995 pfsync_sendout(sc); 996#ifdef __FreeBSD__ 997 PF_UNLOCK(); 998#endif 999 splx(s); 1000 break; 1001 case PFSYNC_ACT_BUS: 1002 /* If we're not waiting for a bulk update, who cares. */ 1003 if (sc->sc_ureq_sent == 0) 1004 break; 1005 1006 if ((mp = m_pulldown(m, iplen + sizeof(*ph), 1007 sizeof(*bus), &offp)) == NULL) { 1008 pfsyncstats.pfsyncs_badlen++; 1009 return; 1010 } 1011 bus = (struct pfsync_state_bus *)(mp->m_data + offp); 1012 switch (bus->status) { 1013 case PFSYNC_BUS_START: 1014#ifdef __FreeBSD__ 1015 callout_reset(&sc->sc_bulkfail_tmo, 1016 pf_pool_limits[PF_LIMIT_STATES].limit / 1017 (PFSYNC_BULKPACKETS * sc->sc_maxcount), 1018 pfsync_bulkfail, pfsyncif); 1019#else 1020 timeout_add(&sc->sc_bulkfail_tmo, 1021 pf_pool_limits[PF_LIMIT_STATES].limit / 1022 (PFSYNC_BULKPACKETS * sc->sc_maxcount)); 1023#endif 1024 if (pf_status.debug >= PF_DEBUG_MISC) 1025 printf("pfsync: received bulk " 1026 "update start\n"); 1027 break; 1028 case PFSYNC_BUS_END: 1029 if (time_uptime - ntohl(bus->endtime) >= 1030 sc->sc_ureq_sent) { 1031 /* that's it, we're happy */ 1032 sc->sc_ureq_sent = 0; 1033 sc->sc_bulk_tries = 0; 1034 timeout_del(&sc->sc_bulkfail_tmo); 1035#if NCARP > 0 1036 if (!pfsync_sync_ok) 1037#ifdef __FreeBSD__ 1038#ifdef CARP_ADVANCED 1039 carp_group_demote_adj(sc->sc_ifp, -1); 1040#endif 1041#else 1042 carp_group_demote_adj(&sc->sc_if, -1); 1043#endif 1044#endif 1045 pfsync_sync_ok = 1; 1046 if (pf_status.debug >= PF_DEBUG_MISC) 1047 printf("pfsync: received valid " 1048 "bulk update end\n"); 1049 } else { 1050 if (pf_status.debug >= PF_DEBUG_MISC) 1051 printf("pfsync: received invalid " 1052 "bulk update end: bad timestamp\n"); 1053 } 1054 break; 1055 } 1056 break; 1057#ifdef PFSYNC_TDB 1058 case PFSYNC_ACT_TDB_UPD: 1059 if ((mp = m_pulldown(m, iplen + sizeof(*ph), 1060 count * sizeof(*pt), &offp)) == NULL) { 1061 pfsyncstats.pfsyncs_badlen++; 1062 return; 1063 } 1064 s = splsoftnet(); 1065#ifdef __FreeBSD__ 1066 PF_LOCK(); 1067#endif 1068 for (i = 0, pt = (struct pfsync_tdb *)(mp->m_data + offp); 1069 i < count; i++, pt++) 1070 pfsync_update_net_tdb(pt); 1071#ifdef __FreeBSD__ 1072 PF_UNLOCK(); 1073#endif 1074 splx(s); 1075 break; 1076#endif 1077 } 1078 1079done: 1080 if (m) 1081 m_freem(m); 1082} 1083 1084int 1085pfsyncoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 1086 struct route *ro) 1087{ 1088 m_freem(m); 1089 return (0); 1090} 1091 1092/* ARGSUSED */ 1093int 1094pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1095{ 1096#ifndef __FreeBSD__ 1097 struct proc *p = curproc; 1098#endif 1099 struct pfsync_softc *sc = ifp->if_softc; 1100 struct ifreq *ifr = (struct ifreq *)data; 1101 struct ip_moptions *imo = &sc->sc_imo; 1102 struct pfsyncreq pfsyncr; 1103 struct ifnet *sifp; 1104 int s, error; 1105 1106 switch (cmd) { 1107 case SIOCSIFADDR: 1108 case SIOCAIFADDR: 1109 case SIOCSIFDSTADDR: 1110 case SIOCSIFFLAGS: 1111#ifdef __FreeBSD__ 1112 if (ifp->if_flags & IFF_UP) 1113 ifp->if_drv_flags |= IFF_DRV_RUNNING; 1114 else 1115 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 1116#else 1117 if (ifp->if_flags & IFF_UP) 1118 ifp->if_flags |= IFF_RUNNING; 1119 else 1120 ifp->if_flags &= ~IFF_RUNNING; 1121#endif 1122 break; 1123 case SIOCSIFMTU: 1124 if (ifr->ifr_mtu < PFSYNC_MINMTU) 1125 return (EINVAL); 1126 if (ifr->ifr_mtu > MCLBYTES) 1127 ifr->ifr_mtu = MCLBYTES; 1128 s = splnet(); 1129#ifdef __FreeBSD__ 1130 PF_LOCK(); 1131#endif 1132 if (ifr->ifr_mtu < ifp->if_mtu) 1133 pfsync_sendout(sc); 1134 pfsync_setmtu(sc, ifr->ifr_mtu); 1135#ifdef __FreeBSD__ 1136 PF_UNLOCK(); 1137#endif 1138 splx(s); 1139 break; 1140 case SIOCGETPFSYNC: 1141 bzero(&pfsyncr, sizeof(pfsyncr)); 1142 if (sc->sc_sync_ifp) 1143 strlcpy(pfsyncr.pfsyncr_syncdev, 1144 sc->sc_sync_ifp->if_xname, IFNAMSIZ); 1145 pfsyncr.pfsyncr_syncpeer = sc->sc_sync_peer; 1146 pfsyncr.pfsyncr_maxupdates = sc->sc_maxupdates; 1147 if ((error = copyout(&pfsyncr, ifr->ifr_data, sizeof(pfsyncr)))) 1148 return (error); 1149 break; 1150 case SIOCSETPFSYNC: 1151#ifdef __FreeBSD__ 1152 if ((error = priv_check(curthread, PRIV_NETINET_PF)) != 0) 1153#else 1154 if ((error = suser(p, p->p_acflag)) != 0) 1155#endif 1156 return (error); 1157 if ((error = copyin(ifr->ifr_data, &pfsyncr, sizeof(pfsyncr)))) 1158 return (error); 1159 1160#ifdef __FreeBSD__ 1161 PF_LOCK(); 1162#endif 1163 if (pfsyncr.pfsyncr_syncpeer.s_addr == 0) 1164#ifdef __FreeBSD__ 1165 sc->sc_sync_peer.s_addr = htonl(INADDR_PFSYNC_GROUP); 1166#else 1167 sc->sc_sync_peer.s_addr = INADDR_PFSYNC_GROUP; 1168#endif 1169 else 1170 sc->sc_sync_peer.s_addr = 1171 pfsyncr.pfsyncr_syncpeer.s_addr; 1172 1173 if (pfsyncr.pfsyncr_maxupdates > 255) 1174#ifdef __FreeBSD__ 1175 { 1176 PF_UNLOCK(); 1177#endif 1178 return (EINVAL); 1179#ifdef __FreeBSD__ 1180 } 1181#endif 1182 sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates; 1183 1184 if (pfsyncr.pfsyncr_syncdev[0] == 0) { 1185 sc->sc_sync_ifp = NULL; 1186 if (sc->sc_mbuf_net != NULL) { 1187 /* Don't keep stale pfsync packets around. */ 1188 s = splnet(); 1189 m_freem(sc->sc_mbuf_net); 1190 sc->sc_mbuf_net = NULL; 1191 sc->sc_statep_net.s = NULL; 1192 splx(s); 1193 } 1194#ifdef __FreeBSD__ 1195 PF_UNLOCK(); 1196#endif 1197 if (imo->imo_num_memberships > 0) { 1198 in_delmulti(imo->imo_membership[--imo->imo_num_memberships]); 1199 imo->imo_multicast_ifp = NULL; 1200 } 1201 break; 1202 } 1203 1204#ifdef __FreeBSD__ 1205 PF_UNLOCK(); 1206#endif 1207 if ((sifp = ifunit(pfsyncr.pfsyncr_syncdev)) == NULL) 1208 return (EINVAL); 1209#ifdef __FreeBSD__ 1210 PF_LOCK(); 1211#endif 1212 1213 s = splnet(); 1214#ifdef __FreeBSD__ 1215 if (sifp->if_mtu < sc->sc_ifp->if_mtu || 1216#else 1217 if (sifp->if_mtu < sc->sc_if.if_mtu || 1218#endif 1219 (sc->sc_sync_ifp != NULL && 1220 sifp->if_mtu < sc->sc_sync_ifp->if_mtu) || 1221 sifp->if_mtu < MCLBYTES - sizeof(struct ip)) 1222 pfsync_sendout(sc); 1223 sc->sc_sync_ifp = sifp; 1224 1225#ifdef __FreeBSD__ 1226 pfsync_setmtu(sc, sc->sc_ifp->if_mtu); 1227#else 1228 pfsync_setmtu(sc, sc->sc_if.if_mtu); 1229#endif 1230 1231 if (imo->imo_num_memberships > 0) { 1232#ifdef __FreeBSD__ 1233 PF_UNLOCK(); 1234#endif 1235 in_delmulti(imo->imo_membership[--imo->imo_num_memberships]); 1236#ifdef __FreeBSD__ 1237 PF_LOCK(); 1238#endif 1239 imo->imo_multicast_ifp = NULL; 1240 } 1241 1242 if (sc->sc_sync_ifp && 1243#ifdef __FreeBSD__ 1244 sc->sc_sync_peer.s_addr == htonl(INADDR_PFSYNC_GROUP)) { 1245#else 1246 sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) { 1247#endif 1248 struct in_addr addr; 1249 1250 if (!(sc->sc_sync_ifp->if_flags & IFF_MULTICAST)) { 1251 sc->sc_sync_ifp = NULL; 1252#ifdef __FreeBSD__ 1253 PF_UNLOCK(); 1254#endif 1255 splx(s); 1256 return (EADDRNOTAVAIL); 1257 } 1258 1259#ifdef __FreeBSD__ 1260 addr.s_addr = htonl(INADDR_PFSYNC_GROUP); 1261#else 1262 addr.s_addr = INADDR_PFSYNC_GROUP; 1263#endif 1264 1265#ifdef __FreeBSD__ 1266 PF_UNLOCK(); 1267#endif 1268 if ((imo->imo_membership[0] = 1269 in_addmulti(&addr, sc->sc_sync_ifp)) == NULL) { 1270 sc->sc_sync_ifp = NULL; 1271 splx(s); 1272 return (ENOBUFS); 1273 } 1274#ifdef __FreeBSD__ 1275 PF_LOCK(); 1276#endif 1277 imo->imo_num_memberships++; 1278 imo->imo_multicast_ifp = sc->sc_sync_ifp; 1279 imo->imo_multicast_ttl = PFSYNC_DFLTTL; 1280 imo->imo_multicast_loop = 0; 1281 } 1282 1283 if (sc->sc_sync_ifp || 1284#ifdef __FreeBSD__ 1285 sc->sc_sendaddr.s_addr != htonl(INADDR_PFSYNC_GROUP)) { 1286#else 1287 sc->sc_sendaddr.s_addr != INADDR_PFSYNC_GROUP) { 1288#endif 1289 /* Request a full state table update. */ 1290 sc->sc_ureq_sent = time_uptime; 1291#if NCARP > 0 1292 if (pfsync_sync_ok) 1293#ifdef __FreeBSD__ 1294#ifdef CARP_ADVANCED 1295 carp_group_demote_adj(sc->sc_ifp, 1); 1296#endif 1297#else 1298 carp_group_demote_adj(&sc->sc_if, 1); 1299#endif 1300#endif 1301 pfsync_sync_ok = 0; 1302 if (pf_status.debug >= PF_DEBUG_MISC) 1303 printf("pfsync: requesting bulk update\n"); 1304#ifdef __FreeBSD__ 1305 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, 1306 pfsync_bulkfail, pfsyncif); 1307#else 1308 timeout_add(&sc->sc_bulkfail_tmo, 5 * hz); 1309#endif 1310 error = pfsync_request_update(NULL, NULL); 1311 if (error == ENOMEM) { 1312#ifdef __FreeBSD__ 1313 PF_UNLOCK(); 1314#endif 1315 splx(s); 1316 return (ENOMEM); 1317 } 1318 pfsync_sendout(sc); 1319 } 1320#ifdef __FreeBSD__ 1321 PF_UNLOCK(); 1322#endif 1323 splx(s); 1324 1325 break; 1326 1327 default: 1328 return (ENOTTY); 1329 } 1330 1331 return (0); 1332} 1333 1334void 1335pfsync_setmtu(struct pfsync_softc *sc, int mtu_req) 1336{ 1337 int mtu; 1338 1339 if (sc->sc_sync_ifp && sc->sc_sync_ifp->if_mtu < mtu_req) 1340 mtu = sc->sc_sync_ifp->if_mtu; 1341 else 1342 mtu = mtu_req; 1343 1344 sc->sc_maxcount = (mtu - sizeof(struct pfsync_header)) / 1345 sizeof(struct pfsync_state); 1346 if (sc->sc_maxcount > 254) 1347 sc->sc_maxcount = 254; 1348#ifdef __FreeBSD__ 1349 sc->sc_ifp->if_mtu = sizeof(struct pfsync_header) + 1350#else 1351 sc->sc_if.if_mtu = sizeof(struct pfsync_header) + 1352#endif 1353 sc->sc_maxcount * sizeof(struct pfsync_state); 1354} 1355 1356struct mbuf * 1357pfsync_get_mbuf(struct pfsync_softc *sc, u_int8_t action, void **sp) 1358{ 1359 struct pfsync_header *h; 1360 struct mbuf *m; 1361 int len; 1362 1363 MGETHDR(m, M_DONTWAIT, MT_DATA); 1364 if (m == NULL) { 1365#ifdef __FreeBSD__ 1366 sc->sc_ifp->if_oerrors++; 1367#else 1368 sc->sc_if.if_oerrors++; 1369#endif 1370 return (NULL); 1371 } 1372 1373 switch (action) { 1374 case PFSYNC_ACT_CLR: 1375 len = sizeof(struct pfsync_header) + 1376 sizeof(struct pfsync_state_clr); 1377 break; 1378 case PFSYNC_ACT_UPD_C: 1379 len = (sc->sc_maxcount * sizeof(struct pfsync_state_upd)) + 1380 sizeof(struct pfsync_header); 1381 break; 1382 case PFSYNC_ACT_DEL_C: 1383 len = (sc->sc_maxcount * sizeof(struct pfsync_state_del)) + 1384 sizeof(struct pfsync_header); 1385 break; 1386 case PFSYNC_ACT_UREQ: 1387 len = (sc->sc_maxcount * sizeof(struct pfsync_state_upd_req)) + 1388 sizeof(struct pfsync_header); 1389 break; 1390 case PFSYNC_ACT_BUS: 1391 len = sizeof(struct pfsync_header) + 1392 sizeof(struct pfsync_state_bus); 1393 break; 1394#ifdef PFSYNC_TDB 1395 case PFSYNC_ACT_TDB_UPD: 1396 len = (sc->sc_maxcount * sizeof(struct pfsync_tdb)) + 1397 sizeof(struct pfsync_header); 1398 break; 1399#endif 1400 default: 1401 len = (sc->sc_maxcount * sizeof(struct pfsync_state)) + 1402 sizeof(struct pfsync_header); 1403 break; 1404 } 1405 1406 if (len > MHLEN) { 1407 MCLGET(m, M_DONTWAIT); 1408 if ((m->m_flags & M_EXT) == 0) { 1409 m_free(m); 1410#ifdef __FreeBSD__ 1411 sc->sc_ifp->if_oerrors++; 1412#else 1413 sc->sc_if.if_oerrors++; 1414#endif 1415 return (NULL); 1416 } 1417 m->m_data += (MCLBYTES - len) &~ (sizeof(long) - 1); 1418 } else 1419 MH_ALIGN(m, len); 1420 1421 m->m_pkthdr.rcvif = NULL; 1422 m->m_pkthdr.len = m->m_len = sizeof(struct pfsync_header); 1423 h = mtod(m, struct pfsync_header *); 1424 h->version = PFSYNC_VERSION; 1425 h->af = 0; 1426 h->count = 0; 1427 h->action = action; 1428#ifndef PFSYNC_TDB 1429 if (action != PFSYNC_ACT_TDB_UPD) 1430#endif 1431 bcopy(&pf_status.pf_chksum, &h->pf_chksum, 1432 PF_MD5_DIGEST_LENGTH); 1433 1434 *sp = (void *)((char *)h + PFSYNC_HDRLEN); 1435#ifdef PFSYNC_TDB 1436 if (action == PFSYNC_ACT_TDB_UPD) 1437#ifdef __FreeBSD__ 1438 callout_reset(&sc->sc_tdb_tmo, hz, pfsync_tdb_timeout, 1439 pfsyncif); 1440#else 1441 timeout_add(&sc->sc_tdb_tmo, hz); 1442#endif 1443 else 1444#endif 1445#ifdef __FreeBSD__ 1446 callout_reset(&sc->sc_tmo, hz, pfsync_timeout, pfsyncif); 1447#else 1448 timeout_add(&sc->sc_tmo, hz); 1449#endif 1450 return (m); 1451} 1452 1453int 1454pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags) 1455{ 1456 struct ifnet *ifp = NULL; 1457 struct pfsync_softc *sc = pfsyncif; 1458 struct pfsync_header *h, *h_net; 1459 struct pfsync_state *sp = NULL; 1460 struct pfsync_state_upd *up = NULL; 1461 struct pfsync_state_del *dp = NULL; 1462 struct pf_rule *r; 1463 u_long secs; 1464 int s, ret = 0; 1465 u_int8_t i = 255, newaction = 0; 1466 1467 if (sc == NULL) 1468 return (0); 1469#ifdef __FreeBSD__ 1470 ifp = sc->sc_ifp; 1471#else 1472 ifp = &sc->sc_if; 1473#endif 1474 1475 /* 1476 * If a packet falls in the forest and there's nobody around to 1477 * hear, does it make a sound? 1478 */ 1479 if (ifp->if_bpf == NULL && sc->sc_sync_ifp == NULL && 1480#ifdef __FreeBSD__ 1481 sc->sc_sync_peer.s_addr == htonl(INADDR_PFSYNC_GROUP)) { 1482#else 1483 sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) { 1484#endif 1485 /* Don't leave any stale pfsync packets hanging around. */ 1486 if (sc->sc_mbuf != NULL) { 1487 m_freem(sc->sc_mbuf); 1488 sc->sc_mbuf = NULL; 1489 sc->sc_statep.s = NULL; 1490 } 1491 return (0); 1492 } 1493 1494 if (action >= PFSYNC_ACT_MAX) 1495 return (EINVAL); 1496 1497 s = splnet(); 1498#ifdef __FreeBSD__ 1499 PF_ASSERT(MA_OWNED); 1500#endif 1501 if (sc->sc_mbuf == NULL) { 1502 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, action, 1503 (void *)&sc->sc_statep.s)) == NULL) { 1504 splx(s); 1505 return (ENOMEM); 1506 } 1507 h = mtod(sc->sc_mbuf, struct pfsync_header *); 1508 } else { 1509 h = mtod(sc->sc_mbuf, struct pfsync_header *); 1510 if (h->action != action) { 1511 pfsync_sendout(sc); 1512 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, action, 1513 (void *)&sc->sc_statep.s)) == NULL) { 1514 splx(s); 1515 return (ENOMEM); 1516 } 1517 h = mtod(sc->sc_mbuf, struct pfsync_header *); 1518 } else { 1519 /* 1520 * If it's an update, look in the packet to see if 1521 * we already have an update for the state. 1522 */ 1523 if (action == PFSYNC_ACT_UPD && sc->sc_maxupdates) { 1524 struct pfsync_state *usp = 1525 (void *)((char *)h + PFSYNC_HDRLEN); 1526 1527 for (i = 0; i < h->count; i++) { 1528 if (!memcmp(usp->id, &st->id, 1529 PFSYNC_ID_LEN) && 1530 usp->creatorid == st->creatorid) { 1531 sp = usp; 1532 sp->updates++; 1533 break; 1534 } 1535 usp++; 1536 } 1537 } 1538 } 1539 } 1540 1541 secs = time_second; 1542 1543 st->pfsync_time = time_uptime; 1544 1545 if (sp == NULL) { 1546 /* not a "duplicate" update */ 1547 i = 255; 1548 sp = sc->sc_statep.s++; 1549 sc->sc_mbuf->m_pkthdr.len = 1550 sc->sc_mbuf->m_len += sizeof(struct pfsync_state); 1551 h->count++; 1552 bzero(sp, sizeof(*sp)); 1553 1554 bcopy(&st->id, sp->id, sizeof(sp->id)); 1555 sp->creatorid = st->creatorid; 1556 1557 strlcpy(sp->ifname, st->u.s.kif->pfik_name, sizeof(sp->ifname)); 1558 pf_state_host_hton(&st->lan, &sp->lan); 1559 pf_state_host_hton(&st->gwy, &sp->gwy); 1560 pf_state_host_hton(&st->ext, &sp->ext); 1561 1562 bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr)); 1563 1564 sp->creation = htonl(secs - st->creation); 1565 pf_state_counter_hton(st->packets[0], sp->packets[0]); 1566 pf_state_counter_hton(st->packets[1], sp->packets[1]); 1567 pf_state_counter_hton(st->bytes[0], sp->bytes[0]); 1568 pf_state_counter_hton(st->bytes[1], sp->bytes[1]); 1569 if ((r = st->rule.ptr) == NULL) 1570 sp->rule = htonl(-1); 1571 else 1572 sp->rule = htonl(r->nr); 1573 if ((r = st->anchor.ptr) == NULL) 1574 sp->anchor = htonl(-1); 1575 else 1576 sp->anchor = htonl(r->nr); 1577 sp->af = st->af; 1578 sp->proto = st->proto; 1579 sp->direction = st->direction; 1580 sp->log = st->log; 1581 sp->allow_opts = st->allow_opts; 1582 sp->timeout = st->timeout; 1583 1584 if (flags & PFSYNC_FLAG_STALE) 1585 sp->sync_flags |= PFSTATE_STALE; 1586 } 1587 1588 pf_state_peer_hton(&st->src, &sp->src); 1589 pf_state_peer_hton(&st->dst, &sp->dst); 1590 1591 if (st->expire <= secs) 1592 sp->expire = htonl(0); 1593 else 1594 sp->expire = htonl(st->expire - secs); 1595 1596 /* do we need to build "compressed" actions for network transfer? */ 1597 if (sc->sc_sync_ifp && flags & PFSYNC_FLAG_COMPRESS) { 1598 switch (action) { 1599 case PFSYNC_ACT_UPD: 1600 newaction = PFSYNC_ACT_UPD_C; 1601 break; 1602 case PFSYNC_ACT_DEL: 1603 newaction = PFSYNC_ACT_DEL_C; 1604 break; 1605 default: 1606 /* by default we just send the uncompressed states */ 1607 break; 1608 } 1609 } 1610 1611 if (newaction) { 1612 if (sc->sc_mbuf_net == NULL) { 1613 if ((sc->sc_mbuf_net = pfsync_get_mbuf(sc, newaction, 1614 (void *)&sc->sc_statep_net.s)) == NULL) { 1615 splx(s); 1616 return (ENOMEM); 1617 } 1618 } 1619 h_net = mtod(sc->sc_mbuf_net, struct pfsync_header *); 1620 1621 switch (newaction) { 1622 case PFSYNC_ACT_UPD_C: 1623 if (i != 255) { 1624 up = (void *)((char *)h_net + 1625 PFSYNC_HDRLEN + (i * sizeof(*up))); 1626 up->updates++; 1627 } else { 1628 h_net->count++; 1629 sc->sc_mbuf_net->m_pkthdr.len = 1630 sc->sc_mbuf_net->m_len += sizeof(*up); 1631 up = sc->sc_statep_net.u++; 1632 1633 bzero(up, sizeof(*up)); 1634 bcopy(&st->id, up->id, sizeof(up->id)); 1635 up->creatorid = st->creatorid; 1636 } 1637 up->timeout = st->timeout; 1638 up->expire = sp->expire; 1639 up->src = sp->src; 1640 up->dst = sp->dst; 1641 break; 1642 case PFSYNC_ACT_DEL_C: 1643 sc->sc_mbuf_net->m_pkthdr.len = 1644 sc->sc_mbuf_net->m_len += sizeof(*dp); 1645 dp = sc->sc_statep_net.d++; 1646 h_net->count++; 1647 1648 bzero(dp, sizeof(*dp)); 1649 bcopy(&st->id, dp->id, sizeof(dp->id)); 1650 dp->creatorid = st->creatorid; 1651 break; 1652 } 1653 } 1654 1655 if (h->count == sc->sc_maxcount || 1656 (sc->sc_maxupdates && (sp->updates >= sc->sc_maxupdates))) 1657 ret = pfsync_sendout(sc); 1658 1659 splx(s); 1660 return (ret); 1661} 1662 1663/* This must be called in splnet() */ 1664int 1665pfsync_request_update(struct pfsync_state_upd *up, struct in_addr *src) 1666{ 1667 struct ifnet *ifp = NULL; 1668 struct pfsync_header *h; 1669 struct pfsync_softc *sc = pfsyncif; 1670 struct pfsync_state_upd_req *rup; 1671 int ret = 0; 1672 1673 if (sc == NULL) 1674 return (0); 1675 1676#ifdef __FreeBSD__ 1677 ifp = sc->sc_ifp; 1678#else 1679 ifp = &sc->sc_if; 1680#endif 1681 if (sc->sc_mbuf == NULL) { 1682 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ, 1683 (void *)&sc->sc_statep.s)) == NULL) 1684 return (ENOMEM); 1685 h = mtod(sc->sc_mbuf, struct pfsync_header *); 1686 } else { 1687 h = mtod(sc->sc_mbuf, struct pfsync_header *); 1688 if (h->action != PFSYNC_ACT_UREQ) { 1689 pfsync_sendout(sc); 1690 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ, 1691 (void *)&sc->sc_statep.s)) == NULL) 1692 return (ENOMEM); 1693 h = mtod(sc->sc_mbuf, struct pfsync_header *); 1694 } 1695 } 1696 1697 if (src != NULL) 1698 sc->sc_sendaddr = *src; 1699 sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*rup); 1700 h->count++; 1701 rup = sc->sc_statep.r++; 1702 bzero(rup, sizeof(*rup)); 1703 if (up != NULL) { 1704 bcopy(up->id, rup->id, sizeof(rup->id)); 1705 rup->creatorid = up->creatorid; 1706 } 1707 1708 if (h->count == sc->sc_maxcount) 1709 ret = pfsync_sendout(sc); 1710 1711 return (ret); 1712} 1713 1714int 1715pfsync_clear_states(u_int32_t creatorid, char *ifname) 1716{ 1717 struct ifnet *ifp = NULL; 1718 struct pfsync_softc *sc = pfsyncif; 1719 struct pfsync_state_clr *cp; 1720 int s, ret; 1721 1722 if (sc == NULL) 1723 return (0); 1724 1725#ifdef __FreeBSD__ 1726 ifp = sc->sc_ifp; 1727#else 1728 ifp = &sc->sc_if; 1729#endif 1730#ifdef __FreeBSD__ 1731 PF_ASSERT(MA_OWNED); 1732#endif 1733 s = splnet(); 1734 if (sc->sc_mbuf != NULL) 1735 pfsync_sendout(sc); 1736 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_CLR, 1737 (void *)&sc->sc_statep.c)) == NULL) { 1738 splx(s); 1739 return (ENOMEM); 1740 } 1741 sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*cp); 1742 cp = sc->sc_statep.c; 1743 cp->creatorid = creatorid; 1744 if (ifname != NULL) 1745 strlcpy(cp->ifname, ifname, IFNAMSIZ); 1746 1747 ret = (pfsync_sendout(sc)); 1748 splx(s); 1749 return (ret); 1750} 1751 1752void 1753pfsync_timeout(void *v) 1754{ 1755 struct pfsync_softc *sc = v; 1756 int s; 1757 1758 s = splnet(); 1759#ifdef __FreeBSD__ 1760 PF_LOCK(); 1761#endif 1762 pfsync_sendout(sc); 1763#ifdef __FreeBSD__ 1764 PF_UNLOCK(); 1765#endif 1766 splx(s); 1767} 1768 1769#ifdef PFSYNC_TDB 1770void 1771pfsync_tdb_timeout(void *v) 1772{ 1773 struct pfsync_softc *sc = v; 1774 int s; 1775 1776 s = splnet(); 1777#ifdef __FreeBSD__ 1778 PF_LOCK(); 1779#endif 1780 pfsync_tdb_sendout(sc); 1781#ifdef __FreeBSD__ 1782 PF_UNLOCK(); 1783#endif 1784 splx(s); 1785} 1786#endif 1787 1788/* This must be called in splnet() */ 1789void 1790pfsync_send_bus(struct pfsync_softc *sc, u_int8_t status) 1791{ 1792 struct pfsync_state_bus *bus; 1793 1794#ifdef __FreeBSD__ 1795 PF_ASSERT(MA_OWNED); 1796#endif 1797 if (sc->sc_mbuf != NULL) 1798 pfsync_sendout(sc); 1799 1800 if (pfsync_sync_ok && 1801 (sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_BUS, 1802 (void *)&sc->sc_statep.b)) != NULL) { 1803 sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*bus); 1804 bus = sc->sc_statep.b; 1805 bus->creatorid = pf_status.hostid; 1806 bus->status = status; 1807 bus->endtime = htonl(time_uptime - sc->sc_ureq_received); 1808 pfsync_sendout(sc); 1809 } 1810} 1811 1812void 1813pfsync_bulk_update(void *v) 1814{ 1815 struct pfsync_softc *sc = v; 1816 int s, i = 0; 1817 struct pf_state *state; 1818 1819 s = splnet(); 1820#ifdef __FreeBSD__ 1821 PF_LOCK(); 1822#endif 1823 if (sc->sc_mbuf != NULL) 1824 pfsync_sendout(sc); 1825 1826 /* 1827 * Grab at most PFSYNC_BULKPACKETS worth of states which have not 1828 * been sent since the latest request was made. 1829 */ 1830 state = sc->sc_bulk_send_next; 1831 if (state) 1832 do { 1833 /* send state update if syncable and not already sent */ 1834 if (!state->sync_flags 1835 && state->timeout < PFTM_MAX 1836 && state->pfsync_time <= sc->sc_ureq_received) { 1837 pfsync_pack_state(PFSYNC_ACT_UPD, state, 0); 1838 i++; 1839 } 1840 1841 /* figure next state to send */ 1842 state = TAILQ_NEXT(state, u.s.entry_list); 1843 1844 /* wrap to start of list if we hit the end */ 1845 if (!state) 1846 state = TAILQ_FIRST(&state_list); 1847 } while (i < sc->sc_maxcount * PFSYNC_BULKPACKETS && 1848 state != sc->sc_bulk_terminator); 1849 1850 if (!state || state == sc->sc_bulk_terminator) { 1851 /* we're done */ 1852 pfsync_send_bus(sc, PFSYNC_BUS_END); 1853 sc->sc_ureq_received = 0; 1854 sc->sc_bulk_send_next = NULL; 1855 sc->sc_bulk_terminator = NULL; 1856 timeout_del(&sc->sc_bulk_tmo); 1857 if (pf_status.debug >= PF_DEBUG_MISC) 1858 printf("pfsync: bulk update complete\n"); 1859 } else { 1860 /* look again for more in a bit */ 1861#ifdef __FreeBSD__ 1862 callout_reset(&sc->sc_bulk_tmo, 1, pfsync_bulk_update, 1863 pfsyncif); 1864#else 1865 timeout_add(&sc->sc_bulk_tmo, 1); 1866#endif 1867 sc->sc_bulk_send_next = state; 1868 } 1869 if (sc->sc_mbuf != NULL) 1870 pfsync_sendout(sc); 1871 splx(s); 1872#ifdef __FreeBSD__ 1873 PF_UNLOCK(); 1874#endif 1875} 1876 1877void 1878pfsync_bulkfail(void *v) 1879{ 1880 struct pfsync_softc *sc = v; 1881 int s, error; 1882 1883#ifdef __FreeBSD__ 1884 PF_LOCK(); 1885#endif 1886 if (sc->sc_bulk_tries++ < PFSYNC_MAX_BULKTRIES) { 1887 /* Try again in a bit */ 1888#ifdef __FreeBSD__ 1889 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, pfsync_bulkfail, 1890 pfsyncif); 1891#else 1892 timeout_add(&sc->sc_bulkfail_tmo, 5 * hz); 1893#endif 1894 s = splnet(); 1895 error = pfsync_request_update(NULL, NULL); 1896 if (error == ENOMEM) { 1897 if (pf_status.debug >= PF_DEBUG_MISC) 1898 printf("pfsync: cannot allocate mbufs for " 1899 "bulk update\n"); 1900 } else 1901 pfsync_sendout(sc); 1902 splx(s); 1903 } else { 1904 /* Pretend like the transfer was ok */ 1905 sc->sc_ureq_sent = 0; 1906 sc->sc_bulk_tries = 0; 1907#if NCARP > 0 1908 if (!pfsync_sync_ok) 1909#ifdef __FreeBSD__ 1910#ifdef CARP_ADVANCED 1911 carp_group_demote_adj(sc->sc_ifp, -1); 1912#endif 1913#else 1914 carp_group_demote_adj(&sc->sc_if, -1); 1915#endif 1916#endif 1917 pfsync_sync_ok = 1; 1918 if (pf_status.debug >= PF_DEBUG_MISC) 1919 printf("pfsync: failed to receive " 1920 "bulk update status\n"); 1921 timeout_del(&sc->sc_bulkfail_tmo); 1922 } 1923#ifdef __FreeBSD__ 1924 PF_UNLOCK(); 1925#endif 1926} 1927 1928/* This must be called in splnet() */ 1929int 1930pfsync_sendout(struct pfsync_softc *sc) 1931{ 1932#if NBPFILTER > 0 1933#ifdef __FreeBSD__ 1934 struct ifnet *ifp = sc->sc_ifp; 1935#else 1936 struct ifnet *ifp = &sc->sc_if; 1937#endif 1938#endif 1939 struct mbuf *m; 1940 1941#ifdef __FreeBSD__ 1942 PF_ASSERT(MA_OWNED); 1943#endif 1944 timeout_del(&sc->sc_tmo); 1945 1946 if (sc->sc_mbuf == NULL) 1947 return (0); 1948 m = sc->sc_mbuf; 1949 sc->sc_mbuf = NULL; 1950 sc->sc_statep.s = NULL; 1951 1952#if NBPFILTER > 0 1953 if (ifp->if_bpf) 1954#ifdef __FreeBSD__ 1955 BPF_MTAP(ifp, m); 1956#else 1957 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); 1958#endif 1959#endif 1960 1961 if (sc->sc_mbuf_net) { 1962 m_freem(m); 1963 m = sc->sc_mbuf_net; 1964 sc->sc_mbuf_net = NULL; 1965 sc->sc_statep_net.s = NULL; 1966 } 1967 1968 return pfsync_sendout_mbuf(sc, m); 1969} 1970 1971#ifdef PFSYNC_TDB 1972int 1973pfsync_tdb_sendout(struct pfsync_softc *sc) 1974{ 1975#if NBPFILTER > 0 1976#ifdef __FreeBSD__ 1977 struct ifnet *ifp = sc->sc_ifp; 1978#else 1979 struct ifnet *ifp = &sc->sc_if; 1980#endif 1981#endif 1982 struct mbuf *m; 1983 1984#ifdef __FreeBSD__ 1985 PF_ASSERT(MA_OWNED); 1986#endif 1987 timeout_del(&sc->sc_tdb_tmo); 1988 1989 if (sc->sc_mbuf_tdb == NULL) 1990 return (0); 1991 m = sc->sc_mbuf_tdb; 1992 sc->sc_mbuf_tdb = NULL; 1993 sc->sc_statep_tdb.t = NULL; 1994 1995#if NBPFILTER > 0 1996 if (ifp->if_bpf) 1997#ifdef __FreeBSD__ 1998 BPF_MTAP(ifp, m); 1999#else 2000 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); 2001#endif 2002#endif 2003 2004 return pfsync_sendout_mbuf(sc, m); 2005} 2006#endif 2007 2008int 2009pfsync_sendout_mbuf(struct pfsync_softc *sc, struct mbuf *m) 2010{ 2011 struct sockaddr sa; 2012 struct ip *ip; 2013 2014#ifdef __FreeBSD__ 2015 PF_ASSERT(MA_OWNED); 2016#endif 2017 if (sc->sc_sync_ifp || 2018#ifdef __FreeBSD__ 2019 sc->sc_sync_peer.s_addr != htonl(INADDR_PFSYNC_GROUP)) { 2020#else 2021 sc->sc_sync_peer.s_addr != INADDR_PFSYNC_GROUP) { 2022#endif 2023 M_PREPEND(m, sizeof(struct ip), M_DONTWAIT); 2024 if (m == NULL) { 2025 pfsyncstats.pfsyncs_onomem++; 2026 return (0); 2027 } 2028 ip = mtod(m, struct ip *); 2029 ip->ip_v = IPVERSION; 2030 ip->ip_hl = sizeof(*ip) >> 2; 2031 ip->ip_tos = IPTOS_LOWDELAY; 2032#ifdef __FreeBSD__ 2033 ip->ip_len = m->m_pkthdr.len; 2034#else 2035 ip->ip_len = htons(m->m_pkthdr.len); 2036#endif 2037 ip->ip_id = htons(ip_randomid()); 2038#ifdef __FreeBSD__ 2039 ip->ip_off = IP_DF; 2040#else 2041 ip->ip_off = htons(IP_DF); 2042#endif 2043 ip->ip_ttl = PFSYNC_DFLTTL; 2044 ip->ip_p = IPPROTO_PFSYNC; 2045 ip->ip_sum = 0; 2046 2047 bzero(&sa, sizeof(sa)); 2048 ip->ip_src.s_addr = INADDR_ANY; 2049 2050#ifdef __FreeBSD__ 2051 if (sc->sc_sendaddr.s_addr == htonl(INADDR_PFSYNC_GROUP)) 2052#else 2053 if (sc->sc_sendaddr.s_addr == INADDR_PFSYNC_GROUP) 2054#endif 2055 m->m_flags |= M_MCAST; 2056 ip->ip_dst = sc->sc_sendaddr; 2057 sc->sc_sendaddr.s_addr = sc->sc_sync_peer.s_addr; 2058 2059 pfsyncstats.pfsyncs_opackets++; 2060 2061#ifdef __FreeBSD__ 2062 if (!IF_HANDOFF(&sc->sc_ifq, m, NULL)) 2063 pfsyncstats.pfsyncs_oerrors++; 2064 taskqueue_enqueue(taskqueue_thread, &pfsyncif->sc_send_task); 2065#else 2066 if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL)) 2067 pfsyncstats.pfsyncs_oerrors++; 2068#endif 2069 } else 2070 m_freem(m); 2071 2072 return (0); 2073} 2074 2075#ifdef PFSYNC_TDB 2076/* Update an in-kernel tdb. Silently fail if no tdb is found. */ 2077void 2078pfsync_update_net_tdb(struct pfsync_tdb *pt) 2079{ 2080 struct tdb *tdb; 2081 int s; 2082 2083 /* check for invalid values */ 2084 if (ntohl(pt->spi) <= SPI_RESERVED_MAX || 2085 (pt->dst.sa.sa_family != AF_INET && 2086 pt->dst.sa.sa_family != AF_INET6)) 2087 goto bad; 2088 2089 s = spltdb(); 2090 tdb = gettdb(pt->spi, &pt->dst, pt->sproto); 2091 if (tdb) { 2092 pt->rpl = ntohl(pt->rpl); 2093 pt->cur_bytes = betoh64(pt->cur_bytes); 2094 2095 /* Neither replay nor byte counter should ever decrease. */ 2096 if (pt->rpl < tdb->tdb_rpl || 2097 pt->cur_bytes < tdb->tdb_cur_bytes) { 2098 splx(s); 2099 goto bad; 2100 } 2101 2102 tdb->tdb_rpl = pt->rpl; 2103 tdb->tdb_cur_bytes = pt->cur_bytes; 2104 } 2105 splx(s); 2106 return; 2107 2108 bad: 2109 if (pf_status.debug >= PF_DEBUG_MISC) 2110 printf("pfsync_insert: PFSYNC_ACT_TDB_UPD: " 2111 "invalid value\n"); 2112 pfsyncstats.pfsyncs_badstate++; 2113 return; 2114} 2115 2116/* One of our local tdbs have been updated, need to sync rpl with others */ 2117int 2118pfsync_update_tdb(struct tdb *tdb, int output) 2119{ 2120 struct ifnet *ifp = NULL; 2121 struct pfsync_softc *sc = pfsyncif; 2122 struct pfsync_header *h; 2123 struct pfsync_tdb *pt = NULL; 2124 int s, i, ret; 2125 2126 if (sc == NULL) 2127 return (0); 2128 2129#ifdef __FreeBSD__ 2130 ifp = sc->sc_ifp; 2131#else 2132 ifp = &sc->sc_if; 2133#endif 2134 if (ifp->if_bpf == NULL && sc->sc_sync_ifp == NULL && 2135#ifdef __FreeBSD__ 2136 sc->sc_sync_peer.s_addr == htonl(INADDR_PFSYNC_GROUP)) { 2137#else 2138 sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) { 2139#endif 2140 /* Don't leave any stale pfsync packets hanging around. */ 2141 if (sc->sc_mbuf_tdb != NULL) { 2142 m_freem(sc->sc_mbuf_tdb); 2143 sc->sc_mbuf_tdb = NULL; 2144 sc->sc_statep_tdb.t = NULL; 2145 } 2146 return (0); 2147 } 2148 2149#ifdef __FreeBSD__ 2150 PF_ASSERT(MA_OWNED); 2151#endif 2152 s = splnet(); 2153 if (sc->sc_mbuf_tdb == NULL) { 2154 if ((sc->sc_mbuf_tdb = pfsync_get_mbuf(sc, PFSYNC_ACT_TDB_UPD, 2155 (void *)&sc->sc_statep_tdb.t)) == NULL) { 2156 splx(s); 2157 return (ENOMEM); 2158 } 2159 h = mtod(sc->sc_mbuf_tdb, struct pfsync_header *); 2160 } else { 2161 h = mtod(sc->sc_mbuf_tdb, struct pfsync_header *); 2162 if (h->action != PFSYNC_ACT_TDB_UPD) { 2163 /* 2164 * XXX will never happen as long as there's 2165 * only one "TDB action". 2166 */ 2167 pfsync_tdb_sendout(sc); 2168 sc->sc_mbuf_tdb = pfsync_get_mbuf(sc, 2169 PFSYNC_ACT_TDB_UPD, (void *)&sc->sc_statep_tdb.t); 2170 if (sc->sc_mbuf_tdb == NULL) { 2171 splx(s); 2172 return (ENOMEM); 2173 } 2174 h = mtod(sc->sc_mbuf_tdb, struct pfsync_header *); 2175 } else if (sc->sc_maxupdates) { 2176 /* 2177 * If it's an update, look in the packet to see if 2178 * we already have an update for the state. 2179 */ 2180 struct pfsync_tdb *u = 2181 (void *)((char *)h + PFSYNC_HDRLEN); 2182 2183 for (i = 0; !pt && i < h->count; i++) { 2184 if (tdb->tdb_spi == u->spi && 2185 tdb->tdb_sproto == u->sproto && 2186 !bcmp(&tdb->tdb_dst, &u->dst, 2187 SA_LEN(&u->dst.sa))) { 2188 pt = u; 2189 pt->updates++; 2190 } 2191 u++; 2192 } 2193 } 2194 } 2195 2196 if (pt == NULL) { 2197 /* not a "duplicate" update */ 2198 pt = sc->sc_statep_tdb.t++; 2199 sc->sc_mbuf_tdb->m_pkthdr.len = 2200 sc->sc_mbuf_tdb->m_len += sizeof(struct pfsync_tdb); 2201 h->count++; 2202 bzero(pt, sizeof(*pt)); 2203 2204 pt->spi = tdb->tdb_spi; 2205 memcpy(&pt->dst, &tdb->tdb_dst, sizeof pt->dst); 2206 pt->sproto = tdb->tdb_sproto; 2207 } 2208 2209 /* 2210 * When a failover happens, the master's rpl is probably above 2211 * what we see here (we may be up to a second late), so 2212 * increase it a bit for outbound tdbs to manage most such 2213 * situations. 2214 * 2215 * For now, just add an offset that is likely to be larger 2216 * than the number of packets we can see in one second. The RFC 2217 * just says the next packet must have a higher seq value. 2218 * 2219 * XXX What is a good algorithm for this? We could use 2220 * a rate-determined increase, but to know it, we would have 2221 * to extend struct tdb. 2222 * XXX pt->rpl can wrap over MAXINT, but if so the real tdb 2223 * will soon be replaced anyway. For now, just don't handle 2224 * this edge case. 2225 */ 2226#define RPL_INCR 16384 2227 pt->rpl = htonl(tdb->tdb_rpl + (output ? RPL_INCR : 0)); 2228 pt->cur_bytes = htobe64(tdb->tdb_cur_bytes); 2229 2230 if (h->count == sc->sc_maxcount || 2231 (sc->sc_maxupdates && (pt->updates >= sc->sc_maxupdates))) 2232 ret = pfsync_tdb_sendout(sc); 2233 2234 splx(s); 2235 return (ret); 2236} 2237#endif /* PFSYNC_TDB */ 2238 2239#ifdef __FreeBSD__ 2240void 2241pfsync_ifdetach(void *arg, struct ifnet *ifp) 2242{ 2243 struct pfsync_softc *sc = (struct pfsync_softc *)arg; 2244 struct ip_moptions *imo; 2245 2246 if (sc == NULL || sc->sc_sync_ifp != ifp) 2247 return; /* not for us; unlocked read */ 2248 2249 PF_LOCK(); 2250 2251 /* Deal with a member interface going away from under us. */ 2252 sc->sc_sync_ifp = NULL; 2253 if (sc->sc_mbuf_net != NULL) { 2254 m_freem(sc->sc_mbuf_net); 2255 sc->sc_mbuf_net = NULL; 2256 sc->sc_statep_net.s = NULL; 2257 } 2258 imo = &sc->sc_imo; 2259 if (imo->imo_num_memberships > 0) { 2260 KASSERT(imo->imo_num_memberships == 1, 2261 ("%s: imo_num_memberships != 1", __func__)); 2262 /* 2263 * Our event handler is always called after protocol 2264 * domains have been detached from the underlying ifnet. 2265 * Do not call in_delmulti(); we held a single reference 2266 * which the protocol domain has purged in in_purgemaddrs(). 2267 */ 2268 PF_UNLOCK(); 2269 imo->imo_membership[--imo->imo_num_memberships] = NULL; 2270 PF_LOCK(); 2271 imo->imo_multicast_ifp = NULL; 2272 } 2273 2274 PF_UNLOCK(); 2275} 2276 2277void 2278pfsync_senddef(void *arg, __unused int pending) 2279{ 2280 struct pfsync_softc *sc = (struct pfsync_softc *)arg; 2281 struct mbuf *m; 2282 2283 for(;;) { 2284 IF_DEQUEUE(&sc->sc_ifq, m); 2285 if (m == NULL) 2286 break; 2287 /* Deal with a member interface going away from under us. */ 2288 if (sc->sc_sync_ifp == NULL) { 2289 pfsyncstats.pfsyncs_oerrors++; 2290 m_freem(m); 2291 continue; 2292 } 2293 if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL)) 2294 pfsyncstats.pfsyncs_oerrors++; 2295 } 2296} 2297 2298static int 2299pfsync_modevent(module_t mod, int type, void *data) 2300{ 2301 int error = 0; 2302 2303 switch (type) { 2304 case MOD_LOAD: 2305 pfsyncattach(0); 2306 break; 2307 case MOD_UNLOAD: 2308 if_clone_detach(&pfsync_cloner); 2309 break; 2310 default: 2311 error = EINVAL; 2312 break; 2313 } 2314 2315 return error; 2316} 2317 2318static moduledata_t pfsync_mod = { 2319 "pfsync", 2320 pfsync_modevent, 2321 0 2322}; 2323 2324#define PFSYNC_MODVER 1 2325 2326DECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); 2327MODULE_VERSION(pfsync, PFSYNC_MODVER); 2328MODULE_DEPEND(pflog, pf, PF_MODVER, PF_MODVER, PF_MODVER); 2329#endif /* __FreeBSD__ */ 2330