if_pfsync.c (cdc231bd49498481801686913872c361dbc01f95) if_pfsync.c (4bf98559d9d6fa7c3571d26ed6f2b18823e3a30b)
1/*-
2 * SPDX-License-Identifier: (BSD-2-Clause AND ISC)
3 *
4 * Copyright (c) 2002 Michael Shalayeff
5 * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 108 unchanged lines hidden (view full) ---

117
118#define PFSYNC_MINPKT ( \
119 sizeof(union inet_template) + \
120 sizeof(struct pfsync_header) + \
121 sizeof(struct pfsync_subheader) )
122
123static int pfsync_upd_tcp(struct pf_kstate *, struct pfsync_state_peer *,
124 struct pfsync_state_peer *);
1/*-
2 * SPDX-License-Identifier: (BSD-2-Clause AND ISC)
3 *
4 * Copyright (c) 2002 Michael Shalayeff
5 * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 108 unchanged lines hidden (view full) ---

117
118#define PFSYNC_MINPKT ( \
119 sizeof(union inet_template) + \
120 sizeof(struct pfsync_header) + \
121 sizeof(struct pfsync_subheader) )
122
123static int pfsync_upd_tcp(struct pf_kstate *, struct pfsync_state_peer *,
124 struct pfsync_state_peer *);
125static int pfsync_in_clr(struct mbuf *, int, int, int);
126static int pfsync_in_ins(struct mbuf *, int, int, int);
127static int pfsync_in_iack(struct mbuf *, int, int, int);
128static int pfsync_in_upd(struct mbuf *, int, int, int);
129static int pfsync_in_upd_c(struct mbuf *, int, int, int);
130static int pfsync_in_ureq(struct mbuf *, int, int, int);
131static int pfsync_in_del_c(struct mbuf *, int, int, int);
132static int pfsync_in_bus(struct mbuf *, int, int, int);
133static int pfsync_in_tdb(struct mbuf *, int, int, int);
134static int pfsync_in_eof(struct mbuf *, int, int, int);
135static int pfsync_in_error(struct mbuf *, int, int, int);
125static int pfsync_in_clr(struct mbuf *, int, int, int, int);
126static int pfsync_in_ins(struct mbuf *, int, int, int, int);
127static int pfsync_in_iack(struct mbuf *, int, int, int, int);
128static int pfsync_in_upd(struct mbuf *, int, int, int, int);
129static int pfsync_in_upd_c(struct mbuf *, int, int, int, int);
130static int pfsync_in_ureq(struct mbuf *, int, int, int, int);
131static int pfsync_in_del_c(struct mbuf *, int, int, int, int);
132static int pfsync_in_bus(struct mbuf *, int, int, int, int);
133static int pfsync_in_tdb(struct mbuf *, int, int, int, int);
134static int pfsync_in_eof(struct mbuf *, int, int, int, int);
135static int pfsync_in_error(struct mbuf *, int, int, int, int);
136
136
137static int (*pfsync_acts[])(struct mbuf *, int, int, int) = {
137static int (*pfsync_acts[])(struct mbuf *, int, int, int, int) = {
138 pfsync_in_clr, /* PFSYNC_ACT_CLR */
138 pfsync_in_clr, /* PFSYNC_ACT_CLR */
139 pfsync_in_ins, /* PFSYNC_ACT_INS */
139 pfsync_in_ins, /* PFSYNC_ACT_INS_1301 */
140 pfsync_in_iack, /* PFSYNC_ACT_INS_ACK */
140 pfsync_in_iack, /* PFSYNC_ACT_INS_ACK */
141 pfsync_in_upd, /* PFSYNC_ACT_UPD */
141 pfsync_in_upd, /* PFSYNC_ACT_UPD_1301 */
142 pfsync_in_upd_c, /* PFSYNC_ACT_UPD_C */
143 pfsync_in_ureq, /* PFSYNC_ACT_UPD_REQ */
144 pfsync_in_error, /* PFSYNC_ACT_DEL */
145 pfsync_in_del_c, /* PFSYNC_ACT_DEL_C */
146 pfsync_in_error, /* PFSYNC_ACT_INS_F */
147 pfsync_in_error, /* PFSYNC_ACT_DEL_F */
148 pfsync_in_bus, /* PFSYNC_ACT_BUS */
149 pfsync_in_tdb, /* PFSYNC_ACT_TDB */
142 pfsync_in_upd_c, /* PFSYNC_ACT_UPD_C */
143 pfsync_in_ureq, /* PFSYNC_ACT_UPD_REQ */
144 pfsync_in_error, /* PFSYNC_ACT_DEL */
145 pfsync_in_del_c, /* PFSYNC_ACT_DEL_C */
146 pfsync_in_error, /* PFSYNC_ACT_INS_F */
147 pfsync_in_error, /* PFSYNC_ACT_DEL_F */
148 pfsync_in_bus, /* PFSYNC_ACT_BUS */
149 pfsync_in_tdb, /* PFSYNC_ACT_TDB */
150 pfsync_in_eof /* PFSYNC_ACT_EOF */
150 pfsync_in_eof, /* PFSYNC_ACT_EOF */
151 pfsync_in_ins, /* PFSYNC_ACT_INS_1400 */
152 pfsync_in_upd, /* PFSYNC_ACT_UPD_1400 */
151};
152
153struct pfsync_q {
154 void (*write)(struct pf_kstate *, void *);
155 size_t len;
156 u_int8_t action;
157};
158
153};
154
155struct pfsync_q {
156 void (*write)(struct pf_kstate *, void *);
157 size_t len;
158 u_int8_t action;
159};
160
159/* we have one of these for every PFSYNC_S_ */
160static void pfsync_out_state(struct pf_kstate *, void *);
161/* We have the following sync queues */
162enum pfsync_q_id {
163 PFSYNC_Q_INS_1301,
164 PFSYNC_Q_INS_1400,
165 PFSYNC_Q_IACK,
166 PFSYNC_Q_UPD_1301,
167 PFSYNC_Q_UPD_1400,
168 PFSYNC_Q_UPD_C,
169 PFSYNC_Q_DEL_C,
170 PFSYNC_Q_COUNT,
171};
172
173/* Functions for building messages for given queue */
174static void pfsync_out_state_1301(struct pf_kstate *, void *);
175static void pfsync_out_state_1400(struct pf_kstate *, void *);
161static void pfsync_out_iack(struct pf_kstate *, void *);
162static void pfsync_out_upd_c(struct pf_kstate *, void *);
163static void pfsync_out_del_c(struct pf_kstate *, void *);
164
176static void pfsync_out_iack(struct pf_kstate *, void *);
177static void pfsync_out_upd_c(struct pf_kstate *, void *);
178static void pfsync_out_del_c(struct pf_kstate *, void *);
179
180/* Attach those functions to queue */
165static struct pfsync_q pfsync_qs[] = {
181static struct pfsync_q pfsync_qs[] = {
166 { pfsync_out_state, sizeof(struct pfsync_state), PFSYNC_ACT_INS },
167 { pfsync_out_iack, sizeof(struct pfsync_ins_ack), PFSYNC_ACT_INS_ACK },
168 { pfsync_out_state, sizeof(struct pfsync_state), PFSYNC_ACT_UPD },
169 { pfsync_out_upd_c, sizeof(struct pfsync_upd_c), PFSYNC_ACT_UPD_C },
170 { pfsync_out_del_c, sizeof(struct pfsync_del_c), PFSYNC_ACT_DEL_C }
182 { pfsync_out_state_1301, sizeof(struct pfsync_state_1301), PFSYNC_ACT_INS_1301 },
183 { pfsync_out_state_1400, sizeof(struct pfsync_state_1400), PFSYNC_ACT_INS_1400 },
184 { pfsync_out_iack, sizeof(struct pfsync_ins_ack), PFSYNC_ACT_INS_ACK },
185 { pfsync_out_state_1301, sizeof(struct pfsync_state_1301), PFSYNC_ACT_UPD_1301 },
186 { pfsync_out_state_1400, sizeof(struct pfsync_state_1400), PFSYNC_ACT_UPD_1400 },
187 { pfsync_out_upd_c, sizeof(struct pfsync_upd_c), PFSYNC_ACT_UPD_C },
188 { pfsync_out_del_c, sizeof(struct pfsync_del_c), PFSYNC_ACT_DEL_C }
171};
172
189};
190
173static void pfsync_q_ins(struct pf_kstate *, int, bool);
191/* Map queue to pf_kstate->sync_state */
192static u_int8_t pfsync_qid_sstate[] = {
193 PFSYNC_S_INS, /* PFSYNC_Q_INS_1301 */
194 PFSYNC_S_INS, /* PFSYNC_Q_INS_1400 */
195 PFSYNC_S_IACK, /* PFSYNC_Q_IACK */
196 PFSYNC_S_UPD, /* PFSYNC_Q_UPD_1301 */
197 PFSYNC_S_UPD, /* PFSYNC_Q_UPD_1400 */
198 PFSYNC_S_UPD_C, /* PFSYNC_Q_UPD_C */
199 PFSYNC_S_DEL_C, /* PFSYNC_Q_DEL_C */
200};
201
202/* Map pf_kstate->sync_state to queue */
203static enum pfsync_q_id pfsync_sstate_to_qid(u_int8_t);
204
205static void pfsync_q_ins(struct pf_kstate *, int sync_state, bool);
174static void pfsync_q_del(struct pf_kstate *, bool, struct pfsync_bucket *);
175
176static void pfsync_update_state(struct pf_kstate *);
177static void pfsync_tx(struct pfsync_softc *, struct mbuf *);
178
179struct pfsync_upd_req_item {
180 TAILQ_ENTRY(pfsync_upd_req_item) ur_entry;
181 struct pfsync_upd_req ur_msg;

--- 13 unchanged lines hidden (view full) ---

195 int b_id;
196 struct pfsync_softc *b_sc;
197 struct mtx b_mtx;
198 struct callout b_tmo;
199 int b_flags;
200#define PFSYNCF_BUCKET_PUSH 0x00000001
201
202 size_t b_len;
206static void pfsync_q_del(struct pf_kstate *, bool, struct pfsync_bucket *);
207
208static void pfsync_update_state(struct pf_kstate *);
209static void pfsync_tx(struct pfsync_softc *, struct mbuf *);
210
211struct pfsync_upd_req_item {
212 TAILQ_ENTRY(pfsync_upd_req_item) ur_entry;
213 struct pfsync_upd_req ur_msg;

--- 13 unchanged lines hidden (view full) ---

227 int b_id;
228 struct pfsync_softc *b_sc;
229 struct mtx b_mtx;
230 struct callout b_tmo;
231 int b_flags;
232#define PFSYNCF_BUCKET_PUSH 0x00000001
233
234 size_t b_len;
203 TAILQ_HEAD(, pf_kstate) b_qs[PFSYNC_S_COUNT];
235 TAILQ_HEAD(, pf_kstate) b_qs[PFSYNC_Q_COUNT];
204 TAILQ_HEAD(, pfsync_upd_req_item) b_upd_req_list;
205 TAILQ_HEAD(, pfsync_deferral) b_deferrals;
206 u_int b_deferred;
207 void *b_plus;
208 size_t b_pluslen;
209
210 struct ifaltq b_snd;
211};
212
213struct pfsync_softc {
214 /* Configuration */
215 struct ifnet *sc_ifp;
216 struct ifnet *sc_sync_if;
217 struct ip_moptions sc_imo;
218 struct sockaddr_storage sc_sync_peer;
219 uint32_t sc_flags;
220 uint8_t sc_maxupdates;
221 union inet_template sc_template;
222 struct mtx sc_mtx;
236 TAILQ_HEAD(, pfsync_upd_req_item) b_upd_req_list;
237 TAILQ_HEAD(, pfsync_deferral) b_deferrals;
238 u_int b_deferred;
239 void *b_plus;
240 size_t b_pluslen;
241
242 struct ifaltq b_snd;
243};
244
245struct pfsync_softc {
246 /* Configuration */
247 struct ifnet *sc_ifp;
248 struct ifnet *sc_sync_if;
249 struct ip_moptions sc_imo;
250 struct sockaddr_storage sc_sync_peer;
251 uint32_t sc_flags;
252 uint8_t sc_maxupdates;
253 union inet_template sc_template;
254 struct mtx sc_mtx;
255 uint32_t sc_version;
223
224 /* Queued data */
225 struct pfsync_bucket *sc_buckets;
226
227 /* Bulk update info */
228 struct mtx sc_bulk_mtx;
229 uint32_t sc_ureq_sent;
230 int sc_bulk_tries;

--- 100 unchanged lines hidden (view full) ---

331#define V_pfsync_cloner VNET(pfsync_cloner)
332
333static int
334pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t param)
335{
336 struct pfsync_softc *sc;
337 struct ifnet *ifp;
338 struct pfsync_bucket *b;
256
257 /* Queued data */
258 struct pfsync_bucket *sc_buckets;
259
260 /* Bulk update info */
261 struct mtx sc_bulk_mtx;
262 uint32_t sc_ureq_sent;
263 int sc_bulk_tries;

--- 100 unchanged lines hidden (view full) ---

364#define V_pfsync_cloner VNET(pfsync_cloner)
365
366static int
367pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t param)
368{
369 struct pfsync_softc *sc;
370 struct ifnet *ifp;
371 struct pfsync_bucket *b;
339 int c, q;
372 int c;
373 enum pfsync_q_id q;
340
341 if (unit != 0)
342 return (EINVAL);
343
344 if (! pfsync_buckets)
345 pfsync_buckets = mp_ncpus * 2;
346
347 sc = malloc(sizeof(struct pfsync_softc), M_PFSYNC, M_WAITOK | M_ZERO);
348 sc->sc_flags |= PFSYNCF_OK;
349 sc->sc_maxupdates = 128;
374
375 if (unit != 0)
376 return (EINVAL);
377
378 if (! pfsync_buckets)
379 pfsync_buckets = mp_ncpus * 2;
380
381 sc = malloc(sizeof(struct pfsync_softc), M_PFSYNC, M_WAITOK | M_ZERO);
382 sc->sc_flags |= PFSYNCF_OK;
383 sc->sc_maxupdates = 128;
384 sc->sc_version = PFSYNC_MSG_VERSION_DEFAULT;
350
351 ifp = sc->sc_ifp = if_alloc(IFT_PFSYNC);
352 if (ifp == NULL) {
353 free(sc, M_PFSYNC);
354 return (ENOSPC);
355 }
356 if_initname(ifp, pfsyncname, unit);
357 ifp->if_softc = sc;

--- 16 unchanged lines hidden (view full) ---

374 for (c = 0; c < pfsync_buckets; c++) {
375 b = &sc->sc_buckets[c];
376 mtx_init(&b->b_mtx, "pfsync bucket", NULL, MTX_DEF);
377
378 b->b_id = c;
379 b->b_sc = sc;
380 b->b_len = PFSYNC_MINPKT;
381
385
386 ifp = sc->sc_ifp = if_alloc(IFT_PFSYNC);
387 if (ifp == NULL) {
388 free(sc, M_PFSYNC);
389 return (ENOSPC);
390 }
391 if_initname(ifp, pfsyncname, unit);
392 ifp->if_softc = sc;

--- 16 unchanged lines hidden (view full) ---

409 for (c = 0; c < pfsync_buckets; c++) {
410 b = &sc->sc_buckets[c];
411 mtx_init(&b->b_mtx, "pfsync bucket", NULL, MTX_DEF);
412
413 b->b_id = c;
414 b->b_sc = sc;
415 b->b_len = PFSYNC_MINPKT;
416
382 for (q = 0; q < PFSYNC_S_COUNT; q++)
417 for (q = 0; q < PFSYNC_Q_COUNT; q++)
383 TAILQ_INIT(&b->b_qs[q]);
384
385 TAILQ_INIT(&b->b_upd_req_list);
386 TAILQ_INIT(&b->b_deferrals);
387
388 callout_init(&b->b_tmo, 1);
389
390 b->b_snd.ifq_maxlen = ifqmaxlen;

--- 69 unchanged lines hidden (view full) ---

460 if (d->scrub == NULL)
461 return (ENOMEM);
462 }
463
464 return (0);
465}
466
467static int
418 TAILQ_INIT(&b->b_qs[q]);
419
420 TAILQ_INIT(&b->b_upd_req_list);
421 TAILQ_INIT(&b->b_deferrals);
422
423 callout_init(&b->b_tmo, 1);
424
425 b->b_snd.ifq_maxlen = ifqmaxlen;

--- 69 unchanged lines hidden (view full) ---

495 if (d->scrub == NULL)
496 return (ENOMEM);
497 }
498
499 return (0);
500}
501
502static int
468pfsync_state_import(struct pfsync_state *sp, int flags)
503pfsync_state_import(union pfsync_state_union *sp, int flags, int msg_version)
469{
470 struct pfsync_softc *sc = V_pfsyncif;
471#ifndef __NO_STRICT_ALIGNMENT
472 struct pfsync_state_key key[2];
473#endif
474 struct pfsync_state_key *kw, *ks;
475 struct pf_kstate *st = NULL;
476 struct pf_state_key *skw = NULL, *sks = NULL;
477 struct pf_krule *r = NULL;
478 struct pfi_kkif *kif;
479 int error;
480
481 PF_RULES_RASSERT();
482
504{
505 struct pfsync_softc *sc = V_pfsyncif;
506#ifndef __NO_STRICT_ALIGNMENT
507 struct pfsync_state_key key[2];
508#endif
509 struct pfsync_state_key *kw, *ks;
510 struct pf_kstate *st = NULL;
511 struct pf_state_key *skw = NULL, *sks = NULL;
512 struct pf_krule *r = NULL;
513 struct pfi_kkif *kif;
514 int error;
515
516 PF_RULES_RASSERT();
517
483 if (sp->creatorid == 0) {
518 if (sp->pfs_1301.creatorid == 0) {
484 if (V_pf_status.debug >= PF_DEBUG_MISC)
485 printf("%s: invalid creator id: %08x\n", __func__,
519 if (V_pf_status.debug >= PF_DEBUG_MISC)
520 printf("%s: invalid creator id: %08x\n", __func__,
486 ntohl(sp->creatorid));
521 ntohl(sp->pfs_1301.creatorid));
487 return (EINVAL);
488 }
489
522 return (EINVAL);
523 }
524
490 if ((kif = pfi_kkif_find(sp->ifname)) == NULL) {
525 if ((kif = pfi_kkif_find(sp->pfs_1301.ifname)) == NULL) {
491 if (V_pf_status.debug >= PF_DEBUG_MISC)
492 printf("%s: unknown interface: %s\n", __func__,
526 if (V_pf_status.debug >= PF_DEBUG_MISC)
527 printf("%s: unknown interface: %s\n", __func__,
493 sp->ifname);
528 sp->pfs_1301.ifname);
494 if (flags & PFSYNC_SI_IOCTL)
495 return (EINVAL);
496 return (0); /* skip this state */
497 }
498
499 /*
500 * If the ruleset checksums match or the state is coming from the ioctl,
501 * it's safe to associate the state with the rule of that number.
502 */
529 if (flags & PFSYNC_SI_IOCTL)
530 return (EINVAL);
531 return (0); /* skip this state */
532 }
533
534 /*
535 * If the ruleset checksums match or the state is coming from the ioctl,
536 * it's safe to associate the state with the rule of that number.
537 */
503 if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) &&
504 (flags & (PFSYNC_SI_IOCTL | PFSYNC_SI_CKSUM)) && ntohl(sp->rule) <
538 if (sp->pfs_1301.rule != htonl(-1) && sp->pfs_1301.anchor == htonl(-1) &&
539 (flags & (PFSYNC_SI_IOCTL | PFSYNC_SI_CKSUM)) && ntohl(sp->pfs_1301.rule) <
505 pf_main_ruleset.rules[PF_RULESET_FILTER].active.rcount)
506 r = pf_main_ruleset.rules[
540 pf_main_ruleset.rules[PF_RULESET_FILTER].active.rcount)
541 r = pf_main_ruleset.rules[
507 PF_RULESET_FILTER].active.ptr_array[ntohl(sp->rule)];
542 PF_RULESET_FILTER].active.ptr_array[ntohl(sp->pfs_1301.rule)];
508 else
509 r = &V_pf_default_rule;
510
511 if ((r->max_states &&
512 counter_u64_fetch(r->states_cur) >= r->max_states))
513 goto cleanup;
514
515 /*
516 * XXXGL: consider M_WAITOK in ioctl path after.
517 */
518 st = pf_alloc_state(M_NOWAIT);
519 if (__predict_false(st == NULL))
520 goto cleanup;
521
522 if ((skw = uma_zalloc(V_pf_state_key_z, M_NOWAIT)) == NULL)
523 goto cleanup;
524
525#ifndef __NO_STRICT_ALIGNMENT
543 else
544 r = &V_pf_default_rule;
545
546 if ((r->max_states &&
547 counter_u64_fetch(r->states_cur) >= r->max_states))
548 goto cleanup;
549
550 /*
551 * XXXGL: consider M_WAITOK in ioctl path after.
552 */
553 st = pf_alloc_state(M_NOWAIT);
554 if (__predict_false(st == NULL))
555 goto cleanup;
556
557 if ((skw = uma_zalloc(V_pf_state_key_z, M_NOWAIT)) == NULL)
558 goto cleanup;
559
560#ifndef __NO_STRICT_ALIGNMENT
526 bcopy(&sp->key, key, sizeof(struct pfsync_state_key) * 2);
561 bcopy(&sp->pfs_1301.key, key, sizeof(struct pfsync_state_key) * 2);
527 kw = &key[PF_SK_WIRE];
528 ks = &key[PF_SK_STACK];
529#else
562 kw = &key[PF_SK_WIRE];
563 ks = &key[PF_SK_STACK];
564#else
530 kw = &sp->key[PF_SK_WIRE];
531 ks = &sp->key[PF_SK_STACK];
565 kw = &sp->pfs_1301.key[PF_SK_WIRE];
566 ks = &sp->pfs_1301.key[PF_SK_STACK];
532#endif
533
567#endif
568
534 if (PF_ANEQ(&kw->addr[0], &ks->addr[0], sp->af) ||
535 PF_ANEQ(&kw->addr[1], &ks->addr[1], sp->af) ||
569 if (PF_ANEQ(&kw->addr[0], &ks->addr[0], sp->pfs_1301.af) ||
570 PF_ANEQ(&kw->addr[1], &ks->addr[1], sp->pfs_1301.af) ||
536 kw->port[0] != ks->port[0] ||
537 kw->port[1] != ks->port[1]) {
538 sks = uma_zalloc(V_pf_state_key_z, M_NOWAIT);
539 if (sks == NULL)
540 goto cleanup;
541 } else
542 sks = skw;
543
544 /* allocate memory for scrub info */
571 kw->port[0] != ks->port[0] ||
572 kw->port[1] != ks->port[1]) {
573 sks = uma_zalloc(V_pf_state_key_z, M_NOWAIT);
574 if (sks == NULL)
575 goto cleanup;
576 } else
577 sks = skw;
578
579 /* allocate memory for scrub info */
545 if (pfsync_alloc_scrub_memory(&sp->src, &st->src) ||
546 pfsync_alloc_scrub_memory(&sp->dst, &st->dst))
580 if (pfsync_alloc_scrub_memory(&sp->pfs_1301.src, &st->src) ||
581 pfsync_alloc_scrub_memory(&sp->pfs_1301.dst, &st->dst))
547 goto cleanup;
548
549 /* Copy to state key(s). */
550 skw->addr[0] = kw->addr[0];
551 skw->addr[1] = kw->addr[1];
552 skw->port[0] = kw->port[0];
553 skw->port[1] = kw->port[1];
582 goto cleanup;
583
584 /* Copy to state key(s). */
585 skw->addr[0] = kw->addr[0];
586 skw->addr[1] = kw->addr[1];
587 skw->port[0] = kw->port[0];
588 skw->port[1] = kw->port[1];
554 skw->proto = sp->proto;
555 skw->af = sp->af;
589 skw->proto = sp->pfs_1301.proto;
590 skw->af = sp->pfs_1301.af;
556 if (sks != skw) {
557 sks->addr[0] = ks->addr[0];
558 sks->addr[1] = ks->addr[1];
559 sks->port[0] = ks->port[0];
560 sks->port[1] = ks->port[1];
591 if (sks != skw) {
592 sks->addr[0] = ks->addr[0];
593 sks->addr[1] = ks->addr[1];
594 sks->port[0] = ks->port[0];
595 sks->port[1] = ks->port[1];
561 sks->proto = sp->proto;
562 sks->af = sp->af;
596 sks->proto = sp->pfs_1301.proto;
597 sks->af = sp->pfs_1301.af;
563 }
564
565 /* copy to state */
598 }
599
600 /* copy to state */
566 bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr));
567 st->creation = time_uptime - ntohl(sp->creation);
601 bcopy(&sp->pfs_1301.rt_addr, &st->rt_addr, sizeof(st->rt_addr));
602 st->creation = time_uptime - ntohl(sp->pfs_1301.creation);
568 st->expire = time_uptime;
603 st->expire = time_uptime;
569 if (sp->expire) {
604 if (sp->pfs_1301.expire) {
570 uint32_t timeout;
571
605 uint32_t timeout;
606
572 timeout = r->timeout[sp->timeout];
607 timeout = r->timeout[sp->pfs_1301.timeout];
573 if (!timeout)
608 if (!timeout)
574 timeout = V_pf_default_rule.timeout[sp->timeout];
609 timeout = V_pf_default_rule.timeout[sp->pfs_1301.timeout];
575
576 /* sp->expire may have been adaptively scaled by export. */
610
611 /* sp->expire may have been adaptively scaled by export. */
577 st->expire -= timeout - ntohl(sp->expire);
612 st->expire -= timeout - ntohl(sp->pfs_1301.expire);
578 }
579
613 }
614
580 st->direction = sp->direction;
581 st->log = sp->log;
582 st->timeout = sp->timeout;
583 /* 8 from old peers, 16 bits from new peers */
584 st->state_flags = sp->state_flags_compat | ntohs(sp->state_flags);
615 st->direction = sp->pfs_1301.direction;
616 st->log = sp->pfs_1301.log;
617 st->timeout = sp->pfs_1301.timeout;
585
618
586 if (r == &V_pf_default_rule) {
587 /* ToS and Prio are not sent over struct pfsync_state */
588 st->state_flags &= ~PFSTATE_SETMASK;
589 } else {
590 /* Most actions are applied form state, not from rule. Until
591 * pfsync can forward all those actions and their parameters we
592 * must relay on restoring them from the found rule.
593 * It's a copy of pf_rule_to_actions() */
594 st->qid = r->qid;
595 st->pqid = r->pqid;
596 st->rtableid = r->rtableid;
597 if (r->scrub_flags & PFSTATE_SETTOS)
598 st->set_tos = r->set_tos;
599 st->min_ttl = r->min_ttl;
600 st->max_mss = r->max_mss;
601 st->state_flags |= (r->scrub_flags & (PFSTATE_NODF|PFSTATE_RANDOMID|
602 PFSTATE_SETTOS|PFSTATE_SCRUB_TCP|PFSTATE_SETPRIO));
603 st->dnpipe = r->dnpipe;
604 st->dnrpipe = r->dnrpipe;
605 /* FIXME: dnflags are not part of state, can't update them */
619 switch (msg_version) {
620 case PFSYNC_MSG_VERSION_1301:
621 st->state_flags = sp->pfs_1301.state_flags;
622 /*
623 * In FreeBSD 13 pfsync lacks many attributes. Copy them
624 * from the rule if possible. If rule can't be matched
625 * clear any set options as we can't recover their
626 * parameters.
627 */
628 if (r == &V_pf_default_rule) {
629 st->state_flags &= ~PFSTATE_SETMASK;
630 } else {
631 /*
632 * Similar to pf_rule_to_actions(). This code
633 * won't set the actions properly if they come
634 * from multiple "match" rules as only rule
635 * creating the state is send over pfsync.
636 */
637 st->qid = r->qid;
638 st->pqid = r->pqid;
639 st->rtableid = r->rtableid;
640 if (r->scrub_flags & PFSTATE_SETTOS)
641 st->set_tos = r->set_tos;
642 st->min_ttl = r->min_ttl;
643 st->max_mss = r->max_mss;
644 st->state_flags |= (r->scrub_flags &
645 (PFSTATE_NODF|PFSTATE_RANDOMID|
646 PFSTATE_SETTOS|PFSTATE_SCRUB_TCP|
647 PFSTATE_SETPRIO));
648 if (r->dnpipe || r->dnrpipe) {
649 if (r->free_flags & PFRULE_DN_IS_PIPE)
650 st->state_flags |= PFSTATE_DN_IS_PIPE;
651 else
652 st->state_flags &= ~PFSTATE_DN_IS_PIPE;
653 }
654 st->dnpipe = r->dnpipe;
655 st->dnrpipe = r->dnrpipe;
656 }
657 break;
658 case PFSYNC_MSG_VERSION_1400:
659 st->state_flags = ntohs(sp->pfs_1400.state_flags);
660 st->qid = ntohs(sp->pfs_1400.qid);
661 st->pqid = ntohs(sp->pfs_1400.pqid);
662 st->dnpipe = ntohs(sp->pfs_1400.dnpipe);
663 st->dnrpipe = ntohs(sp->pfs_1400.dnrpipe);
664 st->rtableid = ntohl(sp->pfs_1400.rtableid);
665 st->min_ttl = sp->pfs_1400.min_ttl;
666 st->set_tos = sp->pfs_1400.set_tos;
667 st->max_mss = ntohs(sp->pfs_1400.max_mss);
668 st->set_prio[0] = sp->pfs_1400.set_prio[0];
669 st->set_prio[1] = sp->pfs_1400.set_prio[1];
670 st->rt = sp->pfs_1400.rt;
671 if (st->rt && (st->rt_kif = pfi_kkif_find(sp->pfs_1400.rt_ifname)) == NULL) {
672 if (V_pf_status.debug >= PF_DEBUG_MISC)
673 printf("%s: unknown route interface: %s\n",
674 __func__, sp->pfs_1400.rt_ifname);
675 if (flags & PFSYNC_SI_IOCTL)
676 return (EINVAL);
677 return (0); /* skip this state */
678 }
679 break;
680 default:
681 panic("%s: Unsupported pfsync_msg_version %d",
682 __func__, msg_version);
606 }
607
683 }
684
608 st->id = sp->id;
609 st->creatorid = sp->creatorid;
610 pf_state_peer_ntoh(&sp->src, &st->src);
611 pf_state_peer_ntoh(&sp->dst, &st->dst);
685 st->id = sp->pfs_1301.id;
686 st->creatorid = sp->pfs_1301.creatorid;
687 pf_state_peer_ntoh(&sp->pfs_1301.src, &st->src);
688 pf_state_peer_ntoh(&sp->pfs_1301.dst, &st->dst);
612
613 st->rule.ptr = r;
614 st->nat_rule.ptr = NULL;
615 st->anchor.ptr = NULL;
689
690 st->rule.ptr = r;
691 st->nat_rule.ptr = NULL;
692 st->anchor.ptr = NULL;
616 st->rt_kif = NULL;
617
618 st->pfsync_time = time_uptime;
619 st->sync_state = PFSYNC_S_NONE;
620
621 if (!(flags & PFSYNC_SI_IOCTL))
622 st->state_flags |= PFSTATE_NOSYNC;
623
624 if ((error = pf_state_insert(kif, kif, skw, sks, st)) != 0)

