Files
lgcosta 1fcd7b3046 M1 progress: engine port compiles except pf.c; AF_DIVERT socket family; ifq framework
- 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
2026-11-11 13:35:53 -03:00

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