- compat layer extended through the full BSD API surface pf_ioctl/pf_lb/ pf_if/pf_norm/pf_table/pf_ruleset/radix/md5/sha2 need (all compile): cpumem/counters model, ifaddr/ifg groups, cred view, endian+in6 names, NAT46/64, SipHash24, mbuf_list, frag6 helpers, ip6 forward/checksum, tcp options/FSM names, taskqueue & sysctl shims (documented in docs/porting-notes.md) - pfsrc/divert_sock.c: real BSD divert(4) as runtime-registered PF_DIVERT=32 socket family inside the module (sock_register; NPROTO=AF_MAX=45 -> zero core patches); divert_packet/divert6_packet wired for pf.c - compat/pfk_ifq.c: OpenBSD 8.0 ifq framework with priq back end; hfsc and fq_codel aliases pending M5 (recorded in feature matrix as pending) - design + plan updated for the divert decision (user-requested) - stage-port.sh: single deterministic rename program for headers and .c
107 lines
2.2 KiB
C
107 lines
2.2 KiB
C
/* PFLINUX compat: <sys/percpu.h> — OpenBSD cpumem over a
|
|
* per-CPU-slot array (preempt disabled during access; counters only). */
|
|
#ifndef _PFK_SYSPERCPU_H
|
|
#define _PFK_SYSPERCPU_H
|
|
|
|
struct cpumem {
|
|
void *cm_base;
|
|
size_t cm_item;
|
|
int cm_ncpu;
|
|
};
|
|
|
|
struct cpumem_iter {
|
|
unsigned int cpumem_iter_num;
|
|
unsigned int cpumem_iter_cpus;
|
|
unsigned int cpumem_iter_cpu;
|
|
unsigned long cpumem_iter_obj;
|
|
struct cpumem *cm;
|
|
};
|
|
|
|
static inline struct cpumem *
|
|
cpumem_malloc(size_t item, int flags)
|
|
{
|
|
struct cpumem *cm;
|
|
gfp_t g = (flags & M_WAITOK) ? GFP_KERNEL : GFP_ATOMIC;
|
|
|
|
cm = kmalloc(sizeof(*cm), g);
|
|
if (!cm)
|
|
return NULL;
|
|
cm->cm_ncpu = num_possible_cpus();
|
|
cm->cm_base = vzalloc((size_t)cm->cm_ncpu * item);
|
|
if (!cm->cm_base) {
|
|
kfree(cm);
|
|
return NULL;
|
|
}
|
|
cm->cm_item = item;
|
|
return cm;
|
|
}
|
|
|
|
static inline void *
|
|
cpumem_enter(struct cpumem *cm)
|
|
{
|
|
preempt_disable();
|
|
return (char *)cm->cm_base + (size_t)smp_processor_id() * cm->cm_item;
|
|
}
|
|
|
|
static inline void
|
|
cpumem_leave(struct cpumem *cm, void *p)
|
|
{
|
|
preempt_enable();
|
|
}
|
|
|
|
static inline void
|
|
cpumem_free(struct cpumem *cm, int size)
|
|
{
|
|
if (!cm)
|
|
return;
|
|
vfree(cm->cm_base);
|
|
kfree(cm);
|
|
}
|
|
|
|
/* BSD CPUMEM_FOREACH: iterate the per-CPU slots of a cpumem area. */
|
|
static inline void *
|
|
pfk_cpumem_at(struct cpumem *cm, unsigned int cpu)
|
|
{
|
|
if (!cm || !cm->cm_base || cpu >= (unsigned int)cm->cm_ncpu)
|
|
return NULL;
|
|
return (char *)cm->cm_base + (size_t)cpu * cm->cm_item;
|
|
}
|
|
|
|
static inline void *
|
|
pfk_cpumem_first(struct cpumem_iter *it, struct cpumem *cm)
|
|
{
|
|
it->cpumem_iter_num = 0;
|
|
it->cm = cm;
|
|
return pfk_cpumem_at(cm, 0);
|
|
}
|
|
|
|
static inline void *
|
|
pfk_cpumem_next(struct cpumem_iter *it, struct cpumem *cm)
|
|
{
|
|
it->cpumem_iter_num++;
|
|
if (it->cpumem_iter_num >= (unsigned int)nr_cpu_ids)
|
|
return NULL;
|
|
return pfk_cpumem_at(cm, it->cpumem_iter_num);
|
|
}
|
|
|
|
#define CPUMEM_FOREACH(var, it, cm) \
|
|
for ((var) = pfk_cpumem_first((it), (cm)); \
|
|
(var) != NULL; \
|
|
(var) = pfk_cpumem_next((it), (cm)))
|
|
|
|
/* BSD cpumem_ref/cpumem_modify aliases */
|
|
static inline void *
|
|
cpumem_ref(struct cpumem *cm)
|
|
{
|
|
preempt_disable();
|
|
return (char *)cm->cm_base + (size_t)smp_processor_id() * cm->cm_item;
|
|
}
|
|
|
|
static inline void
|
|
cpumem_drop(struct cpumem *cm, void *p)
|
|
{
|
|
preempt_enable();
|
|
}
|
|
|
|
#endif
|