--- 115 unchanged lines hidden (view full) ---

740 if (subh.action >= PFSYNC_ACT_MAX) {
741 V_pfsyncstats.pfsyncs_badact++;
742 PF_RULES_RUNLOCK();
743 goto done;
744 }
745
746 count = ntohs(subh.count);
747 V_pfsyncstats.pfsyncs_iacts[subh.action] += count;
693
694 st->pfsync_time = time_uptime;
695 st->sync_state = PFSYNC_S_NONE;
696
697 if (!(flags & PFSYNC_SI_IOCTL))
698 st->state_flags |= PFSTATE_NOSYNC;
699
700 if ((error = pf_state_insert(kif, kif, skw, sks, st)) != 0)

--- 115 unchanged lines hidden (view full) ---

816 if (subh.action >= PFSYNC_ACT_MAX) {
817 V_pfsyncstats.pfsyncs_badact++;
818 PF_RULES_RUNLOCK();
819 goto done;
820 }
821
822 count = ntohs(subh.count);
823 V_pfsyncstats.pfsyncs_iacts[subh.action] += count;
748 rv = (*pfsync_acts[subh.action])(m, offset, count, flags);
824 rv = (*pfsync_acts[subh.action])(m, offset, count, flags, subh.action);
749 if (rv == -1) {
750 PF_RULES_RUNLOCK();
751 return (IPPROTO_DONE);
752 }
753
754 offset += rv;
755 }
756 PF_RULES_RUNLOCK();
757
758done:
759 m_freem(m);
760 return (IPPROTO_DONE);
761}
762#endif
763
764static int
825 if (rv == -1) {
826 PF_RULES_RUNLOCK();
827 return (IPPROTO_DONE);
828 }
829
830 offset += rv;
831 }
832 PF_RULES_RUNLOCK();
833
834done:
835 m_freem(m);
836 return (IPPROTO_DONE);
837}
838#endif
839
840static int
765pfsync_in_clr(struct mbuf *m, int offset, int count, int flags)
841pfsync_in_clr(struct mbuf *m, int offset, int count, int flags, int action)
766{
767 struct pfsync_clr *clr;
768 struct mbuf *mp;
769 int len = sizeof(*clr) * count;
770 int i, offp;
771 u_int32_t creatorid;
772
773 mp = m_pulldown(m, offset, len, &offp);

--- 25 unchanged lines hidden (view full) ---

799 PF_HASHROW_UNLOCK(ih);
800 }
801 }
802
803 return (len);
804}
805
806static int
842{
843 struct pfsync_clr *clr;
844 struct mbuf *mp;
845 int len = sizeof(*clr) * count;
846 int i, offp;
847 u_int32_t creatorid;
848
849 mp = m_pulldown(m, offset, len, &offp);

--- 25 unchanged lines hidden (view full) ---

875 PF_HASHROW_UNLOCK(ih);
876 }
877 }
878
879 return (len);
880}
881
882static int
807pfsync_in_ins(struct mbuf *m, int offset, int count, int flags)
883pfsync_in_ins(struct mbuf *m, int offset, int count, int flags, int action)
808{
809 struct mbuf *mp;
884{
885 struct mbuf *mp;
810 struct pfsync_state *sa, *sp;
811 int len = sizeof(*sp) * count;
812 int i, offp;
886 union pfsync_state_union *sa, *sp;
887 int i, offp, len, msg_version;
813
888
889 switch (action) {
890 case PFSYNC_ACT_INS_1301:
891 len = sizeof(struct pfsync_state_1301) * count;
892 msg_version = PFSYNC_MSG_VERSION_1301;
893 break;
894 case PFSYNC_ACT_INS_1400:
895 len = sizeof(struct pfsync_state_1400) * count;
896 msg_version = PFSYNC_MSG_VERSION_1400;
897 break;
898 default:
899 V_pfsyncstats.pfsyncs_badact++;
900 return (-1);
901 }
902
814 mp = m_pulldown(m, offset, len, &offp);
815 if (mp == NULL) {
816 V_pfsyncstats.pfsyncs_badlen++;
817 return (-1);
818 }
903 mp = m_pulldown(m, offset, len, &offp);
904 if (mp == NULL) {
905 V_pfsyncstats.pfsyncs_badlen++;
906 return (-1);
907 }
819 sa = (struct pfsync_state *)(mp->m_data + offp);
908 sa = (union pfsync_state_union *)(mp->m_data + offp);
820
821 for (i = 0; i < count; i++) {
822 sp = &sa[i];
823
824 /* Check for invalid values. */
909
910 for (i = 0; i < count; i++) {
911 sp = &sa[i];
912
913 /* Check for invalid values. */
825 if (sp->timeout >= PFTM_MAX ||
826 sp->src.state > PF_TCPS_PROXY_DST ||
827 sp->dst.state > PF_TCPS_PROXY_DST ||
828 sp->direction > PF_OUT ||
829 (sp->af != AF_INET && sp->af != AF_INET6)) {
914 if (sp->pfs_1301.timeout >= PFTM_MAX ||
915 sp->pfs_1301.src.state > PF_TCPS_PROXY_DST ||
916 sp->pfs_1301.dst.state > PF_TCPS_PROXY_DST ||
917 sp->pfs_1301.direction > PF_OUT ||
918 (sp->pfs_1301.af != AF_INET &&
919 sp->pfs_1301.af != AF_INET6)) {
830 if (V_pf_status.debug >= PF_DEBUG_MISC)
831 printf("%s: invalid value\n", __func__);
832 V_pfsyncstats.pfsyncs_badval++;
833 continue;
834 }
835
920 if (V_pf_status.debug >= PF_DEBUG_MISC)
921 printf("%s: invalid value\n", __func__);
922 V_pfsyncstats.pfsyncs_badval++;
923 continue;
924 }
925
836 if (pfsync_state_import(sp, flags) == ENOMEM)
926 if (pfsync_state_import(sp, flags, msg_version) == ENOMEM)
837 /* Drop out, but process the rest of the actions. */
838 break;
839 }
840
841 return (len);
842}
843
844static int
927 /* Drop out, but process the rest of the actions. */
928 break;
929 }
930
931 return (len);
932}
933
934static int
845pfsync_in_iack(struct mbuf *m, int offset, int count, int flags)
935pfsync_in_iack(struct mbuf *m, int offset, int count, int flags, int action)
846{
847 struct pfsync_ins_ack *ia, *iaa;
848 struct pf_kstate *st;
849
850 struct mbuf *mp;
851 int len = count * sizeof(*ia);
852 int offp, i;
853

--- 54 unchanged lines hidden (view full) ---

908 sync++;
909 else
910 pf_state_peer_ntoh(dst, &st->dst);
911
912 return (sync);
913}
914
915static int
936{
937 struct pfsync_ins_ack *ia, *iaa;
938 struct pf_kstate *st;
939
940 struct mbuf *mp;
941 int len = count * sizeof(*ia);
942 int offp, i;
943

--- 54 unchanged lines hidden (view full) ---

998 sync++;
999 else
1000 pf_state_peer_ntoh(dst, &st->dst);
1001
1002 return (sync);
1003}
1004
1005static int
916pfsync_in_upd(struct mbuf *m, int offset, int count, int flags)
1006pfsync_in_upd(struct mbuf *m, int offset, int count, int flags, int action)
917{
918 struct pfsync_softc *sc = V_pfsyncif;
1007{
1008 struct pfsync_softc *sc = V_pfsyncif;
919 struct pfsync_state *sa, *sp;
1009 union pfsync_state_union *sa, *sp;
920 struct pf_kstate *st;
1010 struct pf_kstate *st;
921 int sync;
922
923 struct mbuf *mp;
1011 struct mbuf *mp;
924 int len = count * sizeof(*sp);
925 int offp, i;
1012 int sync, offp, i, len, msg_version;
926
1013
1014 switch (action) {
1015 case PFSYNC_ACT_UPD_1301:
1016 len = sizeof(struct pfsync_state_1301) * count;
1017 msg_version = PFSYNC_MSG_VERSION_1301;
1018 break;
1019 case PFSYNC_ACT_UPD_1400:
1020 len = sizeof(struct pfsync_state_1400) * count;
1021 msg_version = PFSYNC_MSG_VERSION_1400;
1022 break;
1023 default:
1024 V_pfsyncstats.pfsyncs_badact++;
1025 return (-1);
1026 }
1027
927 mp = m_pulldown(m, offset, len, &offp);
928 if (mp == NULL) {
929 V_pfsyncstats.pfsyncs_badlen++;
930 return (-1);
931 }
1028 mp = m_pulldown(m, offset, len, &offp);
1029 if (mp == NULL) {
1030 V_pfsyncstats.pfsyncs_badlen++;
1031 return (-1);
1032 }
932 sa = (struct pfsync_state *)(mp->m_data + offp);
1033 sa = (union pfsync_state_union *)(mp->m_data + offp);
933
934 for (i = 0; i < count; i++) {
935 sp = &sa[i];
936
937 /* check for invalid values */
1034
1035 for (i = 0; i < count; i++) {
1036 sp = &sa[i];
1037
1038 /* check for invalid values */
938 if (sp->timeout >= PFTM_MAX ||
939 sp->src.state > PF_TCPS_PROXY_DST ||
940 sp->dst.state > PF_TCPS_PROXY_DST) {
1039 if (sp->pfs_1301.timeout >= PFTM_MAX ||
1040 sp->pfs_1301.src.state > PF_TCPS_PROXY_DST ||
1041 sp->pfs_1301.dst.state > PF_TCPS_PROXY_DST) {
941 if (V_pf_status.debug >= PF_DEBUG_MISC) {
942 printf("pfsync_input: PFSYNC_ACT_UPD: "
943 "invalid value\n");
944 }
945 V_pfsyncstats.pfsyncs_badval++;
946 continue;
947 }
948
1042 if (V_pf_status.debug >= PF_DEBUG_MISC) {
1043 printf("pfsync_input: PFSYNC_ACT_UPD: "
1044 "invalid value\n");
1045 }
1046 V_pfsyncstats.pfsyncs_badval++;
1047 continue;
1048 }
1049
949 st = pf_find_state_byid(sp->id, sp->creatorid);
1050 st = pf_find_state_byid(sp->pfs_1301.id, sp->pfs_1301.creatorid);
950 if (st == NULL) {
951 /* insert the update */
1051 if (st == NULL) {
1052 /* insert the update */
952 if (pfsync_state_import(sp, flags))
1053 if (pfsync_state_import(sp, flags, msg_version))
953 V_pfsyncstats.pfsyncs_badstate++;
954 continue;
955 }
956
957 if (st->state_flags & PFSTATE_ACK) {
958 pfsync_undefer_state(st, 1);
959 }
960
961 if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP)
1054 V_pfsyncstats.pfsyncs_badstate++;
1055 continue;
1056 }
1057
1058 if (st->state_flags & PFSTATE_ACK) {
1059 pfsync_undefer_state(st, 1);
1060 }
1061
1062 if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP)
962 sync = pfsync_upd_tcp(st, &sp->src, &sp->dst);
1063 sync = pfsync_upd_tcp(st, &sp->pfs_1301.src, &sp->pfs_1301.dst);
963 else {
964 sync = 0;
965
966 /*
967 * Non-TCP protocol state machine always go
968 * forwards
969 */
1064 else {
1065 sync = 0;
1066
1067 /*
1068 * Non-TCP protocol state machine always go
1069 * forwards
1070 */
970 if (st->src.state > sp->src.state)
1071 if (st->src.state > sp->pfs_1301.src.state)
971 sync++;
972 else
1072 sync++;
1073 else
973 pf_state_peer_ntoh(&sp->src, &st->src);
974 if (st->dst.state > sp->dst.state)
1074 pf_state_peer_ntoh(&sp->pfs_1301.src, &st->src);
1075 if (st->dst.state > sp->pfs_1301.dst.state)
975 sync++;
976 else
1076 sync++;
1077 else
977 pf_state_peer_ntoh(&sp->dst, &st->dst);
1078 pf_state_peer_ntoh(&sp->pfs_1301.dst, &st->dst);
978 }
979 if (sync < 2) {
1079 }
1080 if (sync < 2) {
980 pfsync_alloc_scrub_memory(&sp->dst, &st->dst);
981 pf_state_peer_ntoh(&sp->dst, &st->dst);
1081 pfsync_alloc_scrub_memory(&sp->pfs_1301.dst, &st->dst);
1082 pf_state_peer_ntoh(&sp->pfs_1301.dst, &st->dst);
982 st->expire = time_uptime;
1083 st->expire = time_uptime;
983 st->timeout = sp->timeout;
1084 st->timeout = sp->pfs_1301.timeout;
984 }
985 st->pfsync_time = time_uptime;
986
987 if (sync) {
988 V_pfsyncstats.pfsyncs_stale++;
989
990 pfsync_update_state(st);
991 PF_STATE_UNLOCK(st);
992 pfsync_push_all(sc);
993 continue;
994 }
995 PF_STATE_UNLOCK(st);
996 }
997
998 return (len);
999}
1000
1001static int
1085 }
1086 st->pfsync_time = time_uptime;
1087
1088 if (sync) {
1089 V_pfsyncstats.pfsyncs_stale++;
1090
1091 pfsync_update_state(st);
1092 PF_STATE_UNLOCK(st);
1093 pfsync_push_all(sc);
1094 continue;
1095 }
1096 PF_STATE_UNLOCK(st);
1097 }
1098
1099 return (len);
1100}
1101
1102static int
1002pfsync_in_upd_c(struct mbuf *m, int offset, int count, int flags)
1103pfsync_in_upd_c(struct mbuf *m, int offset, int count, int flags, int action)
1003{
1004 struct pfsync_softc *sc = V_pfsyncif;
1005 struct pfsync_upd_c *ua, *up;
1006 struct pf_kstate *st;
1007 int len = count * sizeof(*up);
1008 int sync;
1009 struct mbuf *mp;
1010 int offp, i;

--- 70 unchanged lines hidden (view full) ---

1081 }
1082 PF_STATE_UNLOCK(st);
1083 }
1084
1085 return (len);
1086}
1087
1088static int
1104{
1105 struct pfsync_softc *sc = V_pfsyncif;
1106 struct pfsync_upd_c *ua, *up;
1107 struct pf_kstate *st;
1108 int len = count * sizeof(*up);
1109 int sync;
1110 struct mbuf *mp;
1111 int offp, i;

--- 70 unchanged lines hidden (view full) ---

1182 }
1183 PF_STATE_UNLOCK(st);
1184 }
1185
1186 return (len);
1187}
1188
1189static int
1089pfsync_in_ureq(struct mbuf *m, int offset, int count, int flags)
1190pfsync_in_ureq(struct mbuf *m, int offset, int count, int flags, int action)
1090{
1091 struct pfsync_upd_req *ur, *ura;
1092 struct mbuf *mp;
1093 int len = count * sizeof(*ur);
1094 int i, offp;
1095
1096 struct pf_kstate *st;
1097

--- 24 unchanged lines hidden (view full) ---

1122 PF_STATE_UNLOCK(st);
1123 }
1124 }
1125
1126 return (len);
1127}
1128
1129static int
1191{
1192 struct pfsync_upd_req *ur, *ura;
1193 struct mbuf *mp;
1194 int len = count * sizeof(*ur);
1195 int i, offp;
1196
1197 struct pf_kstate *st;
1198

--- 24 unchanged lines hidden (view full) ---

1223 PF_STATE_UNLOCK(st);
1224 }
1225 }
1226
1227 return (len);
1228}
1229
1230static int
1130pfsync_in_del_c(struct mbuf *m, int offset, int count, int flags)
1231pfsync_in_del_c(struct mbuf *m, int offset, int count, int flags, int action)
1131{
1132 struct mbuf *mp;
1133 struct pfsync_del_c *sa, *sp;
1134 struct pf_kstate *st;
1135 int len = count * sizeof(*sp);
1136 int offp, i;
1137
1138 mp = m_pulldown(m, offset, len, &offp);

--- 15 unchanged lines hidden (view full) ---

1154 st->state_flags |= PFSTATE_NOSYNC;
1155 pf_unlink_state(st);
1156 }
1157
1158 return (len);
1159}
1160
1161static int
1232{
1233 struct mbuf *mp;
1234 struct pfsync_del_c *sa, *sp;
1235 struct pf_kstate *st;
1236 int len = count * sizeof(*sp);
1237 int offp, i;
1238
1239 mp = m_pulldown(m, offset, len, &offp);

--- 15 unchanged lines hidden (view full) ---

1255 st->state_flags |= PFSTATE_NOSYNC;
1256 pf_unlink_state(st);
1257 }
1258
1259 return (len);
1260}
1261
1262static int
1162pfsync_in_bus(struct mbuf *m, int offset, int count, int flags)
1263pfsync_in_bus(struct mbuf *m, int offset, int count, int flags, int action)
1163{
1164 struct pfsync_softc *sc = V_pfsyncif;
1165 struct pfsync_bus *bus;
1166 struct mbuf *mp;
1167 int len = count * sizeof(*bus);
1168 int offp;
1169
1170 PFSYNC_BLOCK(sc);

--- 12 unchanged lines hidden (view full) ---

1183 }
1184 bus = (struct pfsync_bus *)(mp->m_data + offp);
1185
1186 switch (bus->status) {
1187 case PFSYNC_BUS_START:
1188 callout_reset(&sc->sc_bulkfail_tmo, 4 * hz +
1189 V_pf_limits[PF_LIMIT_STATES].limit /
1190 ((sc->sc_ifp->if_mtu - PFSYNC_MINPKT) /
1264{
1265 struct pfsync_softc *sc = V_pfsyncif;
1266 struct pfsync_bus *bus;
1267 struct mbuf *mp;
1268 int len = count * sizeof(*bus);
1269 int offp;
1270
1271 PFSYNC_BLOCK(sc);

--- 12 unchanged lines hidden (view full) ---

1284 }
1285 bus = (struct pfsync_bus *)(mp->m_data + offp);
1286
1287 switch (bus->status) {
1288 case PFSYNC_BUS_START:
1289 callout_reset(&sc->sc_bulkfail_tmo, 4 * hz +
1290 V_pf_limits[PF_LIMIT_STATES].limit /
1291 ((sc->sc_ifp->if_mtu - PFSYNC_MINPKT) /
1191 sizeof(struct pfsync_state)),
1292 sizeof(union pfsync_state_union)),
1192 pfsync_bulk_fail, sc);
1193 if (V_pf_status.debug >= PF_DEBUG_MISC)
1194 printf("pfsync: received bulk update start\n");
1195 break;
1196
1197 case PFSYNC_BUS_END:
1198 if (time_uptime - ntohl(bus->endtime) >=
1199 sc->sc_ureq_sent) {

--- 16 unchanged lines hidden (view full) ---

1216 break;
1217 }
1218 PFSYNC_BUNLOCK(sc);
1219
1220 return (len);
1221}
1222
1223static int
1293 pfsync_bulk_fail, sc);
1294 if (V_pf_status.debug >= PF_DEBUG_MISC)
1295 printf("pfsync: received bulk update start\n");
1296 break;
1297
1298 case PFSYNC_BUS_END:
1299 if (time_uptime - ntohl(bus->endtime) >=
1300 sc->sc_ureq_sent) {

--- 16 unchanged lines hidden (view full) ---

1317 break;
1318 }
1319 PFSYNC_BUNLOCK(sc);
1320
1321 return (len);
1322}
1323
1324static int
1224pfsync_in_tdb(struct mbuf *m, int offset, int count, int flags)
1325pfsync_in_tdb(struct mbuf *m, int offset, int count, int flags, int action)
1225{
1226 int len = count * sizeof(struct pfsync_tdb);
1227
1228#if defined(IPSEC)
1229 struct pfsync_tdb *tp;
1230 struct mbuf *mp;
1231 int offp;
1232 int i;

--- 48 unchanged lines hidden (view full) ---

1281 printf("pfsync_insert: PFSYNC_ACT_TDB_UPD: "
1282 "invalid value\n");
1283 V_pfsyncstats.pfsyncs_badstate++;
1284 return;
1285}
1286#endif
1287
1288static int
1326{
1327 int len = count * sizeof(struct pfsync_tdb);
1328
1329#if defined(IPSEC)
1330 struct pfsync_tdb *tp;
1331 struct mbuf *mp;
1332 int offp;
1333 int i;

--- 48 unchanged lines hidden (view full) ---

1382 printf("pfsync_insert: PFSYNC_ACT_TDB_UPD: "
1383 "invalid value\n");
1384 V_pfsyncstats.pfsyncs_badstate++;
1385 return;
1386}
1387#endif
1388
1389static int
1289pfsync_in_eof(struct mbuf *m, int offset, int count, int flags)
1390pfsync_in_eof(struct mbuf *m, int offset, int count, int flags, int action)
1290{
1291 /* check if we are at the right place in the packet */
1292 if (offset != m->m_pkthdr.len)
1293 V_pfsyncstats.pfsyncs_badlen++;
1294
1295 /* we're done. free and let the caller return */
1296 m_freem(m);
1297 return (-1);
1298}
1299
1300static int
1391{
1392 /* check if we are at the right place in the packet */
1393 if (offset != m->m_pkthdr.len)
1394 V_pfsyncstats.pfsyncs_badlen++;
1395
1396 /* we're done. free and let the caller return */
1397 m_freem(m);
1398 return (-1);
1399}
1400
1401static int
1301pfsync_in_error(struct mbuf *m, int offset, int count, int flags)
1402pfsync_in_error(struct mbuf *m, int offset, int count, int flags, int action)
1302{
1303 V_pfsyncstats.pfsyncs_badact++;
1304
1305 m_freem(m);
1306 return (-1);
1307}
1308
1309static int

