- pfk.h: BSD types/ioctl encoding (OpenBSD bit layout), locks (NET_LOCK=rwsem), pools, timeouts, mbuf shim over sk_buff, ifnet registry, toeplitz/siphash - pfk_mod/pfk_hooks: misc /dev/pf (0600), IPv4 netfilter hook skeleton, DIOCGETSTATUS answered (M1 skeleton; engine ioctls land with pf_ioctl.c) - vendorize/stage-port scripts: deterministic upstream staging with seds (struct renames, IFF_*->PFIFF_*, sa_len drops) logged to docs/porting-notes - fixes: modules_prepare+Module.symvers for out-of-tree builds
219 lines
5.5 KiB
C
219 lines
5.5 KiB
C
/* PFLINUX port of OpenBSD 8.0 net/pf_ioctl.c — see docs/porting-notes.md */
|
|
#include <pfk.h>
|
|
|
|
struct pf_statelim_kstat {
|
|
struct kstat_kv name;
|
|
struct kstat_kv inuse;
|
|
struct kstat_kv limit;
|
|
struct kstat_kv admitted;
|
|
struct kstat_kv hardlimited;
|
|
struct kstat_kv ratelimited;
|
|
};
|
|
|
|
static int
|
|
pf_statelim_kstat_read(struct kstat *ks)
|
|
{
|
|
struct pf_statelim *pfstlim = ks->ks_softc;
|
|
struct pf_statelim_kstat *d = ks->ks_data;
|
|
unsigned int gen;
|
|
|
|
strlcpy(kstat_kv_istr(&d->name), pfstlim->pfstlim_nm,
|
|
sizeof(kstat_kv_istr(&d->name)));
|
|
kstat_kv_u32(&d->limit) = pfstlim->pfstlim_limit;
|
|
|
|
pc_cons_enter(&pfstlim->pfstlim_lock, &gen);
|
|
do {
|
|
kstat_kv_u32(&d->inuse) = pfstlim->pfstlim_inuse;
|
|
kstat_kv_u64(&d->admitted) =
|
|
pfstlim->pfstlim_counters.admitted;
|
|
kstat_kv_u64(&d->hardlimited) =
|
|
pfstlim->pfstlim_counters.hardlimited;
|
|
kstat_kv_u64(&d->ratelimited) =
|
|
pfstlim->pfstlim_counters.ratelimited;
|
|
} while (pc_cons_leave(&pfstlim->pfstlim_lock, &gen) != 0);
|
|
|
|
nanouptime(&ks->ks_updated);
|
|
|
|
return (0);
|
|
};
|
|
|
|
static void
|
|
pf_statelim_kstat_attach(struct pf_statelim *pfstlim)
|
|
{
|
|
struct kstat *ks = pfstlim->pfstlim_ks;
|
|
struct pf_statelim_kstat *d;
|
|
|
|
if (ks != NULL)
|
|
return;
|
|
|
|
d = malloc(sizeof(*d), M_DEVBUF, M_WAITOK|M_CANFAIL|M_ZERO);
|
|
if (d == NULL) {
|
|
printf("pf: unable to allocate state-limiter kstat\n");
|
|
return;
|
|
}
|
|
|
|
ks = kstat_create("pf", 0, "state-limiter", pfstlim->pfstlim_id,
|
|
KSTAT_T_KV, 0);
|
|
if (ks == NULL) {
|
|
printf("pf: unable to create state-limiter kstat\n");
|
|
free(d, M_DEVBUF, sizeof(*d));
|
|
return;
|
|
}
|
|
|
|
kstat_kv_init(&d->name, "name", KSTAT_KV_T_ISTR);
|
|
kstat_kv_init(&d->inuse, "in-use", KSTAT_KV_T_UINT32);
|
|
kstat_kv_init(&d->limit, "limit", KSTAT_KV_T_UINT32);
|
|
kstat_kv_init(&d->admitted, "admitted", KSTAT_KV_T_COUNTER64);
|
|
kstat_kv_init(&d->hardlimited, "hard-limited", KSTAT_KV_T_COUNTER64);
|
|
kstat_kv_init(&d->ratelimited, "rate-limited", KSTAT_KV_T_COUNTER64);
|
|
|
|
ks->ks_softc = pfstlim;
|
|
ks->ks_data = d;
|
|
ks->ks_datalen = sizeof(*d);
|
|
ks->ks_read = pf_statelim_kstat_read;
|
|
|
|
kstat_install(ks);
|
|
|
|
pfstlim->pfstlim_ks = ks;
|
|
}
|
|
|
|
static void
|
|
pf_statelim_kstat_detach(struct pf_statelim *pfstlim)
|
|
{
|
|
struct kstat *ks = pfstlim->pfstlim_ks;
|
|
struct pf_statelim_kstat *d;
|
|
|
|
if (ks == NULL)
|
|
return;
|
|
|
|
kstat_remove(ks);
|
|
d = ks->ks_data;
|
|
kstat_destroy(ks);
|
|
|
|
free(d, M_DEVBUF, sizeof(*d));
|
|
}
|
|
|
|
struct pf_sourcelim_kstat {
|
|
struct kstat_kv name;
|
|
|
|
/* pf_source/address/prefix counters */
|
|
struct kstat_kv sourceinuse;
|
|
struct kstat_kv sourcelimit;
|
|
struct kstat_kv sourceallocs;
|
|
struct kstat_kv sourcelimited;
|
|
struct kstat_kv sourcenomem;
|
|
|
|
/* state counters */
|
|
struct kstat_kv inuse;
|
|
struct kstat_kv limit;
|
|
struct kstat_kv admitted;
|
|
struct kstat_kv hardlimited;
|
|
struct kstat_kv ratelimited;
|
|
};
|
|
|
|
static int
|
|
pf_sourcelim_kstat_read(struct kstat *ks)
|
|
{
|
|
struct pf_sourcelim *pfsrlim = ks->ks_softc;
|
|
struct pf_sourcelim_kstat *d = ks->ks_data;
|
|
unsigned int gen;
|
|
|
|
strlcpy(kstat_kv_istr(&d->name), pfsrlim->pfsrlim_nm,
|
|
sizeof(kstat_kv_istr(&d->name)));
|
|
kstat_kv_u32(&d->sourcelimit) = pfsrlim->pfsrlim_entries;
|
|
kstat_kv_u32(&d->limit) = pfsrlim->pfsrlim_limit;
|
|
|
|
pc_cons_enter(&pfsrlim->pfsrlim_lock, &gen);
|
|
do {
|
|
kstat_kv_u32(&d->sourceinuse) =
|
|
pfsrlim->pfsrlim_nsources;
|
|
kstat_kv_u64(&d->sourceallocs) =
|
|
pfsrlim->pfsrlim_counters.addrallocs;
|
|
kstat_kv_u64(&d->sourcelimited) =
|
|
pfsrlim->pfsrlim_counters.addrlimited;
|
|
kstat_kv_u64(&d->sourcenomem) =
|
|
pfsrlim->pfsrlim_counters.addrnomem;
|
|
|
|
kstat_kv_u32(&d->inuse) =
|
|
pfsrlim->pfsrlim_counters.inuse;
|
|
kstat_kv_u64(&d->admitted) =
|
|
pfsrlim->pfsrlim_counters.admitted;
|
|
kstat_kv_u64(&d->hardlimited) =
|
|
pfsrlim->pfsrlim_counters.hardlimited;
|
|
kstat_kv_u64(&d->ratelimited) =
|
|
pfsrlim->pfsrlim_counters.ratelimited;
|
|
} while (pc_cons_leave(&pfsrlim->pfsrlim_lock, &gen) != 0);
|
|
|
|
nanouptime(&ks->ks_updated);
|
|
|
|
return (0);
|
|
};
|
|
|
|
static void
|
|
pf_sourcelim_kstat_attach(struct pf_sourcelim *pfsrlim)
|
|
{
|
|
struct kstat *ks = pfsrlim->pfsrlim_ks;
|
|
struct pf_sourcelim_kstat *d;
|
|
|
|
if (ks != NULL)
|
|
return;
|
|
|
|
d = malloc(sizeof(*d), M_DEVBUF, M_WAITOK|M_CANFAIL|M_ZERO);
|
|
if (d == NULL) {
|
|
printf("pf: unable to allocate source-limiter kstat\n");
|
|
return;
|
|
}
|
|
|
|
ks = kstat_create("pf", 0, "source-limiter", pfsrlim->pfsrlim_id,
|
|
KSTAT_T_KV, 0);
|
|
if (ks == NULL) {
|
|
printf("pf: unable to create source-limiter kstat\n");
|
|
free(d, M_DEVBUF, sizeof(*d));
|
|
return;
|
|
}
|
|
|
|
kstat_kv_init(&d->name, "name", KSTAT_KV_T_ISTR);
|
|
|
|
kstat_kv_init(&d->sourceinuse, "source-in-use", KSTAT_KV_T_UINT32);
|
|
kstat_kv_init(&d->sourcelimit, "source-limit", KSTAT_KV_T_UINT32);
|
|
kstat_kv_init(&d->sourceallocs, "source-allocs",
|
|
KSTAT_KV_T_COUNTER64);
|
|
kstat_kv_init(&d->sourcelimited, "source-limited",
|
|
KSTAT_KV_T_COUNTER64);
|
|
kstat_kv_init(&d->sourcenomem, "source-nomem",
|
|
KSTAT_KV_T_COUNTER64);
|
|
|
|
kstat_kv_init(&d->inuse, "in-use", KSTAT_KV_T_UINT32);
|
|
kstat_kv_init(&d->limit, "limit", KSTAT_KV_T_UINT32);
|
|
kstat_kv_init(&d->admitted, "admitted", KSTAT_KV_T_COUNTER64);
|
|
kstat_kv_init(&d->hardlimited, "hard-limited", KSTAT_KV_T_COUNTER64);
|
|
kstat_kv_init(&d->ratelimited, "rate-limited", KSTAT_KV_T_COUNTER64);
|
|
|
|
ks->ks_softc = pfsrlim;
|
|
ks->ks_data = d;
|
|
ks->ks_datalen = sizeof(*d);
|
|
ks->ks_read = pf_sourcelim_kstat_read;
|
|
|
|
kstat_install(ks);
|
|
|
|
pfsrlim->pfsrlim_ks = ks;
|
|
}
|
|
|
|
static void
|
|
pf_sourcelim_kstat_detach(struct pf_sourcelim *pfsrlim)
|
|
{
|
|
struct kstat *ks = pfsrlim->pfsrlim_ks;
|
|
struct pf_sourcelim_kstat *d;
|
|
|
|
if (ks == NULL)
|
|
return;
|
|
|
|
kstat_remove(ks);
|
|
d = ks->ks_data;
|
|
kstat_destroy(ks);
|
|
|
|
free(d, M_DEVBUF, sizeof(*d));
|
|
}
|
|
|
|
#endif /* NKSTAT > 0 */
|