if_pfsync.c revision 1.1.1.2 1 /* $OpenBSD: if_pfsync.c,v 1.37 2004/08/30 07:44:28 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 #include "bpfilter.h"
30 #include "pfsync.h"
31
32 #include <sys/param.h>
33 #include <sys/proc.h>
34 #include <sys/systm.h>
35 #include <sys/time.h>
36 #include <sys/mbuf.h>
37 #include <sys/socket.h>
38 #include <sys/ioctl.h>
39 #include <sys/timeout.h>
40 #include <sys/kernel.h>
41
42 #include <net/if.h>
43 #include <net/if_types.h>
44 #include <net/route.h>
45 #include <net/bpf.h>
46 #include <netinet/tcp.h>
47 #include <netinet/tcp_seq.h>
48
49 #ifdef INET
50 #include <netinet/in.h>
51 #include <netinet/in_systm.h>
52 #include <netinet/in_var.h>
53 #include <netinet/ip.h>
54 #include <netinet/ip_var.h>
55 #endif
56
57 #ifdef INET6
58 #ifndef INET
59 #include <netinet/in.h>
60 #endif
61 #include <netinet6/nd6.h>
62 #endif /* INET6 */
63
64 #include "carp.h"
65 #if NCARP > 0
66 extern int carp_suppress_preempt;
67 #endif
68
69 #include <net/pfvar.h>
70 #include <net/if_pfsync.h>
71
72 #define PFSYNC_MINMTU \
73 (sizeof(struct pfsync_header) + sizeof(struct pf_state))
74
75 #ifdef PFSYNCDEBUG
76 #define DPRINTF(x) do { if (pfsyncdebug) printf x ; } while (0)
77 int pfsyncdebug;
78 #else
79 #define DPRINTF(x)
80 #endif
81
82 struct pfsync_softc pfsyncif;
83 struct pfsyncstats pfsyncstats;
84
85 void pfsyncattach(int);
86 void pfsync_setmtu(struct pfsync_softc *, int);
87 int pfsync_insert_net_state(struct pfsync_state *);
88 int pfsyncoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
89 struct rtentry *);
90 int pfsyncioctl(struct ifnet *, u_long, caddr_t);
91 void pfsyncstart(struct ifnet *);
92
93 struct mbuf *pfsync_get_mbuf(struct pfsync_softc *, u_int8_t, void **);
94 int pfsync_request_update(struct pfsync_state_upd *, struct in_addr *);
95 int pfsync_sendout(struct pfsync_softc *);
96 void pfsync_timeout(void *);
97 void pfsync_send_bus(struct pfsync_softc *, u_int8_t);
98 void pfsync_bulk_update(void *);
99 void pfsync_bulkfail(void *);
100
101 int pfsync_sync_ok;
102 extern int ifqmaxlen;
103
104 void
105 pfsyncattach(int npfsync)
106 {
107 struct ifnet *ifp;
108
109 pfsync_sync_ok = 1;
110 bzero(&pfsyncif, sizeof(pfsyncif));
111 pfsyncif.sc_mbuf = NULL;
112 pfsyncif.sc_mbuf_net = NULL;
113 pfsyncif.sc_statep.s = NULL;
114 pfsyncif.sc_statep_net.s = NULL;
115 pfsyncif.sc_maxupdates = 128;
116 pfsyncif.sc_sync_peer.s_addr = INADDR_PFSYNC_GROUP;
117 pfsyncif.sc_sendaddr.s_addr = INADDR_PFSYNC_GROUP;
118 pfsyncif.sc_ureq_received = 0;
119 pfsyncif.sc_ureq_sent = 0;
120 ifp = &pfsyncif.sc_if;
121 strlcpy(ifp->if_xname, "pfsync0", sizeof ifp->if_xname);
122 ifp->if_softc = &pfsyncif;
123 ifp->if_ioctl = pfsyncioctl;
124 ifp->if_output = pfsyncoutput;
125 ifp->if_start = pfsyncstart;
126 ifp->if_type = IFT_PFSYNC;
127 ifp->if_snd.ifq_maxlen = ifqmaxlen;
128 ifp->if_hdrlen = PFSYNC_HDRLEN;
129 pfsync_setmtu(&pfsyncif, MCLBYTES);
130 timeout_set(&pfsyncif.sc_tmo, pfsync_timeout, &pfsyncif);
131 timeout_set(&pfsyncif.sc_bulk_tmo, pfsync_bulk_update, &pfsyncif);
132 timeout_set(&pfsyncif.sc_bulkfail_tmo, pfsync_bulkfail, &pfsyncif);
133 if_attach(ifp);
134 if_alloc_sadl(ifp);
135
136 #if NBPFILTER > 0
137 bpfattach(&pfsyncif.sc_if.if_bpf, ifp, DLT_PFSYNC, PFSYNC_HDRLEN);
138 #endif
139 }
140
141 /*
142 * Start output on the pfsync interface.
143 */
144 void
145 pfsyncstart(struct ifnet *ifp)
146 {
147 struct mbuf *m;
148 int s;
149
150 for (;;) {
151 s = splimp();
152 IF_DROP(&ifp->if_snd);
153 IF_DEQUEUE(&ifp->if_snd, m);
154 splx(s);
155
156 if (m == NULL)
157 return;
158 else
159 m_freem(m);
160 }
161 }
162
163 int
164 pfsync_insert_net_state(struct pfsync_state *sp)
165 {
166 struct pf_state *st = NULL;
167 struct pf_rule *r = NULL;
168 struct pfi_kif *kif;
169
170 if (sp->creatorid == 0 && pf_status.debug >= PF_DEBUG_MISC) {
171 printf("pfsync_insert_net_state: invalid creator id:"
172 " %08x\n", ntohl(sp->creatorid));
173 return (EINVAL);
174 }
175
176 kif = pfi_lookup_create(sp->ifname);
177 if (kif == NULL) {
178 if (pf_status.debug >= PF_DEBUG_MISC)
179 printf("pfsync_insert_net_state: "
180 "unknown interface: %s\n", sp->ifname);
181 /* skip this state */
182 return (0);
183 }
184
185 /*
186 * Just use the default rule until we have infrastructure to find the
187 * best matching rule.
188 */
189 r = &pf_default_rule;
190
191 if (!r->max_states || r->states < r->max_states)
192 st = pool_get(&pf_state_pl, PR_NOWAIT);
193 if (st == NULL) {
194 pfi_maybe_destroy(kif);
195 return (ENOMEM);
196 }
197 bzero(st, sizeof(*st));
198
199 st->rule.ptr = r;
200 /* XXX get pointers to nat_rule and anchor */
201
202 r->states++;
203
204 /* fill in the rest of the state entry */
205 pf_state_host_ntoh(&sp->lan, &st->lan);
206 pf_state_host_ntoh(&sp->gwy, &st->gwy);
207 pf_state_host_ntoh(&sp->ext, &st->ext);
208
209 pf_state_peer_ntoh(&sp->src, &st->src);
210 pf_state_peer_ntoh(&sp->dst, &st->dst);
211
212 bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr));
213 st->creation = ntohl(sp->creation) + time_second;
214 st->expire = ntohl(sp->expire) + time_second;
215
216 st->af = sp->af;
217 st->proto = sp->proto;
218 st->direction = sp->direction;
219 st->log = sp->log;
220 st->timeout = sp->timeout;
221 st->allow_opts = sp->allow_opts;
222
223 bcopy(sp->id, &st->id, sizeof(st->id));
224 st->creatorid = sp->creatorid;
225 st->sync_flags = sp->sync_flags | PFSTATE_FROMSYNC;
226
227
228 if (pf_insert_state(kif, st)) {
229 pfi_maybe_destroy(kif);
230 pool_put(&pf_state_pl, st);
231 return (EINVAL);
232 }
233
234 return (0);
235 }
236
237 void
238 pfsync_input(struct mbuf *m, ...)
239 {
240 struct ip *ip = mtod(m, struct ip *);
241 struct pfsync_header *ph;
242 struct pfsync_softc *sc = &pfsyncif;
243 struct pf_state *st, key;
244 struct pfsync_state *sp;
245 struct pfsync_state_upd *up;
246 struct pfsync_state_del *dp;
247 struct pfsync_state_clr *cp;
248 struct pfsync_state_upd_req *rup;
249 struct pfsync_state_bus *bus;
250 struct in_addr src;
251 struct mbuf *mp;
252 int iplen, action, error, i, s, count, offp, sfail, stale = 0;
253
254 pfsyncstats.pfsyncs_ipackets++;
255
256 /* verify that we have a sync interface configured */
257 if (!sc->sc_sync_ifp || !pf_status.running)
258 goto done;
259
260 /* verify that the packet came in on the right interface */
261 if (sc->sc_sync_ifp != m->m_pkthdr.rcvif) {
262 pfsyncstats.pfsyncs_badif++;
263 goto done;
264 }
265
266 /* verify that the IP TTL is 255. */
267 if (ip->ip_ttl != PFSYNC_DFLTTL) {
268 pfsyncstats.pfsyncs_badttl++;
269 goto done;
270 }
271
272 iplen = ip->ip_hl << 2;
273
274 if (m->m_pkthdr.len < iplen + sizeof(*ph)) {
275 pfsyncstats.pfsyncs_hdrops++;
276 goto done;
277 }
278
279 if (iplen + sizeof(*ph) > m->m_len) {
280 if ((m = m_pullup(m, iplen + sizeof(*ph))) == NULL) {
281 pfsyncstats.pfsyncs_hdrops++;
282 goto done;
283 }
284 ip = mtod(m, struct ip *);
285 }
286 ph = (struct pfsync_header *)((char *)ip + iplen);
287
288 /* verify the version */
289 if (ph->version != PFSYNC_VERSION) {
290 pfsyncstats.pfsyncs_badver++;
291 goto done;
292 }
293
294 action = ph->action;
295 count = ph->count;
296
297 /* make sure it's a valid action code */
298 if (action >= PFSYNC_ACT_MAX) {
299 pfsyncstats.pfsyncs_badact++;
300 goto done;
301 }
302
303 /* Cheaper to grab this now than having to mess with mbufs later */
304 src = ip->ip_src;
305
306 switch (action) {
307 case PFSYNC_ACT_CLR: {
308 struct pfi_kif *kif;
309 u_int32_t creatorid;
310 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
311 sizeof(*cp), &offp)) == NULL) {
312 pfsyncstats.pfsyncs_badlen++;
313 return;
314 }
315 cp = (struct pfsync_state_clr *)(mp->m_data + offp);
316 creatorid = cp->creatorid;
317
318 s = splsoftnet();
319 if (cp->ifname[0] == '\0') {
320 RB_FOREACH(st, pf_state_tree_id, &tree_id) {
321 if (st->creatorid == creatorid)
322 st->timeout = PFTM_PURGE;
323 }
324 } else {
325 kif = pfi_lookup_if(cp->ifname);
326 if (kif == NULL) {
327 if (pf_status.debug >= PF_DEBUG_MISC)
328 printf("pfsync_input: PFSYNC_ACT_CLR "
329 "bad interface: %s\n", cp->ifname);
330 splx(s);
331 goto done;
332 }
333 RB_FOREACH(st, pf_state_tree_lan_ext,
334 &kif->pfik_lan_ext) {
335 if (st->creatorid == creatorid) {
336 st->timeout = PFTM_PURGE;
337 pf_purge_expired_state(st);
338 }
339 }
340 }
341 splx(s);
342
343 break;
344 }
345 case PFSYNC_ACT_INS:
346 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
347 count * sizeof(*sp), &offp)) == NULL) {
348 pfsyncstats.pfsyncs_badlen++;
349 return;
350 }
351
352 s = splsoftnet();
353 for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp);
354 i < count; i++, sp++) {
355 /* check for invalid values */
356 if (sp->timeout >= PFTM_MAX ||
357 sp->src.state > PF_TCPS_PROXY_DST ||
358 sp->dst.state > PF_TCPS_PROXY_DST ||
359 sp->direction > PF_OUT ||
360 (sp->af != AF_INET && sp->af != AF_INET6)) {
361 if (pf_status.debug >= PF_DEBUG_MISC)
362 printf("pfsync_insert: PFSYNC_ACT_INS: "
363 "invalid value\n");
364 pfsyncstats.pfsyncs_badstate++;
365 continue;
366 }
367
368 if ((error = pfsync_insert_net_state(sp))) {
369 if (error == ENOMEM) {
370 splx(s);
371 goto done;
372 }
373 continue;
374 }
375 }
376 splx(s);
377 break;
378 case PFSYNC_ACT_UPD:
379 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
380 count * sizeof(*sp), &offp)) == NULL) {
381 pfsyncstats.pfsyncs_badlen++;
382 return;
383 }
384
385 s = splsoftnet();
386 for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp);
387 i < count; i++, sp++) {
388 /* check for invalid values */
389 if (sp->timeout >= PFTM_MAX ||
390 sp->src.state > PF_TCPS_PROXY_DST ||
391 sp->dst.state > PF_TCPS_PROXY_DST) {
392 if (pf_status.debug >= PF_DEBUG_MISC)
393 printf("pfsync_insert: PFSYNC_ACT_UPD: "
394 "invalid value\n");
395 pfsyncstats.pfsyncs_badstate++;
396 continue;
397 }
398
399 bcopy(sp->id, &key.id, sizeof(key.id));
400 key.creatorid = sp->creatorid;
401
402 st = pf_find_state_byid(&key);
403 if (st == NULL) {
404 /* insert the update */
405 if (pfsync_insert_net_state(sp))
406 pfsyncstats.pfsyncs_badstate++;
407 continue;
408 }
409 sfail = 0;
410 if (st->proto == IPPROTO_TCP) {
411 /*
412 * The state should never go backwards except
413 * for syn-proxy states. Neither should the
414 * sequence window slide backwards.
415 */
416 if (st->src.state > sp->src.state &&
417 (st->src.state < PF_TCPS_PROXY_SRC ||
418 sp->src.state >= PF_TCPS_PROXY_SRC))
419 sfail = 1;
420 else if (st->dst.state > sp->dst.state)
421 sfail = 2;
422 else if (SEQ_GT(st->src.seqlo,
423 ntohl(sp->src.seqlo)))
424 sfail = 3;
425 else if (st->dst.state >= TCPS_SYN_SENT &&
426 SEQ_GT(st->dst.seqlo, ntohl(sp->dst.seqlo)))
427 sfail = 4;
428 } else {
429 /*
430 * Non-TCP protocol state machine always go
431 * forwards
432 */
433 if (st->src.state > sp->src.state)
434 sfail = 5;
435 else if ( st->dst.state > sp->dst.state)
436 sfail = 6;
437 }
438 if (sfail) {
439 if (pf_status.debug >= PF_DEBUG_MISC)
440 printf("pfsync: ignoring stale update "
441 "(%d) id: %016llx "
442 "creatorid: %08x\n", sfail,
443 betoh64(st->id),
444 ntohl(st->creatorid));
445 pfsyncstats.pfsyncs_badstate++;
446
447 /* we have a better state, send it out */
448 if (sc->sc_mbuf != NULL && !stale)
449 pfsync_sendout(sc);
450 stale++;
451 pfsync_pack_state(PFSYNC_ACT_UPD, st, 0);
452 continue;
453 }
454 pf_state_peer_ntoh(&sp->src, &st->src);
455 pf_state_peer_ntoh(&sp->dst, &st->dst);
456 st->expire = ntohl(sp->expire) + time_second;
457 st->timeout = sp->timeout;
458 }
459 if (stale && sc->sc_mbuf != NULL)
460 pfsync_sendout(sc);
461 splx(s);
462 break;
463 /*
464 * It's not strictly necessary for us to support the "uncompressed"
465 * delete action, but it's relatively simple and maintains consistency.
466 */
467 case PFSYNC_ACT_DEL:
468 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
469 count * sizeof(*sp), &offp)) == NULL) {
470 pfsyncstats.pfsyncs_badlen++;
471 return;
472 }
473
474 s = splsoftnet();
475 for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp);
476 i < count; i++, sp++) {
477 bcopy(sp->id, &key.id, sizeof(key.id));
478 key.creatorid = sp->creatorid;
479
480 st = pf_find_state_byid(&key);
481 if (st == NULL) {
482 pfsyncstats.pfsyncs_badstate++;
483 continue;
484 }
485 st->timeout = PFTM_PURGE;
486 st->sync_flags |= PFSTATE_FROMSYNC;
487 pf_purge_expired_state(st);
488 }
489 splx(s);
490 break;
491 case PFSYNC_ACT_UPD_C: {
492 int update_requested = 0;
493
494 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
495 count * sizeof(*up), &offp)) == NULL) {
496 pfsyncstats.pfsyncs_badlen++;
497 return;
498 }
499
500 s = splsoftnet();
501 for (i = 0, up = (struct pfsync_state_upd *)(mp->m_data + offp);
502 i < count; i++, up++) {
503 /* check for invalid values */
504 if (up->timeout >= PFTM_MAX ||
505 up->src.state > PF_TCPS_PROXY_DST ||
506 up->dst.state > PF_TCPS_PROXY_DST) {
507 if (pf_status.debug >= PF_DEBUG_MISC)
508 printf("pfsync_insert: "
509 "PFSYNC_ACT_UPD_C: "
510 "invalid value\n");
511 pfsyncstats.pfsyncs_badstate++;
512 continue;
513 }
514
515 bcopy(up->id, &key.id, sizeof(key.id));
516 key.creatorid = up->creatorid;
517
518 st = pf_find_state_byid(&key);
519 if (st == NULL) {
520 /* We don't have this state. Ask for it. */
521 error = pfsync_request_update(up, &src);
522 if (error == ENOMEM) {
523 splx(s);
524 goto done;
525 }
526 update_requested = 1;
527 pfsyncstats.pfsyncs_badstate++;
528 continue;
529 }
530 sfail = 0;
531 if (st->proto == IPPROTO_TCP) {
532 /*
533 * The state should never go backwards except
534 * for syn-proxy states. Neither should the
535 * sequence window slide backwards.
536 */
537 if (st->src.state > up->src.state &&
538 (st->src.state < PF_TCPS_PROXY_SRC ||
539 up->src.state >= PF_TCPS_PROXY_SRC))
540 sfail = 1;
541 else if (st->dst.state > up->dst.state)
542 sfail = 2;
543 else if (SEQ_GT(st->src.seqlo,
544 ntohl(up->src.seqlo)))
545 sfail = 3;
546 else if (st->dst.state >= TCPS_SYN_SENT &&
547 SEQ_GT(st->dst.seqlo, ntohl(up->dst.seqlo)))
548 sfail = 4;
549 } else {
550 /*
551 * Non-TCP protocol state machine always go
552 * forwards
553 */
554 if (st->src.state > up->src.state)
555 sfail = 5;
556 else if (st->dst.state > up->dst.state)
557 sfail = 6;
558 }
559 if (sfail) {
560 if (pf_status.debug >= PF_DEBUG_MISC)
561 printf("pfsync: ignoring stale update "
562 "(%d) id: %016llx "
563 "creatorid: %08x\n", sfail,
564 betoh64(st->id),
565 ntohl(st->creatorid));
566 pfsyncstats.pfsyncs_badstate++;
567
568 /* we have a better state, send it out */
569 if ((!stale || update_requested) &&
570 sc->sc_mbuf != NULL) {
571 pfsync_sendout(sc);
572 update_requested = 0;
573 }
574 stale++;
575 pfsync_pack_state(PFSYNC_ACT_UPD, st, 0);
576 continue;
577 }
578 pf_state_peer_ntoh(&up->src, &st->src);
579 pf_state_peer_ntoh(&up->dst, &st->dst);
580 st->expire = ntohl(up->expire) + time_second;
581 st->timeout = up->timeout;
582 }
583 if ((update_requested || stale) && sc->sc_mbuf)
584 pfsync_sendout(sc);
585 splx(s);
586 break;
587 }
588 case PFSYNC_ACT_DEL_C:
589 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
590 count * sizeof(*dp), &offp)) == NULL) {
591 pfsyncstats.pfsyncs_badlen++;
592 return;
593 }
594
595 s = splsoftnet();
596 for (i = 0, dp = (struct pfsync_state_del *)(mp->m_data + offp);
597 i < count; i++, dp++) {
598 bcopy(dp->id, &key.id, sizeof(key.id));
599 key.creatorid = dp->creatorid;
600
601 st = pf_find_state_byid(&key);
602 if (st == NULL) {
603 pfsyncstats.pfsyncs_badstate++;
604 continue;
605 }
606 st->timeout = PFTM_PURGE;
607 st->sync_flags |= PFSTATE_FROMSYNC;
608 pf_purge_expired_state(st);
609 }
610 splx(s);
611 break;
612 case PFSYNC_ACT_INS_F:
613 case PFSYNC_ACT_DEL_F:
614 /* not implemented */
615 break;
616 case PFSYNC_ACT_UREQ:
617 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
618 count * sizeof(*rup), &offp)) == NULL) {
619 pfsyncstats.pfsyncs_badlen++;
620 return;
621 }
622
623 s = splsoftnet();
624 if (sc->sc_mbuf != NULL)
625 pfsync_sendout(sc);
626 for (i = 0,
627 rup = (struct pfsync_state_upd_req *)(mp->m_data + offp);
628 i < count; i++, rup++) {
629 bcopy(rup->id, &key.id, sizeof(key.id));
630 key.creatorid = rup->creatorid;
631
632 if (key.id == 0 && key.creatorid == 0) {
633 sc->sc_ureq_received = time_uptime;
634 if (pf_status.debug >= PF_DEBUG_MISC)
635 printf("pfsync: received "
636 "bulk update request\n");
637 pfsync_send_bus(sc, PFSYNC_BUS_START);
638 timeout_add(&sc->sc_bulk_tmo, 1 * hz);
639 } else {
640 st = pf_find_state_byid(&key);
641 if (st == NULL) {
642 pfsyncstats.pfsyncs_badstate++;
643 continue;
644 }
645 pfsync_pack_state(PFSYNC_ACT_UPD, st, 0);
646 }
647 }
648 if (sc->sc_mbuf != NULL)
649 pfsync_sendout(sc);
650 splx(s);
651 break;
652 case PFSYNC_ACT_BUS:
653 /* If we're not waiting for a bulk update, who cares. */
654 if (sc->sc_ureq_sent == 0)
655 break;
656
657 if ((mp = m_pulldown(m, iplen + sizeof(*ph),
658 sizeof(*bus), &offp)) == NULL) {
659 pfsyncstats.pfsyncs_badlen++;
660 return;
661 }
662 bus = (struct pfsync_state_bus *)(mp->m_data + offp);
663 switch (bus->status) {
664 case PFSYNC_BUS_START:
665 timeout_add(&sc->sc_bulkfail_tmo,
666 pf_pool_limits[PF_LIMIT_STATES].limit /
667 (PFSYNC_BULKPACKETS * sc->sc_maxcount));
668 if (pf_status.debug >= PF_DEBUG_MISC)
669 printf("pfsync: received bulk "
670 "update start\n");
671 break;
672 case PFSYNC_BUS_END:
673 if (time_uptime - ntohl(bus->endtime) >=
674 sc->sc_ureq_sent) {
675 /* that's it, we're happy */
676 sc->sc_ureq_sent = 0;
677 sc->sc_bulk_tries = 0;
678 timeout_del(&sc->sc_bulkfail_tmo);
679 #if NCARP > 0
680 if (!pfsync_sync_ok)
681 carp_suppress_preempt--;
682 #endif
683 pfsync_sync_ok = 1;
684 if (pf_status.debug >= PF_DEBUG_MISC)
685 printf("pfsync: received valid "
686 "bulk update end\n");
687 } else {
688 if (pf_status.debug >= PF_DEBUG_MISC)
689 printf("pfsync: received invalid "
690 "bulk update end: bad timestamp\n");
691 }
692 break;
693 }
694 break;
695 }
696
697 done:
698 if (m)
699 m_freem(m);
700 }
701
702 int
703 pfsyncoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
704 struct rtentry *rt)
705 {
706 m_freem(m);
707 return (0);
708 }
709
710 /* ARGSUSED */
711 int
712 pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
713 {
714 struct proc *p = curproc;
715 struct pfsync_softc *sc = ifp->if_softc;
716 struct ifreq *ifr = (struct ifreq *)data;
717 struct ip_moptions *imo = &sc->sc_imo;
718 struct pfsyncreq pfsyncr;
719 struct ifnet *sifp;
720 int s, error;
721
722 switch (cmd) {
723 case SIOCSIFADDR:
724 case SIOCAIFADDR:
725 case SIOCSIFDSTADDR:
726 case SIOCSIFFLAGS:
727 if (ifp->if_flags & IFF_UP)
728 ifp->if_flags |= IFF_RUNNING;
729 else
730 ifp->if_flags &= ~IFF_RUNNING;
731 break;
732 case SIOCSIFMTU:
733 if (ifr->ifr_mtu < PFSYNC_MINMTU)
734 return (EINVAL);
735 if (ifr->ifr_mtu > MCLBYTES)
736 ifr->ifr_mtu = MCLBYTES;
737 s = splnet();
738 if (ifr->ifr_mtu < ifp->if_mtu)
739 pfsync_sendout(sc);
740 pfsync_setmtu(sc, ifr->ifr_mtu);
741 splx(s);
742 break;
743 case SIOCGETPFSYNC:
744 bzero(&pfsyncr, sizeof(pfsyncr));
745 if (sc->sc_sync_ifp)
746 strlcpy(pfsyncr.pfsyncr_syncif,
747 sc->sc_sync_ifp->if_xname, IFNAMSIZ);
748 pfsyncr.pfsyncr_syncpeer = sc->sc_sync_peer;
749 pfsyncr.pfsyncr_maxupdates = sc->sc_maxupdates;
750 if ((error = copyout(&pfsyncr, ifr->ifr_data, sizeof(pfsyncr))))
751 return (error);
752 break;
753 case SIOCSETPFSYNC:
754 if ((error = suser(p, p->p_acflag)) != 0)
755 return (error);
756 if ((error = copyin(ifr->ifr_data, &pfsyncr, sizeof(pfsyncr))))
757 return (error);
758
759 if (pfsyncr.pfsyncr_syncpeer.s_addr == 0)
760 sc->sc_sync_peer.s_addr = INADDR_PFSYNC_GROUP;
761 else
762 sc->sc_sync_peer.s_addr =
763 pfsyncr.pfsyncr_syncpeer.s_addr;
764
765 if (pfsyncr.pfsyncr_maxupdates > 255)
766 return (EINVAL);
767 sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates;
768
769 if (pfsyncr.pfsyncr_syncif[0] == 0) {
770 sc->sc_sync_ifp = NULL;
771 if (sc->sc_mbuf_net != NULL) {
772 /* Don't keep stale pfsync packets around. */
773 s = splnet();
774 m_freem(sc->sc_mbuf_net);
775 sc->sc_mbuf_net = NULL;
776 sc->sc_statep_net.s = NULL;
777 splx(s);
778 }
779 if (imo->imo_num_memberships > 0) {
780 in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
781 imo->imo_multicast_ifp = NULL;
782 }
783 break;
784 }
785
786 if ((sifp = ifunit(pfsyncr.pfsyncr_syncif)) == NULL)
787 return (EINVAL);
788
789 s = splnet();
790 if (sifp->if_mtu < sc->sc_if.if_mtu ||
791 (sc->sc_sync_ifp != NULL &&
792 sifp->if_mtu < sc->sc_sync_ifp->if_mtu) ||
793 sifp->if_mtu < MCLBYTES - sizeof(struct ip))
794 pfsync_sendout(sc);
795 sc->sc_sync_ifp = sifp;
796
797 pfsync_setmtu(sc, sc->sc_if.if_mtu);
798
799 if (imo->imo_num_memberships > 0) {
800 in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
801 imo->imo_multicast_ifp = NULL;
802 }
803
804 if (sc->sc_sync_ifp &&
805 sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
806 struct in_addr addr;
807
808 if (!(sc->sc_sync_ifp->if_flags & IFF_MULTICAST)) {
809 splx(s);
810 return (EADDRNOTAVAIL);
811 }
812
813 addr.s_addr = INADDR_PFSYNC_GROUP;
814
815 if ((imo->imo_membership[0] =
816 in_addmulti(&addr, sc->sc_sync_ifp)) == NULL) {
817 splx(s);
818 return (ENOBUFS);
819 }
820 imo->imo_num_memberships++;
821 imo->imo_multicast_ifp = sc->sc_sync_ifp;
822 imo->imo_multicast_ttl = PFSYNC_DFLTTL;
823 imo->imo_multicast_loop = 0;
824 }
825
826 if (sc->sc_sync_ifp ||
827 sc->sc_sendaddr.s_addr != INADDR_PFSYNC_GROUP) {
828 /* Request a full state table update. */
829 sc->sc_ureq_sent = time_uptime;
830 #if NCARP > 0
831 if (pfsync_sync_ok)
832 carp_suppress_preempt++;
833 #endif
834 pfsync_sync_ok = 0;
835 if (pf_status.debug >= PF_DEBUG_MISC)
836 printf("pfsync: requesting bulk update\n");
837 timeout_add(&sc->sc_bulkfail_tmo, 5 * hz);
838 error = pfsync_request_update(NULL, NULL);
839 if (error == ENOMEM) {
840 splx(s);
841 return (ENOMEM);
842 }
843 pfsync_sendout(sc);
844 }
845 splx(s);
846
847 break;
848
849 default:
850 return (ENOTTY);
851 }
852
853 return (0);
854 }
855
856 void
857 pfsync_setmtu(struct pfsync_softc *sc, int mtu_req)
858 {
859 int mtu;
860
861 if (sc->sc_sync_ifp && sc->sc_sync_ifp->if_mtu < mtu_req)
862 mtu = sc->sc_sync_ifp->if_mtu;
863 else
864 mtu = mtu_req;
865
866 sc->sc_maxcount = (mtu - sizeof(struct pfsync_header)) /
867 sizeof(struct pfsync_state);
868 if (sc->sc_maxcount > 254)
869 sc->sc_maxcount = 254;
870 sc->sc_if.if_mtu = sizeof(struct pfsync_header) +
871 sc->sc_maxcount * sizeof(struct pfsync_state);
872 }
873
874 struct mbuf *
875 pfsync_get_mbuf(struct pfsync_softc *sc, u_int8_t action, void **sp)
876 {
877 struct pfsync_header *h;
878 struct mbuf *m;
879 int len;
880
881 MGETHDR(m, M_DONTWAIT, MT_DATA);
882 if (m == NULL) {
883 sc->sc_if.if_oerrors++;
884 return (NULL);
885 }
886
887 switch (action) {
888 case PFSYNC_ACT_CLR:
889 len = sizeof(struct pfsync_header) +
890 sizeof(struct pfsync_state_clr);
891 break;
892 case PFSYNC_ACT_UPD_C:
893 len = (sc->sc_maxcount * sizeof(struct pfsync_state_upd)) +
894 sizeof(struct pfsync_header);
895 break;
896 case PFSYNC_ACT_DEL_C:
897 len = (sc->sc_maxcount * sizeof(struct pfsync_state_del)) +
898 sizeof(struct pfsync_header);
899 break;
900 case PFSYNC_ACT_UREQ:
901 len = (sc->sc_maxcount * sizeof(struct pfsync_state_upd_req)) +
902 sizeof(struct pfsync_header);
903 break;
904 case PFSYNC_ACT_BUS:
905 len = sizeof(struct pfsync_header) +
906 sizeof(struct pfsync_state_bus);
907 break;
908 default:
909 len = (sc->sc_maxcount * sizeof(struct pfsync_state)) +
910 sizeof(struct pfsync_header);
911 break;
912 }
913
914 if (len > MHLEN) {
915 MCLGET(m, M_DONTWAIT);
916 if ((m->m_flags & M_EXT) == 0) {
917 m_free(m);
918 sc->sc_if.if_oerrors++;
919 return (NULL);
920 }
921 m->m_data += (MCLBYTES - len) &~ (sizeof(long) - 1);
922 } else
923 MH_ALIGN(m, len);
924
925 m->m_pkthdr.rcvif = NULL;
926 m->m_pkthdr.len = m->m_len = sizeof(struct pfsync_header);
927 h = mtod(m, struct pfsync_header *);
928 h->version = PFSYNC_VERSION;
929 h->af = 0;
930 h->count = 0;
931 h->action = action;
932
933 *sp = (void *)((char *)h + PFSYNC_HDRLEN);
934 timeout_add(&sc->sc_tmo, hz);
935 return (m);
936 }
937
938 int
939 pfsync_pack_state(u_int8_t action, struct pf_state *st, int compress)
940 {
941 struct ifnet *ifp = &pfsyncif.sc_if;
942 struct pfsync_softc *sc = ifp->if_softc;
943 struct pfsync_header *h, *h_net;
944 struct pfsync_state *sp = NULL;
945 struct pfsync_state_upd *up = NULL;
946 struct pfsync_state_del *dp = NULL;
947 struct pf_rule *r;
948 u_long secs;
949 int s, ret = 0;
950 u_int8_t i = 255, newaction = 0;
951
952 /*
953 * If a packet falls in the forest and there's nobody around to
954 * hear, does it make a sound?
955 */
956 if (ifp->if_bpf == NULL && sc->sc_sync_ifp == NULL &&
957 sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
958 /* Don't leave any stale pfsync packets hanging around. */
959 if (sc->sc_mbuf != NULL) {
960 m_freem(sc->sc_mbuf);
961 sc->sc_mbuf = NULL;
962 sc->sc_statep.s = NULL;
963 }
964 return (0);
965 }
966
967 if (action >= PFSYNC_ACT_MAX)
968 return (EINVAL);
969
970 s = splnet();
971 if (sc->sc_mbuf == NULL) {
972 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, action,
973 (void *)&sc->sc_statep.s)) == NULL) {
974 splx(s);
975 return (ENOMEM);
976 }
977 h = mtod(sc->sc_mbuf, struct pfsync_header *);
978 } else {
979 h = mtod(sc->sc_mbuf, struct pfsync_header *);
980 if (h->action != action) {
981 pfsync_sendout(sc);
982 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, action,
983 (void *)&sc->sc_statep.s)) == NULL) {
984 splx(s);
985 return (ENOMEM);
986 }
987 h = mtod(sc->sc_mbuf, struct pfsync_header *);
988 } else {
989 /*
990 * If it's an update, look in the packet to see if
991 * we already have an update for the state.
992 */
993 if (action == PFSYNC_ACT_UPD && sc->sc_maxupdates) {
994 struct pfsync_state *usp =
995 (void *)((char *)h + PFSYNC_HDRLEN);
996
997 for (i = 0; i < h->count; i++) {
998 if (!memcmp(usp->id, &st->id,
999 PFSYNC_ID_LEN) &&
1000 usp->creatorid == st->creatorid) {
1001 sp = usp;
1002 sp->updates++;
1003 break;
1004 }
1005 usp++;
1006 }
1007 }
1008 }
1009 }
1010
1011 secs = time_second;
1012
1013 st->pfsync_time = time_uptime;
1014 TAILQ_REMOVE(&state_updates, st, u.s.entry_updates);
1015 TAILQ_INSERT_TAIL(&state_updates, st, u.s.entry_updates);
1016
1017 if (sp == NULL) {
1018 /* not a "duplicate" update */
1019 i = 255;
1020 sp = sc->sc_statep.s++;
1021 sc->sc_mbuf->m_pkthdr.len =
1022 sc->sc_mbuf->m_len += sizeof(struct pfsync_state);
1023 h->count++;
1024 bzero(sp, sizeof(*sp));
1025
1026 bcopy(&st->id, sp->id, sizeof(sp->id));
1027 sp->creatorid = st->creatorid;
1028
1029 strlcpy(sp->ifname, st->u.s.kif->pfik_name, sizeof(sp->ifname));
1030 pf_state_host_hton(&st->lan, &sp->lan);
1031 pf_state_host_hton(&st->gwy, &sp->gwy);
1032 pf_state_host_hton(&st->ext, &sp->ext);
1033
1034 bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
1035
1036 sp->creation = htonl(secs - st->creation);
1037 sp->packets[0] = htonl(st->packets[0]);
1038 sp->packets[1] = htonl(st->packets[1]);
1039 sp->bytes[0] = htonl(st->bytes[0]);
1040 sp->bytes[1] = htonl(st->bytes[1]);
1041 if ((r = st->rule.ptr) == NULL)
1042 sp->rule = htonl(-1);
1043 else
1044 sp->rule = htonl(r->nr);
1045 if ((r = st->anchor.ptr) == NULL)
1046 sp->anchor = htonl(-1);
1047 else
1048 sp->anchor = htonl(r->nr);
1049 sp->af = st->af;
1050 sp->proto = st->proto;
1051 sp->direction = st->direction;
1052 sp->log = st->log;
1053 sp->allow_opts = st->allow_opts;
1054 sp->timeout = st->timeout;
1055
1056 sp->sync_flags = st->sync_flags & PFSTATE_NOSYNC;
1057 }
1058
1059 pf_state_peer_hton(&st->src, &sp->src);
1060 pf_state_peer_hton(&st->dst, &sp->dst);
1061
1062 if (st->expire <= secs)
1063 sp->expire = htonl(0);
1064 else
1065 sp->expire = htonl(st->expire - secs);
1066
1067 /* do we need to build "compressed" actions for network transfer? */
1068 if (sc->sc_sync_ifp && compress) {
1069 switch (action) {
1070 case PFSYNC_ACT_UPD:
1071 newaction = PFSYNC_ACT_UPD_C;
1072 break;
1073 case PFSYNC_ACT_DEL:
1074 newaction = PFSYNC_ACT_DEL_C;
1075 break;
1076 default:
1077 /* by default we just send the uncompressed states */
1078 break;
1079 }
1080 }
1081
1082 if (newaction) {
1083 if (sc->sc_mbuf_net == NULL) {
1084 if ((sc->sc_mbuf_net = pfsync_get_mbuf(sc, newaction,
1085 (void *)&sc->sc_statep_net.s)) == NULL) {
1086 splx(s);
1087 return (ENOMEM);
1088 }
1089 }
1090 h_net = mtod(sc->sc_mbuf_net, struct pfsync_header *);
1091
1092 switch (newaction) {
1093 case PFSYNC_ACT_UPD_C:
1094 if (i != 255) {
1095 up = (void *)((char *)h_net +
1096 PFSYNC_HDRLEN + (i * sizeof(*up)));
1097 up->updates++;
1098 } else {
1099 h_net->count++;
1100 sc->sc_mbuf_net->m_pkthdr.len =
1101 sc->sc_mbuf_net->m_len += sizeof(*up);
1102 up = sc->sc_statep_net.u++;
1103
1104 bzero(up, sizeof(*up));
1105 bcopy(&st->id, up->id, sizeof(up->id));
1106 up->creatorid = st->creatorid;
1107 }
1108 up->timeout = st->timeout;
1109 up->expire = sp->expire;
1110 up->src = sp->src;
1111 up->dst = sp->dst;
1112 break;
1113 case PFSYNC_ACT_DEL_C:
1114 sc->sc_mbuf_net->m_pkthdr.len =
1115 sc->sc_mbuf_net->m_len += sizeof(*dp);
1116 dp = sc->sc_statep_net.d++;
1117 h_net->count++;
1118
1119 bzero(dp, sizeof(*dp));
1120 bcopy(&st->id, dp->id, sizeof(dp->id));
1121 dp->creatorid = st->creatorid;
1122 break;
1123 }
1124 }
1125
1126 if (h->count == sc->sc_maxcount ||
1127 (sc->sc_maxupdates && (sp->updates >= sc->sc_maxupdates)))
1128 ret = pfsync_sendout(sc);
1129
1130 splx(s);
1131 return (ret);
1132 }
1133
1134 /* This must be called in splnet() */
1135 int
1136 pfsync_request_update(struct pfsync_state_upd *up, struct in_addr *src)
1137 {
1138 struct ifnet *ifp = &pfsyncif.sc_if;
1139 struct pfsync_header *h;
1140 struct pfsync_softc *sc = ifp->if_softc;
1141 struct pfsync_state_upd_req *rup;
1142 int ret = 0;
1143
1144 if (sc->sc_mbuf == NULL) {
1145 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ,
1146 (void *)&sc->sc_statep.s)) == NULL)
1147 return (ENOMEM);
1148 h = mtod(sc->sc_mbuf, struct pfsync_header *);
1149 } else {
1150 h = mtod(sc->sc_mbuf, struct pfsync_header *);
1151 if (h->action != PFSYNC_ACT_UREQ) {
1152 pfsync_sendout(sc);
1153 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ,
1154 (void *)&sc->sc_statep.s)) == NULL)
1155 return (ENOMEM);
1156 h = mtod(sc->sc_mbuf, struct pfsync_header *);
1157 }
1158 }
1159
1160 if (src != NULL)
1161 sc->sc_sendaddr = *src;
1162 sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*rup);
1163 h->count++;
1164 rup = sc->sc_statep.r++;
1165 bzero(rup, sizeof(*rup));
1166 if (up != NULL) {
1167 bcopy(up->id, rup->id, sizeof(rup->id));
1168 rup->creatorid = up->creatorid;
1169 }
1170
1171 if (h->count == sc->sc_maxcount)
1172 ret = pfsync_sendout(sc);
1173
1174 return (ret);
1175 }
1176
1177 int
1178 pfsync_clear_states(u_int32_t creatorid, char *ifname)
1179 {
1180 struct ifnet *ifp = &pfsyncif.sc_if;
1181 struct pfsync_softc *sc = ifp->if_softc;
1182 struct pfsync_state_clr *cp;
1183 int s, ret;
1184
1185 s = splnet();
1186 if (sc->sc_mbuf != NULL)
1187 pfsync_sendout(sc);
1188 if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_CLR,
1189 (void *)&sc->sc_statep.c)) == NULL) {
1190 splx(s);
1191 return (ENOMEM);
1192 }
1193 sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*cp);
1194 cp = sc->sc_statep.c;
1195 cp->creatorid = creatorid;
1196 if (ifname != NULL)
1197 strlcpy(cp->ifname, ifname, IFNAMSIZ);
1198
1199 ret = (pfsync_sendout(sc));
1200 splx(s);
1201 return (ret);
1202 }
1203
1204 void
1205 pfsync_timeout(void *v)
1206 {
1207 struct pfsync_softc *sc = v;
1208 int s;
1209
1210 s = splnet();
1211 pfsync_sendout(sc);
1212 splx(s);
1213 }
1214
1215 /* This must be called in splnet() */
1216 void
1217 pfsync_send_bus(struct pfsync_softc *sc, u_int8_t status)
1218 {
1219 struct pfsync_state_bus *bus;
1220
1221 if (sc->sc_mbuf != NULL)
1222 pfsync_sendout(sc);
1223
1224 if (pfsync_sync_ok &&
1225 (sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_BUS,
1226 (void *)&sc->sc_statep.b)) != NULL) {
1227 sc->sc_mbuf->m_pkthdr.len = sc->sc_mbuf->m_len += sizeof(*bus);
1228 bus = sc->sc_statep.b;
1229 bus->creatorid = pf_status.hostid;
1230 bus->status = status;
1231 bus->endtime = htonl(time_uptime - sc->sc_ureq_received);
1232 pfsync_sendout(sc);
1233 }
1234 }
1235
1236 void
1237 pfsync_bulk_update(void *v)
1238 {
1239 struct pfsync_softc *sc = v;
1240 int s, i = 0;
1241 struct pf_state *state;
1242
1243 s = splnet();
1244 if (sc->sc_mbuf != NULL)
1245 pfsync_sendout(sc);
1246
1247 /*
1248 * Grab at most PFSYNC_BULKPACKETS worth of states which have not
1249 * been sent since the latest request was made.
1250 */
1251 while ((state = TAILQ_FIRST(&state_updates)) != NULL &&
1252 ++i < (sc->sc_maxcount * PFSYNC_BULKPACKETS)) {
1253 if (state->pfsync_time > sc->sc_ureq_received) {
1254 /* we're done */
1255 pfsync_send_bus(sc, PFSYNC_BUS_END);
1256 sc->sc_ureq_received = 0;
1257 timeout_del(&sc->sc_bulk_tmo);
1258 if (pf_status.debug >= PF_DEBUG_MISC)
1259 printf("pfsync: bulk update complete\n");
1260 break;
1261 } else {
1262 /* send an update and move to end of list */
1263 if (!state->sync_flags)
1264 pfsync_pack_state(PFSYNC_ACT_UPD, state, 0);
1265 state->pfsync_time = time_uptime;
1266 TAILQ_REMOVE(&state_updates, state, u.s.entry_updates);
1267 TAILQ_INSERT_TAIL(&state_updates, state,
1268 u.s.entry_updates);
1269
1270 /* look again for more in a bit */
1271 timeout_add(&sc->sc_bulk_tmo, 1);
1272 }
1273 }
1274 if (sc->sc_mbuf != NULL)
1275 pfsync_sendout(sc);
1276 splx(s);
1277 }
1278
1279 void
1280 pfsync_bulkfail(void *v)
1281 {
1282 struct pfsync_softc *sc = v;
1283 int s, error;
1284
1285 if (sc->sc_bulk_tries++ < PFSYNC_MAX_BULKTRIES) {
1286 /* Try again in a bit */
1287 timeout_add(&sc->sc_bulkfail_tmo, 5 * hz);
1288 s = splnet();
1289 error = pfsync_request_update(NULL, NULL);
1290 if (error == ENOMEM) {
1291 if (pf_status.debug >= PF_DEBUG_MISC)
1292 printf("pfsync: cannot allocate mbufs for "
1293 "bulk update\n");
1294 } else
1295 pfsync_sendout(sc);
1296 splx(s);
1297 } else {
1298 /* Pretend like the transfer was ok */
1299 sc->sc_ureq_sent = 0;
1300 sc->sc_bulk_tries = 0;
1301 #if NCARP > 0
1302 if (!pfsync_sync_ok)
1303 carp_suppress_preempt--;
1304 #endif
1305 pfsync_sync_ok = 1;
1306 if (pf_status.debug >= PF_DEBUG_MISC)
1307 printf("pfsync: failed to receive "
1308 "bulk update status\n");
1309 timeout_del(&sc->sc_bulkfail_tmo);
1310 }
1311 }
1312
1313 /* This must be called in splnet() */
1314 int
1315 pfsync_sendout(sc)
1316 struct pfsync_softc *sc;
1317 {
1318 struct ifnet *ifp = &sc->sc_if;
1319 struct mbuf *m;
1320
1321 timeout_del(&sc->sc_tmo);
1322
1323 if (sc->sc_mbuf == NULL)
1324 return (0);
1325 m = sc->sc_mbuf;
1326 sc->sc_mbuf = NULL;
1327 sc->sc_statep.s = NULL;
1328
1329 #if NBPFILTER > 0
1330 if (ifp->if_bpf)
1331 bpf_mtap(ifp->if_bpf, m);
1332 #endif
1333
1334 if (sc->sc_mbuf_net) {
1335 m_freem(m);
1336 m = sc->sc_mbuf_net;
1337 sc->sc_mbuf_net = NULL;
1338 sc->sc_statep_net.s = NULL;
1339 }
1340
1341 if (sc->sc_sync_ifp || sc->sc_sync_peer.s_addr != INADDR_PFSYNC_GROUP) {
1342 struct ip *ip;
1343 struct sockaddr sa;
1344
1345 M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
1346 if (m == NULL) {
1347 pfsyncstats.pfsyncs_onomem++;
1348 return (0);
1349 }
1350 ip = mtod(m, struct ip *);
1351 ip->ip_v = IPVERSION;
1352 ip->ip_hl = sizeof(*ip) >> 2;
1353 ip->ip_tos = IPTOS_LOWDELAY;
1354 ip->ip_len = htons(m->m_pkthdr.len);
1355 ip->ip_id = htons(ip_randomid());
1356 ip->ip_off = htons(IP_DF);
1357 ip->ip_ttl = PFSYNC_DFLTTL;
1358 ip->ip_p = IPPROTO_PFSYNC;
1359 ip->ip_sum = 0;
1360
1361 bzero(&sa, sizeof(sa));
1362 ip->ip_src.s_addr = INADDR_ANY;
1363
1364 if (sc->sc_sendaddr.s_addr == INADDR_PFSYNC_GROUP)
1365 m->m_flags |= M_MCAST;
1366 ip->ip_dst = sc->sc_sendaddr;
1367 sc->sc_sendaddr.s_addr = sc->sc_sync_peer.s_addr;
1368
1369 pfsyncstats.pfsyncs_opackets++;
1370
1371 if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL))
1372 pfsyncstats.pfsyncs_oerrors++;
1373 } else
1374 m_freem(m);
1375
1376 return (0);
1377 }
1378