M1: compat layer + pf.ko skeleton builds against Linux 7.3.4

- 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
This commit is contained in:
lgcosta committed 2026-11-11 12:09:34 -03:00
1 parent ba81284bd3
commit da2e9b679a
87 files changed
+47256 -3

No files matched your search

+179
View File
@@ -0,0 +1,179 @@
/* $OpenBSD: _endian.h,v 1.8 2018/01/11 23:13:37 dlg Exp $ */
/*-
* Copyright (c) 1997 Niklas Hallqvist. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Internal endianness macros. This pulls in <machine/endian.h> to
* get the correct setting direction for the platform and sets internal
* ('__' prefix) macros appropriately.
*/
#ifndef _SYS__ENDIAN_H_
#define _SYS__ENDIAN_H_
#include <sys/_types.h>
#define __FROM_SYS__ENDIAN
#include <machine/endian.h>
#undef __FROM_SYS__ENDIAN
#define _LITTLE_ENDIAN 1234
#define _BIG_ENDIAN 4321
#define _PDP_ENDIAN 3412
/* Note that these macros evaluate their arguments several times. */
#define __swap16gen(x) \
(__uint16_t)(((__uint16_t)(x) & 0xffU) << 8 | ((__uint16_t)(x) & 0xff00U) >> 8)
#define __swap32gen(x) \
(__uint32_t)(((__uint32_t)(x) & 0xff) << 24 | \
((__uint32_t)(x) & 0xff00) << 8 | ((__uint32_t)(x) & 0xff0000) >> 8 |\
((__uint32_t)(x) & 0xff000000) >> 24)
#define __swap64gen(x) \
(__uint64_t)((((__uint64_t)(x) & 0xff) << 56) | \
((__uint64_t)(x) & 0xff00ULL) << 40 | \
((__uint64_t)(x) & 0xff0000ULL) << 24 | \
((__uint64_t)(x) & 0xff000000ULL) << 8 | \
((__uint64_t)(x) & 0xff00000000ULL) >> 8 | \
((__uint64_t)(x) & 0xff0000000000ULL) >> 24 | \
((__uint64_t)(x) & 0xff000000000000ULL) >> 40 | \
((__uint64_t)(x) & 0xff00000000000000ULL) >> 56)
#ifndef __HAVE_MD_SWAP
static __inline __uint16_t
__swap16md(__uint16_t x)
{
return (__swap16gen(x));
}
static __inline __uint32_t
__swap32md(__uint32_t x)
{
return (__swap32gen(x));
}
static __inline __uint64_t
__swap64md(__uint64_t x)
{
return (__swap64gen(x));
}
#endif
#define __swap16(x) \
(__uint16_t)(__builtin_constant_p(x) ? __swap16gen(x) : __swap16md(x))
#define __swap32(x) \
(__uint32_t)(__builtin_constant_p(x) ? __swap32gen(x) : __swap32md(x))
#define __swap64(x) \
(__uint64_t)(__builtin_constant_p(x) ? __swap64gen(x) : __swap64md(x))
#if _BYTE_ORDER == _LITTLE_ENDIAN
#define _QUAD_HIGHWORD 1
#define _QUAD_LOWWORD 0
#define __htobe16 __swap16
#define __htobe32 __swap32
#define __htobe64 __swap64
#define __htole16(x) ((__uint16_t)(x))
#define __htole32(x) ((__uint32_t)(x))
#define __htole64(x) ((__uint64_t)(x))
#ifdef _KERNEL
#ifdef __HAVE_MD_SWAPIO
#define __bemtoh16(_x) __mswap16(_x)
#define __bemtoh32(_x) __mswap32(_x)
#define __bemtoh64(_x) __mswap64(_x)
#define __htobem16(_x, _v) __swapm16((_x), (_v))
#define __htobem32(_x, _v) __swapm32((_x), (_v))
#define __htobem64(_x, _v) __swapm64((_x), (_v))
#endif /* __HAVE_MD_SWAPIO */
#endif /* _KERNEL */
#endif /* _BYTE_ORDER == _LITTLE_ENDIAN */
#if _BYTE_ORDER == _BIG_ENDIAN
#define _QUAD_HIGHWORD 0
#define _QUAD_LOWWORD 1
#define __htobe16(x) ((__uint16_t)(x))
#define __htobe32(x) ((__uint32_t)(x))
#define __htobe64(x) ((__uint64_t)(x))
#define __htole16 __swap16
#define __htole32 __swap32
#define __htole64 __swap64
#ifdef _KERNEL
#ifdef __HAVE_MD_SWAPIO
#define __lemtoh16(_x) __mswap16(_x)
#define __lemtoh32(_x) __mswap32(_x)
#define __lemtoh64(_x) __mswap64(_x)
#define __htolem16(_x, _v) __swapm16((_x), (_v))
#define __htolem32(_x, _v) __swapm32((_x), (_v))
#define __htolem64(_x, _v) __swapm64((_x), (_v))
#endif /* __HAVE_MD_SWAPIO */
#endif /* _KERNEL */
#endif /* _BYTE_ORDER == _BIG_ENDIAN */
#ifdef _KERNEL
/*
* Fill in the __hto[bl]em{16,32,64} and __[bl]emtoh{16,32,64} macros
* that haven't been defined yet
*/
#ifndef __bemtoh16
#define __bemtoh16(_x) __htobe16(*(__uint16_t *)(_x))
#define __bemtoh32(_x) __htobe32(*(__uint32_t *)(_x))
#define __bemtoh64(_x) __htobe64(*(__uint64_t *)(_x))
#endif
#ifndef __htobem16
#define __htobem16(_x, _v) (*(__uint16_t *)(_x) = __htobe16(_v))
#define __htobem32(_x, _v) (*(__uint32_t *)(_x) = __htobe32(_v))
#define __htobem64(_x, _v) (*(__uint64_t *)(_x) = __htobe64(_v))
#endif
#ifndef __lemtoh16
#define __lemtoh16(_x) __htole16(*(__uint16_t *)(_x))
#define __lemtoh32(_x) __htole32(*(__uint32_t *)(_x))
#define __lemtoh64(_x) __htole64(*(__uint64_t *)(_x))
#endif
#ifndef __htolem16
#define __htolem16(_x, _v) (*(__uint16_t *)(_x) = __htole16(_v))
#define __htolem32(_x, _v) (*(__uint32_t *)(_x) = __htole32(_v))
#define __htolem64(_x, _v) (*(__uint64_t *)(_x) = __htole64(_v))
#endif
#endif /* _KERNEL */
#endif /* _SYS__ENDIAN_H_ */
+7
View File
@@ -0,0 +1,7 @@
/* PFLINUX compat: <sys/_null.h> */
#ifndef _SYS__NULL_H_
#define _SYS__NULL_H_
#ifndef NULL
#define NULL 0L
#endif
#endif
+34
View File
@@ -0,0 +1,34 @@
/* PFLINUX compat: <sys/cdefs.h> minimal for queue.h/tree.h */
#ifndef _PFK_CDEFS_H
#define _PFK_CDEFS_H
#include <linux/compiler.h>
#define __BEGIN_DECLS
#define __END_DECLS
#ifndef __aligned
#define __aligned(x) __attribute__((__aligned__(x)))
#endif
#ifndef __packed
#define __packed __attribute__((__packed__))
#endif
#ifndef __unused
#define __unused __attribute__((__unused__))
#endif
#ifndef __dead
#define __dead __attribute__((__noreturn__))
#endif
#ifndef __predict_false
#define __predict_false(x) unlikely(x)
#endif
#ifndef __predict_true
#define __predict_true(x) likely(x)
#endif
#ifndef __arraycount
#define __arraycount(a) (sizeof(a)/sizeof((a)[0]))
#endif
#ifndef __predict
#define __predict(x, y) ((y) ? likely(x) : unlikely(x))
#endif
#ifndef __restrict
#define __restrict
#endif
#endif
+6
View File
@@ -0,0 +1,6 @@
/* PFLINUX compat: <sys/endian.h> */
#ifndef _PFK_SYS_ENDIAN_H
#define _PFK_SYS_ENDIAN_H
#include <linux/byteorder/generic.h>
#include <linux/byteorder/little_endian.h>
#endif
+10
View File
@@ -0,0 +1,10 @@
/* PFLINUX compat: <sys/param.h> */
#ifndef _PFK_PARAM_H
#define _PFK_PARAM_H
#include <linux/limits.h>
#define MAXHOSTNAMELEN 64
#define NOFILE 256
#define BSD 20260101
#define BSD_VERSION BSD
#define NETBSD 0
#endif
+633
View File
@@ -0,0 +1,633 @@
/* $OpenBSD: queue.h,v 1.47 2026/06/12 01:04:42 millert Exp $ */
/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)queue.h 8.5 (Berkeley) 8/20/94
*/
#ifndef _SYS_QUEUE_H_
#define _SYS_QUEUE_H_
#include <sys/_null.h>
/*
* This file defines five types of data structures: singly-linked lists,
* lists, simple queues, tail queues and XOR simple queues.
*
*
* A singly-linked list is headed by a single forward pointer. The elements
* are singly linked for minimum space and pointer manipulation overhead at
* the expense of O(n) removal for arbitrary elements. New elements can be
* added to the list after an existing element or at the head of the list.
* Elements being removed from the head of the list should use the explicit
* macro for this purpose for optimum efficiency. A singly-linked list may
* only be traversed in the forward direction. Singly-linked lists are ideal
* for applications with large datasets and few or no removals or for
* implementing a LIFO queue.
*
* A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction.
*
* A simple queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are singly
* linked to save space, so elements can only be removed from the
* head of the list. New elements can be added to the list before or after
* an existing element, at the head of the list, or at the end of the
* list. A simple queue may only be traversed in the forward direction.
*
* A tail queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or
* after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction.
*
* An XOR simple queue is used in the same way as a regular simple queue.
* The difference is that the head structure also includes a "cookie" that
* is XOR'd with the queue pointer (first, last or next) to generate the
* real pointer value.
*
* For details on the use of these macros, see the queue(3) manual page.
*/
#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
#define _Q_INVALID ((void *)-1)
#define _Q_INVALIDATE(a) (a) = _Q_INVALID
#else
#define _Q_INVALIDATE(a)
#endif
/*
* Singly-linked List definitions.
*/
#define SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first; /* first element */ \
}
#define SLIST_HEAD_INITIALIZER(head) \
{ NULL }
#define SLIST_ENTRY(type) \
struct { \
struct type *sle_next; /* next element */ \
}
/*
* Singly-linked List access methods.
*/
#define SLIST_FIRST(head) ((head)->slh_first)
#define SLIST_END(head) NULL
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
#define SLIST_FOREACH(var, head, field) \
for((var) = SLIST_FIRST(head); \
(var) != SLIST_END(head); \
(var) = SLIST_NEXT(var, field))
#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = SLIST_FIRST(head); \
(var) && ((tvar) = SLIST_NEXT(var, field), 1); \
(var) = (tvar))
/*
* Singly-linked List functions.
*/
#define SLIST_INIT(head) { \
SLIST_FIRST(head) = SLIST_END(head); \
}
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
(elm)->field.sle_next = (slistelm)->field.sle_next; \
(slistelm)->field.sle_next = (elm); \
} while (0)
#define SLIST_INSERT_HEAD(head, elm, field) do { \
(elm)->field.sle_next = (head)->slh_first; \
(head)->slh_first = (elm); \
} while (0)
#define SLIST_REMOVE_AFTER(elm, field) do { \
(elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
} while (0)
#define SLIST_REMOVE_HEAD(head, field) do { \
(head)->slh_first = (head)->slh_first->field.sle_next; \
} while (0)
#define SLIST_REMOVE(head, elm, type, field) do { \
if ((head)->slh_first == (elm)) { \
SLIST_REMOVE_HEAD((head), field); \
} else { \
struct type *curelm = (head)->slh_first; \
\
while (curelm->field.sle_next != (elm)) \
curelm = curelm->field.sle_next; \
curelm->field.sle_next = \
curelm->field.sle_next->field.sle_next; \
} \
_Q_INVALIDATE((elm)->field.sle_next); \
} while (0)
/*
* List definitions.
*/
#define LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \
}
/*
* List access methods.
*/
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_END(head) NULL
#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
#define LIST_FOREACH(var, head, field) \
for((var) = LIST_FIRST(head); \
(var)!= LIST_END(head); \
(var) = LIST_NEXT(var, field))
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = LIST_FIRST(head); \
(var) && ((tvar) = LIST_NEXT(var, field), 1); \
(var) = (tvar))
/*
* List functions.
*/
#define LIST_INIT(head) do { \
LIST_FIRST(head) = LIST_END(head); \
} while (0)
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
(listelm)->field.le_next->field.le_prev = \
&(elm)->field.le_next; \
(listelm)->field.le_next = (elm); \
(elm)->field.le_prev = &(listelm)->field.le_next; \
} while (0)
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.le_prev = (listelm)->field.le_prev; \
(elm)->field.le_next = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &(elm)->field.le_next; \
} while (0)
#define LIST_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
(head)->lh_first = (elm); \
(elm)->field.le_prev = &(head)->lh_first; \
} while (0)
#define LIST_REMOVE(elm, field) do { \
if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = (elm)->field.le_next; \
_Q_INVALIDATE((elm)->field.le_prev); \
_Q_INVALIDATE((elm)->field.le_next); \
} while (0)
#define LIST_REPLACE(elm, elm2, field) do { \
if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
(elm2)->field.le_next->field.le_prev = \
&(elm2)->field.le_next; \
(elm2)->field.le_prev = (elm)->field.le_prev; \
*(elm2)->field.le_prev = (elm2); \
_Q_INVALIDATE((elm)->field.le_prev); \
_Q_INVALIDATE((elm)->field.le_next); \
} while (0)
/*
* Simple queue definitions.
*/
#define SIMPLEQ_HEAD(name, type) \
struct name { \
struct type *sqh_first; /* first element */ \
struct type **sqh_last; /* addr of last next element */ \
}
#define SIMPLEQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).sqh_first }
#define SIMPLEQ_ENTRY(type) \
struct { \
struct type *sqe_next; /* next element */ \
}
/*
* Simple queue access methods.
*/
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
#define SIMPLEQ_END(head) NULL
#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
#define SIMPLEQ_FOREACH(var, head, field) \
for((var) = SIMPLEQ_FIRST(head); \
(var) != SIMPLEQ_END(head); \
(var) = SIMPLEQ_NEXT(var, field))
#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = SIMPLEQ_FIRST(head); \
(var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \
(var) = (tvar))
/*
* Simple queue functions.
*/
#define SIMPLEQ_INIT(head) do { \
(head)->sqh_first = NULL; \
(head)->sqh_last = &(head)->sqh_first; \
} while (0)
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \
(head)->sqh_first = (elm); \
} while (0)
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.sqe_next = NULL; \
*(head)->sqh_last = (elm); \
(head)->sqh_last = &(elm)->field.sqe_next; \
} while (0)
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
(head)->sqh_last = &(elm)->field.sqe_next; \
(listelm)->field.sqe_next = (elm); \
} while (0)
#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
(head)->sqh_last = &(head)->sqh_first; \
} while (0)
#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
== NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \
} while (0)
#define SIMPLEQ_CONCAT(head1, head2) do { \
if (!SIMPLEQ_EMPTY((head2))) { \
*(head1)->sqh_last = (head2)->sqh_first; \
(head1)->sqh_last = (head2)->sqh_last; \
SIMPLEQ_INIT((head2)); \
} \
} while (0)
/*
* XOR Simple queue definitions.
*/
#define XSIMPLEQ_HEAD(name, type) \
struct name { \
struct type *sqx_first; /* first element */ \
struct type **sqx_last; /* addr of last next element */ \
unsigned long sqx_cookie; \
}
#define XSIMPLEQ_ENTRY(type) \
struct { \
struct type *sqx_next; /* next element */ \
}
/*
* XOR Simple queue access methods.
*/
#define XSIMPLEQ_XOR(head, ptr) ((__typeof(ptr))((head)->sqx_cookie ^ \
(unsigned long)(ptr)))
#define XSIMPLEQ_FIRST(head) XSIMPLEQ_XOR(head, ((head)->sqx_first))
#define XSIMPLEQ_END(head) NULL
#define XSIMPLEQ_EMPTY(head) (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
#define XSIMPLEQ_NEXT(head, elm, field) XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))
#define XSIMPLEQ_FOREACH(var, head, field) \
for ((var) = XSIMPLEQ_FIRST(head); \
(var) != XSIMPLEQ_END(head); \
(var) = XSIMPLEQ_NEXT(head, var, field))
#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = XSIMPLEQ_FIRST(head); \
(var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \
(var) = (tvar))
/*
* XOR Simple queue functions.
*/
#define XSIMPLEQ_INIT(head) do { \
arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \
(head)->sqx_first = XSIMPLEQ_XOR(head, NULL); \
(head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
} while (0)
#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.sqx_next = (head)->sqx_first) == \
XSIMPLEQ_XOR(head, NULL)) \
(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
(head)->sqx_first = XSIMPLEQ_XOR(head, (elm)); \
} while (0)
#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL); \
*(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \
(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
} while (0)
#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.sqx_next = (listelm)->field.sqx_next) == \
XSIMPLEQ_XOR(head, NULL)) \
(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
(listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm)); \
} while (0)
#define XSIMPLEQ_REMOVE_HEAD(head, field) do { \
if (((head)->sqx_first = XSIMPLEQ_XOR(head, \
(head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \
(head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
} while (0)
#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head, \
(elm)->field.sqx_next)->field.sqx_next) \
== XSIMPLEQ_XOR(head, NULL)) \
(head)->sqx_last = \
XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
} while (0)
/*
* Tail queue definitions.
*/
#define TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
}
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
#define TAILQ_ENTRY(type) \
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
}
/*
* Tail queue access methods.
*/
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_END(head) NULL
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
/* XXX */
#define TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
#define TAILQ_EMPTY(head) \
(TAILQ_FIRST(head) == TAILQ_END(head))
#define TAILQ_FOREACH(var, head, field) \
for((var) = TAILQ_FIRST(head); \
(var) != TAILQ_END(head); \
(var) = TAILQ_NEXT(var, field))
#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = TAILQ_FIRST(head); \
(var) != TAILQ_END(head) && \
((tvar) = TAILQ_NEXT(var, field), 1); \
(var) = (tvar))
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
for((var) = TAILQ_LAST(head, headname); \
(var) != TAILQ_END(head); \
(var) = TAILQ_PREV(var, headname, field))
#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
for ((var) = TAILQ_LAST(head, headname); \
(var) != TAILQ_END(head) && \
((tvar) = TAILQ_PREV(var, headname, field), 1); \
(var) = (tvar))
/*
* Tail queue functions.
*/
#define TAILQ_INIT(head) do { \
(head)->tqh_first = NULL; \
(head)->tqh_last = &(head)->tqh_first; \
} while (0)
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
(head)->tqh_first->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(head)->tqh_first = (elm); \
(elm)->field.tqe_prev = &(head)->tqh_first; \
} while (0)
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.tqe_next = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &(elm)->field.tqe_next; \
} while (0)
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
(elm)->field.tqe_next->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(listelm)->field.tqe_next = (elm); \
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
} while (0)
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (0)
#define TAILQ_REMOVE(head, elm, field) do { \
if (((elm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \
(elm)->field.tqe_prev; \
else \
(head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
_Q_INVALIDATE((elm)->field.tqe_prev); \
_Q_INVALIDATE((elm)->field.tqe_next); \
} while (0)
#define TAILQ_REPLACE(head, elm, elm2, field) do { \
if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
(elm2)->field.tqe_next->field.tqe_prev = \
&(elm2)->field.tqe_next; \
else \
(head)->tqh_last = &(elm2)->field.tqe_next; \
(elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
*(elm2)->field.tqe_prev = (elm2); \
_Q_INVALIDATE((elm)->field.tqe_prev); \
_Q_INVALIDATE((elm)->field.tqe_next); \
} while (0)
#define TAILQ_CONCAT(head1, head2, field) do { \
if (!TAILQ_EMPTY(head2)) { \
*(head1)->tqh_last = (head2)->tqh_first; \
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
(head1)->tqh_last = (head2)->tqh_last; \
TAILQ_INIT((head2)); \
} \
} while (0)
/*
* Singly-linked Tail queue declarations.
*/
#define STAILQ_HEAD(name, type) \
struct name { \
struct type *stqh_first; /* first element */ \
struct type **stqh_last; /* addr of last next element */ \
}
#define STAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).stqh_first }
#define STAILQ_ENTRY(type) \
struct { \
struct type *stqe_next; /* next element */ \
}
/*
* Singly-linked Tail queue access methods.
*/
#define STAILQ_FIRST(head) ((head)->stqh_first)
#define STAILQ_END(head) NULL
#define STAILQ_EMPTY(head) (STAILQ_FIRST(head) == STAILQ_END(head))
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
#define STAILQ_FOREACH(var, head, field) \
for ((var) = STAILQ_FIRST(head); \
(var) != STAILQ_END(head); \
(var) = STAILQ_NEXT(var, field))
#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = STAILQ_FIRST(head); \
(var) && ((tvar) = STAILQ_NEXT(var, field), 1); \
(var) = (tvar))
/*
* Singly-linked Tail queue functions.
*/
#define STAILQ_INIT(head) do { \
STAILQ_FIRST((head)) = NULL; \
(head)->stqh_last = &STAILQ_FIRST((head)); \
} while (0)
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
STAILQ_FIRST((head)) = (elm); \
} while (0)
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
STAILQ_NEXT((elm), field) = NULL; \
*(head)->stqh_last = (elm); \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
} while (0)
#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((listelm), field)) == NULL)\
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
STAILQ_NEXT((listelm), field) = (elm); \
} while (0)
#define STAILQ_REMOVE_HEAD(head, field) do { \
if ((STAILQ_FIRST((head)) = \
STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
(head)->stqh_last = &STAILQ_FIRST((head)); \
} while (0)
#define STAILQ_REMOVE_AFTER(head, elm, field) do { \
if ((STAILQ_NEXT(elm, field) = \
STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
} while (0)
#define STAILQ_REMOVE(head, elm, type, field) do { \
if (STAILQ_FIRST((head)) == (elm)) { \
STAILQ_REMOVE_HEAD((head), field); \
} else { \
struct type *curelm = (head)->stqh_first; \
while (STAILQ_NEXT(curelm, field) != (elm)) \
curelm = STAILQ_NEXT(curelm, field); \
STAILQ_REMOVE_AFTER(head, curelm, field); \
} \
} while (0)
#define STAILQ_CONCAT(head1, head2) do { \
if (!STAILQ_EMPTY((head2))) { \
*(head1)->stqh_last = (head2)->stqh_first; \
(head1)->stqh_last = (head2)->stqh_last; \
STAILQ_INIT((head2)); \
} \
} while (0)
#define STAILQ_LAST(head, type, field) \
(STAILQ_EMPTY((head)) ? NULL : \
((struct type *)(void *) \
((char *)((head)->stqh_last) - offsetof(struct type, field))))
#endif /* !_SYS_QUEUE_H_ */
+38
View File
@@ -0,0 +1,38 @@
/* PFLINUX compat: <sys/refcnt.h> — refcount_t wrapper with OpenBSD API */
#ifndef _PFK_REFCNT_H
#define _PFK_REFCNT_H
#include <linux/refcount.h>
struct refcnt { refcount_t rc; };
#define REFCNT_INITIALIZER { .rc = REFCNT_INIT }
static inline void refcnt_init(struct refcnt *r, unsigned int v)
{
refcount_set(&r->rc, v ? (int)v : 1);
}
static inline unsigned int refcnt_value(const struct refcnt *r)
{
return refcount_read((refcount_t *)&r->rc);
}
static inline void refcnt_take(struct refcnt *r)
{
refcount_inc(&r->rc);
}
/* returns true if ref was valid and taken (OpenBSD refcnt_take_if) */
static inline bool refcnt_take_not0(struct refcnt *r)
{
return refcount_inc_not_zero(&r->rc);
}
static inline unsigned int refcnt_rele(struct refcnt *r)
{
return (unsigned int)refcount_dec_and_test(&r->rc) ?
refcnt_value(r) : refcnt_value(r) + 1;
}
static inline unsigned int refcnt_rele_wake(struct refcnt *r)
{
return refcnt_rele(r);
}
static inline void refcnt_finalize(struct refcnt *r, const void *unused)
{
}
#endif
+46
View File
@@ -0,0 +1,46 @@
/* PFLINUX compat: <sys/socket.h> — BSD sockaddrs stay Linux-layout;
* sa_len fields are removed by the staging sed (see PORTING.md).
* Provides BSD sockaddr accessor macros + address family constants. */
#ifndef _PFK_SOCKET_H
#define _PFK_SOCKET_H
#include <linux/types.h>
struct pfk_sockaddr_union {
struct sockaddr_storage ss;
};
#define sintosa(x) ((struct sockaddr_in *)(void *)(x))
#define sin6tosa(x) ((struct sockaddr_in6 *)(void *)(x))
#define sa_tosa(x) ((struct sockaddr *)(void *)(x))
#define satosa(x) ((struct sockaddr *)(void *)(x))
#define satoxp(x) ((void *)(x)) /* unused; keep symbol */
#define SA_LEN(x) (((x)->sa_family == AF_INET) ? \
sizeof(struct sockaddr_in) : \
((x)->sa_family == AF_INET6) ? \
sizeof(struct sockaddr_in6) : 16)
#define PFK_SA(x) ((struct sockaddr *)(x))
#define PFK_INA(x) (&((struct sockaddr_in *)(x))->sin_addr)
#define PFK_SA6(x) ((struct sockaddr_in6 *)(x))
/* BSD sin_port/sin_addr == Linux: both network byte order fields */
#ifndef SIN_IS_PRIVATE
#define SIN_IS_PRIVATE 1
#endif
/* AF_INET6 == 10 on both sides */
#ifndef AF_LINK
#define AF_LINK 18 /* OpenBSD value; used by pf for link sa */
#endif
static inline int pfk_sa_cmp(const struct sockaddr *a, const struct sockaddr *b)
{
if (a->sa_family != b->sa_family)
return 1;
switch (a->sa_family) {
case AF_INET:
return memcmp(sintosa(a), sintosa(b), sizeof(struct sockaddr_in));
case AF_INET6:
return memcmp(sin6tosa(a), sin6tosa(b), sizeof(struct sockaddr_in6));
}
return 1;
}
#endif
+9
View File
@@ -0,0 +1,9 @@
/* PFLINUX compat: <sys/syslimits.h> */
#ifndef _PFK_SYSLIMITS_H
#define _PFK_SYSLIMITS_H
#include <linux/limits.h>
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
#define MAXSYMLINKS 8
#endif
+17
View File
@@ -0,0 +1,17 @@
/* PFLINUX compat: <sys/timeout.h> */
#ifndef _PFK_TIMEOUT_H
#define _PFK_TIMEOUT_H
#include <linux/timer.h>
#include <linux/workqueue.h>
typedef void (timeout_fn)(void *);
struct timeout {
struct timer_list timer;
struct work_struct work;
timeout_fn *fn;
void *arg;
unsigned long deadline_jif;
int period_ms;
int pending;
int running;
};
#endif
File diff suppressed because it is too large. Load diff
+6
View File
@@ -0,0 +1,6 @@
/* PFLINUX compat: <sys/types.h> */
#ifndef _PFK_SYS_TYPES_H
#define _PFK_SYS_TYPES_H
#include <linux/types.h>
typedef unsigned long u_long;
#endif