--- 64 unchanged lines hidden (view full) ---

1374
1375 if (nvl == NULL)
1376 return (ENOMEM);
1377
1378 if (sc->sc_sync_if)
1379 nvlist_add_string(nvl, "syncdev", sc->sc_sync_if->if_xname);
1380 nvlist_add_number(nvl, "maxupdates", sc->sc_maxupdates);
1381 nvlist_add_number(nvl, "flags", sc->sc_flags);
1403{
1404 V_pfsyncstats.pfsyncs_badact++;
1405
1406 m_freem(m);
1407 return (-1);
1408}
1409
1410static int

--- 64 unchanged lines hidden (view full) ---

1475
1476 if (nvl == NULL)
1477 return (ENOMEM);
1478
1479 if (sc->sc_sync_if)
1480 nvlist_add_string(nvl, "syncdev", sc->sc_sync_if->if_xname);
1481 nvlist_add_number(nvl, "maxupdates", sc->sc_maxupdates);
1482 nvlist_add_number(nvl, "flags", sc->sc_flags);
1483 nvlist_add_number(nvl, "version", sc->sc_version);
1382 if ((nvl_syncpeer = pfsync_sockaddr_to_syncpeer_nvlist(&sc->sc_sync_peer)) != NULL)
1383 nvlist_add_nvlist(nvl, "syncpeer", nvl_syncpeer);
1384
1385 void *packed = NULL;
1386 packed = nvlist_pack(nvl, &nvbuflen);
1387 if (packed == NULL) {
1388 free(packed, M_NVLIST);
1389 nvlist_destroy(nvl);

--- 69 unchanged lines hidden (view full) ---

1459 default:
1460 return (ENOTTY);
1461 }
1462
1463 return (0);
1464}
1465
1466static void
1484 if ((nvl_syncpeer = pfsync_sockaddr_to_syncpeer_nvlist(&sc->sc_sync_peer)) != NULL)
1485 nvlist_add_nvlist(nvl, "syncpeer", nvl_syncpeer);
1486
1487 void *packed = NULL;
1488 packed = nvlist_pack(nvl, &nvbuflen);
1489 if (packed == NULL) {
1490 free(packed, M_NVLIST);
1491 nvlist_destroy(nvl);

--- 69 unchanged lines hidden (view full) ---

1561 default:
1562 return (ENOTTY);
1563 }
1564
1565 return (0);
1566}
1567
1568static void
1467pfsync_out_state(struct pf_kstate *st, void *buf)
1569pfsync_out_state_1301(struct pf_kstate *st, void *buf)
1468{
1570{
1469 struct pfsync_state *sp = buf;
1571 union pfsync_state_union *sp = buf;
1470
1572
1471 pfsync_state_export(sp, st);
1573 pfsync_state_export(sp, st, PFSYNC_MSG_VERSION_1301);
1472}
1473
1474static void
1574}
1575
1576static void
1577pfsync_out_state_1400(struct pf_kstate *st, void *buf)
1578{
1579 union pfsync_state_union *sp = buf;
1580
1581 pfsync_state_export(sp, st, PFSYNC_MSG_VERSION_1400);
1582}
1583
1584static void
1475pfsync_out_iack(struct pf_kstate *st, void *buf)
1476{
1477 struct pfsync_ins_ack *iack = buf;
1478
1479 iack->id = st->id;
1480 iack->creatorid = st->creatorid;
1481}
1482

