Index: npf.c =================================================================== RCS file: /cvsroot/src/sys/net/npf/npf.c,v retrieving revision 1.34 retrieving revision 1.35 diff -u -r1.34 -r1.35 --- npf.c 1 Jun 2017 02:45:14 -0000 1.34 +++ npf.c 12 Sep 2018 21:58:38 -0000 1.35 @@ -35,7 +35,7 @@ #ifdef _KERNEL #include -__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.34 2017/06/01 02:45:14 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.35 2018/09/12 21:58:38 christos Exp $"); #include #include @@ -56,6 +56,7 @@ npf_bpf_sysinit(); npf_tableset_sysinit(); npf_nat_sysinit(); + npf_alg_sysinit(); return npf_worker_sysinit(nworkers); } @@ -63,6 +64,7 @@ npf_sysfini(void) { npf_worker_sysfini(); + npf_alg_sysfini(); npf_nat_sysfini(); npf_tableset_sysfini(); npf_bpf_sysfini(); Index: npf_alg.c =================================================================== RCS file: /cvsroot/src/sys/net/npf/npf_alg.c,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- npf_alg.c 26 Dec 2016 23:05:06 -0000 1.16 +++ npf_alg.c 12 Sep 2018 21:58:38 -0000 1.17 @@ -35,13 +35,14 @@ #ifdef _KERNEL #include -__KERNEL_RCSID(0, "$NetBSD: npf_alg.c,v 1.16 2016/12/26 23:05:06 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_alg.c,v 1.17 2018/09/12 21:58:38 christos Exp $"); #include #include #include #include +#include #include #include #include @@ -67,11 +68,31 @@ /* Matching, inspection and translation functions. */ npfa_funcs_t alg_funcs[NPF_MAX_ALGS]; + + /* Passive reference until we npf conn lookup is pserialize-safe. */ + struct psref_target alg_psref[NPF_MAX_ALGS]; }; static const char alg_prefix[] = "npf_alg_"; #define NPF_EXT_PREFLEN (sizeof(alg_prefix) - 1) +__read_mostly static struct psref_class * npf_alg_psref_class = NULL; + +void +npf_alg_sysinit(void) +{ + + npf_alg_psref_class = psref_class_create("npf_alg", IPL_SOFTNET); +} + +void +npf_alg_sysfini(void) +{ + + psref_class_destroy(npf_alg_psref_class); + npf_alg_psref_class = NULL; +} + void npf_alg_init(npf_t *npf) { @@ -160,6 +181,10 @@ alg->na_name = name; alg->na_slot = i; + /* Prepare a psref target. */ + psref_target_init(&aset->alg_psref[i], npf_alg_psref_class); + membar_producer(); + /* Assign the functions. */ afuncs = &aset->alg_funcs[i]; afuncs->match = funcs->match; @@ -189,6 +214,7 @@ afuncs->translate = NULL; afuncs->inspect = NULL; pserialize_perform(npf->qsbr); + psref_target_destroy(&aset->alg_psref[i], npf_alg_psref_class); /* Finally, unregister the ALG. */ npf_ruleset_freealg(npf_config_natset(npf), alg); @@ -246,15 +272,23 @@ { npf_algset_t *aset = npc->npc_ctx->algset; npf_conn_t *con = NULL; + struct psref psref; int s; s = pserialize_read_enter(); for (u_int i = 0; i < aset->alg_count; i++) { const npfa_funcs_t *f = &aset->alg_funcs[i]; + struct psref_target *psref_target = &aset->alg_psref[i]; if (!f->inspect) continue; - if ((con = f->inspect(npc, di)) != NULL) + membar_consumer(); + psref_acquire(&psref, psref_target, npf_alg_psref_class); + pserialize_read_exit(s); + con = f->inspect(npc, di); + s = pserialize_read_enter(); + psref_release(&psref, psref_target, npf_alg_psref_class); + if (con != NULL) break; } pserialize_read_exit(s); Index: npf_impl.h =================================================================== RCS file: /cvsroot/src/sys/net/npf/npf_impl.h,v retrieving revision 1.71 retrieving revision 1.72 diff -u -r1.71 -r1.72 --- npf_impl.h 31 Aug 2018 14:16:06 -0000 1.71 +++ npf_impl.h 12 Sep 2018 21:58:38 -0000 1.72 @@ -405,6 +405,8 @@ npf_conn_t *); /* ALG interface. */ +void npf_alg_sysinit(void); +void npf_alg_sysfini(void); void npf_alg_init(npf_t *); void npf_alg_fini(npf_t *); npf_alg_t * npf_alg_register(npf_t *, const char *, const npfa_funcs_t *);