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
This commit is contained in:
lgcosta committed 2026-11-11 13:35:53 -03:00
1 parent a84b2c91f3
commit 1fcd7b3046
77 files changed
+28002 -1114

No files matched your search

+5 -1
View File
@@ -10,8 +10,12 @@
#ifndef __packed
#define __packed __attribute__((__packed__))
#endif
/* NOTE: the kernel redefines 'inline' as a macro that expands to
* 'inline __gnu_inline __inline_maybe_unused notrace'; any attribute placed
* between those tokens breaks the parse. Therefore __unused expands to
* nothing here (unused *static inline* functions do not warn in GCC). */
#ifndef __unused
#define __unused __attribute__((__unused__))
#define __unused
#endif
#ifndef __dead
#define __dead __attribute__((__noreturn__))
+34
View File
@@ -0,0 +1,34 @@
/* PFLINUX compat: <sys/mutex.h> — OpenBSD struct mutex over a Linux
* counting semaphore. BSD entry points are MACROS calling pfk_* helpers,
* after #undef of any same-named kernel macros (the kernel's own mutex_*
* functions were expanded before pfk.h and are unaffected). */
#ifndef _PFK_SYS_MUTEX_H
#define _PFK_SYS_MUTEX_H
#define IPL_SOFTNET 6
struct pfk_mutex {
struct semaphore s;
const char *name;
};
void pfk_mutex_setup(struct pfk_mutex *m, const char *name);
#define PFK_MUTEX_INIT(obj) \
{ .s = __SEMAPHORE_INITIALIZER(obj, 1), .name = #obj }
#undef mutex_init
#undef mutex_destroy
#undef mutex_is_locked
#define mutex_init(m, n, f) pfk_mutex_setup((m), (n))
#define mutex_enter(m) down(&(m)->s)
#define mutex_leave(m) up(&(m)->s)
#define mutex_try_enter(m, t) (down_trylock(&(m)->s) == 0)
#define mutex_destroy(m) do { } while (0)
#define mutex_is_locked(m) (atomic_long_read(&(m)->s.count) < 1)
/* MUTEX_INITIALIZER(ipl) used in static definitions:
* struct mutex x = MUTEX_INITIALIZER(IPL_SOFTNET); */
#define MUTEX_INITIALIZER(ipl) PFK_MUTEX_INIT(pfk_mtx_static)
#endif
+8
View File
@@ -0,0 +1,8 @@
/* PFLINUX compat: <sys/pclock.h> — passclock type (PF uses struct pclock
* members for per-domain stats; kept as a simple counter here). */
#ifndef _PFK_PCLK_H
#define _PFK_PCLK_H
struct pclock {
u_int64_t pclock_count[4];
};
#endif
+106
View File
@@ -0,0 +1,106 @@
/* 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
+2 -2
View File
@@ -6,9 +6,9 @@
struct refcnt { refcount_t rc; };
#define REFCNT_INITIALIZER { .rc = REFCNT_INIT }
static inline void refcnt_init(struct refcnt *r, unsigned int v)
static inline void refcnt_init(struct refcnt *r)
{
refcount_set(&r->rc, v ? (int)v : 1);
refcount_set(&r->rc, 1);
}
static inline unsigned int refcnt_value(const struct refcnt *r)
{
+7
View File
@@ -0,0 +1,7 @@
/* PFLINUX compat: <sys/rwlock.h> — struct pfk_rwlock alias provided by
* pfk.h before this point (include-guard re-entrancy); wrapper is a marker. */
#ifndef _PFK_RWLOCK_H
#define _PFK_RWLOCK_H
/* struct rwlock == struct pfk_rwlock (see pfk.h) */
#define LCK_MRW 0
#endif
+19 -19
View File
@@ -821,115 +821,115 @@ int _rb_check(const struct rb_type *, void *, unsigned long);
#define RBT_PROTOTYPE(_name, _type, _field, _cmp) \
extern const struct rb_type *const _name##_RBT_TYPE; \
\
__unused static inline void \
static inline void \
_name##_RBT_INIT(struct _name *head) \
{ \
_rb_init(&head->rbh_root); \
} \
\
__unused static inline struct _type * \
static inline struct _type * \
_name##_RBT_INSERT(struct _name *head, struct _type *elm) \
{ \
return _rb_insert(_name##_RBT_TYPE, &head->rbh_root, elm); \
} \
\
__unused static inline struct _type * \
static inline struct _type * \
_name##_RBT_REMOVE(struct _name *head, struct _type *elm) \
{ \
return _rb_remove(_name##_RBT_TYPE, &head->rbh_root, elm); \
} \
\
__unused static inline struct _type * \
static inline struct _type * \
_name##_RBT_FIND(struct _name *head, const struct _type *key) \
{ \
return _rb_find(_name##_RBT_TYPE, &head->rbh_root, key); \
} \
\
__unused static inline struct _type * \
static inline struct _type * \
_name##_RBT_NFIND(struct _name *head, const struct _type *key) \
{ \
return _rb_nfind(_name##_RBT_TYPE, &head->rbh_root, key); \
} \
\
__unused static inline struct _type * \
static inline struct _type * \
_name##_RBT_ROOT(struct _name *head) \
{ \
return _rb_root(_name##_RBT_TYPE, &head->rbh_root); \
} \
\
__unused static inline int \
static inline int \
_name##_RBT_EMPTY(struct _name *head) \
{ \
return _rb_empty(&head->rbh_root); \
} \
\
__unused static inline struct _type * \
static inline struct _type * \
_name##_RBT_MIN(struct _name *head) \
{ \
return _rb_min(_name##_RBT_TYPE, &head->rbh_root); \
} \
\
__unused static inline struct _type * \
static inline struct _type * \
_name##_RBT_MAX(struct _name *head) \
{ \
return _rb_max(_name##_RBT_TYPE, &head->rbh_root); \
} \
\
__unused static inline struct _type * \
static inline struct _type * \
_name##_RBT_NEXT(struct _type *elm) \
{ \
return _rb_next(_name##_RBT_TYPE, elm); \
} \
\
__unused static inline struct _type * \
static inline struct _type * \
_name##_RBT_PREV(struct _type *elm) \
{ \
return _rb_prev(_name##_RBT_TYPE, elm); \
} \
\
__unused static inline struct _type * \
static inline struct _type * \
_name##_RBT_LEFT(struct _type *elm) \
{ \
return _rb_left(_name##_RBT_TYPE, elm); \
} \
\
__unused static inline struct _type * \
static inline struct _type * \
_name##_RBT_RIGHT(struct _type *elm) \
{ \
return _rb_right(_name##_RBT_TYPE, elm); \
} \
\
__unused static inline struct _type * \
static inline struct _type * \
_name##_RBT_PARENT(struct _type *elm) \
{ \
return _rb_parent(_name##_RBT_TYPE, elm); \
} \
\
__unused static inline void \
static inline void \
_name##_RBT_SET_LEFT(struct _type *elm, struct _type *left) \
{ \
_rb_set_left(_name##_RBT_TYPE, elm, left); \
} \
\
__unused static inline void \
static inline void \
_name##_RBT_SET_RIGHT(struct _type *elm, struct _type *right) \
{ \
_rb_set_right(_name##_RBT_TYPE, elm, right); \
} \
\
__unused static inline void \
static inline void \
_name##_RBT_SET_PARENT(struct _type *elm, struct _type *parent) \
{ \
_rb_set_parent(_name##_RBT_TYPE, elm, parent); \
} \
\
__unused static inline void \
static inline void \
_name##_RBT_POISON(struct _type *elm, unsigned long poison) \
{ \
_rb_poison(_name##_RBT_TYPE, elm, poison); \
} \
\
__unused static inline int \
static inline int \
_name##_RBT_CHECK(struct _type *elm, unsigned long poison) \
{ \
return _rb_check(_name##_RBT_TYPE, elm, poison); \