root/net/if_pfsync.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pfsyncattach
  2. pfsync_clone_create
  3. pfsync_clone_destroy
  4. pfsyncstart
  5. pfsync_alloc_scrub_memory
  6. pfsync_insert_net_state
  7. pfsync_input
  8. pfsyncoutput
  9. pfsyncioctl
  10. pfsync_setmtu
  11. pfsync_get_mbuf
  12. pfsync_pack_state
  13. pfsync_request_update
  14. pfsync_clear_states
  15. pfsync_timeout
  16. pfsync_tdb_timeout
  17. pfsync_send_bus
  18. pfsync_bulk_update
  19. pfsync_bulkfail
  20. pfsync_sendout
  21. pfsync_tdb_sendout
  22. pfsync_sendout_mbuf
  23. pfsync_update_net_tdb
  24. pfsync_update_tdb

    1 /*      $OpenBSD: if_pfsync.c,v 1.83 2007/06/26 14:44:12 mcbride 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 
   30 #include <sys/param.h>
   31 #include <sys/proc.h>
   32 #include <sys/systm.h>
   33 #include <sys/time.h>
   34 #include <sys/mbuf.h>
   35 #include <sys/socket.h>
   36 #include <sys/ioctl.h>
   37 #include <sys/timeout.h>
   38 #include <sys/kernel.h>
   39 
   40 #include <net/if.h>
   41 #include <net/if_types.h>
   42 #include <net/route.h>
   43 #include <net/bpf.h>
   44 #include <netinet/in.h>
   45 #include <netinet/if_ether.h>
   46 #include <netinet/tcp.h>
   47 #include <netinet/tcp_seq.h>
   48 
   49 #ifdef  INET
   50 #include <netinet/in_systm.h>
   51 #include <netinet/in_var.h>
   52 #include <netinet/ip.h>
   53 #include <netinet/ip_var.h>
   54 #endif
   55 
   56 #ifdef INET6
   57 #include <netinet6/nd6.h>
   58 #endif /* INET6 */
   59 
   60 #include "carp.h"
   61 #if NCARP > 0
   62 #include <netinet/ip_carp.h>
   63 #endif
   64 
   65 #include <net/pfvar.h>
   66 #include <net/if_pfsync.h>
   67 
   68 #include "bpfilter.h"
   69 #include "pfsync.h"
   70 
   71 #define PFSYNC_MINMTU   \
   72     (sizeof(struct pfsync_header) + sizeof(struct pf_state))
   73 
   74 #ifdef PFSYNCDEBUG
   75 #define DPRINTF(x)    do { if (pfsyncdebug) printf x ; } while (0)
   76 int pfsyncdebug;
   77 #else
   78 #define DPRINTF(x)
   79 #endif
   80 
   81 struct pfsync_softc     *pfsyncif = NULL;
   82 struct pfsyncstats       pfsyncstats;
   83 
   84 void    pfsyncattach(int);
   85 int     pfsync_clone_create(struct if_clone *, int);
   86 int     pfsync_clone_destroy(struct ifnet *);
   87 void    pfsync_setmtu(struct pfsync_softc *, int);
   88 int     pfsync_alloc_scrub_memory(struct pfsync_state_peer *,
   89             struct pf_state_peer *);
   90 int     pfsync_insert_net_state(struct pfsync_state *, u_int8_t);
   91 void    pfsync_update_net_tdb(struct pfsync_tdb *);
   92 int     pfsyncoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
   93             struct rtentry *);
   94 int     pfsyncioctl(struct ifnet *, u_long, caddr_t);
   95 void    pfsyncstart(struct ifnet *);
   96 
   97 struct mbuf *pfsync_get_mbuf(struct pfsync_softc *, u_int8_t, void **);
   98 int     pfsync_request_update(struct pfsync_state_upd *, struct in_addr *);
   99 int     pfsync_sendout(struct pfsync_softc *);
  100 int     pfsync_tdb_sendout(struct pfsync_softc *);
  101 int     pfsync_sendout_mbuf(struct pfsync_softc *, struct mbuf *);
  102 void    pfsync_timeout(void *);
  103 void    pfsync_tdb_timeout(void *);
  104 void    pfsync_send_bus(struct pfsync_softc *, u_int8_t);
  105 void    pfsync_bulk_update(void *);
  106 void    pfsync_bulkfail(void *);
  107 
  108 int     pfsync_sync_ok;
  109 
  110 struct if_clone pfsync_cloner =
  111     IF_CLONE_INITIALIZER("pfsync", pfsync_clone_create, pfsync_clone_destroy);
  112 
  113 void
  114 pfsyncattach(int npfsync)
  115 {
  116         if_clone_attach(&pfsync_cloner);
  117 }
  118 int
  119 pfsync_clone_create(struct if_clone *ifc, int unit)
  120 {
  121         struct ifnet *ifp;
  122 
  123         if (unit != 0)
  124                 return (EINVAL);
  125 
  126         pfsync_sync_ok = 1;
  127         if ((pfsyncif = malloc(sizeof(*pfsyncif), M_DEVBUF, M_NOWAIT)) == NULL)
  128                 return (ENOMEM);
  129         bzero(pfsyncif, sizeof(*pfsyncif));
  130         pfsyncif->sc_mbuf = NULL;
  131         pfsyncif->sc_mbuf_net = NULL;
  132         pfsyncif->sc_mbuf_tdb = NULL;
  133         pfsyncif->sc_statep.s = NULL;
  134         pfsyncif->sc_statep_net.s = NULL;
  135         pfsyncif->sc_statep_tdb.t = NULL;
  136         pfsyncif->sc_maxupdates = 128;
  137         pfsyncif->sc_sync_peer.s_addr = INADDR_PFSYNC_GROUP;
  138         pfsyncif->sc_sendaddr.s_addr = INADDR_PFSYNC_GROUP;
  139         pfsyncif->sc_ureq_received = 0;
  140         pfsyncif->sc_ureq_sent = 0;
  141         pfsyncif->sc_bulk_send_next = NULL;
  142         pfsyncif->sc_bulk_terminator = NULL;
  143         ifp = &pfsyncif->sc_if;
  144         snprintf(ifp->if_xname, sizeof ifp->if_xname, "pfsync%d", unit);
  145         ifp->if_softc = pfsyncif;
  146         ifp->if_ioctl = pfsyncioctl;
  147         ifp->if_output = pfsyncoutput;
  148         ifp->if_start = pfsyncstart;
  149         ifp->if_type = IFT_PFSYNC;
  150         ifp->if_snd.ifq_maxlen = ifqmaxlen;
  151         ifp->if_hdrlen = PFSYNC_HDRLEN;
  152         pfsync_setmtu(pfsyncif, ETHERMTU);
  153         timeout_set(&pfsyncif->sc_tmo, pfsync_timeout, pfsyncif);
  154         timeout_set(&pfsyncif->sc_tdb_tmo, pfsync_tdb_timeout, pfsyncif);
  155         timeout_set(&pfsyncif->sc_bulk_tmo, pfsync_bulk_update, pfsyncif);
  156         timeout_set(&pfsyncif->sc_bulkfail_tmo, pfsync_bulkfail, pfsyncif);
  157         if_attach(ifp);
  158         if_alloc_sadl(ifp);
  159 
  160 #if NCARP > 0
  161         if_addgroup(ifp, "carp");
  162 #endif
  163 
  164 #if NBPFILTER > 0
  165         bpfattach(&pfsyncif->sc_if.if_bpf, ifp, DLT_PFSYNC, PFSYNC_HDRLEN);
  166 #endif
  167 
  168         return (0);
  169 }
  170 
  171 int
  172 pfsync_clone_destroy(struct ifnet *ifp)
  173 {
  174 #if NBPFILTER > 0
  175         bpfdetach(ifp);
  176 #endif
  177         if_detach(ifp);
  178         free(pfsyncif, M_DEVBUF);
  179         pfsyncif = NULL;
  180         return (0);
  181 }
  182 
  183 /*
  184  * Start output on the pfsync interface.
  185  */
  186 void
  187 pfsyncstart(struct ifnet *ifp)
  188 {
  189         struct mbuf *m;
  190         int s;
  191 
  192         for (;;) {
  193                 s = splnet();
  194                 IF_DROP(&ifp->if_snd);
  195                 IF_DEQUEUE(&ifp->if_snd, m);
  196                 splx(s);
  197 
  198                 if (m == NULL)
  199                         return;
  200                 else
  201                         m_freem(m);
  202         }
  203 }
  204 
  205 int
  206 pfsync_alloc_scrub_memory(struct pfsync_state_peer *s,
  207     struct pf_state_peer *d)
  208 {
  209         if (s->scrub.scrub_flag && d->scrub == NULL) {
  210                 d->scrub = pool_get(&pf_state_scrub_pl, PR_NOWAIT);
  211                 if (d->scrub == NULL)
  212                         return (ENOMEM);
  213                 bzero(d->scrub, sizeof(*d->scrub));
  214         }
  215 
  216         return (0);
  217 }
  218 
  219 int
  220 pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag)
  221 {
  222         struct pf_state *st = NULL;
  223         struct pf_state_key *sk = NULL;
  224         struct pf_rule *r = NULL;
  225         struct pfi_kif  *kif;
  226 
  227         if (sp->creatorid == 0 && pf_status.debug >= PF_DEBUG_MISC) {
  228                 printf("pfsync_insert_net_state: invalid creator id:"
  229                     " %08x\n", ntohl(sp->creatorid));
  230                 return (EINVAL);
  231         }
  232 
  233         kif = pfi_kif_get(sp->ifname);
  234         if (kif == NULL) {
  235                 if (pf_status.debug >= PF_DEBUG_MISC)
  236                         printf("pfsync_insert_net_state: "
  237                             "unknown interface: %s\n", sp->ifname);
  238                 /* skip this state */
  239                 return (0);
  240         }
  241 
  242         /*
  243          * If the ruleset checksums match, it's safe to associate the state
  244          * with the rule of that number.
  245          */
  246         if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) && chksum_flag &&
  247             ntohl(sp->rule) <
  248             pf_main_ruleset.rules[PF_RULESET_FILTER].active.rcount)
  249                 r = pf_main_ruleset.rules[
  250                     PF_RULESET_FILTER].active.ptr_array[ntohl(sp->rule)];
  251         else
  252                 r = &pf_default_rule;
  253 
  254         if (!r->max_states || r->states < r->max_states)
  255                 st = pool_get(&pf_state_pl, PR_NOWAIT);
  256         if (st == NULL) {
  257                 pfi_kif_unref(kif, PFI_KIF_REF_NONE);
  258                 return (ENOMEM);
  259         }
  260         bzero(st, sizeof(*st));
  261 
  262         if ((sk = pf_alloc_state_key(st)) == NULL) {
  263                 pool_put(&pf_state_pl, st);
  264                 pfi_kif_unref(kif, PFI_KIF_REF_NONE);
  265                 return (ENOMEM);
  266         }
  267 
  268         /* allocate memory for scrub info */
  269         if (pfsync_alloc_scrub_memory(&sp->src, &st->src) ||
  270             pfsync_alloc_scrub_memory(&sp->dst, &st->dst)) {
  271                 pfi_kif_unref(kif, PFI_KIF_REF_NONE);
  272                 if (st->src.scrub)
  273                         pool_put(&pf_state_scrub_pl, st->src.scrub);
  274                 pool_put(&pf_state_pl, st);
  275                 pool_put(&pf_state_key_pl, sk);
  276                 return (ENOMEM);
  277         }
  278 
  279         st->rule.ptr = r;
  280         /* XXX get pointers to nat_rule and anchor */
  281 
  282         /* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */
  283         r->states++;
  284 
  285         /* fill in the rest of the state entry */
  286         pf_state_host_ntoh(&sp->lan, &sk->lan);
  287         pf_state_host_ntoh(&sp->gwy, &sk->gwy);
  288         pf_state_host_ntoh(&sp->ext, &sk->ext);
  289 
  290         pf_state_peer_ntoh(&sp->src, &st->src);
  291         pf_state_peer_ntoh(&sp->dst, &st->dst);
  292 
  293         bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr));
  294         st->creation = time_second - ntohl(sp->creation);
  295         st->expire = ntohl(sp->expire) + time_second;
  296 
  297         sk->af = sp->af;
  298         sk->proto = sp->proto;
  299         sk->direction = sp->direction;
  300         st->log = sp->log;
  301         st->timeout = sp->timeout;
  302         st->allow_opts = sp->allow_opts;
  303 
  304         bcopy(sp->id, &st->id, sizeof(st->id));
  305         st->creatorid = sp->creatorid;
  306         st->sync_flags = PFSTATE_FROMSYNC;
  307 
  308         if (pf_insert_state(kif, st)) {
  309                 pfi_kif_unref(kif, PFI_KIF_REF_NONE);
  310                 /* XXX when we have nat_rule/anchors, use STATE_DEC_COUNTERS */
  311                 r->states--;
  312                 if (st->dst.scrub)
  313                         pool_put(&pf_state_scrub_pl, st->dst.scrub);
  314                 if (st->src.scrub)
  315                         pool_put(&pf_state_scrub_pl, st->src.scrub);
  316                 pool_put(&pf_state_pl, st);
  317                 return (EINVAL);
  318         }
  319 
  320         return (0);
  321 }
  322 
  323 void
  324 pfsync_input(struct mbuf *m, ...)
  325 {
  326         struct ip *ip = mtod(m, struct ip *);
  327         struct pfsync_header *ph;
  328         struct pfsync_softc *sc = pfsyncif;
  329         struct pf_state *st;
  330         struct pf_state_key *sk;
  331         struct pf_state_cmp id_key;
  332         struct pfsync_state *sp;
  333         struct pfsync_state_upd *up;
  334         struct pfsync_state_del *dp;
  335         struct pfsync_state_clr *cp;
  336         struct pfsync_state_upd_req *rup;
  337         struct pfsync_state_bus *bus;
  338 #ifdef IPSEC
  339         struct pfsync_tdb *pt;
  340 #endif
  341         struct in_addr src;
  342         struct mbuf *mp;
  343         int iplen, action, error, i, s, count, offp, sfail, stale = 0;
  344         u_int8_t chksum_flag = 0;
  345 
  346         pfsyncstats.pfsyncs_ipackets++;
  347 
  348         /* verify that we have a sync interface configured */
  349         if (!sc || !sc->sc_sync_ifp || !pf_status.running)
  350                 goto done;
  351 
  352         /* verify that the packet came in on the right interface */
  353         if (sc->sc_sync_ifp != m->m_pkthdr.rcvif) {
  354                 pfsyncstats.pfsyncs_badif++;
  355                 goto done;
  356         }
  357 
  358         /* verify that the IP TTL is 255.  */
  359         if (ip->ip_ttl != PFSYNC_DFLTTL) {
  360                 pfsyncstats.pfsyncs_badttl++;
  361                 goto done;
  362         }
  363 
  364         iplen = ip->ip_hl << 2;
  365 
  366         if (m->m_pkthdr.len < iplen + sizeof(*ph)) {
  367                 pfsyncstats.pfsyncs_hdrops++;
  368                 goto done;
  369         }
  370 
  371         if (iplen + sizeof(*ph) > m->m_len) {
  372                 if ((m = m_pullup(m, iplen + sizeof(*ph))) == NULL) {
  373                         pfsyncstats.pfsyncs_hdrops++;
  374                         goto done;
  375                 }
  376                 ip = mtod(m, struct ip *);
  377         }
  378         ph = (struct pfsync_header *)((char *)ip + iplen);
  379 
  380         /* verify the version */
  381         if (ph->version != PFSYNC_VERSION) {
  382                 pfsyncstats.pfsyncs_badver++;
  383                 goto done;
  384         }
  385 
  386         action = ph->action;
  387         count = ph->count;
  388 
  389         /* make sure it's a valid action code */
  390         if (action >= PFSYNC_ACT_MAX) {
  391                 pfsyncstats.pfsyncs_badact++;
  392                 goto done;
  393         }
  394 
  395         /* Cheaper to grab this now than having to mess with mbufs later */
  396         src = ip->ip_src;
  397 
  398         if (!bcmp(&ph->pf_chksum, &pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH))
  399                 chksum_flag++;
  400 
  401         switch (action) {
  402         case PFSYNC_ACT_CLR: {
  403                 struct pf_state *nexts;
  404                 struct pf_state_key *nextsk;
  405                 struct pfi_kif *kif;
  406                 u_int32_t creatorid;
  407                 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
  408                     sizeof(*cp), &offp)) == NULL) {
  409                         pfsyncstats.pfsyncs_badlen++;
  410                         return;
  411                 }
  412                 cp = (struct pfsync_state_clr *)(mp->m_data + offp);
  413                 creatorid = cp->creatorid;
  414 
  415                 s = splsoftnet();
  416                 if (cp->ifname[0] == '\0') {
  417                         for (st = RB_MIN(pf_state_tree_id, &tree_id);
  418                             st; st = nexts) {
  419                                 nexts = RB_NEXT(pf_state_tree_id, &tree_id, st);
  420                                 if (st->creatorid == creatorid) {
  421                                         st->sync_flags |= PFSTATE_FROMSYNC;
  422                                         pf_unlink_state(st);
  423                                 }
  424                         }
  425                 } else {
  426                         if ((kif = pfi_kif_get(cp->ifname)) == NULL) {
  427                                 splx(s);
  428                                 return;
  429                         }
  430                         for (sk = RB_MIN(pf_state_tree_lan_ext,
  431                             &pf_statetbl_lan_ext); sk; sk = nextsk) {
  432                                 nextsk = RB_NEXT(pf_state_tree_lan_ext,
  433                                     &pf_statetbl_lan_ext, sk);
  434                                 TAILQ_FOREACH(st, &sk->states, next) {
  435                                         if (st->creatorid == creatorid) {
  436                                                 st->sync_flags |=
  437                                                     PFSTATE_FROMSYNC;
  438                                                 pf_unlink_state(st);
  439                                         }
  440                                 }
  441                         }
  442                 }
  443                 splx(s);
  444 
  445                 break;
  446         }
  447         case PFSYNC_ACT_INS:
  448                 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
  449                     count * sizeof(*sp), &offp)) == NULL) {
  450                         pfsyncstats.pfsyncs_badlen++;
  451                         return;
  452                 }
  453 
  454                 s = splsoftnet();
  455                 for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp);
  456                     i < count; i++, sp++) {
  457                         /* check for invalid values */
  458                         if (sp->timeout >= PFTM_MAX ||
  459                             sp->src.state > PF_TCPS_PROXY_DST ||
  460                             sp->dst.state > PF_TCPS_PROXY_DST ||
  461                             sp->direction > PF_OUT ||
  462                             (sp->af != AF_INET && sp->af != AF_INET6)) {
  463                                 if (pf_status.debug >= PF_DEBUG_MISC)
  464                                         printf("pfsync_insert: PFSYNC_ACT_INS: "
  465                                             "invalid value\n");
  466                                 pfsyncstats.pfsyncs_badstate++;
  467                                 continue;
  468                         }
  469 
  470                         if ((error = pfsync_insert_net_state(sp,
  471                             chksum_flag))) {
  472                                 if (error == ENOMEM) {
  473                                         splx(s);
  474                                         goto done;
  475                                 }
  476                                 continue;
  477                         }
  478                 }
  479                 splx(s);
  480                 break;
  481         case PFSYNC_ACT_UPD:
  482                 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
  483                     count * sizeof(*sp), &offp)) == NULL) {
  484                         pfsyncstats.pfsyncs_badlen++;
  485                         return;
  486                 }
  487 
  488                 s = splsoftnet();
  489                 for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp);
  490                     i < count; i++, sp++) {
  491                         int flags = PFSYNC_FLAG_STALE;
  492 
  493                         /* check for invalid values */
  494                         if (sp->timeout >= PFTM_MAX ||
  495                             sp->src.state > PF_TCPS_PROXY_DST ||
  496                             sp->dst.state > PF_TCPS_PROXY_DST) {
  497                                 if (pf_status.debug >= PF_DEBUG_MISC)
  498                                         printf("pfsync_insert: PFSYNC_ACT_UPD: "
  499                                             "invalid value\n");
  500                                 pfsyncstats.pfsyncs_badstate++;
  501                                 continue;
  502                         }
  503 
  504                         bcopy(sp->id, &id_key.id, sizeof(id_key.id));
  505                         id_key.creatorid = sp->creatorid;
  506 
  507                         st = pf_find_state_byid(&id_key);
  508                         if (st == NULL) {
  509                                 /* insert the update */
  510                                 if (pfsync_insert_net_state(sp, chksum_flag))
  511                                         pfsyncstats.pfsyncs_badstate++;
  512                                 continue;
  513                         }
  514                         sk = st->state_key;
  515                         sfail = 0;
  516                         if (sk->proto == IPPROTO_TCP) {
  517                                 /*
  518                                  * The state should never go backwards except
  519                                  * for syn-proxy states.  Neither should the
  520                                  * sequence window slide backwards.
  521                                  */
  522                                 if (st->src.state > sp->src.state &&
  523                                     (st->src.state < PF_TCPS_PROXY_SRC ||
  524                                     sp->src.state >= PF_TCPS_PROXY_SRC))
  525                                         sfail = 1;
  526                                 else if (SEQ_GT(st->src.seqlo,
  527                                     ntohl(sp->src.seqlo)))
  528                                         sfail = 3;
  529                                 else if (st->dst.state > sp->dst.state) {
  530                                         /* There might still be useful
  531                                          * information about the src state here,
  532                                          * so import that part of the update,
  533                                          * then "fail" so we send the updated
  534                                          * state back to the peer who is missing
  535                                          * our what we know. */
  536                                         pf_state_peer_ntoh(&sp->src, &st->src);
  537                                         /* XXX do anything with timeouts? */
  538                                         sfail = 7;
  539                                         flags = 0;
  540                                 } else if (st->dst.state >= TCPS_SYN_SENT &&
  541                                     SEQ_GT(st->dst.seqlo, ntohl(sp->dst.seqlo)))
  542                                         sfail = 4;
  543                         } else {
  544                                 /*
  545                                  * Non-TCP protocol state machine always go
  546                                  * forwards
  547                                  */
  548                                 if (st->src.state > sp->src.state)
  549                                         sfail = 5;
  550                                 else if (st->dst.state > sp->dst.state)
  551                                         sfail = 6;
  552                         }
  553                         if (sfail) {
  554                                 if (pf_status.debug >= PF_DEBUG_MISC)
  555                                         printf("pfsync: %s stale update "
  556                                             "(%d) id: %016llx "
  557                                             "creatorid: %08x\n",
  558                                             (sfail < 7 ?  "ignoring"
  559                                              : "partial"), sfail,
  560                                             betoh64(st->id),
  561                                             ntohl(st->creatorid));
  562                                 pfsyncstats.pfsyncs_badstate++;
  563 
  564                                 if (!(sp->sync_flags & PFSTATE_STALE)) {
  565                                         /* we have a better state, send it */
  566                                         if (sc->sc_mbuf != NULL && !stale)
  567                                                 pfsync_sendout(sc);
  568                                         stale++;
  569                                         if (!st->sync_flags)
  570                                                 pfsync_pack_state(
  571                                                     PFSYNC_ACT_UPD, st, flags);
  572                                 }
  573                                 continue;
  574                         }
  575                         pfsync_alloc_scrub_memory(&sp->dst, &st->dst);
  576                         pf_state_peer_ntoh(&sp->src, &st->src);
  577                         pf_state_peer_ntoh(&sp->dst, &st->dst);
  578                         st->expire = ntohl(sp->expire) + time_second;
  579                         st->timeout = sp->timeout;
  580                 }
  581                 if (stale && sc->sc_mbuf != NULL)
  582                         pfsync_sendout(sc);
  583                 splx(s);
  584                 break;
  585         /*
  586          * It's not strictly necessary for us to support the "uncompressed"
  587          * delete action, but it's relatively simple and maintains consistency.
  588          */
  589         case PFSYNC_ACT_DEL:
  590                 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
  591                     count * sizeof(*sp), &offp)) == NULL) {
  592                         pfsyncstats.pfsyncs_badlen++;
  593                         return;
  594                 }
  595 
  596                 s = splsoftnet();
  597                 for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp);
  598                     i < count; i++, sp++) {
  599                         bcopy(sp->id, &id_key.id, sizeof(id_key.id));
  600                         id_key.creatorid = sp->creatorid;
  601 
  602                         st = pf_find_state_byid(&id_key);
  603                         if (st == NULL) {
  604                                 pfsyncstats.pfsyncs_badstate++;
  605                                 continue;
  606                         }
  607                         st->sync_flags |= PFSTATE_FROMSYNC;
  608                         pf_unlink_state(st);
  609                 }
  610                 splx(s);
  611                 break;
  612         case PFSYNC_ACT_UPD_C: {
  613                 int update_requested = 0;
  614 
  615                 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
  616                     count * sizeof(*up), &offp)) == NULL) {
  617                         pfsyncstats.pfsyncs_badlen++;
  618                         return;
  619                 }
  620 
  621                 s = splsoftnet();
  622                 for (i = 0, up = (struct pfsync_state_upd *)(mp->m_data + offp);
  623                     i < count; i++, up++) {
  624                         /* check for invalid values */
  625                         if (up->timeout >= PFTM_MAX ||
  626                             up->src.state > PF_TCPS_PROXY_DST ||
  627                             up->dst.state > PF_TCPS_PROXY_DST) {
  628                                 if (pf_status.debug >= PF_DEBUG_MISC)
  629                                         printf("pfsync_insert: "
  630                                             "PFSYNC_ACT_UPD_C: "
  631                                             "invalid value\n");
  632                                 pfsyncstats.pfsyncs_badstate++;
  633                                 continue;
  634                         }
  635 
  636                         bcopy(up->id, &id_key.id, sizeof(id_key.id));
  637                         id_key.creatorid = up->creatorid;
  638 
  639                         st = pf_find_state_byid(&id_key);
  640                         if (st == NULL) {
  641                                 /* We don't have this state. Ask for it. */
  642                                 error = pfsync_request_update(up, &src);
  643                                 if (error == ENOMEM) {
  644                                         splx(s);
  645                                         goto done;
  646                                 }
  647                                 update_requested = 1;
  648                                 pfsyncstats.pfsyncs_badstate++;
  649                                 continue;
  650                         }
  651                         sk = st->state_key;
  652                         sfail = 0;
  653                         if (sk->proto == IPPROTO_TCP) {
  654                                 /*
  655                                  * The state should never go backwards except
  656                                  * for syn-proxy states.  Neither should the
  657                                  * sequence window slide backwards.
  658                                  */
  659                                 if (st->src.state > up->src.state &&
  660                                     (st->src.state < PF_TCPS_PROXY_SRC ||
  661                                     up->src.state >= PF_TCPS_PROXY_SRC))
  662                                         sfail = 1;
  663                                 else if (st->dst.state > up->dst.state)
  664                                         sfail = 2;
  665                                 else if (SEQ_GT(st->src.seqlo,
  666                                     ntohl(up->src.seqlo)))
  667                                         sfail = 3;
  668                                 else if (st->dst.state >= TCPS_SYN_SENT &&
  669                                     SEQ_GT(st->dst.seqlo, ntohl(up->dst.seqlo)))
  670                                         sfail = 4;
  671                         } else {
  672                                 /*
  673                                  * Non-TCP protocol state machine always go
  674                                  * forwards
  675                                  */
  676                                 if (st->src.state > up->src.state)
  677                                         sfail = 5;
  678                                 else if (st->dst.state > up->dst.state)
  679                                         sfail = 6;
  680                         }
  681                         if (sfail) {
  682                                 if (pf_status.debug >= PF_DEBUG_MISC)
  683                                         printf("pfsync: ignoring stale update "
  684                                             "(%d) id: %016llx "
  685                                             "creatorid: %08x\n", sfail,
  686                                             betoh64(st->id),
  687                                             ntohl(st->creatorid));
  688                                 pfsyncstats.pfsyncs_badstate++;
  689 
  690                                 /* we have a better state, send it out */
  691                                 if ((!stale || update_requested) &&
  692                                     sc->sc_mbuf != NULL) {
  693                                         pfsync_sendout(sc);
  694                                         update_requested = 0;
  695                                 }
  696                                 stale++;
  697                                 if (!st->sync_flags)
  698                                         pfsync_pack_state(PFSYNC_ACT_UPD, st,
  699                                             PFSYNC_FLAG_STALE);
  700                                 continue;
  701                         }
  702                         pfsync_alloc_scrub_memory(&up->dst, &st->dst);
  703                         pf_state_peer_ntoh(&up->src, &st->src);
  704                         pf_state_peer_ntoh(&up->dst, &st->dst);
  705                         st->expire = ntohl(up->expire) + time_second;
  706                         st->timeout = up->timeout;
  707                 }
  708                 if ((update_requested || stale) && sc->sc_mbuf)
  709                         pfsync_sendout(sc);
  710                 splx(s);
  711                 break;
  712         }
  713         case PFSYNC_ACT_DEL_C:
  714                 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
  715                     count * sizeof(*dp), &offp)) == NULL) {
  716                         pfsyncstats.pfsyncs_badlen++;
  717                         return;
  718                 }
  719 
  720                 s = splsoftnet();
  721                 for (i = 0, dp = (struct pfsync_state_del *)(mp->m_data + offp);
  722                     i < count; i++, dp++) {
  723                         bcopy(dp->id, &id_key.id, sizeof(id_key.id));
  724                         id_key.creatorid = dp->creatorid;
  725 
  726                         st = pf_find_state_byid(&id_key);
  727                         if (st == NULL) {
  728                                 pfsyncstats.pfsyncs_badstate++;
  729                                 continue;
  730                         }
  731                         st->sync_flags |= PFSTATE_FROMSYNC;
  732                         pf_unlink_state(st);
  733                 }
  734                 splx(s);
  735                 break;
  736         case PFSYNC_ACT_INS_F:
  737         case PFSYNC_ACT_DEL_F:
  738                 /* not implemented */
  739                 break;
  740         case PFSYNC_ACT_UREQ:
  741                 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
  742                     count * sizeof(*rup), &offp)) == NULL) {
  743                         pfsyncstats.pfsyncs_badlen++;
  744                         return;
  745                 }
  746 
  747                 s = splsoftnet();
  748                 if (sc->sc_mbuf != NULL)
  749                         pfsync_sendout(sc);
  750                 for (i = 0,
  751                     rup = (struct pfsync_state_upd_req *)(mp->m_data + offp);
  752                     i < count; i++, rup++) {
  753                         bcopy(rup->id, &id_key.id, sizeof(id_key.id));
  754                         id_key.creatorid = rup->creatorid;
  755 
  756                         if (id_key.id == 0 && id_key.creatorid == 0) {
  757                                 sc->sc_ureq_received = time_uptime;
  758                                 if (sc->sc_bulk_send_next == NULL)
  759                                         sc->sc_bulk_send_next =
  760                                             TAILQ_FIRST(&state_list);
  761                                 sc->sc_bulk_terminator = sc->sc_bulk_send_next;
  762                                 if (pf_status.debug >= PF_DEBUG_MISC)
  763                                         printf("pfsync: received "
  764                                             "bulk update request\n");
  765                                 pfsync_send_bus(sc, PFSYNC_BUS_START);
  766                                 timeout_add(&sc->sc_bulk_tmo, 1 * hz);
  767                         } else {
  768                                 st = pf_find_state_byid(&id_key);
  769                                 if (st == NULL) {
  770                                         pfsyncstats.pfsyncs_badstate++;
  771                                         continue;
  772                                 }
  773                                 if (!st->sync_flags)
  774                                         pfsync_pack_state(PFSYNC_ACT_UPD,
  775                                             st, 0);
  776                         }
  777                 }
  778                 if (sc->sc_mbuf != NULL)
  779                         pfsync_sendout(sc);
  780                 splx(s);
  781                 break;
  782         case PFSYNC_ACT_BUS:
  783                 /* If we're not waiting for a bulk update, who cares. */
  784                 if (sc->sc_ureq_sent == 0)
  785                         break;
  786 
  787                 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
  788                     sizeof(*bus), &offp)) == NULL) {
  789                         pfsyncstats.pfsyncs_badlen++;
  790                         return;
  791                 }
  792                 bus = (struct pfsync_state_bus *)(mp->m_data + offp);
  793                 switch (bus->status) {
  794                 case PFSYNC_BUS_START:
  795                         timeout_add(&sc->sc_bulkfail_tmo,
  796                             pf_pool_limits[PF_LIMIT_STATES].limit /
  797                             (PFSYNC_BULKPACKETS * sc->sc_maxcount));
  798                         if (pf_status.debug >= PF_DEBUG_MISC)
  799                                 printf("pfsync: received bulk "
  800                                     "update start\n");
  801                         break;
  802                 case PFSYNC_BUS_END:
  803                         if (time_uptime - ntohl(bus->endtime) >=
  804                             sc->sc_ureq_sent) {
  805                                 /* that's it, we're happy */
  806                                 sc->sc_ureq_sent = 0;
  807                                 sc->sc_bulk_tries = 0;
  808                                 timeout_del(&sc->sc_bulkfail_tmo);
  809 #if NCARP > 0
  810                                 if (!pfsync_sync_ok)
  811                                         carp_group_demote_adj(&sc->sc_if, -1);
  812 #endif
  813                                 pfsync_sync_ok = 1;
  814                                 if (pf_status.debug >= PF_DEBUG_MISC)
  815                                         printf("pfsync: received valid "
  816                                             "bulk update end\n");
  817                         } else {
  818                                 if (pf_status.debug >= PF_DEBUG_MISC)
  819                                         printf("pfsync: received invalid "
  820                                             "bulk update end: bad timestamp\n");
  821                         }
  822                         break;
  823                 }
  824                 break;
  825 #ifdef IPSEC
  826         case PFSYNC_ACT_TDB_UPD:
  827                 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
  828                     count * sizeof(*pt), &offp)) == NULL) {
  829                         pfsyncstats.pfsyncs_badlen++;
  830                         return;
  831                 }
  832                 s = splsoftnet();
  833                 for (i = 0, pt = (struct pfsync_tdb *)(mp->m_data + offp);
  834                     i < count; i++, pt++)
  835                         pfsync_update_net_tdb(pt);
  836                 splx(s);
  837                 break;
  838 #endif
  839         }
  840 
  841 done:
  842         if (m)
  843                 m_freem(m);
  844 }
  845 
  846 int
  847 pfsyncoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
  848         struct rtentry *rt)
  849 {
  850         m_freem(m);
  851         return (0);
  852 }
  853 
  854 /* ARGSUSED */
  855 int
  856 pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  857 {
  858         struct proc *p = curproc;
  859         struct pfsync_softc *sc = ifp->if_softc;
  860         struct ifreq *ifr = (struct ifreq *)data;
  861         struct ip_moptions *imo = &sc->sc_imo;
  862         struct pfsyncreq pfsyncr;
  863         struct ifnet    *sifp;
  864         int s, error;
  865 
  866         switch (cmd) {
  867         case SIOCSIFADDR:
  868         case SIOCAIFADDR:
  869         case SIOCSIFDSTADDR:
  870         case SIOCSIFFLAGS:
  871                 if (ifp->if_flags & IFF_UP)
  872                         ifp->if_flags |= IFF_RUNNING;
  873                 else
  874                         ifp->if_flags &= ~IFF_RUNNING;
  875                 break;
  876         case SIOCSIFMTU:
  877                 if (ifr->ifr_mtu < PFSYNC_MINMTU)
  878                         return (EINVAL);
  879                 if (ifr->ifr_mtu > MCLBYTES)
  880                         ifr->ifr_mtu = MCLBYTES;
  881                 s = splnet();
  882                 if (ifr->ifr_mtu < ifp->if_mtu)
  883                         pfsync_sendout(sc);
  884                 pfsync_setmtu(sc, ifr->ifr_mtu);
  885                 splx(s);
  886                 break;
  887         case SIOCGETPFSYNC:
  888                 bzero(&pfsyncr, sizeof(pfsyncr));
  889                 if (sc->sc_sync_ifp)
  890                         strlcpy(pfsyncr.pfsyncr_syncdev,
  891                             sc->sc_sync_ifp->if_xname, IFNAMSIZ);
  892                 pfsyncr.pfsyncr_syncpeer = sc->sc_sync_peer;
  893                 pfsyncr.pfsyncr_maxupdates = sc->sc_maxupdates;
  894                 if ((error = copyout(&pfsyncr, ifr->ifr_data, sizeof(pfsyncr))))
  895                         return (error);
  896                 break;
  897         case SIOCSETPFSYNC:
  898                 if ((error = suser(p, p->p_acflag)) != 0)
  899                         return (error);
  900                 if ((error = copyin(ifr->ifr_data, &pfsyncr, sizeof(pfsyncr))))
  901                         return (error);
  902 
  903                 if (pfsyncr.pfsyncr_syncpeer.s_addr == 0)
  904                         sc->sc_sync_peer.s_addr = INADDR_PFSYNC_GROUP;
  905                 else
  906                         sc->sc_sync_peer.s_addr =
  907                             pfsyncr.pfsyncr_syncpeer.s_addr;
  908 
  909                 if (pfsyncr.pfsyncr_maxupdates > 255)
  910                         return (EINVAL);
  911                 sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates;
  912 
  913                 if (pfsyncr.pfsyncr_syncdev[0] == 0) {
  914                         sc->sc_sync_ifp = NULL;
  915                         if (sc->sc_mbuf_net != NULL) {
  916                                 /* Don't keep stale pfsync packets around. */
  917                                 s = splnet();
  918                                 m_freem(sc->sc_mbuf_net);
  919                                 sc->sc_mbuf_net = NULL;
  920                                 sc->sc_statep_net.s = NULL;
  921                                 splx(s);
  922                         }
  923                         if (imo->imo_num_memberships > 0) {
  924                                 in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
  925                                 imo->imo_multicast_ifp = NULL;
  926                         }
  927                         break;
  928                 }
  929 
  930                 if ((sifp = ifunit(pfsyncr.pfsyncr_syncdev)) == NULL)
  931                         return (EINVAL);
  932 
  933                 s = splnet();
  934                 if (sifp->if_mtu < sc->sc_if.if_mtu ||
  935                     (sc->sc_sync_ifp != NULL &&
  936                     sifp->if_mtu < sc->sc_sync_ifp->if_mtu) ||
  937                     sifp->if_mtu < MCLBYTES - sizeof(struct ip))
  938                         pfsync_sendout(sc);
  939                 sc->sc_sync_ifp = sifp;
  940 
  941                 pfsync_setmtu(sc, sc->sc_if.if_mtu);
  942 
  943                 if (imo->imo_num_memberships > 0) {
  944                         in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
  945                         imo->imo_multicast_ifp = NULL;
  946                 }
  947 
  948                 if (sc->sc_sync_ifp &&
  949                     sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
  950                         struct in_addr addr;
  951 
  952                         if (!(sc->sc_sync_ifp->if_flags & IFF_MULTICAST)) {
  953                                 sc->sc_sync_ifp = NULL;
  954                                 splx(s);
  955                                 return (EADDRNOTAVAIL);
  956                         }
  957 
  958                         addr.s_addr = INADDR_PFSYNC_GROUP;
  959 
  960                         if ((imo->imo_membership[0] =
  961                             in_addmulti(&addr, sc->sc_sync_ifp)) == NULL) {
  962                                 sc->sc_sync_ifp = NULL;
  963                                 splx(s);
  964                                 return (ENOBUFS);
  965                         }
  966                         imo->imo_num_memberships++;
  967                         imo->imo_multicast_ifp = sc->sc_sync_ifp;
  968                         imo->imo_multicast_ttl = PFSYNC_DFLTTL;
  969                         imo->imo_multicast_loop = 0;
  970                 }
  971 
  972                 if (sc->sc_sync_ifp ||
  973                     sc->sc_sendaddr.s_addr != INADDR_PFSYNC_GROUP) {
  974                         /* Request a full state table update. */
  975                         sc->sc_ureq_sent = time_uptime;
  976 #if NCARP > 0
  977                         if (pfsync_sync_ok)
  978                                 carp_group_demote_adj(&sc->sc_if, 1);
  979 #endif
  980                         pfsync_sync_ok = 0;
  981                         if (pf_status.debug >= PF_DEBUG_MISC)
  982                                 printf("pfsync: requesting bulk update\n");
  983                         timeout_add(&sc->sc_bulkfail_tmo, 5 * hz);
  984                         error = pfsync_request_update(NULL, NULL);
  985                         if (error == ENOMEM) {
  986                                 splx(s);
  987                                 return (ENOMEM);
  988                         }
  989                         pfsync_sendout(sc);
  990                 }
  991                 splx(s);
  992 
  993                 break;
  994 
  995         default:
  996                 return (ENOTTY);
  997         }
  998 
  999         return (0);
 1000 }
 1001 
 1002 void
 1003 pfsync_setmtu(struct pfsync_softc *sc, int mtu_req)
 1004 {
 1005         int mtu;
 1006 
 1007         if (sc->sc_sync_ifp && sc->sc_sync_ifp->if_mtu < mtu_req)
 1008                 mtu = sc->sc_sync_ifp->if_mtu;
 1009         else
 1010                 mtu = mtu_req;
 1011 
 1012         sc->sc_maxcount = (mtu - sizeof(struct pfsync_header)) /
 1013             sizeof(struct pfsync_state);
 1014         if (sc->sc_maxcount > 254)
 1015             sc->sc_maxcount = 254;
 1016         sc->sc_if.if_mtu = sizeof(struct pfsync_header) +
 1017             sc->sc_maxcount * sizeof(struct pfsync_state);
 1018 }
 1019 
 1020 struct mbuf *
 1021 pfsync_get_mbuf(struct pfsync_softc *sc, u_int8_t action, void **sp)
 1022 {
 1023         struct pfsync_header *h;
 1024         struct mbuf *m;
 1025         int len;
 1026 
 1027         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1028         if (m == NULL) {
 1029                 sc->sc_if.if_oerrors++;
 1030                 return (NULL);
 1031         }
 1032 
 1033         switch (action) {
 1034         case PFSYNC_ACT_CLR:
 1035                 len = sizeof(struct pfsync_header) +
 1036                     sizeof(struct pfsync_state_clr);
 1037                 break;
 1038         case PFSYNC_ACT_UPD_C:
 1039                 len = (sc->sc_maxcount * sizeof(struct pfsync_state_upd)) +
 1040                     sizeof(struct pfsync_header);
 1041                 break;
 1042         case PFSYNC_ACT_DEL_C:
 1043                 len = (sc->sc_maxcount * sizeof(struct pfsync_state_del)) +
 1044                     sizeof(struct pfsync_header);
 1045                 break;
 1046         case PFSYNC_ACT_UREQ:
 1047                 len = (sc->sc_maxcount * sizeof(struct pfsync_state_upd_req)) +
 1048                     sizeof(struct pfsync_header);
 1049                 break;
 1050         case PFSYNC_ACT_BUS:
 1051                 len = sizeof(struct pfsync_header) +
 1052                     sizeof(struct pfsync_state_bus);
 1053                 break;
 1054         case PFSYNC_ACT_TDB_UPD:
 1055                 len = (sc->sc_maxcount * sizeof(struct pfsync_tdb)) +
 1056                     sizeof(struct pfsync_header);
 1057                 break;
 1058         default:
 1059                 len = (sc->sc_maxcount * sizeof(struct pfsync_state)) +
 1060                     sizeof(struct pfsync_header);
 1061                 break;
 1062         }
 1063 
 1064         if (len > MHLEN) {
 1065                 MCLGET(m, M_DONTWAIT);
 1066                 if ((m->m_flags & M_EXT) == 0) {
 1067                         m_free(m);
 1068                         sc->sc_if.if_oerrors++;
 1069                         return (NULL);
 1070                 }
 1071                 m->m_data += (MCLBYTES - len) &~ (sizeof(long) - 1);
 1072         } else
 1073                 MH_ALIGN(m, len);
 1074 
 1075         m->m_pkthdr.rcvif = NULL;
 1076         m->m_pkthdr.len = m->m_len = sizeof(struct pfsync_header);
 1077         h = mtod(m, struct pfsync_header *);
 1078         h->version = PFSYNC_VERSION;
 1079         h->af = 0;
 1080         h->count = 0;
 1081         h->action = action;
 1082         if (action != PFSYNC_ACT_TDB_UPD)
 1083                 bcopy(&pf_status.pf_chksum, &h->pf_chksum,
 1084                     PF_MD5_DIGEST_LENGTH);
 1085 
 1086         *sp = (void *)((char *)h + PFSYNC_HDRLEN);
 1087         if (action == PFSYNC_ACT_TDB_UPD)
 1088                 timeout_add(&sc->sc_tdb_tmo, hz);
 1089         else
 1090                 timeout_add(&sc->sc_tmo, hz);
 1091         return (m);
 1092 }
 1093 
 1094 int
 1095 pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags)
 1096 {
 1097         struct ifnet *ifp = NULL;
 1098         struct pfsync_softc *sc = pfsyncif;
 1099         struct pfsync_header *h, *h_net;
 1100         struct pfsync_state *sp = NULL;
 1101         struct pfsync_state_upd *up = NULL;
 1102         struct pfsync_state_del *dp = NULL;
 1103         struct pf_state_key *sk = st->state_key;
 1104         struct pf_rule *r;
 1105         u_long secs;
 1106         int s, ret = 0;
 1107         u_int8_t i = 255, newaction = 0;
 1108 
 1109         if (sc == NULL)
 1110                 return (0);
 1111         ifp = &sc->sc_if;
 1112 
 1113         /*
 1114          * If a packet falls in the forest and there's nobody around to
 1115          * hear, does it make a sound?
 1116          */
 1117         if (ifp->if_bpf == NULL && sc->sc_sync_ifp == NULL &&
 1118             sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
 1119                 /* Don't leave any stale pfsync packets hanging around. */
 1120                 if (sc->sc_mbuf != NULL) {
 1121                         m_freem(sc->sc_mbuf);
 1122                         sc->sc_mbuf = NULL;
 1123                         sc->sc_statep.s = NULL;
 1124                 }
 1125                 return (0);
 1126         }
 1127 
 1128         if (action >= PFSYNC_ACT_MAX)
 1129                 return (EINVAL);
 1130 
 1131         s = splnet();
 1132         if (sc->sc_mbuf == NULL) {
 1133                 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, action,
 1134                     (void *)&sc->sc_statep.s)) == NULL) {
 1135                         splx(s);
 1136                         return (ENOMEM);
 1137                 }
 1138                 h = mtod(sc->sc_mbuf, struct pfsync_header *);
 1139         } else {
 1140                 h = mtod(sc->sc_mbuf, struct pfsync_header *);
 1141                 if (h->action != action) {
 1142                         pfsync_sendout(sc);
 1143                         if ((sc->sc_mbuf = pfsync_get_mbuf(sc, action,
 1144                             (void *)&sc->sc_statep.s)) == NULL) {
 1145                                 splx(s);
 1146                                 return (ENOMEM);
 1147                         }
 1148                         h = mtod(sc->sc_mbuf, struct pfsync_header *);
 1149                 } else {
 1150                         /*
 1151                          * If it's an update, look in the packet to see if
 1152                          * we already have an update for the state.
 1153                          */
 1154                         if (action == PFSYNC_ACT_UPD && sc->sc_maxupdates) {
 1155                                 struct pfsync_state *usp =
 1156                                     (void *)((char *)h + PFSYNC_HDRLEN);
 1157 
 1158                                 for (i = 0; i < h->count; i++) {
 1159                                         if (!memcmp(usp->id, &st->id,
 1160                                             PFSYNC_ID_LEN) &&
 1161                                             usp->creatorid == st->creatorid) {
 1162                                                 sp = usp;
 1163                                                 sp->updates++;
 1164                                                 break;
 1165                                         }
 1166                                         usp++;
 1167                                 }
 1168                         }
 1169                 }
 1170         }
 1171 
 1172         secs = time_second;
 1173 
 1174         st->pfsync_time = time_uptime;
 1175 
 1176         if (sp == NULL) {
 1177                 /* not a "duplicate" update */
 1178                 i = 255;
 1179                 sp = sc->sc_statep.s++;
 1180                 sc->sc_mbuf->m_pkthdr.len =
 1181                     sc->sc_mbuf->m_len += sizeof(struct pfsync_state);
 1182                 h->count++;
 1183                 bzero(sp, sizeof(*sp));
 1184 
 1185                 bcopy(&st->id, sp->id, sizeof(sp->id));
 1186                 sp->creatorid = st->creatorid;
 1187 
 1188                 strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
 1189                 pf_state_host_hton(&sk->lan, &sp->lan);
 1190                 pf_state_host_hton(&sk->gwy, &sp->gwy);
 1191                 pf_state_host_hton(&sk->ext, &sp->ext);
 1192 
 1193                 bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
 1194 
 1195                 sp->creation = htonl(secs - st->creation);
 1196                 pf_state_counter_hton(st->packets[0], sp->packets[0]);
 1197                 pf_state_counter_hton(st->packets[1], sp->packets[1]);
 1198                 pf_state_counter_hton(st->bytes[0], sp->bytes[0]);
 1199                 pf_state_counter_hton(st->bytes[1], sp->bytes[1]);
 1200                 if ((r = st->rule.ptr) == NULL)
 1201                         sp->rule = htonl(-1);
 1202                 else
 1203                         sp->rule = htonl(r->nr);
 1204                 if ((r = st->anchor.ptr) == NULL)
 1205                         sp->anchor = htonl(-1);
 1206                 else
 1207                         sp->anchor = htonl(r->nr);
 1208                 sp->af = sk->af;
 1209                 sp->proto = sk->proto;
 1210                 sp->direction = sk->direction;
 1211                 sp->log = st->log;
 1212                 sp->allow_opts = st->allow_opts;
 1213                 sp->timeout = st->timeout;
 1214 
 1215                 if (flags & PFSYNC_FLAG_STALE)
 1216                         sp->sync_flags |= PFSTATE_STALE;
 1217         }
 1218 
 1219         pf_state_peer_hton(&st->src, &sp->src);
 1220         pf_state_peer_hton(&st->dst, &sp->dst);
 1221 
 1222         if (st->expire <= secs)
 1223                 sp->expire = htonl(0);
 1224         else
 1225                 sp->expire = htonl(st->expire - secs);
 1226 
 1227         /* do we need to build "compressed" actions for network transfer? */
 1228         if (sc->sc_sync_ifp && flags & PFSYNC_FLAG_COMPRESS) {
 1229                 switch (action) {
 1230                 case PFSYNC_ACT_UPD:
 1231                         newaction = PFSYNC_ACT_UPD_C;
 1232                         break;
 1233                 case PFSYNC_ACT_DEL:
 1234                         newaction = PFSYNC_ACT_DEL_C;
 1235                         break;
 1236                 default:
 1237                         /* by default we just send the uncompressed states */
 1238                         break;
 1239                 }
 1240         }
 1241 
 1242         if (newaction) {
 1243                 if (sc->sc_mbuf_net == NULL) {
 1244                         if ((sc->sc_mbuf_net = pfsync_get_mbuf(sc, newaction,
 1245                             (void *)&sc->sc_statep_net.s)) == NULL) {
 1246                                 splx(s);
 1247                                 return (ENOMEM);
 1248                         }
 1249                 }
 1250                 h_net = mtod(sc->sc_mbuf_net, struct pfsync_header *);
 1251 
 1252                 switch (newaction) {
 1253                 case PFSYNC_ACT_UPD_C:
 1254                         if (i != 255) {
 1255                                 up = (void *)((char *)h_net +
 1256                                     PFSYNC_HDRLEN + (i * sizeof(*up)));
 1257                                 up->updates++;
 1258                         } else {
 1259                                 h_net->count++;
 1260                                 sc->sc_mbuf_net->m_pkthdr.len =
 1261                                     sc->sc_mbuf_net->m_len += sizeof(*up);
 1262                                 up = sc->sc_statep_net.u++;
 1263 
 1264                                 bzero(up, sizeof(*up));
 1265                                 bcopy(&st->id, up->id, sizeof(up->id));
 1266                                 up->creatorid = st->creatorid;
 1267                         }
 1268                         up->timeout = st->timeout;
 1269                         up->expire = sp->expire;
 1270                         up->src = sp->src;
 1271                         up->dst = sp->dst;
 1272                         break;
 1273                 case PFSYNC_ACT_DEL_C:
 1274                         sc->sc_mbuf_net->m_pkthdr.len =
 1275                             sc->sc_mbuf_net->m_len += sizeof(*dp);
 1276                         dp = sc->sc_statep_net.d++;
 1277                         h_net->count++;
 1278 
 1279                         bzero(dp, sizeof(*dp));
 1280                         bcopy(&st->id, dp->id, sizeof(dp->id));
 1281                         dp->creatorid = st->creatorid;
 1282                         break;
 1283                 }
 1284         }
 1285 
 1286         if (h->count == sc->sc_maxcount ||
 1287             (sc->sc_maxupdates && (sp->updates >= sc->sc_maxupdates)))
 1288                 ret = pfsync_sendout(sc);
 1289 
 1290         splx(s);
 1291         return (ret);
 1292 }
 1293 
 1294 /* This must be called in splnet() */
 1295 int
 1296 pfsync_request_update(struct pfsync_state_upd *up, struct in_addr *src)
 1297 {
 1298         struct ifnet *ifp = NULL;
 1299         struct pfsync_header *h;
 1300         struct pfsync_softc *sc = pfsyncif;
 1301         struct pfsync_state_upd_req *rup;
 1302         int ret = 0;
 1303 
 1304         if (sc == NULL)
 1305                 return (0);
 1306 
 1307         ifp = &sc->sc_if;
 1308         if (sc->sc_mbuf == NULL) {
 1309                 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ,
 1310                     (void *)&sc->sc_statep.s)) == NULL)
 1311                         return (ENOMEM);
 1312                 h = mtod(sc->sc_mbuf, struct pfsync_header *);
 1313         } else {
 1314                 h = mtod(sc->sc_mbuf, struct pfsync_header *);
 1315                 if (h->action != PFSYNC_ACT_UREQ) {
 1316                         pfsync_sendout(sc);
 1317                         if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ,
 1318                             (void *)&sc->sc_statep.s)) == NULL)
 1319                                 return (ENOMEM);
 1320                         h = mtod(sc->sc_mbuf, struct pfsync_header *);
 1321                 }
 1322         }
 1323 
 1324         if (src != NULL)
 1325                 sc->sc_sendaddr = *src;
 1326         sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*rup);
 1327         h->count++;
 1328         rup = sc->sc_statep.r++;
 1329         bzero(rup, sizeof(*rup));
 1330         if (up != NULL) {
 1331                 bcopy(up->id, rup->id, sizeof(rup->id));
 1332                 rup->creatorid = up->creatorid;
 1333         }
 1334 
 1335         if (h->count == sc->sc_maxcount)
 1336                 ret = pfsync_sendout(sc);
 1337 
 1338         return (ret);
 1339 }
 1340 
 1341 int
 1342 pfsync_clear_states(u_int32_t creatorid, char *ifname)
 1343 {
 1344         struct ifnet *ifp = NULL;
 1345         struct pfsync_softc *sc = pfsyncif;
 1346         struct pfsync_state_clr *cp;
 1347         int s, ret;
 1348 
 1349         if (sc == NULL)
 1350                 return (0);
 1351 
 1352         ifp = &sc->sc_if;
 1353         s = splnet();
 1354         if (sc->sc_mbuf != NULL)
 1355                 pfsync_sendout(sc);
 1356         if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_CLR,
 1357             (void *)&sc->sc_statep.c)) == NULL) {
 1358                 splx(s);
 1359                 return (ENOMEM);
 1360         }
 1361         sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*cp);
 1362         cp = sc->sc_statep.c;
 1363         cp->creatorid = creatorid;
 1364         if (ifname != NULL)
 1365                 strlcpy(cp->ifname, ifname, IFNAMSIZ);
 1366 
 1367         ret = (pfsync_sendout(sc));
 1368         splx(s);
 1369         return (ret);
 1370 }
 1371 
 1372 void
 1373 pfsync_timeout(void *v)
 1374 {
 1375         struct pfsync_softc *sc = v;
 1376         int s;
 1377 
 1378         s = splnet();
 1379         pfsync_sendout(sc);
 1380         splx(s);
 1381 }
 1382 
 1383 void
 1384 pfsync_tdb_timeout(void *v)
 1385 {
 1386         struct pfsync_softc *sc = v;
 1387         int s;
 1388 
 1389         s = splnet();
 1390         pfsync_tdb_sendout(sc);
 1391         splx(s);
 1392 }
 1393 
 1394 /* This must be called in splnet() */
 1395 void
 1396 pfsync_send_bus(struct pfsync_softc *sc, u_int8_t status)
 1397 {
 1398         struct pfsync_state_bus *bus;
 1399 
 1400         if (sc->sc_mbuf != NULL)
 1401                 pfsync_sendout(sc);
 1402 
 1403         if (pfsync_sync_ok &&
 1404             (sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_BUS,
 1405             (void *)&sc->sc_statep.b)) != NULL) {
 1406                 sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*bus);
 1407                 bus = sc->sc_statep.b;
 1408                 bus->creatorid = pf_status.hostid;
 1409                 bus->status = status;
 1410                 bus->endtime = htonl(time_uptime - sc->sc_ureq_received);
 1411                 pfsync_sendout(sc);
 1412         }
 1413 }
 1414 
 1415 void
 1416 pfsync_bulk_update(void *v)
 1417 {
 1418         struct pfsync_softc *sc = v;
 1419         int s, i = 0;
 1420         struct pf_state *state;
 1421 
 1422         s = splnet();
 1423         if (sc->sc_mbuf != NULL)
 1424                 pfsync_sendout(sc);
 1425 
 1426         /*
 1427          * Grab at most PFSYNC_BULKPACKETS worth of states which have not
 1428          * been sent since the latest request was made.
 1429          */
 1430         state = sc->sc_bulk_send_next;
 1431         if (state)
 1432                 do {
 1433                         /* send state update if syncable and not already sent */
 1434                         if (!state->sync_flags
 1435                             && state->timeout < PFTM_MAX
 1436                             && state->pfsync_time <= sc->sc_ureq_received) {
 1437                                 pfsync_pack_state(PFSYNC_ACT_UPD, state, 0);
 1438                                 i++;
 1439                         }
 1440 
 1441                         /* figure next state to send */
 1442                         state = TAILQ_NEXT(state, entry_list);
 1443 
 1444                         /* wrap to start of list if we hit the end */
 1445                         if (!state)
 1446                                 state = TAILQ_FIRST(&state_list);
 1447                 } while (i < sc->sc_maxcount * PFSYNC_BULKPACKETS &&
 1448                     state != sc->sc_bulk_terminator);
 1449 
 1450         if (!state || state == sc->sc_bulk_terminator) {
 1451                 /* we're done */
 1452                 pfsync_send_bus(sc, PFSYNC_BUS_END);
 1453                 sc->sc_ureq_received = 0;
 1454                 sc->sc_bulk_send_next = NULL;
 1455                 sc->sc_bulk_terminator = NULL;
 1456                 timeout_del(&sc->sc_bulk_tmo);
 1457                 if (pf_status.debug >= PF_DEBUG_MISC)
 1458                         printf("pfsync: bulk update complete\n");
 1459         } else {
 1460                 /* look again for more in a bit */
 1461                 timeout_add(&sc->sc_bulk_tmo, 1);
 1462                 sc->sc_bulk_send_next = state;
 1463         }
 1464         if (sc->sc_mbuf != NULL)
 1465                 pfsync_sendout(sc);
 1466         splx(s);
 1467 }
 1468 
 1469 void
 1470 pfsync_bulkfail(void *v)
 1471 {
 1472         struct pfsync_softc *sc = v;
 1473         int s, error;
 1474 
 1475         if (sc->sc_bulk_tries++ < PFSYNC_MAX_BULKTRIES) {
 1476                 /* Try again in a bit */
 1477                 timeout_add(&sc->sc_bulkfail_tmo, 5 * hz);
 1478                 s = splnet();
 1479                 error = pfsync_request_update(NULL, NULL);
 1480                 if (error == ENOMEM) {
 1481                         if (pf_status.debug >= PF_DEBUG_MISC)
 1482                                 printf("pfsync: cannot allocate mbufs for "
 1483                                     "bulk update\n");
 1484                 } else
 1485                         pfsync_sendout(sc);
 1486                 splx(s);
 1487         } else {
 1488                 /* Pretend like the transfer was ok */
 1489                 sc->sc_ureq_sent = 0;
 1490                 sc->sc_bulk_tries = 0;
 1491 #if NCARP > 0
 1492                 if (!pfsync_sync_ok)
 1493                         carp_group_demote_adj(&sc->sc_if, -1);
 1494 #endif
 1495                 pfsync_sync_ok = 1;
 1496                 if (pf_status.debug >= PF_DEBUG_MISC)
 1497                         printf("pfsync: failed to receive "
 1498                             "bulk update status\n");
 1499                 timeout_del(&sc->sc_bulkfail_tmo);
 1500         }
 1501 }
 1502 
 1503 /* This must be called in splnet() */
 1504 int
 1505 pfsync_sendout(struct pfsync_softc *sc)
 1506 {
 1507 #if NBPFILTER > 0
 1508         struct ifnet *ifp = &sc->sc_if;
 1509 #endif
 1510         struct mbuf *m;
 1511 
 1512         timeout_del(&sc->sc_tmo);
 1513 
 1514         if (sc->sc_mbuf == NULL)
 1515                 return (0);
 1516         m = sc->sc_mbuf;
 1517         sc->sc_mbuf = NULL;
 1518         sc->sc_statep.s = NULL;
 1519 
 1520 #if NBPFILTER > 0
 1521         if (ifp->if_bpf)
 1522                 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
 1523 #endif
 1524 
 1525         if (sc->sc_mbuf_net) {
 1526                 m_freem(m);
 1527                 m = sc->sc_mbuf_net;
 1528                 sc->sc_mbuf_net = NULL;
 1529                 sc->sc_statep_net.s = NULL;
 1530         }
 1531 
 1532         return pfsync_sendout_mbuf(sc, m);
 1533 }
 1534 
 1535 int
 1536 pfsync_tdb_sendout(struct pfsync_softc *sc)
 1537 {
 1538 #if NBPFILTER > 0
 1539         struct ifnet *ifp = &sc->sc_if;
 1540 #endif
 1541         struct mbuf *m;
 1542 
 1543         timeout_del(&sc->sc_tdb_tmo);
 1544 
 1545         if (sc->sc_mbuf_tdb == NULL)
 1546                 return (0);
 1547         m = sc->sc_mbuf_tdb;
 1548         sc->sc_mbuf_tdb = NULL;
 1549         sc->sc_statep_tdb.t = NULL;
 1550 
 1551 #if NBPFILTER > 0
 1552         if (ifp->if_bpf)
 1553                 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
 1554 #endif
 1555 
 1556         return pfsync_sendout_mbuf(sc, m);
 1557 }
 1558 
 1559 int
 1560 pfsync_sendout_mbuf(struct pfsync_softc *sc, struct mbuf *m)
 1561 {
 1562         struct sockaddr sa;
 1563         struct ip *ip;
 1564 
 1565         if (sc->sc_sync_ifp ||
 1566             sc->sc_sync_peer.s_addr != INADDR_PFSYNC_GROUP) {
 1567                 M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
 1568                 if (m == NULL) {
 1569                         pfsyncstats.pfsyncs_onomem++;
 1570                         return (0);
 1571                 }
 1572                 ip = mtod(m, struct ip *);
 1573                 ip->ip_v = IPVERSION;
 1574                 ip->ip_hl = sizeof(*ip) >> 2;
 1575                 ip->ip_tos = IPTOS_LOWDELAY;
 1576                 ip->ip_len = htons(m->m_pkthdr.len);
 1577                 ip->ip_id = htons(ip_randomid());
 1578                 ip->ip_off = htons(IP_DF);
 1579                 ip->ip_ttl = PFSYNC_DFLTTL;
 1580                 ip->ip_p = IPPROTO_PFSYNC;
 1581                 ip->ip_sum = 0;
 1582 
 1583                 bzero(&sa, sizeof(sa));
 1584                 ip->ip_src.s_addr = INADDR_ANY;
 1585 
 1586                 if (sc->sc_sendaddr.s_addr == INADDR_PFSYNC_GROUP)
 1587                         m->m_flags |= M_MCAST;
 1588                 ip->ip_dst = sc->sc_sendaddr;
 1589                 sc->sc_sendaddr.s_addr = sc->sc_sync_peer.s_addr;
 1590 
 1591                 pfsyncstats.pfsyncs_opackets++;
 1592 
 1593                 if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL))
 1594                         pfsyncstats.pfsyncs_oerrors++;
 1595         } else
 1596                 m_freem(m);
 1597 
 1598         return (0);
 1599 }
 1600 
 1601 #ifdef IPSEC
 1602 /* Update an in-kernel tdb. Silently fail if no tdb is found. */
 1603 void
 1604 pfsync_update_net_tdb(struct pfsync_tdb *pt)
 1605 {
 1606         struct tdb              *tdb;
 1607         int                      s;
 1608 
 1609         /* check for invalid values */
 1610         if (ntohl(pt->spi) <= SPI_RESERVED_MAX ||
 1611             (pt->dst.sa.sa_family != AF_INET &&
 1612              pt->dst.sa.sa_family != AF_INET6))
 1613                 goto bad;
 1614 
 1615         s = spltdb();
 1616         tdb = gettdb(pt->spi, &pt->dst, pt->sproto);
 1617         if (tdb) {
 1618                 pt->rpl = ntohl(pt->rpl);
 1619                 pt->cur_bytes = betoh64(pt->cur_bytes);
 1620 
 1621                 /* Neither replay nor byte counter should ever decrease. */
 1622                 if (pt->rpl < tdb->tdb_rpl ||
 1623                     pt->cur_bytes < tdb->tdb_cur_bytes) {
 1624                         splx(s);
 1625                         goto bad;
 1626                 }
 1627 
 1628                 tdb->tdb_rpl = pt->rpl;
 1629                 tdb->tdb_cur_bytes = pt->cur_bytes;
 1630         }
 1631         splx(s);
 1632         return;
 1633 
 1634  bad:
 1635         if (pf_status.debug >= PF_DEBUG_MISC)
 1636                 printf("pfsync_insert: PFSYNC_ACT_TDB_UPD: "
 1637                     "invalid value\n");
 1638         pfsyncstats.pfsyncs_badstate++;
 1639         return;
 1640 }
 1641 
 1642 /* One of our local tdbs have been updated, need to sync rpl with others */
 1643 int
 1644 pfsync_update_tdb(struct tdb *tdb, int output)
 1645 {
 1646         struct ifnet *ifp = NULL;
 1647         struct pfsync_softc *sc = pfsyncif;
 1648         struct pfsync_header *h;
 1649         struct pfsync_tdb *pt = NULL;
 1650         int s, i, ret;
 1651 
 1652         if (sc == NULL)
 1653                 return (0);
 1654 
 1655         ifp = &sc->sc_if;
 1656         if (ifp->if_bpf == NULL && sc->sc_sync_ifp == NULL &&
 1657             sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
 1658                 /* Don't leave any stale pfsync packets hanging around. */
 1659                 if (sc->sc_mbuf_tdb != NULL) {
 1660                         m_freem(sc->sc_mbuf_tdb);
 1661                         sc->sc_mbuf_tdb = NULL;
 1662                         sc->sc_statep_tdb.t = NULL;
 1663                 }
 1664                 return (0);
 1665         }
 1666 
 1667         s = splnet();
 1668         if (sc->sc_mbuf_tdb == NULL) {
 1669                 if ((sc->sc_mbuf_tdb = pfsync_get_mbuf(sc, PFSYNC_ACT_TDB_UPD,
 1670                     (void *)&sc->sc_statep_tdb.t)) == NULL) {
 1671                         splx(s);
 1672                         return (ENOMEM);
 1673                 }
 1674                 h = mtod(sc->sc_mbuf_tdb, struct pfsync_header *);
 1675         } else {
 1676                 h = mtod(sc->sc_mbuf_tdb, struct pfsync_header *);
 1677                 if (h->action != PFSYNC_ACT_TDB_UPD) {
 1678                         /*
 1679                          * XXX will never happen as long as there's
 1680                          * only one "TDB action".
 1681                          */
 1682                         pfsync_tdb_sendout(sc);
 1683                         sc->sc_mbuf_tdb = pfsync_get_mbuf(sc,
 1684                             PFSYNC_ACT_TDB_UPD, (void *)&sc->sc_statep_tdb.t);
 1685                         if (sc->sc_mbuf_tdb == NULL) {
 1686                                 splx(s);
 1687                                 return (ENOMEM);
 1688                         }
 1689                         h = mtod(sc->sc_mbuf_tdb, struct pfsync_header *);
 1690                 } else if (sc->sc_maxupdates) {
 1691                         /*
 1692                          * If it's an update, look in the packet to see if
 1693                          * we already have an update for the state.
 1694                          */
 1695                         struct pfsync_tdb *u =
 1696                             (void *)((char *)h + PFSYNC_HDRLEN);
 1697 
 1698                         for (i = 0; !pt && i < h->count; i++) {
 1699                                 if (tdb->tdb_spi == u->spi &&
 1700                                     tdb->tdb_sproto == u->sproto &&
 1701                                     !bcmp(&tdb->tdb_dst, &u->dst,
 1702                                     SA_LEN(&u->dst.sa))) {
 1703                                         pt = u;
 1704                                         pt->updates++;
 1705                                 }
 1706                                 u++;
 1707                         }
 1708                 }
 1709         }
 1710 
 1711         if (pt == NULL) {
 1712                 /* not a "duplicate" update */
 1713                 pt = sc->sc_statep_tdb.t++;
 1714                 sc->sc_mbuf_tdb->m_pkthdr.len =
 1715                     sc->sc_mbuf_tdb->m_len += sizeof(struct pfsync_tdb);
 1716                 h->count++;
 1717                 bzero(pt, sizeof(*pt));
 1718 
 1719                 pt->spi = tdb->tdb_spi;
 1720                 memcpy(&pt->dst, &tdb->tdb_dst, sizeof pt->dst);
 1721                 pt->sproto = tdb->tdb_sproto;
 1722         }
 1723 
 1724         /*
 1725          * When a failover happens, the master's rpl is probably above
 1726          * what we see here (we may be up to a second late), so
 1727          * increase it a bit for outbound tdbs to manage most such
 1728          * situations.
 1729          *
 1730          * For now, just add an offset that is likely to be larger
 1731          * than the number of packets we can see in one second. The RFC
 1732          * just says the next packet must have a higher seq value.
 1733          *
 1734          * XXX What is a good algorithm for this? We could use
 1735          * a rate-determined increase, but to know it, we would have
 1736          * to extend struct tdb.
 1737          * XXX pt->rpl can wrap over MAXINT, but if so the real tdb
 1738          * will soon be replaced anyway. For now, just don't handle
 1739          * this edge case.
 1740          */
 1741 #define RPL_INCR 16384
 1742         pt->rpl = htonl(tdb->tdb_rpl + (output ? RPL_INCR : 0));
 1743         pt->cur_bytes = htobe64(tdb->tdb_cur_bytes);
 1744 
 1745         if (h->count == sc->sc_maxcount ||
 1746             (sc->sc_maxupdates && (pt->updates >= sc->sc_maxupdates)))
 1747                 ret = pfsync_tdb_sendout(sc);
 1748 
 1749         splx(s);
 1750         return (ret);
 1751 }
 1752 #endif

/* [<][>][^][v][top][bottom][index][help] */