if_pfsync.c (141584) | if_pfsync.c (145836) |
---|---|
1/* $FreeBSD: head/sys/contrib/pf/net/if_pfsync.c 141584 2005-02-09 19:29:13Z mlaier $ */ 2/* $OpenBSD: if_pfsync.c,v 1.26 2004/03/28 18:14:20 mcbride Exp $ */ | 1/* $FreeBSD: head/sys/contrib/pf/net/if_pfsync.c 145836 2005-05-03 16:43:32Z mlaier $ */ 2/* $OpenBSD: if_pfsync.c,v 1.46 2005/02/20 15:58:38 mcbride Exp $ */ |
3 4/* 5 * Copyright (c) 2002 Michael Shalayeff 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: --- 32 unchanged lines hidden (view full) --- 43#endif 44 45#include <sys/param.h> 46#include <sys/proc.h> 47#include <sys/systm.h> 48#include <sys/time.h> 49#include <sys/mbuf.h> 50#include <sys/socket.h> | 3 4/* 5 * Copyright (c) 2002 Michael Shalayeff 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: --- 32 unchanged lines hidden (view full) --- 43#endif 44 45#include <sys/param.h> 46#include <sys/proc.h> 47#include <sys/systm.h> 48#include <sys/time.h> 49#include <sys/mbuf.h> 50#include <sys/socket.h> |
51#ifdef __FreeBSD__ | |
52#include <sys/kernel.h> | 51#include <sys/kernel.h> |
52#ifdef __FreeBSD__ 53#include <sys/endian.h> |
|
53#include <sys/malloc.h> 54#include <sys/module.h> 55#include <sys/sockio.h> 56#include <sys/lock.h> 57#include <sys/mutex.h> 58#else 59#include <sys/ioctl.h> 60#include <sys/timeout.h> 61#endif 62 63#include <net/if.h> 64#if defined(__FreeBSD__) 65#include <net/if_clone.h> 66#endif 67#include <net/if_types.h> 68#include <net/route.h> 69#include <net/bpf.h> | 54#include <sys/malloc.h> 55#include <sys/module.h> 56#include <sys/sockio.h> 57#include <sys/lock.h> 58#include <sys/mutex.h> 59#else 60#include <sys/ioctl.h> 61#include <sys/timeout.h> 62#endif 63 64#include <net/if.h> 65#if defined(__FreeBSD__) 66#include <net/if_clone.h> 67#endif 68#include <net/if_types.h> 69#include <net/route.h> 70#include <net/bpf.h> |
71#include <netinet/tcp.h> 72#include <netinet/tcp_seq.h> |
|
70 71#ifdef INET 72#include <netinet/in.h> 73#include <netinet/in_systm.h> 74#include <netinet/in_var.h> 75#include <netinet/ip.h> 76#include <netinet/ip_var.h> 77#endif 78 79#ifdef INET6 80#ifndef INET 81#include <netinet/in.h> 82#endif 83#include <netinet6/nd6.h> 84#endif /* INET6 */ 85 | 73 74#ifdef INET 75#include <netinet/in.h> 76#include <netinet/in_systm.h> 77#include <netinet/in_var.h> 78#include <netinet/ip.h> 79#include <netinet/ip_var.h> 80#endif 81 82#ifdef INET6 83#ifndef INET 84#include <netinet/in.h> 85#endif 86#include <netinet6/nd6.h> 87#endif /* INET6 */ 88 |
89#ifdef __FreeBSD__ 90#include "opt_carp.h" 91#ifdef DEV_CARP 92#define NCARP 1 93#endif 94#else 95#include "carp.h" 96#endif 97#if NCARP > 0 98extern int carp_suppress_preempt; 99#endif 100 |
|
86#include <net/pfvar.h> 87#include <net/if_pfsync.h> 88 89#ifdef __FreeBSD__ 90#define PFSYNCNAME "pfsync" 91#endif 92 93#define PFSYNC_MINMTU \ --- 4 unchanged lines hidden (view full) --- 98int pfsyncdebug; 99#else 100#define DPRINTF(x) 101#endif 102 103#ifndef __FreeBSD__ 104struct pfsync_softc pfsyncif; 105#endif | 101#include <net/pfvar.h> 102#include <net/if_pfsync.h> 103 104#ifdef __FreeBSD__ 105#define PFSYNCNAME "pfsync" 106#endif 107 108#define PFSYNC_MINMTU \ --- 4 unchanged lines hidden (view full) --- 113int pfsyncdebug; 114#else 115#define DPRINTF(x) 116#endif 117 118#ifndef __FreeBSD__ 119struct pfsync_softc pfsyncif; 120#endif |
106int pfsync_sync_ok; | |
107struct pfsyncstats pfsyncstats; 108 109#ifdef __FreeBSD__ 110 111/* 112 * Locking notes: 113 * Whenever we really touch/look at the state table we have to hold the 114 * PF_LOCK. Functions that do just the interface handling, grab the per --- 16 unchanged lines hidden (view full) --- 131struct mbuf *pfsync_get_mbuf(struct pfsync_softc *, u_int8_t, void **); 132int pfsync_request_update(struct pfsync_state_upd *, struct in_addr *); 133int pfsync_sendout(struct pfsync_softc *); 134void pfsync_timeout(void *); 135void pfsync_send_bus(struct pfsync_softc *, u_int8_t); 136void pfsync_bulk_update(void *); 137void pfsync_bulkfail(void *); 138 | 121struct pfsyncstats pfsyncstats; 122 123#ifdef __FreeBSD__ 124 125/* 126 * Locking notes: 127 * Whenever we really touch/look at the state table we have to hold the 128 * PF_LOCK. Functions that do just the interface handling, grab the per --- 16 unchanged lines hidden (view full) --- 145struct mbuf *pfsync_get_mbuf(struct pfsync_softc *, u_int8_t, void **); 146int pfsync_request_update(struct pfsync_state_upd *, struct in_addr *); 147int pfsync_sendout(struct pfsync_softc *); 148void pfsync_timeout(void *); 149void pfsync_send_bus(struct pfsync_softc *, u_int8_t); 150void pfsync_bulk_update(void *); 151void pfsync_bulkfail(void *); 152 |
153int pfsync_sync_ok; |
|
139#ifndef __FreeBSD__ 140extern int ifqmaxlen; 141extern struct timeval time; 142extern struct timeval mono_time; 143extern int hz; 144#endif 145 146#ifdef __FreeBSD__ --- 75 unchanged lines hidden (view full) --- 222 223 pfsync_sync_ok = 1; 224 bzero(&pfsyncif, sizeof(pfsyncif)); 225 pfsyncif.sc_mbuf = NULL; 226 pfsyncif.sc_mbuf_net = NULL; 227 pfsyncif.sc_statep.s = NULL; 228 pfsyncif.sc_statep_net.s = NULL; 229 pfsyncif.sc_maxupdates = 128; | 154#ifndef __FreeBSD__ 155extern int ifqmaxlen; 156extern struct timeval time; 157extern struct timeval mono_time; 158extern int hz; 159#endif 160 161#ifdef __FreeBSD__ --- 75 unchanged lines hidden (view full) --- 237 238 pfsync_sync_ok = 1; 239 bzero(&pfsyncif, sizeof(pfsyncif)); 240 pfsyncif.sc_mbuf = NULL; 241 pfsyncif.sc_mbuf_net = NULL; 242 pfsyncif.sc_statep.s = NULL; 243 pfsyncif.sc_statep_net.s = NULL; 244 pfsyncif.sc_maxupdates = 128; |
245 pfsyncif.sc_sync_peer.s_addr = INADDR_PFSYNC_GROUP; |
|
230 pfsyncif.sc_sendaddr.s_addr = INADDR_PFSYNC_GROUP; 231 pfsyncif.sc_ureq_received = 0; 232 pfsyncif.sc_ureq_sent = 0; 233 ifp = &pfsyncif.sc_if; 234 strlcpy(ifp->if_xname, "pfsync0", sizeof ifp->if_xname); 235 ifp->if_softc = &pfsyncif; 236 ifp->if_ioctl = pfsyncioctl; 237 ifp->if_output = pfsyncoutput; --- 80 unchanged lines hidden (view full) --- 318 pfi_maybe_destroy(kif); 319 return (ENOMEM); 320 } 321 bzero(st, sizeof(*st)); 322 323 st->rule.ptr = r; 324 /* XXX get pointers to nat_rule and anchor */ 325 | 246 pfsyncif.sc_sendaddr.s_addr = INADDR_PFSYNC_GROUP; 247 pfsyncif.sc_ureq_received = 0; 248 pfsyncif.sc_ureq_sent = 0; 249 ifp = &pfsyncif.sc_if; 250 strlcpy(ifp->if_xname, "pfsync0", sizeof ifp->if_xname); 251 ifp->if_softc = &pfsyncif; 252 ifp->if_ioctl = pfsyncioctl; 253 ifp->if_output = pfsyncoutput; --- 80 unchanged lines hidden (view full) --- 334 pfi_maybe_destroy(kif); 335 return (ENOMEM); 336 } 337 bzero(st, sizeof(*st)); 338 339 st->rule.ptr = r; 340 /* XXX get pointers to nat_rule and anchor */ 341 |
342 /* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */ 343 r->states++; 344 |
|
326 /* fill in the rest of the state entry */ 327 pf_state_host_ntoh(&sp->lan, &st->lan); 328 pf_state_host_ntoh(&sp->gwy, &st->gwy); 329 pf_state_host_ntoh(&sp->ext, &st->ext); 330 331 pf_state_peer_ntoh(&sp->src, &st->src); 332 pf_state_peer_ntoh(&sp->dst, &st->dst); 333 334 bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr)); | 345 /* fill in the rest of the state entry */ 346 pf_state_host_ntoh(&sp->lan, &st->lan); 347 pf_state_host_ntoh(&sp->gwy, &st->gwy); 348 pf_state_host_ntoh(&sp->ext, &st->ext); 349 350 pf_state_peer_ntoh(&sp->src, &st->src); 351 pf_state_peer_ntoh(&sp->dst, &st->dst); 352 353 bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr)); |
335#ifdef __FreeBSD__ 336 st->creation = ntohl(sp->creation) + time_second; | 354 st->creation = time_second - ntohl(sp->creation); |
337 st->expire = ntohl(sp->expire) + time_second; | 355 st->expire = ntohl(sp->expire) + time_second; |
338#else 339 st->creation = ntohl(sp->creation) + time.tv_sec; 340 st->expire = ntohl(sp->expire) + time.tv_sec; 341#endif | |
342 343 st->af = sp->af; 344 st->proto = sp->proto; 345 st->direction = sp->direction; 346 st->log = sp->log; 347 st->timeout = sp->timeout; 348 st->allow_opts = sp->allow_opts; 349 350 bcopy(sp->id, &st->id, sizeof(st->id)); 351 st->creatorid = sp->creatorid; | 356 357 st->af = sp->af; 358 st->proto = sp->proto; 359 st->direction = sp->direction; 360 st->log = sp->log; 361 st->timeout = sp->timeout; 362 st->allow_opts = sp->allow_opts; 363 364 bcopy(sp->id, &st->id, sizeof(st->id)); 365 st->creatorid = sp->creatorid; |
352 st->sync_flags = sp->sync_flags | PFSTATE_FROMSYNC; | 366 st->sync_flags = PFSTATE_FROMSYNC; |
353 354 355 if (pf_insert_state(kif, st)) { 356 pfi_maybe_destroy(kif); | 367 368 369 if (pf_insert_state(kif, st)) { 370 pfi_maybe_destroy(kif); |
371 /* XXX when we have nat_rule/anchors, use STATE_DEC_COUNTERS */ 372 r->states--; |
|
357 pool_put(&pf_state_pl, st); 358 return (EINVAL); 359 } 360 361 return (0); 362} 363 364void --- 14 unchanged lines hidden (view full) --- 379 struct pfsync_state *sp; 380 struct pfsync_state_upd *up; 381 struct pfsync_state_del *dp; 382 struct pfsync_state_clr *cp; 383 struct pfsync_state_upd_req *rup; 384 struct pfsync_state_bus *bus; 385 struct in_addr src; 386 struct mbuf *mp; | 373 pool_put(&pf_state_pl, st); 374 return (EINVAL); 375 } 376 377 return (0); 378} 379 380void --- 14 unchanged lines hidden (view full) --- 395 struct pfsync_state *sp; 396 struct pfsync_state_upd *up; 397 struct pfsync_state_del *dp; 398 struct pfsync_state_clr *cp; 399 struct pfsync_state_upd_req *rup; 400 struct pfsync_state_bus *bus; 401 struct in_addr src; 402 struct mbuf *mp; |
387 int iplen, action, error, i, s, count, offp; | 403 int iplen, action, error, i, s, count, offp, sfail, stale = 0; |
388 389 pfsyncstats.pfsyncs_ipackets++; 390 391 /* verify that we have a sync interface configured */ 392 if (!sc->sc_sync_ifp || !pf_status.running) /* XXX PF_LOCK? */ 393 goto done; 394 395 /* verify that the packet came in on the right interface */ --- 39 unchanged lines hidden (view full) --- 435 goto done; 436 } 437 438 /* Cheaper to grab this now than having to mess with mbufs later */ 439 src = ip->ip_src; 440 441 switch (action) { 442 case PFSYNC_ACT_CLR: { | 404 405 pfsyncstats.pfsyncs_ipackets++; 406 407 /* verify that we have a sync interface configured */ 408 if (!sc->sc_sync_ifp || !pf_status.running) /* XXX PF_LOCK? */ 409 goto done; 410 411 /* verify that the packet came in on the right interface */ --- 39 unchanged lines hidden (view full) --- 451 goto done; 452 } 453 454 /* Cheaper to grab this now than having to mess with mbufs later */ 455 src = ip->ip_src; 456 457 switch (action) { 458 case PFSYNC_ACT_CLR: { |
459 struct pf_state *nexts; |
|
443 struct pfi_kif *kif; 444 u_int32_t creatorid; 445 if ((mp = m_pulldown(m, iplen + sizeof(*ph), 446 sizeof(*cp), &offp)) == NULL) { 447 pfsyncstats.pfsyncs_badlen++; 448 return; 449 } 450 cp = (struct pfsync_state_clr *)(mp->m_data + offp); 451 creatorid = cp->creatorid; 452 453 s = splsoftnet(); 454#ifdef __FreeBSD__ 455 PF_LOCK(); 456#endif 457 if (cp->ifname[0] == '\0') { | 460 struct pfi_kif *kif; 461 u_int32_t creatorid; 462 if ((mp = m_pulldown(m, iplen + sizeof(*ph), 463 sizeof(*cp), &offp)) == NULL) { 464 pfsyncstats.pfsyncs_badlen++; 465 return; 466 } 467 cp = (struct pfsync_state_clr *)(mp->m_data + offp); 468 creatorid = cp->creatorid; 469 470 s = splsoftnet(); 471#ifdef __FreeBSD__ 472 PF_LOCK(); 473#endif 474 if (cp->ifname[0] == '\0') { |
458 RB_FOREACH(st, pf_state_tree_id, &tree_id) { 459 if (st->creatorid == creatorid) | 475 for (st = RB_MIN(pf_state_tree_id, &tree_id); 476 st; st = nexts) { 477 nexts = RB_NEXT(pf_state_tree_id, &tree_id, st); 478 if (st->creatorid == creatorid) { |
460 st->timeout = PFTM_PURGE; | 479 st->timeout = PFTM_PURGE; |
480 pf_purge_expired_state(st); 481 } |
|
461 } 462 } else { 463 kif = pfi_lookup_if(cp->ifname); 464 if (kif == NULL) { 465 if (pf_status.debug >= PF_DEBUG_MISC) 466 printf("pfsync_input: PFSYNC_ACT_CLR " 467 "bad interface: %s\n", cp->ifname); 468 splx(s); 469#ifdef __FreeBSD__ 470 PF_UNLOCK(); 471#endif 472 goto done; 473 } | 482 } 483 } else { 484 kif = pfi_lookup_if(cp->ifname); 485 if (kif == NULL) { 486 if (pf_status.debug >= PF_DEBUG_MISC) 487 printf("pfsync_input: PFSYNC_ACT_CLR " 488 "bad interface: %s\n", cp->ifname); 489 splx(s); 490#ifdef __FreeBSD__ 491 PF_UNLOCK(); 492#endif 493 goto done; 494 } |
474 RB_FOREACH(st, pf_state_tree_lan_ext, 475 &kif->pfik_lan_ext) { 476 if (st->creatorid == creatorid) | 495 for (st = RB_MIN(pf_state_tree_lan_ext, 496 &kif->pfik_lan_ext); st; st = nexts) { 497 nexts = RB_NEXT(pf_state_tree_lan_ext, 498 &kif->pfik_lan_ext, st); 499 if (st->creatorid == creatorid) { |
477 st->timeout = PFTM_PURGE; | 500 st->timeout = PFTM_PURGE; |
501 pf_purge_expired_state(st); 502 } |
|
478 } 479 } | 503 } 504 } |
480 pf_purge_expired_states(); | |
481#ifdef __FreeBSD__ 482 PF_UNLOCK(); 483#endif 484 splx(s); 485 486 break; 487 } 488 case PFSYNC_ACT_INS: --- 46 unchanged lines hidden (view full) --- 535 } 536 537 s = splsoftnet(); 538#ifdef __FreeBSD__ 539 PF_LOCK(); 540#endif 541 for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp); 542 i < count; i++, sp++) { | 505#ifdef __FreeBSD__ 506 PF_UNLOCK(); 507#endif 508 splx(s); 509 510 break; 511 } 512 case PFSYNC_ACT_INS: --- 46 unchanged lines hidden (view full) --- 559 } 560 561 s = splsoftnet(); 562#ifdef __FreeBSD__ 563 PF_LOCK(); 564#endif 565 for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp); 566 i < count; i++, sp++) { |
567 int flags = PFSYNC_FLAG_STALE; 568 |
|
543 /* check for invalid values */ 544 if (sp->timeout >= PFTM_MAX || 545 sp->src.state > PF_TCPS_PROXY_DST || 546 sp->dst.state > PF_TCPS_PROXY_DST) { 547 if (pf_status.debug >= PF_DEBUG_MISC) 548 printf("pfsync_insert: PFSYNC_ACT_UPD: " 549 "invalid value\n"); 550 pfsyncstats.pfsyncs_badstate++; --- 5 unchanged lines hidden (view full) --- 556 557 st = pf_find_state_byid(&key); 558 if (st == NULL) { 559 /* insert the update */ 560 if (pfsync_insert_net_state(sp)) 561 pfsyncstats.pfsyncs_badstate++; 562 continue; 563 } | 569 /* check for invalid values */ 570 if (sp->timeout >= PFTM_MAX || 571 sp->src.state > PF_TCPS_PROXY_DST || 572 sp->dst.state > PF_TCPS_PROXY_DST) { 573 if (pf_status.debug >= PF_DEBUG_MISC) 574 printf("pfsync_insert: PFSYNC_ACT_UPD: " 575 "invalid value\n"); 576 pfsyncstats.pfsyncs_badstate++; --- 5 unchanged lines hidden (view full) --- 582 583 st = pf_find_state_byid(&key); 584 if (st == NULL) { 585 /* insert the update */ 586 if (pfsync_insert_net_state(sp)) 587 pfsyncstats.pfsyncs_badstate++; 588 continue; 589 } |
564 pf_state_peer_ntoh(&sp->src, &st->src); 565 pf_state_peer_ntoh(&sp->dst, &st->dst); | 590 sfail = 0; 591 if (st->proto == IPPROTO_TCP) { 592 /* 593 * The state should never go backwards except 594 * for syn-proxy states. Neither should the 595 * sequence window slide backwards. 596 */ 597 if (st->src.state > sp->src.state && 598 (st->src.state < PF_TCPS_PROXY_SRC || 599 sp->src.state >= PF_TCPS_PROXY_SRC)) 600 sfail = 1; 601 else if (SEQ_GT(st->src.seqlo, 602 ntohl(sp->src.seqlo))) 603 sfail = 3; 604 else if (st->dst.state > sp->dst.state) { 605 /* There might still be useful 606 * information about the src state here, 607 * so import that part of the update, 608 * then "fail" so we send the updated 609 * state back to the peer who is missing 610 * our what we know. */ 611 pf_state_peer_ntoh(&sp->src, &st->src); 612 /* XXX do anything with timeouts? */ 613 sfail = 7; 614 flags = 0; 615 } else if (st->dst.state >= TCPS_SYN_SENT && 616 SEQ_GT(st->dst.seqlo, ntohl(sp->dst.seqlo))) 617 sfail = 4; 618 } else { 619 /* 620 * Non-TCP protocol state machine always go 621 * forwards 622 */ 623 if (st->src.state > sp->src.state) 624 sfail = 5; 625 else if ( st->dst.state > sp->dst.state) 626 sfail = 6; 627 } 628 if (sfail) { 629 if (pf_status.debug >= PF_DEBUG_MISC) 630 printf("pfsync: %s stale update " 631 "(%d) id: %016llx " 632 "creatorid: %08x\n", 633 (sfail < 7 ? "ignoring" 634 : "partial"), sfail, |
566#ifdef __FreeBSD__ | 635#ifdef __FreeBSD__ |
567 st->expire = ntohl(sp->expire) + time_second; | 636 (unsigned long long)be64toh(st->id), |
568#else | 637#else |
569 st->expire = ntohl(sp->expire) + time.tv_sec; | 638 betoh64(st->id), |
570#endif | 639#endif |
571 st->timeout = sp->timeout; | 640 ntohl(st->creatorid)); 641 pfsyncstats.pfsyncs_badstate++; |
572 | 642 |
643 if (!(sp->sync_flags & PFSTATE_STALE)) { 644 /* we have a better state, send it */ 645 if (sc->sc_mbuf != NULL && !stale) 646 pfsync_sendout(sc); 647 stale++; 648 if (!st->sync_flags) 649 pfsync_pack_state( 650 PFSYNC_ACT_UPD, st, flags); 651 } 652 continue; 653 } 654 pf_state_peer_ntoh(&sp->src, &st->src); 655 pf_state_peer_ntoh(&sp->dst, &st->dst); 656 st->expire = ntohl(sp->expire) + time_second; 657 st->timeout = sp->timeout; |
|
573 } | 658 } |
659 if (stale && sc->sc_mbuf != NULL) 660 pfsync_sendout(sc); |
|
574#ifdef __FreeBSD__ 575 PF_UNLOCK(); 576#endif 577 splx(s); 578 break; 579 /* 580 * It's not strictly necessary for us to support the "uncompressed" 581 * delete action, but it's relatively simple and maintains consistency. --- 14 unchanged lines hidden (view full) --- 596 bcopy(sp->id, &key.id, sizeof(key.id)); 597 key.creatorid = sp->creatorid; 598 599 st = pf_find_state_byid(&key); 600 if (st == NULL) { 601 pfsyncstats.pfsyncs_badstate++; 602 continue; 603 } | 661#ifdef __FreeBSD__ 662 PF_UNLOCK(); 663#endif 664 splx(s); 665 break; 666 /* 667 * It's not strictly necessary for us to support the "uncompressed" 668 * delete action, but it's relatively simple and maintains consistency. --- 14 unchanged lines hidden (view full) --- 683 bcopy(sp->id, &key.id, sizeof(key.id)); 684 key.creatorid = sp->creatorid; 685 686 st = pf_find_state_byid(&key); 687 if (st == NULL) { 688 pfsyncstats.pfsyncs_badstate++; 689 continue; 690 } |
604 /* 605 * XXX 606 * pf_purge_expired_states() is expensive, 607 * we really want to purge the state directly. 608 */ | |
609 st->timeout = PFTM_PURGE; 610 st->sync_flags |= PFSTATE_FROMSYNC; | 691 st->timeout = PFTM_PURGE; 692 st->sync_flags |= PFSTATE_FROMSYNC; |
693 pf_purge_expired_state(st); |
|
611 } | 694 } |
612 pf_purge_expired_states(); | |
613#ifdef __FreeBSD__ 614 PF_UNLOCK(); 615#endif 616 splx(s); 617 break; 618 case PFSYNC_ACT_UPD_C: { 619 int update_requested = 0; 620 --- 22 unchanged lines hidden (view full) --- 643 } 644 645 bcopy(up->id, &key.id, sizeof(key.id)); 646 key.creatorid = up->creatorid; 647 648 st = pf_find_state_byid(&key); 649 if (st == NULL) { 650 /* We don't have this state. Ask for it. */ | 695#ifdef __FreeBSD__ 696 PF_UNLOCK(); 697#endif 698 splx(s); 699 break; 700 case PFSYNC_ACT_UPD_C: { 701 int update_requested = 0; 702 --- 22 unchanged lines hidden (view full) --- 725 } 726 727 bcopy(up->id, &key.id, sizeof(key.id)); 728 key.creatorid = up->creatorid; 729 730 st = pf_find_state_byid(&key); 731 if (st == NULL) { 732 /* We don't have this state. Ask for it. */ |
651 pfsync_request_update(up, &src); | 733 error = pfsync_request_update(up, &src); 734 if (error == ENOMEM) { 735 splx(s); 736 goto done; 737 } |
652 update_requested = 1; 653 pfsyncstats.pfsyncs_badstate++; 654 continue; 655 } | 738 update_requested = 1; 739 pfsyncstats.pfsyncs_badstate++; 740 continue; 741 } |
656 pf_state_peer_ntoh(&up->src, &st->src); 657 pf_state_peer_ntoh(&up->dst, &st->dst); | 742 sfail = 0; 743 if (st->proto == IPPROTO_TCP) { 744 /* 745 * The state should never go backwards except 746 * for syn-proxy states. Neither should the 747 * sequence window slide backwards. 748 */ 749 if (st->src.state > up->src.state && 750 (st->src.state < PF_TCPS_PROXY_SRC || 751 up->src.state >= PF_TCPS_PROXY_SRC)) 752 sfail = 1; 753 else if (st->dst.state > up->dst.state) 754 sfail = 2; 755 else if (SEQ_GT(st->src.seqlo, 756 ntohl(up->src.seqlo))) 757 sfail = 3; 758 else if (st->dst.state >= TCPS_SYN_SENT && 759 SEQ_GT(st->dst.seqlo, ntohl(up->dst.seqlo))) 760 sfail = 4; 761 } else { 762 /* 763 * Non-TCP protocol state machine always go 764 * forwards 765 */ 766 if (st->src.state > up->src.state) 767 sfail = 5; 768 else if (st->dst.state > up->dst.state) 769 sfail = 6; 770 } 771 if (sfail) { 772 if (pf_status.debug >= PF_DEBUG_MISC) 773 printf("pfsync: ignoring stale update " 774 "(%d) id: %016llx " 775 "creatorid: %08x\n", sfail, |
658#ifdef __FreeBSD__ | 776#ifdef __FreeBSD__ |
659 st->expire = ntohl(up->expire) + time_second; | 777 (unsigned long long)be64toh(st->id), |
660#else | 778#else |
661 st->expire = ntohl(up->expire) + time.tv_sec; | 779 betoh64(st->id), |
662#endif | 780#endif |
781 ntohl(st->creatorid)); 782 pfsyncstats.pfsyncs_badstate++; 783 784 /* we have a better state, send it out */ 785 if ((!stale || update_requested) && 786 sc->sc_mbuf != NULL) { 787 pfsync_sendout(sc); 788 update_requested = 0; 789 } 790 stale++; 791 if (!st->sync_flags) 792 pfsync_pack_state(PFSYNC_ACT_UPD, st, 793 PFSYNC_FLAG_STALE); 794 continue; 795 } 796 pf_state_peer_ntoh(&up->src, &st->src); 797 pf_state_peer_ntoh(&up->dst, &st->dst); 798 st->expire = ntohl(up->expire) + time_second; |
|
663 st->timeout = up->timeout; 664 } | 799 st->timeout = up->timeout; 800 } |
665 if (update_requested) | 801 if ((update_requested || stale) && sc->sc_mbuf) |
666 pfsync_sendout(sc); 667#ifdef __FreeBSD__ 668 PF_UNLOCK(); 669#endif 670 splx(s); 671 break; 672 } 673 case PFSYNC_ACT_DEL_C: --- 12 unchanged lines hidden (view full) --- 686 bcopy(dp->id, &key.id, sizeof(key.id)); 687 key.creatorid = dp->creatorid; 688 689 st = pf_find_state_byid(&key); 690 if (st == NULL) { 691 pfsyncstats.pfsyncs_badstate++; 692 continue; 693 } | 802 pfsync_sendout(sc); 803#ifdef __FreeBSD__ 804 PF_UNLOCK(); 805#endif 806 splx(s); 807 break; 808 } 809 case PFSYNC_ACT_DEL_C: --- 12 unchanged lines hidden (view full) --- 822 bcopy(dp->id, &key.id, sizeof(key.id)); 823 key.creatorid = dp->creatorid; 824 825 st = pf_find_state_byid(&key); 826 if (st == NULL) { 827 pfsyncstats.pfsyncs_badstate++; 828 continue; 829 } |
694 /* 695 * XXX 696 * pf_purge_expired_states() is expensive, 697 * we really want to purge the state directly. 698 */ | |
699 st->timeout = PFTM_PURGE; 700 st->sync_flags |= PFSTATE_FROMSYNC; | 830 st->timeout = PFTM_PURGE; 831 st->sync_flags |= PFSTATE_FROMSYNC; |
832 pf_purge_expired_state(st); |
|
701 } | 833 } |
702 pf_purge_expired_states(); | |
703#ifdef __FreeBSD__ 704 PF_UNLOCK(); 705#endif 706 splx(s); 707 break; 708 case PFSYNC_ACT_INS_F: 709 case PFSYNC_ACT_DEL_F: 710 /* not implemented */ 711 break; 712 case PFSYNC_ACT_UREQ: 713 if ((mp = m_pulldown(m, iplen + sizeof(*ph), 714 count * sizeof(*rup), &offp)) == NULL) { 715 pfsyncstats.pfsyncs_badlen++; 716 return; 717 } 718 719 s = splsoftnet(); | 834#ifdef __FreeBSD__ 835 PF_UNLOCK(); 836#endif 837 splx(s); 838 break; 839 case PFSYNC_ACT_INS_F: 840 case PFSYNC_ACT_DEL_F: 841 /* not implemented */ 842 break; 843 case PFSYNC_ACT_UREQ: 844 if ((mp = m_pulldown(m, iplen + sizeof(*ph), 845 count * sizeof(*rup), &offp)) == NULL) { 846 pfsyncstats.pfsyncs_badlen++; 847 return; 848 } 849 850 s = splsoftnet(); |
720 /* XXX send existing. pfsync_pack_state should handle this. */ | |
721#ifdef __FreeBSD__ 722 PF_LOCK(); 723#endif 724 if (sc->sc_mbuf != NULL) 725 pfsync_sendout(sc); 726 for (i = 0, 727 rup = (struct pfsync_state_upd_req *)(mp->m_data + offp); 728 i < count; i++, rup++) { 729 bcopy(rup->id, &key.id, sizeof(key.id)); 730 key.creatorid = rup->creatorid; 731 732 if (key.id == 0 && key.creatorid == 0) { | 851#ifdef __FreeBSD__ 852 PF_LOCK(); 853#endif 854 if (sc->sc_mbuf != NULL) 855 pfsync_sendout(sc); 856 for (i = 0, 857 rup = (struct pfsync_state_upd_req *)(mp->m_data + offp); 858 i < count; i++, rup++) { 859 bcopy(rup->id, &key.id, sizeof(key.id)); 860 key.creatorid = rup->creatorid; 861 862 if (key.id == 0 && key.creatorid == 0) { |
733#ifdef __FreeBSD__ | |
734 sc->sc_ureq_received = time_uptime; | 863 sc->sc_ureq_received = time_uptime; |
735#else 736 sc->sc_ureq_received = mono_time.tv_sec; 737#endif | |
738 if (pf_status.debug >= PF_DEBUG_MISC) 739 printf("pfsync: received " 740 "bulk update request\n"); 741 pfsync_send_bus(sc, PFSYNC_BUS_START); 742#ifdef __FreeBSD__ 743 callout_reset(&sc->sc_bulk_tmo, 1 * hz, 744 pfsync_bulk_update, 745 LIST_FIRST(&pfsync_list)); 746#else 747 timeout_add(&sc->sc_bulk_tmo, 1 * hz); 748#endif 749 } else { 750 st = pf_find_state_byid(&key); 751 if (st == NULL) { 752 pfsyncstats.pfsyncs_badstate++; 753 continue; 754 } | 864 if (pf_status.debug >= PF_DEBUG_MISC) 865 printf("pfsync: received " 866 "bulk update request\n"); 867 pfsync_send_bus(sc, PFSYNC_BUS_START); 868#ifdef __FreeBSD__ 869 callout_reset(&sc->sc_bulk_tmo, 1 * hz, 870 pfsync_bulk_update, 871 LIST_FIRST(&pfsync_list)); 872#else 873 timeout_add(&sc->sc_bulk_tmo, 1 * hz); 874#endif 875 } else { 876 st = pf_find_state_byid(&key); 877 if (st == NULL) { 878 pfsyncstats.pfsyncs_badstate++; 879 continue; 880 } |
755 pfsync_pack_state(PFSYNC_ACT_UPD, st, 0); | 881 if (!st->sync_flags) 882 pfsync_pack_state(PFSYNC_ACT_UPD, 883 st, 0); |
756 } 757 } 758 if (sc->sc_mbuf != NULL) 759 pfsync_sendout(sc); 760#ifdef __FreeBSD__ 761 PF_UNLOCK(); 762#endif 763 splx(s); --- 21 unchanged lines hidden (view full) --- 785 pf_pool_limits[PF_LIMIT_STATES].limit / 786 (PFSYNC_BULKPACKETS * sc->sc_maxcount)); 787#endif 788 if (pf_status.debug >= PF_DEBUG_MISC) 789 printf("pfsync: received bulk " 790 "update start\n"); 791 break; 792 case PFSYNC_BUS_END: | 884 } 885 } 886 if (sc->sc_mbuf != NULL) 887 pfsync_sendout(sc); 888#ifdef __FreeBSD__ 889 PF_UNLOCK(); 890#endif 891 splx(s); --- 21 unchanged lines hidden (view full) --- 913 pf_pool_limits[PF_LIMIT_STATES].limit / 914 (PFSYNC_BULKPACKETS * sc->sc_maxcount)); 915#endif 916 if (pf_status.debug >= PF_DEBUG_MISC) 917 printf("pfsync: received bulk " 918 "update start\n"); 919 break; 920 case PFSYNC_BUS_END: |
793#ifdef __FreeBSD__ | |
794 if (time_uptime - ntohl(bus->endtime) >= | 921 if (time_uptime - ntohl(bus->endtime) >= |
795#else 796 if (mono_time.tv_sec - ntohl(bus->endtime) >= 797#endif | |
798 sc->sc_ureq_sent) { 799 /* that's it, we're happy */ 800 sc->sc_ureq_sent = 0; 801 sc->sc_bulk_tries = 0; 802#ifdef __FreeBSD__ 803 callout_stop(&sc->sc_bulkfail_tmo); 804#else 805 timeout_del(&sc->sc_bulkfail_tmo); 806#endif | 922 sc->sc_ureq_sent) { 923 /* that's it, we're happy */ 924 sc->sc_ureq_sent = 0; 925 sc->sc_bulk_tries = 0; 926#ifdef __FreeBSD__ 927 callout_stop(&sc->sc_bulkfail_tmo); 928#else 929 timeout_del(&sc->sc_bulkfail_tmo); 930#endif |
931#if NCARP > 0 /* XXX_IMPORT */ 932 if (!pfsync_sync_ok) 933 carp_suppress_preempt--; 934#endif |
|
807 pfsync_sync_ok = 1; 808 if (pf_status.debug >= PF_DEBUG_MISC) 809 printf("pfsync: received valid " 810 "bulk update end\n"); 811 } else { 812 if (pf_status.debug >= PF_DEBUG_MISC) 813 printf("pfsync: received invalid " 814 "bulk update end: bad timestamp\n"); --- 59 unchanged lines hidden (view full) --- 874 splx(s); 875 break; 876 case SIOCGETPFSYNC: 877#ifdef __FreeBSD__ 878 /* XXX: read unlocked */ 879#endif 880 bzero(&pfsyncr, sizeof(pfsyncr)); 881 if (sc->sc_sync_ifp) | 935 pfsync_sync_ok = 1; 936 if (pf_status.debug >= PF_DEBUG_MISC) 937 printf("pfsync: received valid " 938 "bulk update end\n"); 939 } else { 940 if (pf_status.debug >= PF_DEBUG_MISC) 941 printf("pfsync: received invalid " 942 "bulk update end: bad timestamp\n"); --- 59 unchanged lines hidden (view full) --- 1002 splx(s); 1003 break; 1004 case SIOCGETPFSYNC: 1005#ifdef __FreeBSD__ 1006 /* XXX: read unlocked */ 1007#endif 1008 bzero(&pfsyncr, sizeof(pfsyncr)); 1009 if (sc->sc_sync_ifp) |
882 strlcpy(pfsyncr.pfsyncr_syncif, | 1010 strlcpy(pfsyncr.pfsyncr_syncdev, |
883 sc->sc_sync_ifp->if_xname, IFNAMSIZ); | 1011 sc->sc_sync_ifp->if_xname, IFNAMSIZ); |
1012 pfsyncr.pfsyncr_syncpeer = sc->sc_sync_peer; |
|
884 pfsyncr.pfsyncr_maxupdates = sc->sc_maxupdates; 885 if ((error = copyout(&pfsyncr, ifr->ifr_data, sizeof(pfsyncr)))) 886 return (error); 887 break; 888 case SIOCSETPFSYNC: 889#ifdef __FreeBSD__ 890 if ((error = suser(curthread)) != 0) 891#else 892 if ((error = suser(p, p->p_acflag)) != 0) 893#endif 894 return (error); 895 if ((error = copyin(ifr->ifr_data, &pfsyncr, sizeof(pfsyncr)))) 896 return (error); 897 | 1013 pfsyncr.pfsyncr_maxupdates = sc->sc_maxupdates; 1014 if ((error = copyout(&pfsyncr, ifr->ifr_data, sizeof(pfsyncr)))) 1015 return (error); 1016 break; 1017 case SIOCSETPFSYNC: 1018#ifdef __FreeBSD__ 1019 if ((error = suser(curthread)) != 0) 1020#else 1021 if ((error = suser(p, p->p_acflag)) != 0) 1022#endif 1023 return (error); 1024 if ((error = copyin(ifr->ifr_data, &pfsyncr, sizeof(pfsyncr)))) 1025 return (error); 1026 |
1027 if (pfsyncr.pfsyncr_syncpeer.s_addr == 0) 1028 sc->sc_sync_peer.s_addr = INADDR_PFSYNC_GROUP; 1029 else 1030 sc->sc_sync_peer.s_addr = 1031 pfsyncr.pfsyncr_syncpeer.s_addr; 1032 |
|
898 if (pfsyncr.pfsyncr_maxupdates > 255) 899 return (EINVAL); 900#ifdef __FreeBSD__ 901 PF_LOCK(); 902#endif 903 sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates; 904 | 1033 if (pfsyncr.pfsyncr_maxupdates > 255) 1034 return (EINVAL); 1035#ifdef __FreeBSD__ 1036 PF_LOCK(); 1037#endif 1038 sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates; 1039 |
905 if (pfsyncr.pfsyncr_syncif[0] == 0) { | 1040 if (pfsyncr.pfsyncr_syncdev[0] == 0) { |
906 sc->sc_sync_ifp = NULL; 907 if (sc->sc_mbuf_net != NULL) { 908 /* Don't keep stale pfsync packets around. */ 909 s = splnet(); 910 m_freem(sc->sc_mbuf_net); 911 sc->sc_mbuf_net = NULL; 912 sc->sc_statep_net.s = NULL; 913 splx(s); 914 } | 1041 sc->sc_sync_ifp = NULL; 1042 if (sc->sc_mbuf_net != NULL) { 1043 /* Don't keep stale pfsync packets around. */ 1044 s = splnet(); 1045 m_freem(sc->sc_mbuf_net); 1046 sc->sc_mbuf_net = NULL; 1047 sc->sc_statep_net.s = NULL; 1048 splx(s); 1049 } |
1050 if (imo->imo_num_memberships > 0) { 1051 in_delmulti(imo->imo_membership[--imo->imo_num_memberships]); 1052 imo->imo_multicast_ifp = NULL; 1053 } |
|
915#ifdef __FreeBSD__ 916 PF_UNLOCK(); 917#endif 918 break; 919 } | 1054#ifdef __FreeBSD__ 1055 PF_UNLOCK(); 1056#endif 1057 break; 1058 } |
920 if ((sifp = ifunit(pfsyncr.pfsyncr_syncif)) == NULL) { | 1059 1060 if ((sifp = ifunit(pfsyncr.pfsyncr_syncdev)) == NULL) { |
921#ifdef __FreeBSD__ 922 PF_UNLOCK(); 923#endif 924 return (EINVAL); 925 } | 1061#ifdef __FreeBSD__ 1062 PF_UNLOCK(); 1063#endif 1064 return (EINVAL); 1065 } |
926 else if (sifp == sc->sc_sync_ifp) { 927#ifdef __FreeBSD__ 928 PF_UNLOCK(); 929#endif 930 break; 931 } | |
932 933 s = splnet(); 934#ifdef __FreeBSD__ 935 if (sifp->if_mtu < SCP2IFP(sc)->if_mtu || 936#else 937 if (sifp->if_mtu < sc->sc_if.if_mtu || 938#endif 939 (sc->sc_sync_ifp != NULL && --- 8 unchanged lines hidden (view full) --- 948 pfsync_setmtu(sc, sc->sc_if.if_mtu); 949#endif 950 951 if (imo->imo_num_memberships > 0) { 952 in_delmulti(imo->imo_membership[--imo->imo_num_memberships]); 953 imo->imo_multicast_ifp = NULL; 954 } 955 | 1066 1067 s = splnet(); 1068#ifdef __FreeBSD__ 1069 if (sifp->if_mtu < SCP2IFP(sc)->if_mtu || 1070#else 1071 if (sifp->if_mtu < sc->sc_if.if_mtu || 1072#endif 1073 (sc->sc_sync_ifp != NULL && --- 8 unchanged lines hidden (view full) --- 1082 pfsync_setmtu(sc, sc->sc_if.if_mtu); 1083#endif 1084 1085 if (imo->imo_num_memberships > 0) { 1086 in_delmulti(imo->imo_membership[--imo->imo_num_memberships]); 1087 imo->imo_multicast_ifp = NULL; 1088 } 1089 |
956 if (sc->sc_sync_ifp) { | 1090 if (sc->sc_sync_ifp && 1091 sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) { |
957 struct in_addr addr; 958 | 1092 struct in_addr addr; 1093 |
1094 if (!(sc->sc_sync_ifp->if_flags & IFF_MULTICAST)) { 1095 sc->sc_sync_ifp = NULL; |
|
959#ifdef __FreeBSD__ | 1096#ifdef __FreeBSD__ |
1097 PF_UNLOCK(); 1098#endif 1099 splx(s); 1100 return (EADDRNOTAVAIL); 1101 } 1102#ifdef __FreeBSD__ |
|
960 PF_UNLOCK(); /* addmulti mallocs w/ WAITOK */ 961 addr.s_addr = htonl(INADDR_PFSYNC_GROUP); 962#else 963 addr.s_addr = INADDR_PFSYNC_GROUP; 964#endif | 1103 PF_UNLOCK(); /* addmulti mallocs w/ WAITOK */ 1104 addr.s_addr = htonl(INADDR_PFSYNC_GROUP); 1105#else 1106 addr.s_addr = INADDR_PFSYNC_GROUP; 1107#endif |
1108 |
|
965 if ((imo->imo_membership[0] = 966 in_addmulti(&addr, sc->sc_sync_ifp)) == NULL) { | 1109 if ((imo->imo_membership[0] = 1110 in_addmulti(&addr, sc->sc_sync_ifp)) == NULL) { |
1111 sc->sc_sync_ifp = NULL; |
|
967 splx(s); 968 return (ENOBUFS); 969 } 970 imo->imo_num_memberships++; 971 imo->imo_multicast_ifp = sc->sc_sync_ifp; 972 imo->imo_multicast_ttl = PFSYNC_DFLTTL; 973 imo->imo_multicast_loop = 0; | 1112 splx(s); 1113 return (ENOBUFS); 1114 } 1115 imo->imo_num_memberships++; 1116 imo->imo_multicast_ifp = sc->sc_sync_ifp; 1117 imo->imo_multicast_ttl = PFSYNC_DFLTTL; 1118 imo->imo_multicast_loop = 0; |
1119 } |
|
974 | 1120 |
1121 if (sc->sc_sync_ifp || 1122 sc->sc_sendaddr.s_addr != INADDR_PFSYNC_GROUP) { |
|
975 /* Request a full state table update. */ 976#ifdef __FreeBSD__ 977 PF_LOCK(); | 1123 /* Request a full state table update. */ 1124#ifdef __FreeBSD__ 1125 PF_LOCK(); |
1126#endif |
|
978 sc->sc_ureq_sent = time_uptime; | 1127 sc->sc_ureq_sent = time_uptime; |
979#else 980 sc->sc_ureq_sent = mono_time.tv_sec; | 1128#if NCARP > 0 1129 if (pfsync_sync_ok) 1130 carp_suppress_preempt++; |
981#endif 982 pfsync_sync_ok = 0; 983 if (pf_status.debug >= PF_DEBUG_MISC) 984 printf("pfsync: requesting bulk update\n"); 985#ifdef __FreeBSD__ 986 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, 987 pfsync_bulkfail, LIST_FIRST(&pfsync_list)); 988#else 989 timeout_add(&sc->sc_bulkfail_tmo, 5 * hz); 990#endif | 1131#endif 1132 pfsync_sync_ok = 0; 1133 if (pf_status.debug >= PF_DEBUG_MISC) 1134 printf("pfsync: requesting bulk update\n"); 1135#ifdef __FreeBSD__ 1136 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, 1137 pfsync_bulkfail, LIST_FIRST(&pfsync_list)); 1138#else 1139 timeout_add(&sc->sc_bulkfail_tmo, 5 * hz); 1140#endif |
991 pfsync_request_update(NULL, NULL); | 1141 error = pfsync_request_update(NULL, NULL); 1142 if (error == ENOMEM) { 1143#ifdef __FreeBSD__ 1144 PF_UNLOCK(); 1145#endif 1146 splx(s); 1147 return (ENOMEM); 1148 } |
992 pfsync_sendout(sc); 993 } 994#ifdef __FreeBSD__ 995 PF_UNLOCK(); 996#endif 997 splx(s); 998 999 break; --- 104 unchanged lines hidden (view full) --- 1104 LIST_FIRST(&pfsync_list)); 1105#else 1106 timeout_add(&sc->sc_tmo, hz); 1107#endif 1108 return (m); 1109} 1110 1111int | 1149 pfsync_sendout(sc); 1150 } 1151#ifdef __FreeBSD__ 1152 PF_UNLOCK(); 1153#endif 1154 splx(s); 1155 1156 break; --- 104 unchanged lines hidden (view full) --- 1261 LIST_FIRST(&pfsync_list)); 1262#else 1263 timeout_add(&sc->sc_tmo, hz); 1264#endif 1265 return (m); 1266} 1267 1268int |
1112pfsync_pack_state(u_int8_t action, struct pf_state *st, int compress) | 1269pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags) |
1113{ 1114#ifdef __FreeBSD__ 1115 struct ifnet *ifp = SCP2IFP(LIST_FIRST(&pfsync_list)); 1116#else 1117 struct ifnet *ifp = &pfsyncif.sc_if; 1118#endif 1119 struct pfsync_softc *sc = ifp->if_softc; 1120 struct pfsync_header *h, *h_net; --- 7 unchanged lines hidden (view full) --- 1128 1129#ifdef __FreeBSD__ 1130 PF_ASSERT(MA_OWNED); 1131#endif 1132 /* 1133 * If a packet falls in the forest and there's nobody around to 1134 * hear, does it make a sound? 1135 */ | 1270{ 1271#ifdef __FreeBSD__ 1272 struct ifnet *ifp = SCP2IFP(LIST_FIRST(&pfsync_list)); 1273#else 1274 struct ifnet *ifp = &pfsyncif.sc_if; 1275#endif 1276 struct pfsync_softc *sc = ifp->if_softc; 1277 struct pfsync_header *h, *h_net; --- 7 unchanged lines hidden (view full) --- 1285 1286#ifdef __FreeBSD__ 1287 PF_ASSERT(MA_OWNED); 1288#endif 1289 /* 1290 * If a packet falls in the forest and there's nobody around to 1291 * hear, does it make a sound? 1292 */ |
1136 if (ifp->if_bpf == NULL && sc->sc_sync_ifp == NULL) { | 1293 if (ifp->if_bpf == NULL && sc->sc_sync_ifp == NULL && 1294 sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) { |
1137 /* Don't leave any stale pfsync packets hanging around. */ 1138 if (sc->sc_mbuf != NULL) { 1139 m_freem(sc->sc_mbuf); 1140 sc->sc_mbuf = NULL; 1141 sc->sc_statep.s = NULL; 1142 } 1143 return (0); 1144 } --- 37 unchanged lines hidden (view full) --- 1182 break; 1183 } 1184 usp++; 1185 } 1186 } 1187 } 1188 } 1189 | 1295 /* Don't leave any stale pfsync packets hanging around. */ 1296 if (sc->sc_mbuf != NULL) { 1297 m_freem(sc->sc_mbuf); 1298 sc->sc_mbuf = NULL; 1299 sc->sc_statep.s = NULL; 1300 } 1301 return (0); 1302 } --- 37 unchanged lines hidden (view full) --- 1340 break; 1341 } 1342 usp++; 1343 } 1344 } 1345 } 1346 } 1347 |
1190#ifdef __FreeBSD__ | |
1191 secs = time_second; 1192 1193 st->pfsync_time = time_uptime; | 1348 secs = time_second; 1349 1350 st->pfsync_time = time_uptime; |
1194#else 1195 secs = time.tv_sec; 1196 1197 st->pfsync_time = mono_time.tv_sec; 1198#endif | |
1199 TAILQ_REMOVE(&state_updates, st, u.s.entry_updates); 1200 TAILQ_INSERT_TAIL(&state_updates, st, u.s.entry_updates); 1201 1202 if (sp == NULL) { 1203 /* not a "duplicate" update */ 1204 i = 255; 1205 sp = sc->sc_statep.s++; 1206 sc->sc_mbuf->m_pkthdr.len = --- 26 unchanged lines hidden (view full) --- 1233 sp->anchor = htonl(r->nr); 1234 sp->af = st->af; 1235 sp->proto = st->proto; 1236 sp->direction = st->direction; 1237 sp->log = st->log; 1238 sp->allow_opts = st->allow_opts; 1239 sp->timeout = st->timeout; 1240 | 1351 TAILQ_REMOVE(&state_updates, st, u.s.entry_updates); 1352 TAILQ_INSERT_TAIL(&state_updates, st, u.s.entry_updates); 1353 1354 if (sp == NULL) { 1355 /* not a "duplicate" update */ 1356 i = 255; 1357 sp = sc->sc_statep.s++; 1358 sc->sc_mbuf->m_pkthdr.len = --- 26 unchanged lines hidden (view full) --- 1385 sp->anchor = htonl(r->nr); 1386 sp->af = st->af; 1387 sp->proto = st->proto; 1388 sp->direction = st->direction; 1389 sp->log = st->log; 1390 sp->allow_opts = st->allow_opts; 1391 sp->timeout = st->timeout; 1392 |
1241 sp->sync_flags = st->sync_flags & PFSTATE_NOSYNC; | 1393 if (flags & PFSYNC_FLAG_STALE) 1394 sp->sync_flags |= PFSTATE_STALE; |
1242 } 1243 1244 pf_state_peer_hton(&st->src, &sp->src); 1245 pf_state_peer_hton(&st->dst, &sp->dst); 1246 1247 if (st->expire <= secs) 1248 sp->expire = htonl(0); 1249 else 1250 sp->expire = htonl(st->expire - secs); 1251 1252 /* do we need to build "compressed" actions for network transfer? */ | 1395 } 1396 1397 pf_state_peer_hton(&st->src, &sp->src); 1398 pf_state_peer_hton(&st->dst, &sp->dst); 1399 1400 if (st->expire <= secs) 1401 sp->expire = htonl(0); 1402 else 1403 sp->expire = htonl(st->expire - secs); 1404 1405 /* do we need to build "compressed" actions for network transfer? */ |
1253 if (sc->sc_sync_ifp && compress) { | 1406 if (sc->sc_sync_ifp && flags & PFSYNC_FLAG_COMPRESS) { |
1254 switch (action) { 1255 case PFSYNC_ACT_UPD: 1256 newaction = PFSYNC_ACT_UPD_C; 1257 break; 1258 case PFSYNC_ACT_DEL: 1259 newaction = PFSYNC_ACT_DEL_C; 1260 break; 1261 default: --- 61 unchanged lines hidden (view full) --- 1323#ifdef __FreeBSD__ 1324 struct ifnet *ifp = SCP2IFP(LIST_FIRST(&pfsync_list)); 1325#else 1326 struct ifnet *ifp = &pfsyncif.sc_if; 1327#endif 1328 struct pfsync_header *h; 1329 struct pfsync_softc *sc = ifp->if_softc; 1330 struct pfsync_state_upd_req *rup; | 1407 switch (action) { 1408 case PFSYNC_ACT_UPD: 1409 newaction = PFSYNC_ACT_UPD_C; 1410 break; 1411 case PFSYNC_ACT_DEL: 1412 newaction = PFSYNC_ACT_DEL_C; 1413 break; 1414 default: --- 61 unchanged lines hidden (view full) --- 1476#ifdef __FreeBSD__ 1477 struct ifnet *ifp = SCP2IFP(LIST_FIRST(&pfsync_list)); 1478#else 1479 struct ifnet *ifp = &pfsyncif.sc_if; 1480#endif 1481 struct pfsync_header *h; 1482 struct pfsync_softc *sc = ifp->if_softc; 1483 struct pfsync_state_upd_req *rup; |
1331 int s = 0, ret = 0; /* make the compiler happy */ | 1484 int ret = 0; |
1332 1333#ifdef __FreeBSD__ 1334 PF_ASSERT(MA_OWNED); 1335#endif 1336 if (sc->sc_mbuf == NULL) { 1337 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ, | 1485 1486#ifdef __FreeBSD__ 1487 PF_ASSERT(MA_OWNED); 1488#endif 1489 if (sc->sc_mbuf == NULL) { 1490 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ, |
1338 (void *)&sc->sc_statep.s)) == NULL) { 1339 splx(s); | 1491 (void *)&sc->sc_statep.s)) == NULL) |
1340 return (ENOMEM); | 1492 return (ENOMEM); |
1341 } | |
1342 h = mtod(sc->sc_mbuf, struct pfsync_header *); 1343 } else { 1344 h = mtod(sc->sc_mbuf, struct pfsync_header *); 1345 if (h->action != PFSYNC_ACT_UREQ) { 1346 pfsync_sendout(sc); 1347 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ, | 1493 h = mtod(sc->sc_mbuf, struct pfsync_header *); 1494 } else { 1495 h = mtod(sc->sc_mbuf, struct pfsync_header *); 1496 if (h->action != PFSYNC_ACT_UREQ) { 1497 pfsync_sendout(sc); 1498 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ, |
1348 (void *)&sc->sc_statep.s)) == NULL) { 1349 splx(s); | 1499 (void *)&sc->sc_statep.s)) == NULL) |
1350 return (ENOMEM); | 1500 return (ENOMEM); |
1351 } | |
1352 h = mtod(sc->sc_mbuf, struct pfsync_header *); 1353 } 1354 } 1355 1356 if (src != NULL) 1357 sc->sc_sendaddr = *src; 1358 sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*rup); 1359 h->count++; --- 56 unchanged lines hidden (view full) --- 1416#endif 1417 pfsync_sendout(sc); 1418#ifdef __FreeBSD__ 1419 PF_UNLOCK(); 1420#endif 1421 splx(s); 1422} 1423 | 1501 h = mtod(sc->sc_mbuf, struct pfsync_header *); 1502 } 1503 } 1504 1505 if (src != NULL) 1506 sc->sc_sendaddr = *src; 1507 sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*rup); 1508 h->count++; --- 56 unchanged lines hidden (view full) --- 1565#endif 1566 pfsync_sendout(sc); 1567#ifdef __FreeBSD__ 1568 PF_UNLOCK(); 1569#endif 1570 splx(s); 1571} 1572 |
1573/* This must be called in splnet() */ |
|
1424void 1425pfsync_send_bus(struct pfsync_softc *sc, u_int8_t status) 1426{ 1427 struct pfsync_state_bus *bus; 1428 1429#ifdef __FreeBSD__ 1430 PF_ASSERT(MA_OWNED); 1431#endif 1432 if (sc->sc_mbuf != NULL) 1433 pfsync_sendout(sc); 1434 1435 if (pfsync_sync_ok && 1436 (sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_BUS, 1437 (void *)&sc->sc_statep.b)) != NULL) { 1438 sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*bus); 1439 bus = sc->sc_statep.b; 1440 bus->creatorid = pf_status.hostid; 1441 bus->status = status; | 1574void 1575pfsync_send_bus(struct pfsync_softc *sc, u_int8_t status) 1576{ 1577 struct pfsync_state_bus *bus; 1578 1579#ifdef __FreeBSD__ 1580 PF_ASSERT(MA_OWNED); 1581#endif 1582 if (sc->sc_mbuf != NULL) 1583 pfsync_sendout(sc); 1584 1585 if (pfsync_sync_ok && 1586 (sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_BUS, 1587 (void *)&sc->sc_statep.b)) != NULL) { 1588 sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*bus); 1589 bus = sc->sc_statep.b; 1590 bus->creatorid = pf_status.hostid; 1591 bus->status = status; |
1442#ifdef __FreeBSD__ | |
1443 bus->endtime = htonl(time_uptime - sc->sc_ureq_received); | 1592 bus->endtime = htonl(time_uptime - sc->sc_ureq_received); |
1444#else 1445 bus->endtime = htonl(mono_time.tv_sec - sc->sc_ureq_received); 1446#endif | |
1447 pfsync_sendout(sc); 1448 } 1449} 1450 1451void 1452pfsync_bulk_update(void *v) 1453{ 1454 struct pfsync_softc *sc = v; --- 24 unchanged lines hidden (view full) --- 1479#endif 1480 if (pf_status.debug >= PF_DEBUG_MISC) 1481 printf("pfsync: bulk update complete\n"); 1482 break; 1483 } else { 1484 /* send an update and move to end of list */ 1485 if (!state->sync_flags) 1486 pfsync_pack_state(PFSYNC_ACT_UPD, state, 0); | 1593 pfsync_sendout(sc); 1594 } 1595} 1596 1597void 1598pfsync_bulk_update(void *v) 1599{ 1600 struct pfsync_softc *sc = v; --- 24 unchanged lines hidden (view full) --- 1625#endif 1626 if (pf_status.debug >= PF_DEBUG_MISC) 1627 printf("pfsync: bulk update complete\n"); 1628 break; 1629 } else { 1630 /* send an update and move to end of list */ 1631 if (!state->sync_flags) 1632 pfsync_pack_state(PFSYNC_ACT_UPD, state, 0); |
1487#ifdef __FreeBSD__ | |
1488 state->pfsync_time = time_uptime; | 1633 state->pfsync_time = time_uptime; |
1489#else 1490 state->pfsync_time = mono_time.tv_sec; 1491#endif | |
1492 TAILQ_REMOVE(&state_updates, state, u.s.entry_updates); 1493 TAILQ_INSERT_TAIL(&state_updates, state, 1494 u.s.entry_updates); 1495 1496 /* look again for more in a bit */ 1497#ifdef __FreeBSD__ 1498 callout_reset(&sc->sc_bulk_tmo, 1, pfsync_timeout, 1499 LIST_FIRST(&pfsync_list)); --- 9 unchanged lines hidden (view full) --- 1509 PF_UNLOCK(); 1510#endif 1511} 1512 1513void 1514pfsync_bulkfail(void *v) 1515{ 1516 struct pfsync_softc *sc = v; | 1634 TAILQ_REMOVE(&state_updates, state, u.s.entry_updates); 1635 TAILQ_INSERT_TAIL(&state_updates, state, 1636 u.s.entry_updates); 1637 1638 /* look again for more in a bit */ 1639#ifdef __FreeBSD__ 1640 callout_reset(&sc->sc_bulk_tmo, 1, pfsync_timeout, 1641 LIST_FIRST(&pfsync_list)); --- 9 unchanged lines hidden (view full) --- 1651 PF_UNLOCK(); 1652#endif 1653} 1654 1655void 1656pfsync_bulkfail(void *v) 1657{ 1658 struct pfsync_softc *sc = v; |
1659 int s, error; |
|
1517 1518#ifdef __FreeBSD__ 1519 PF_LOCK(); 1520#endif 1521 if (sc->sc_bulk_tries++ < PFSYNC_MAX_BULKTRIES) { 1522 /* Try again in a bit */ 1523#ifdef __FreeBSD__ 1524 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, pfsync_bulkfail, 1525 LIST_FIRST(&pfsync_list)); 1526#else 1527 timeout_add(&sc->sc_bulkfail_tmo, 5 * hz); 1528#endif | 1660 1661#ifdef __FreeBSD__ 1662 PF_LOCK(); 1663#endif 1664 if (sc->sc_bulk_tries++ < PFSYNC_MAX_BULKTRIES) { 1665 /* Try again in a bit */ 1666#ifdef __FreeBSD__ 1667 callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, pfsync_bulkfail, 1668 LIST_FIRST(&pfsync_list)); 1669#else 1670 timeout_add(&sc->sc_bulkfail_tmo, 5 * hz); 1671#endif |
1529 pfsync_request_update(NULL, NULL); 1530 pfsync_sendout(sc); | 1672 s = splnet(); 1673 error = pfsync_request_update(NULL, NULL); 1674 if (error == ENOMEM) { 1675 if (pf_status.debug >= PF_DEBUG_MISC) 1676 printf("pfsync: cannot allocate mbufs for " 1677 "bulk update\n"); 1678 } else 1679 pfsync_sendout(sc); 1680 splx(s); |
1531 } else { 1532 /* Pretend like the transfer was ok */ 1533 sc->sc_ureq_sent = 0; 1534 sc->sc_bulk_tries = 0; | 1681 } else { 1682 /* Pretend like the transfer was ok */ 1683 sc->sc_ureq_sent = 0; 1684 sc->sc_bulk_tries = 0; |
1685#if NCARP > 0 1686 if (!pfsync_sync_ok) 1687 carp_suppress_preempt--; 1688#endif |
|
1535 pfsync_sync_ok = 1; 1536 if (pf_status.debug >= PF_DEBUG_MISC) 1537 printf("pfsync: failed to receive " 1538 "bulk update status\n"); 1539#ifdef __FreeBSD__ 1540 callout_stop(&sc->sc_bulkfail_tmo); 1541#else 1542 timeout_del(&sc->sc_bulkfail_tmo); 1543#endif 1544 } 1545#ifdef __FreeBSD__ 1546 PF_UNLOCK(); 1547#endif 1548} 1549 | 1689 pfsync_sync_ok = 1; 1690 if (pf_status.debug >= PF_DEBUG_MISC) 1691 printf("pfsync: failed to receive " 1692 "bulk update status\n"); 1693#ifdef __FreeBSD__ 1694 callout_stop(&sc->sc_bulkfail_tmo); 1695#else 1696 timeout_del(&sc->sc_bulkfail_tmo); 1697#endif 1698 } 1699#ifdef __FreeBSD__ 1700 PF_UNLOCK(); 1701#endif 1702} 1703 |
1704/* This must be called in splnet() */ |
|
1550int 1551pfsync_sendout(sc) 1552 struct pfsync_softc *sc; 1553{ 1554#if NBPFILTER > 0 1555# ifdef __FreeBSD__ 1556 struct ifnet *ifp = SCP2IFP(sc); 1557# else --- 25 unchanged lines hidden (view full) --- 1583 1584 if (sc->sc_mbuf_net) { 1585 m_freem(m); 1586 m = sc->sc_mbuf_net; 1587 sc->sc_mbuf_net = NULL; 1588 sc->sc_statep_net.s = NULL; 1589 } 1590 | 1705int 1706pfsync_sendout(sc) 1707 struct pfsync_softc *sc; 1708{ 1709#if NBPFILTER > 0 1710# ifdef __FreeBSD__ 1711 struct ifnet *ifp = SCP2IFP(sc); 1712# else --- 25 unchanged lines hidden (view full) --- 1738 1739 if (sc->sc_mbuf_net) { 1740 m_freem(m); 1741 m = sc->sc_mbuf_net; 1742 sc->sc_mbuf_net = NULL; 1743 sc->sc_statep_net.s = NULL; 1744 } 1745 |
1591 if (sc->sc_sync_ifp) { | 1746 if (sc->sc_sync_ifp || sc->sc_sync_peer.s_addr != INADDR_PFSYNC_GROUP) { |
1592 struct ip *ip; | 1747 struct ip *ip; |
1593 struct ifaddr *ifa; | |
1594 struct sockaddr sa; 1595 1596 M_PREPEND(m, sizeof(struct ip), M_DONTWAIT); 1597 if (m == NULL) { 1598 pfsyncstats.pfsyncs_onomem++; 1599 return (0); 1600 } 1601 ip = mtod(m, struct ip *); --- 11 unchanged lines hidden (view full) --- 1613#else 1614 ip->ip_off = htons(IP_DF); 1615#endif 1616 ip->ip_ttl = PFSYNC_DFLTTL; 1617 ip->ip_p = IPPROTO_PFSYNC; 1618 ip->ip_sum = 0; 1619 1620 bzero(&sa, sizeof(sa)); | 1748 struct sockaddr sa; 1749 1750 M_PREPEND(m, sizeof(struct ip), M_DONTWAIT); 1751 if (m == NULL) { 1752 pfsyncstats.pfsyncs_onomem++; 1753 return (0); 1754 } 1755 ip = mtod(m, struct ip *); --- 11 unchanged lines hidden (view full) --- 1767#else 1768 ip->ip_off = htons(IP_DF); 1769#endif 1770 ip->ip_ttl = PFSYNC_DFLTTL; 1771 ip->ip_p = IPPROTO_PFSYNC; 1772 ip->ip_sum = 0; 1773 1774 bzero(&sa, sizeof(sa)); |
1621 sa.sa_family = AF_INET; 1622 ifa = ifaof_ifpforaddr(&sa, sc->sc_sync_ifp); 1623 if (ifa == NULL) 1624 return (0); 1625 ip->ip_src.s_addr = ifatoia(ifa)->ia_addr.sin_addr.s_addr; | 1775 ip->ip_src.s_addr = INADDR_ANY; |
1626 1627#ifdef __FreeBSD__ 1628 if (sc->sc_sendaddr.s_addr == htonl(INADDR_PFSYNC_GROUP)) 1629#else 1630 if (sc->sc_sendaddr.s_addr == INADDR_PFSYNC_GROUP) 1631#endif 1632 m->m_flags |= M_MCAST; 1633 ip->ip_dst = sc->sc_sendaddr; 1634#ifdef __FreeBSD__ | 1776 1777#ifdef __FreeBSD__ 1778 if (sc->sc_sendaddr.s_addr == htonl(INADDR_PFSYNC_GROUP)) 1779#else 1780 if (sc->sc_sendaddr.s_addr == INADDR_PFSYNC_GROUP) 1781#endif 1782 m->m_flags |= M_MCAST; 1783 ip->ip_dst = sc->sc_sendaddr; 1784#ifdef __FreeBSD__ |
1635 sc->sc_sendaddr.s_addr = htonl(INADDR_PFSYNC_GROUP); | 1785 /* XXX_IMPORT */ 1786 sc->sc_sendaddr.s_addr = htonl(sc->sc_sync_peer.s_addr); |
1636#else | 1787#else |
1637 sc->sc_sendaddr.s_addr = INADDR_PFSYNC_GROUP; | 1788 sc->sc_sendaddr.s_addr = sc->sc_sync_peer.s_addr; |
1638#endif 1639 1640 pfsyncstats.pfsyncs_opackets++; 1641 1642#ifdef __FreeBSD__ 1643 PF_UNLOCK(); 1644#endif 1645 if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL)) --- 50 unchanged lines hidden --- | 1789#endif 1790 1791 pfsyncstats.pfsyncs_opackets++; 1792 1793#ifdef __FreeBSD__ 1794 PF_UNLOCK(); 1795#endif 1796 if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL)) --- 50 unchanged lines hidden --- |