--- 21 unchanged lines hidden (view full) ---

1504}
1505
1506static void
1507pfsync_drop(struct pfsync_softc *sc)
1508{
1509 struct pf_kstate *st, *next;
1510 struct pfsync_upd_req_item *ur;
1511 struct pfsync_bucket *b;
1585pfsync_out_iack(struct pf_kstate *st, void *buf)
1586{
1587 struct pfsync_ins_ack *iack = buf;
1588
1589 iack->id = st->id;
1590 iack->creatorid = st->creatorid;
1591}
1592

--- 21 unchanged lines hidden (view full) ---

1614}
1615
1616static void
1617pfsync_drop(struct pfsync_softc *sc)
1618{
1619 struct pf_kstate *st, *next;
1620 struct pfsync_upd_req_item *ur;
1621 struct pfsync_bucket *b;
1512 int c, q;
1622 int c;
1623 enum pfsync_q_id q;
1513
1514 for (c = 0; c < pfsync_buckets; c++) {
1515 b = &sc->sc_buckets[c];
1624
1625 for (c = 0; c < pfsync_buckets; c++) {
1626 b = &sc->sc_buckets[c];
1516 for (q = 0; q < PFSYNC_S_COUNT; q++) {
1627 for (q = 0; q < PFSYNC_Q_COUNT; q++) {
1517 if (TAILQ_EMPTY(&b->b_qs[q]))
1518 continue;
1519
1520 TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, next) {
1628 if (TAILQ_EMPTY(&b->b_qs[q]))
1629 continue;
1630
1631 TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, next) {
1521 KASSERT(st->sync_state == q,
1632 KASSERT(st->sync_state == pfsync_qid_sstate[q],
1522 ("%s: st->sync_state == q",
1523 __func__));
1524 st->sync_state = PFSYNC_S_NONE;
1525 pf_release_state(st);
1526 }
1527 TAILQ_INIT(&b->b_qs[q]);
1528 }
1529

--- 13 unchanged lines hidden (view full) ---

1543 struct pfsync_softc *sc = V_pfsyncif;
1544 struct ifnet *ifp = sc->sc_ifp;
1545 struct mbuf *m;
1546 struct pfsync_header *ph;
1547 struct pfsync_subheader *subh;
1548 struct pf_kstate *st, *st_next;
1549 struct pfsync_upd_req_item *ur;
1550 struct pfsync_bucket *b = &sc->sc_buckets[c];
1633 ("%s: st->sync_state == q",
1634 __func__));
1635 st->sync_state = PFSYNC_S_NONE;
1636 pf_release_state(st);
1637 }
1638 TAILQ_INIT(&b->b_qs[q]);
1639 }
1640

--- 13 unchanged lines hidden (view full) ---

1654 struct pfsync_softc *sc = V_pfsyncif;
1655 struct ifnet *ifp = sc->sc_ifp;
1656 struct mbuf *m;
1657 struct pfsync_header *ph;
1658 struct pfsync_subheader *subh;
1659 struct pf_kstate *st, *st_next;
1660 struct pfsync_upd_req_item *ur;
1661 struct pfsync_bucket *b = &sc->sc_buckets[c];
1551 int aflen, offset;
1552 int q, count = 0;
1662 int aflen, offset, count = 0;
1663 enum pfsync_q_id q;
1553
1554 KASSERT(sc != NULL, ("%s: null sc", __func__));
1555 KASSERT(b->b_len > PFSYNC_MINPKT,
1556 ("%s: sc_len %zu", __func__, b->b_len));
1557 PFSYNC_BUCKET_LOCK_ASSERT(b);
1558
1559 if (ifp->if_bpf == NULL && sc->sc_sync_if == NULL) {
1560 pfsync_drop(sc);

--- 25 unchanged lines hidden (view full) ---

1586 break;
1587 }
1588#endif
1589 default:
1590 m_freem(m);
1591 return;
1592 }
1593
1664
1665 KASSERT(sc != NULL, ("%s: null sc", __func__));
1666 KASSERT(b->b_len > PFSYNC_MINPKT,
1667 ("%s: sc_len %zu", __func__, b->b_len));
1668 PFSYNC_BUCKET_LOCK_ASSERT(b);
1669
1670 if (ifp->if_bpf == NULL && sc->sc_sync_if == NULL) {
1671 pfsync_drop(sc);

--- 25 unchanged lines hidden (view full) ---

1697 break;
1698 }
1699#endif
1700 default:
1701 m_freem(m);
1702 return;
1703 }
1704
1594
1595 /* build the pfsync header */
1596 ph = (struct pfsync_header *)(m->m_data + offset);
1597 bzero(ph, sizeof(*ph));
1598 offset += sizeof(*ph);
1599
1600 ph->version = PFSYNC_VERSION;
1601 ph->len = htons(b->b_len - aflen);
1602 bcopy(V_pf_status.pf_chksum, ph->pfcksum, PF_MD5_DIGEST_LENGTH);
1603
1604 /* walk the queues */
1705 /* build the pfsync header */
1706 ph = (struct pfsync_header *)(m->m_data + offset);
1707 bzero(ph, sizeof(*ph));
1708 offset += sizeof(*ph);
1709
1710 ph->version = PFSYNC_VERSION;
1711 ph->len = htons(b->b_len - aflen);
1712 bcopy(V_pf_status.pf_chksum, ph->pfcksum, PF_MD5_DIGEST_LENGTH);
1713
1714 /* walk the queues */
1605 for (q = 0; q < PFSYNC_S_COUNT; q++) {
1715 for (q = 0; q < PFSYNC_Q_COUNT; q++) {
1606 if (TAILQ_EMPTY(&b->b_qs[q]))
1607 continue;
1608
1609 subh = (struct pfsync_subheader *)(m->m_data + offset);
1610 offset += sizeof(*subh);
1611
1612 count = 0;
1613 TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, st_next) {
1716 if (TAILQ_EMPTY(&b->b_qs[q]))
1717 continue;
1718
1719 subh = (struct pfsync_subheader *)(m->m_data + offset);
1720 offset += sizeof(*subh);
1721
1722 count = 0;
1723 TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, st_next) {
1614 KASSERT(st->sync_state == q,
1724 KASSERT(st->sync_state == pfsync_qid_sstate[q],
1615 ("%s: st->sync_state == q",
1616 __func__));
1617 /*
1618 * XXXGL: some of write methods do unlocked reads
1619 * of state data :(
1620 */
1621 pfsync_qs[q].write(st, m->m_data + offset);
1622 offset += pfsync_qs[q].len;

--- 387 unchanged lines hidden (view full) ---

2010 case PFSYNC_S_DEL_C:
2011 /* we're already handling it */
2012 break;
2013
2014 default:
2015 panic("%s: unexpected sync state %d", __func__, st->sync_state);
2016 }
2017
1725 ("%s: st->sync_state == q",
1726 __func__));
1727 /*
1728 * XXXGL: some of write methods do unlocked reads
1729 * of state data :(
1730 */
1731 pfsync_qs[q].write(st, m->m_data + offset);
1732 offset += pfsync_qs[q].len;

--- 387 unchanged lines hidden (view full) ---

2120 case PFSYNC_S_DEL_C:
2121 /* we're already handling it */
2122 break;
2123
2124 default:
2125 panic("%s: unexpected sync state %d", __func__, st->sync_state);
2126 }
2127
2018 if ((sc->sc_ifp->if_mtu - b->b_len) < sizeof(struct pfsync_state))
2128 if ((sc->sc_ifp->if_mtu - b->b_len) < sizeof(union pfsync_state_union))
2019 full = true;
2020
2021 PFSYNC_BUCKET_UNLOCK(b);
2022
2023 return (full);
2024}
2025
2026static void

