This source file includes following definitions.
- pfsyncattach
- pfsync_clone_create
- pfsync_clone_destroy
- pfsyncstart
- pfsync_alloc_scrub_memory
- pfsync_insert_net_state
- pfsync_input
- pfsyncoutput
- pfsyncioctl
- pfsync_setmtu
- pfsync_get_mbuf
- pfsync_pack_state
- pfsync_request_update
- pfsync_clear_states
- pfsync_timeout
- pfsync_tdb_timeout
- pfsync_send_bus
- pfsync_bulk_update
- pfsync_bulkfail
- pfsync_sendout
- pfsync_tdb_sendout
- pfsync_sendout_mbuf
- pfsync_update_net_tdb
- pfsync_update_tdb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
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
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
239 return (0);
240 }
241
242
243
244
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
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
281
282
283 r->states++;
284
285
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
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
349 if (!sc || !sc->sc_sync_ifp || !pf_status.running)
350 goto done;
351
352
353 if (sc->sc_sync_ifp != m->m_pkthdr.rcvif) {
354 pfsyncstats.pfsyncs_badif++;
355 goto done;
356 }
357
358
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
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
390 if (action >= PFSYNC_ACT_MAX) {
391 pfsyncstats.pfsyncs_badact++;
392 goto done;
393 }
394
395
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
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
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
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
519
520
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
531
532
533
534
535
536 pf_state_peer_ntoh(&sp->src, &st->src);
537
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
546
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
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
587
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
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
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
656
657
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
674
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
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
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
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
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
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
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
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
1115
1116
1117 if (ifp->if_bpf == NULL && sc->sc_sync_ifp == NULL &&
1118 sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
1119
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
1152
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
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
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
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
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
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
1428
1429
1430 state = sc->sc_bulk_send_next;
1431 if (state)
1432 do {
1433
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
1442 state = TAILQ_NEXT(state, entry_list);
1443
1444
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
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
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
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
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
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
1603 void
1604 pfsync_update_net_tdb(struct pfsync_tdb *pt)
1605 {
1606 struct tdb *tdb;
1607 int s;
1608
1609
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
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
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
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
1680
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
1693
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
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
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
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