--- 55 unchanged lines hidden (view full) ---

2082 V_pfsyncstats.pfsyncs_oacts[PFSYNC_ACT_CLR]++;
2083
2084 strlcpy(r.clr.ifname, ifname, sizeof(r.clr.ifname));
2085 r.clr.creatorid = creatorid;
2086
2087 pfsync_send_plus(&r, sizeof(r));
2088}
2089
2129 full = true;
2130
2131 PFSYNC_BUCKET_UNLOCK(b);
2132
2133 return (full);
2134}
2135
2136static void

--- 55 unchanged lines hidden (view full) ---

2192 V_pfsyncstats.pfsyncs_oacts[PFSYNC_ACT_CLR]++;
2193
2194 strlcpy(r.clr.ifname, ifname, sizeof(r.clr.ifname));
2195 r.clr.creatorid = creatorid;
2196
2197 pfsync_send_plus(&r, sizeof(r));
2198}
2199
2200static enum pfsync_q_id
2201pfsync_sstate_to_qid(u_int8_t sync_state)
2202{
2203 struct pfsync_softc *sc = V_pfsyncif;
2204
2205 switch (sync_state) {
2206 case PFSYNC_S_INS:
2207 switch (sc->sc_version) {
2208 case PFSYNC_MSG_VERSION_1301:
2209 return PFSYNC_Q_INS_1301;
2210 case PFSYNC_MSG_VERSION_1400:
2211 return PFSYNC_Q_INS_1400;
2212 }
2213 break;
2214 case PFSYNC_S_IACK:
2215 return PFSYNC_Q_IACK;
2216 case PFSYNC_S_UPD:
2217 switch (sc->sc_version) {
2218 case PFSYNC_MSG_VERSION_1301:
2219 return PFSYNC_Q_UPD_1301;
2220 case PFSYNC_MSG_VERSION_1400:
2221 return PFSYNC_Q_UPD_1400;
2222 }
2223 break;
2224 case PFSYNC_S_UPD_C:
2225 return PFSYNC_Q_UPD_C;
2226 case PFSYNC_S_DEL_C:
2227 return PFSYNC_Q_DEL_C;
2228 default:
2229 panic("%s: Unsupported st->sync_state 0x%02x",
2230 __func__, sync_state);
2231 }
2232
2233 panic("%s: Unsupported pfsync_msg_version %d",
2234 __func__, sc->sc_version);
2235}
2236
2090static void
2237static void
2091pfsync_q_ins(struct pf_kstate *st, int q, bool ref)
2238pfsync_q_ins(struct pf_kstate *st, int sync_state, bool ref)
2092{
2239{
2240 enum pfsync_q_id q = pfsync_sstate_to_qid(sync_state);
2093 struct pfsync_softc *sc = V_pfsyncif;
2094 size_t nlen = pfsync_qs[q].len;
2095 struct pfsync_bucket *b = pfsync_get_bucket(sc, st);
2096
2097 PFSYNC_BUCKET_LOCK_ASSERT(b);
2098
2099 KASSERT(st->sync_state == PFSYNC_S_NONE,
2100 ("%s: st->sync_state %u", __func__, st->sync_state));

--- 6 unchanged lines hidden (view full) ---

2107 if (b->b_len + nlen > sc->sc_ifp->if_mtu) {
2108 pfsync_sendout(1, b->b_id);
2109
2110 nlen = sizeof(struct pfsync_subheader) + pfsync_qs[q].len;
2111 }
2112
2113 b->b_len += nlen;
2114 TAILQ_INSERT_TAIL(&b->b_qs[q], st, sync_list);
2241 struct pfsync_softc *sc = V_pfsyncif;
2242 size_t nlen = pfsync_qs[q].len;
2243 struct pfsync_bucket *b = pfsync_get_bucket(sc, st);
2244
2245 PFSYNC_BUCKET_LOCK_ASSERT(b);
2246
2247 KASSERT(st->sync_state == PFSYNC_S_NONE,
2248 ("%s: st->sync_state %u", __func__, st->sync_state));

--- 6 unchanged lines hidden (view full) ---

2255 if (b->b_len + nlen > sc->sc_ifp->if_mtu) {
2256 pfsync_sendout(1, b->b_id);
2257
2258 nlen = sizeof(struct pfsync_subheader) + pfsync_qs[q].len;
2259 }
2260
2261 b->b_len += nlen;
2262 TAILQ_INSERT_TAIL(&b->b_qs[q], st, sync_list);
2115 st->sync_state = q;
2263 st->sync_state = pfsync_qid_sstate[q];
2116 if (ref)
2117 pf_ref_state(st);
2118}
2119
2120static void
2121pfsync_q_del(struct pf_kstate *st, bool unref, struct pfsync_bucket *b)
2122{
2264 if (ref)
2265 pf_ref_state(st);
2266}
2267
2268static void
2269pfsync_q_del(struct pf_kstate *st, bool unref, struct pfsync_bucket *b)
2270{
2123 int q = st->sync_state;
2271 enum pfsync_q_id q;
2124
2125 PFSYNC_BUCKET_LOCK_ASSERT(b);
2126 KASSERT(st->sync_state != PFSYNC_S_NONE,
2127 ("%s: st->sync_state != PFSYNC_S_NONE", __func__));
2128
2272
2273 PFSYNC_BUCKET_LOCK_ASSERT(b);
2274 KASSERT(st->sync_state != PFSYNC_S_NONE,
2275 ("%s: st->sync_state != PFSYNC_S_NONE", __func__));
2276
2277 q = pfsync_sstate_to_qid(st->sync_state);
2129 b->b_len -= pfsync_qs[q].len;
2130 TAILQ_REMOVE(&b->b_qs[q], st, sync_list);
2131 st->sync_state = PFSYNC_S_NONE;
2132 if (unref)
2133 pf_release_state(st);
2134
2135 if (TAILQ_EMPTY(&b->b_qs[q]))
2136 b->b_len -= sizeof(struct pfsync_subheader);

--- 380 unchanged lines hidden (view full) ---

2517 struct sockaddr_in *status_sin =
2518 (struct sockaddr_in *)&(status->syncpeer);
2519 if (sifp != NULL && (status_sin->sin_addr.s_addr == 0 ||
2520 status_sin->sin_addr.s_addr ==
2521 htonl(INADDR_PFSYNC_GROUP)))
2522 imf = ip_mfilter_alloc(M_WAITOK, 0, 0);
2523
2524 PFSYNC_LOCK(sc);
2278 b->b_len -= pfsync_qs[q].len;
2279 TAILQ_REMOVE(&b->b_qs[q], st, sync_list);
2280 st->sync_state = PFSYNC_S_NONE;
2281 if (unref)
2282 pf_release_state(st);
2283
2284 if (TAILQ_EMPTY(&b->b_qs[q]))
2285 b->b_len -= sizeof(struct pfsync_subheader);

--- 380 unchanged lines hidden (view full) ---

2666 struct sockaddr_in *status_sin =
2667 (struct sockaddr_in *)&(status->syncpeer);
2668 if (sifp != NULL && (status_sin->sin_addr.s_addr == 0 ||
2669 status_sin->sin_addr.s_addr ==
2670 htonl(INADDR_PFSYNC_GROUP)))
2671 imf = ip_mfilter_alloc(M_WAITOK, 0, 0);
2672
2673 PFSYNC_LOCK(sc);
2674
2675 switch (status->version) {
2676 case PFSYNC_MSG_VERSION_UNSPECIFIED:
2677 sc->sc_version = PFSYNC_MSG_VERSION_DEFAULT;
2678 break;
2679 case PFSYNC_MSG_VERSION_1301:
2680 case PFSYNC_MSG_VERSION_1400:
2681 sc->sc_version = status->version;
2682 break;
2683 default:
2684 PFSYNC_UNLOCK(sc);
2685 return (EINVAL);
2686 }
2687
2525 struct sockaddr_in *sc_sin = (struct sockaddr_in *)&sc->sc_sync_peer;
2526 sc_sin->sin_family = AF_INET;
2527 sc_sin->sin_len = sizeof(*sc_sin);
2528 if (status_sin->sin_addr.s_addr == 0) {
2529 sc_sin->sin_addr.s_addr = htonl(INADDR_PFSYNC_GROUP);
2530 } else {
2531 sc_sin->sin_addr.s_addr = status_sin->sin_addr.s_addr;
2532 }

--- 197 unchanged lines hidden ---
2688 struct sockaddr_in *sc_sin = (struct sockaddr_in *)&sc->sc_sync_peer;
2689 sc_sin->sin_family = AF_INET;
2690 sc_sin->sin_len = sizeof(*sc_sin);
2691 if (status_sin->sin_addr.s_addr == 0) {
2692 sc_sin->sin_addr.s_addr = htonl(INADDR_PFSYNC_GROUP);
2693 } else {
2694 sc_sin->sin_addr.s_addr = status_sin->sin_addr.s_addr;
2695 }

--- 197 unchanged lines hidden ---