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:
1 parent
ba81284bd3
commit
da2e9b679a
87 files changed
+47256
-3
No files matched your search
@@ -0,0 +1,83 @@
|
||||
/* $OpenBSD: sha2.h,v 1.5 2014/11/16 17:39:09 tedu Exp $ */
|
||||
|
||||
/*
|
||||
* FILE: sha2.h
|
||||
* AUTHOR: Aaron D. Gifford <me@aarongifford.com>
|
||||
*
|
||||
* Copyright (c) 2000-2001, Aaron D. Gifford
|
||||
* 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 copyright holder nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 OR CONTRIBUTOR(S) 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.
|
||||
*
|
||||
* $From: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $
|
||||
*/
|
||||
|
||||
#ifndef _SHA2_H
|
||||
#define _SHA2_H
|
||||
|
||||
|
||||
/*** SHA-256/384/512 Various Length Definitions ***********************/
|
||||
#define SHA256_BLOCK_LENGTH 64
|
||||
#define SHA256_DIGEST_LENGTH 32
|
||||
#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
|
||||
#define SHA384_BLOCK_LENGTH 128
|
||||
#define SHA384_DIGEST_LENGTH 48
|
||||
#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
|
||||
#define SHA512_BLOCK_LENGTH 128
|
||||
#define SHA512_DIGEST_LENGTH 64
|
||||
#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
|
||||
|
||||
|
||||
/*** SHA-256/384/512 Context Structure *******************************/
|
||||
typedef struct _SHA2_CTX {
|
||||
union {
|
||||
u_int32_t st32[8];
|
||||
u_int64_t st64[8];
|
||||
} state;
|
||||
u_int64_t bitcount[2];
|
||||
u_int8_t buffer[SHA512_BLOCK_LENGTH];
|
||||
} SHA2_CTX;
|
||||
|
||||
__BEGIN_DECLS
|
||||
void SHA256Init(SHA2_CTX *);
|
||||
void SHA256Update(SHA2_CTX *, const void *, size_t)
|
||||
__attribute__((__bounded__(__string__,2,3)));
|
||||
void SHA256Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA2_CTX *)
|
||||
__attribute__((__bounded__(__minbytes__,1,SHA256_DIGEST_LENGTH)));
|
||||
|
||||
void SHA384Init(SHA2_CTX *);
|
||||
void SHA384Update(SHA2_CTX *, const void *, size_t)
|
||||
__attribute__((__bounded__(__string__,2,3)));
|
||||
void SHA384Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA2_CTX *)
|
||||
__attribute__((__bounded__(__minbytes__,1,SHA384_DIGEST_LENGTH)));
|
||||
|
||||
void SHA512Init(SHA2_CTX *);
|
||||
void SHA512Update(SHA2_CTX *, const void *, size_t)
|
||||
__attribute__((__bounded__(__string__,2,3)));
|
||||
void SHA512Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA2_CTX *)
|
||||
__attribute__((__bounded__(__minbytes__,1,SHA512_DIGEST_LENGTH)));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _SHA2_H */
|
||||
@@ -0,0 +1,27 @@
|
||||
/* PFLINUX compat: <crypto/siphash.h> — SipHash-2-4 (Aumasson–Bernstein)
|
||||
* API compatible with OpenBSD's SIPHASH_CTX/KEY usage in pf_syncookies.c.
|
||||
* Implementation: compat/siphash.c (ISC 2026). */
|
||||
#ifndef _PFK_SIPHASH_H
|
||||
#define _PFK_SIPHASH_H
|
||||
#include <linux/types.h>
|
||||
|
||||
#define SIPHASH_KEY_LENGTH 16
|
||||
|
||||
typedef struct {
|
||||
__u64 v[2];
|
||||
} SIPHASH_KEY;
|
||||
|
||||
typedef struct {
|
||||
__u64 v[3];
|
||||
__u64 total_len;
|
||||
unsigned char block[8];
|
||||
unsigned char block_len;
|
||||
} SIPHASH_CTX;
|
||||
|
||||
void SipHash24_Init(SIPHASH_CTX *ctx, const SIPHASH_KEY *key);
|
||||
void SipHash24_Update(SIPHASH_CTX *ctx, const void *in, __u64 inlen);
|
||||
void SipHash24_Final(SIPHASH_CTX *ctx, unsigned char *out);
|
||||
void SipHash24_Generate(const SIPHASH_KEY *key, const void *in, __u64 inlen,
|
||||
unsigned char *out);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,72 @@
|
||||
/* $OpenBSD: if_pflog.h,v 1.29 2021/01/13 09:13:30 mvs Exp $ */
|
||||
/*
|
||||
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_PFLOG_H_
|
||||
#define _NET_IF_PFLOG_H_
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <net/pfvar.h>
|
||||
|
||||
#define PFLOG_RULESET_NAME_SIZE 16
|
||||
|
||||
struct pfloghdr {
|
||||
u_int8_t length;
|
||||
sa_family_t af;
|
||||
u_int8_t action;
|
||||
u_int8_t reason;
|
||||
char ifname[IFNAMSIZ];
|
||||
char ruleset[PFLOG_RULESET_NAME_SIZE];
|
||||
u_int32_t rulenr;
|
||||
u_int32_t subrulenr;
|
||||
uid_t uid;
|
||||
pid_t pid;
|
||||
uid_t rule_uid;
|
||||
pid_t rule_pid;
|
||||
u_int8_t dir;
|
||||
u_int8_t rewritten;
|
||||
sa_family_t naf;
|
||||
u_int8_t pad[1];
|
||||
struct pf_addr saddr;
|
||||
struct pf_addr daddr;
|
||||
u_int16_t sport;
|
||||
u_int16_t dport;
|
||||
};
|
||||
|
||||
#define PFLOG_HDRLEN sizeof(struct pfloghdr)
|
||||
/* used to be minus pad, also used as a signature */
|
||||
#define PFLOG_REAL_HDRLEN PFLOG_HDRLEN
|
||||
#define PFLOG_OLD_HDRLEN offsetof(struct pfloghdr, pad)
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
struct pflog_softc {
|
||||
LIST_ENTRY(pflog_softc) sc_entry;
|
||||
struct ifnet sc_if; /* the interface */
|
||||
int sc_unit;
|
||||
};
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif /* _NET_IF_PFLOG_H_ */
|
||||
@@ -0,0 +1,16 @@
|
||||
/* PFLINUX compat: <net/if_types.h> — OpenBSD IFT_* constants
|
||||
* (values must match OpenBSD: they travel in pf_rule/pfk_if ioctls). */
|
||||
#ifndef _PFK_IF_TYPES_H
|
||||
#define _PFK_IF_TYPES_H
|
||||
#define IFT_OTHER 0x1
|
||||
#define IFT_ETHER 0x6
|
||||
#define IFT_TOKENRING 0xf
|
||||
#define IFT_FDDI 0x12
|
||||
#define IFT_LOOP 0x18
|
||||
#define IFT_SLIP 0x1f
|
||||
#define IFT_PPPOINT 0x1e
|
||||
#define IFT_GIF 0xe6
|
||||
#define IFT_PFLOG 0xf0
|
||||
#define IFT_PFSYNC 0xf1
|
||||
#define IFT_CARP 0xf8
|
||||
#endif
|
||||
@@ -0,0 +1,5 @@
|
||||
/* PFLINUX compat: <net/if_var.h> — ifnet view comes from pfk_if.h */
|
||||
#ifndef _PFK_IF_VAR_H
|
||||
#define _PFK_IF_VAR_H
|
||||
/* intentionally minimal; struct pfk_ifnet is the ifnet */
|
||||
#endif
|
||||
@@ -0,0 +1,507 @@
|
||||
/* $OpenBSD: ifq.h,v 1.44 2025/03/04 01:13:37 dlg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015 David Gwynne <dlg@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _NET_IFQ_H_
|
||||
#define _NET_IFQ_H_
|
||||
|
||||
struct ifnet;
|
||||
struct kstat;
|
||||
|
||||
struct ifq_ops;
|
||||
|
||||
struct ifqueue {
|
||||
struct ifnet *ifq_if;
|
||||
struct taskq *ifq_softnet;
|
||||
union {
|
||||
void *_ifq_softc;
|
||||
/*
|
||||
* a rings sndq is found by looking up an array of pointers.
|
||||
* by default we only have one sndq and the default drivers
|
||||
* dont use ifq_softc, so we can borrow it for the map until
|
||||
* we need to allocate a proper map.
|
||||
*/
|
||||
struct ifqueue *_ifq_ifqs[1];
|
||||
} _ifq_ptr;
|
||||
#define ifq_softc _ifq_ptr._ifq_softc
|
||||
#define ifq_ifqs _ifq_ptr._ifq_ifqs
|
||||
|
||||
/* mbuf handling */
|
||||
struct mutex ifq_mtx;
|
||||
const struct ifq_ops *ifq_ops;
|
||||
void *ifq_q;
|
||||
struct mbuf_list ifq_free;
|
||||
unsigned int ifq_len;
|
||||
unsigned int ifq_oactive;
|
||||
|
||||
/* statistics */
|
||||
uint64_t ifq_packets;
|
||||
uint64_t ifq_bytes;
|
||||
uint64_t ifq_qdrops;
|
||||
uint64_t ifq_errors;
|
||||
uint64_t ifq_mcasts;
|
||||
uint32_t ifq_oactives;
|
||||
|
||||
struct kstat *ifq_kstat;
|
||||
|
||||
/* work serialisation */
|
||||
struct mutex ifq_task_mtx;
|
||||
struct task_list ifq_task_list;
|
||||
void *ifq_serializer;
|
||||
struct task ifq_bundle;
|
||||
|
||||
/* work to be serialised */
|
||||
struct task ifq_start;
|
||||
struct task ifq_restart;
|
||||
|
||||
/* properties */
|
||||
unsigned int ifq_maxlen;
|
||||
unsigned int ifq_idx;
|
||||
};
|
||||
|
||||
struct ifiqueue {
|
||||
struct ifnet *ifiq_if;
|
||||
caddr_t *ifiq_bpfp;
|
||||
struct taskq *ifiq_softnet;
|
||||
union {
|
||||
void *_ifiq_softc;
|
||||
struct ifiqueue *_ifiq_ifiqs[1];
|
||||
} _ifiq_ptr;
|
||||
#define ifiq_softc _ifiq_ptr._ifiq_softc
|
||||
#define ifiq_ifiqs _ifiq_ptr._ifiq_ifiqs
|
||||
|
||||
struct mutex ifiq_mtx;
|
||||
struct mbuf_list ifiq_ml;
|
||||
struct task ifiq_task;
|
||||
unsigned int ifiq_pressure;
|
||||
|
||||
/* counters */
|
||||
uint64_t ifiq_packets;
|
||||
uint64_t ifiq_bytes;
|
||||
uint64_t ifiq_fdrops;
|
||||
uint64_t ifiq_qdrops;
|
||||
uint64_t ifiq_errors;
|
||||
uint64_t ifiq_mcasts;
|
||||
uint64_t ifiq_noproto;
|
||||
|
||||
/* number of times a list of packets were put on ifiq_ml */
|
||||
uint64_t ifiq_enqueues;
|
||||
/* number of times a list of packets were pulled off ifiq_ml */
|
||||
uint64_t ifiq_dequeues;
|
||||
|
||||
struct kstat *ifiq_kstat;
|
||||
|
||||
/* properties */
|
||||
unsigned int ifiq_idx;
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#define IFQ_MAXLEN 256
|
||||
|
||||
/*
|
||||
*
|
||||
* Interface Send Queues
|
||||
*
|
||||
* struct ifqueue sits between the network stack and a drivers
|
||||
* transmission of packets. The high level view is that when the stack
|
||||
* has finished generating a packet it hands it to a driver for
|
||||
* transmission. It does this by queueing the packet on an ifqueue and
|
||||
* notifying the driver to start transmission of the queued packets.
|
||||
*
|
||||
* A network device may have multiple contexts for the transmission
|
||||
* of packets, ie, independent transmit rings. Such a network device,
|
||||
* represented by a struct ifnet, would then have multiple ifqueue
|
||||
* structures, each of which maps to an independent transmit ring.
|
||||
*
|
||||
* struct ifqueue also provides the point where conditioning of
|
||||
* traffic (ie, priq and hfsc) is implemented, and provides some
|
||||
* infrastructure to assist in the implementation of network drivers.
|
||||
*
|
||||
* = ifq API
|
||||
*
|
||||
* The ifq API provides functions for three distinct consumers:
|
||||
*
|
||||
* 1. The network stack
|
||||
* 2. Traffic QoS/conditioning implementations
|
||||
* 3. Network drivers
|
||||
*
|
||||
* == Network Stack API
|
||||
*
|
||||
* The network stack is responsible for initialising and destroying
|
||||
* the ifqueue structures, changing the traffic conditioner on an
|
||||
* interface, enqueuing packets for transmission, and notifying
|
||||
* the driver to start transmission of a particular ifqueue.
|
||||
*
|
||||
* === ifq_init()
|
||||
*
|
||||
* During if_attach(), the network stack calls ifq_init to initialise
|
||||
* the ifqueue structure. By default it configures the priq traffic
|
||||
* conditioner.
|
||||
*
|
||||
* === ifq_destroy()
|
||||
*
|
||||
* The network stack calls ifq_destroy() during if_detach to tear down
|
||||
* the ifqueue structure. It frees the traffic conditioner state, and
|
||||
* frees any mbufs that were left queued.
|
||||
*
|
||||
* === ifq_attach()
|
||||
*
|
||||
* ifq_attach() is used to replace the current traffic conditioner on
|
||||
* the ifqueue. All the pending mbufs are removed from the previous
|
||||
* conditioner and requeued on the new.
|
||||
*
|
||||
* === ifq_idx()
|
||||
*
|
||||
* ifq_idx() selects a specific ifqueue from the current ifnet
|
||||
* structure for use in the transmission of the mbuf.
|
||||
*
|
||||
* === ifq_enqueue()
|
||||
*
|
||||
* ifq_enqueue() attempts to fit an mbuf onto the ifqueue. The
|
||||
* current traffic conditioner may drop a packet to make space on the
|
||||
* queue.
|
||||
*
|
||||
* === ifq_start()
|
||||
*
|
||||
* Once a packet has been successfully queued with ifq_enqueue(),
|
||||
* the network card is notified with a call to ifq_start().
|
||||
* Calls to ifq_start() run in the ifqueue serialisation context,
|
||||
* guaranteeing that only one instance of ifp->if_qstart() will be
|
||||
* running on behalf of a specific ifqueue in the system at any point
|
||||
* in time.
|
||||
*
|
||||
* == Traffic conditioners API
|
||||
*
|
||||
* The majority of interaction between struct ifqueue and a traffic
|
||||
* conditioner occurs via the callbacks a traffic conditioner provides
|
||||
* in an instance of struct ifq_ops.
|
||||
*
|
||||
* XXX document ifqop_*
|
||||
*
|
||||
* The ifqueue API implements the locking on behalf of the conditioning
|
||||
* implementations so conditioners only have to reject or keep mbufs.
|
||||
* If something needs to inspect a conditioners internals, the queue lock
|
||||
* needs to be taken to allow for a consistent or safe view. The queue
|
||||
* lock may be taken and released with ifq_q_enter() and ifq_q_leave().
|
||||
*
|
||||
* === ifq_q_enter()
|
||||
*
|
||||
* Code wishing to access a conditioners internals may take the queue
|
||||
* lock with ifq_q_enter(). The caller must pass a reference to the
|
||||
* conditioners ifq_ops structure so the infrastructure can ensure the
|
||||
* caller is able to understand the internals. ifq_q_enter() returns
|
||||
* a pointer to the conditioners internal structures, or NULL if the
|
||||
* ifq_ops did not match the current conditioner.
|
||||
*
|
||||
* === ifq_q_leave()
|
||||
*
|
||||
* The queue lock acquired with ifq_q_enter() is released with
|
||||
* ifq_q_leave().
|
||||
*
|
||||
* === ifq_mfreem() and ifq_mfreeml()
|
||||
*
|
||||
* A goal of the API is to avoid freeing an mbuf while mutexes are
|
||||
* held. Because the ifq API manages the lock on behalf of the backend
|
||||
* ifqops, the backend should not directly free mbufs. If a conditioner
|
||||
* backend needs to drop a packet during the handling of ifqop_deq_begin,
|
||||
* it may free it by calling ifq_mfreem(). This accounts for the drop,
|
||||
* and schedules the free of the mbuf outside the hold of ifq_mtx.
|
||||
* ifq_mfreeml() takes an mbuf list as an argument instead.
|
||||
*
|
||||
*
|
||||
* == Network Driver API
|
||||
*
|
||||
* The API used by network drivers is mostly documented in the
|
||||
* ifq_dequeue(9) manpage except for ifq_serialize().
|
||||
*
|
||||
* === ifq_serialize()
|
||||
*
|
||||
* A driver may run arbitrary work in the ifqueue serialiser context
|
||||
* via ifq_serialize(). The work to be done is represented by a task
|
||||
* that has been prepared with task_set.
|
||||
*
|
||||
* The work will be run in series with any other work dispatched by
|
||||
* ifq_start(), ifq_restart(), or other ifq_serialize() calls.
|
||||
*
|
||||
* Because the work may be run on another CPU, the lifetime of the
|
||||
* task and the work it represents can extend beyond the end of the
|
||||
* call to ifq_serialize() that dispatched it.
|
||||
*
|
||||
*
|
||||
* = ifqueue work serialisation
|
||||
*
|
||||
* ifqueues provide a mechanism to dispatch work to be run in a single
|
||||
* context. Work in this mechanism is represented by task structures.
|
||||
*
|
||||
* The tasks are run in a context similar to a taskq serviced by a
|
||||
* single kernel thread, except the work is run immediately by the
|
||||
* first CPU that dispatches work. If a second CPU attempts to dispatch
|
||||
* additional tasks while the first is still running, it will be queued
|
||||
* to be run by the first CPU. The second CPU will return immediately.
|
||||
*
|
||||
* = MP Safe Network Drivers
|
||||
*
|
||||
* An MP safe network driver is one in which its start routine can be
|
||||
* called by the network stack without holding the big kernel lock.
|
||||
*
|
||||
* == Attach
|
||||
*
|
||||
* A driver advertises its ability to run its start routine without
|
||||
* the kernel lock by setting the IFXF_MPSAFE flag in ifp->if_xflags
|
||||
* before calling if_attach(). Advertising an MPSAFE start routine
|
||||
* also implies that the driver understands that a network card can
|
||||
* have multiple rings or transmit queues, and therefore provides
|
||||
* if_qstart function (which takes an ifqueue pointer) instead of an
|
||||
* if_start function (which takes an ifnet pointer).
|
||||
*
|
||||
* If the hardware supports multiple transmit rings, it advertises
|
||||
* support for multiple rings to the network stack with if_attach_queues()
|
||||
* after the call to if_attach(). if_attach_queues allocates a struct
|
||||
* ifqueue for each hardware ring, which can then be initialised by
|
||||
* the driver with data for each ring.
|
||||
*
|
||||
* void drv_start(struct ifqueue *);
|
||||
*
|
||||
* void
|
||||
* drv_attach()
|
||||
* {
|
||||
* ...
|
||||
* ifp->if_xflags = IFXF_MPSAFE;
|
||||
* ifp->if_qstart = drv_start;
|
||||
* if_attach(ifp);
|
||||
*
|
||||
* if_attach_queues(ifp, DRV_NUM_TX_RINGS);
|
||||
* for (i = 0; i < DRV_NUM_TX_RINGS; i++) {
|
||||
* struct ifqueue *ifq = ifp->if_ifqs[i];
|
||||
* struct drv_tx_ring *ring = &sc->sc_tx_rings[i];
|
||||
*
|
||||
* ifq->ifq_softc = ring;
|
||||
* ring->ifq = ifq;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* The network stack will then call ifp->if_qstart via ifq_start()
|
||||
* to guarantee there is only one instance of that function running
|
||||
* for each ifq in the system, and to serialise it with other work
|
||||
* the driver may provide.
|
||||
*
|
||||
* == Initialise
|
||||
*
|
||||
* When the stack requests an interface be brought up (ie, drv_ioctl()
|
||||
* is called to handle SIOCSIFFLAGS with IFF_UP set in ifp->if_flags)
|
||||
* drivers should set IFF_RUNNING in ifp->if_flags, and then call
|
||||
* ifq_clr_oactive() against each ifq.
|
||||
*
|
||||
* == if_start
|
||||
*
|
||||
* ifq_start() checks that IFF_RUNNING is set in ifp->if_flags, that
|
||||
* ifq_is_oactive() does not return true, and that there are pending
|
||||
* packets to transmit via a call to ifq_len(). Therefore, drivers are
|
||||
* no longer responsible for doing this themselves.
|
||||
*
|
||||
* If a driver should not transmit packets while its link is down, use
|
||||
* ifq_purge() to flush pending packets from the transmit queue.
|
||||
*
|
||||
* Drivers for hardware should use the following pattern to transmit
|
||||
* packets:
|
||||
*
|
||||
* void
|
||||
* drv_start(struct ifqueue *ifq)
|
||||
* {
|
||||
* struct drv_tx_ring *ring = ifq->ifq_softc;
|
||||
* struct ifnet *ifp = ifq->ifq_if;
|
||||
* struct drv_softc *sc = ifp->if_softc;
|
||||
* struct mbuf *m;
|
||||
* int kick = 0;
|
||||
*
|
||||
* if (NO_LINK) {
|
||||
* ifq_purge(ifq);
|
||||
* return;
|
||||
* }
|
||||
*
|
||||
* for (;;) {
|
||||
* if (NO_SPACE(ring)) {
|
||||
* ifq_set_oactive(ifq);
|
||||
* break;
|
||||
* }
|
||||
*
|
||||
* m = ifq_dequeue(ifq);
|
||||
* if (m == NULL)
|
||||
* break;
|
||||
*
|
||||
* if (drv_encap(sc, ring, m) != 0) { // map and fill ring
|
||||
* m_freem(m);
|
||||
* continue;
|
||||
* }
|
||||
*
|
||||
* bpf_mtap();
|
||||
* }
|
||||
*
|
||||
* drv_kick(ring); // notify hw of new descriptors on the ring
|
||||
* }
|
||||
*
|
||||
* == Transmission completion
|
||||
*
|
||||
* The following pattern should be used for transmit queue interrupt
|
||||
* processing:
|
||||
*
|
||||
* void
|
||||
* drv_txeof(struct drv_tx_ring *ring)
|
||||
* {
|
||||
* struct ifqueue *ifq = ring->ifq;
|
||||
*
|
||||
* while (COMPLETED_PKTS(ring)) {
|
||||
* // unmap packets, m_freem() the mbufs.
|
||||
* }
|
||||
*
|
||||
* if (ifq_is_oactive(ifq))
|
||||
* ifq_restart(ifq);
|
||||
* }
|
||||
*
|
||||
* == Stop
|
||||
*
|
||||
* Bringing an interface down (ie, IFF_UP was cleared in ifp->if_flags)
|
||||
* should clear IFF_RUNNING in ifp->if_flags, and guarantee the start
|
||||
* routine is not running before freeing any resources it uses:
|
||||
*
|
||||
* void
|
||||
* drv_down(struct drv_softc *sc)
|
||||
* {
|
||||
* struct ifnet *ifp = &sc->sc_if;
|
||||
* struct ifqueue *ifq;
|
||||
* int i;
|
||||
*
|
||||
* CLR(ifp->if_flags, IFF_RUNNING);
|
||||
* DISABLE_INTERRUPTS();
|
||||
*
|
||||
* for (i = 0; i < sc->sc_num_queues; i++) {
|
||||
* ifq = ifp->if_ifqs[i];
|
||||
* ifq_barrier(ifq);
|
||||
* }
|
||||
*
|
||||
* intr_barrier(sc->sc_ih);
|
||||
*
|
||||
* FREE_RESOURCES();
|
||||
*
|
||||
* for (i = 0; i < sc->sc_num_queues; i++) {
|
||||
* ifq = ifp->if_ifqs[i];
|
||||
* ifq_clr_oactive(ifq);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
*/
|
||||
|
||||
struct ifq_ops {
|
||||
unsigned int (*ifqop_idx)(unsigned int,
|
||||
const struct mbuf *);
|
||||
struct mbuf *(*ifqop_enq)(struct ifqueue *, struct mbuf *);
|
||||
struct mbuf *(*ifqop_deq_begin)(struct ifqueue *, void **);
|
||||
void (*ifqop_deq_commit)(struct ifqueue *,
|
||||
struct mbuf *, void *);
|
||||
void (*ifqop_purge)(struct ifqueue *,
|
||||
struct mbuf_list *);
|
||||
void *(*ifqop_alloc)(unsigned int, void *);
|
||||
void (*ifqop_free)(unsigned int, void *);
|
||||
};
|
||||
|
||||
extern const struct ifq_ops * const ifq_priq_ops;
|
||||
|
||||
/*
|
||||
* Interface send queues.
|
||||
*/
|
||||
|
||||
void ifq_init(struct ifqueue *, struct ifnet *, unsigned int);
|
||||
void ifq_attach(struct ifqueue *, const struct ifq_ops *, void *);
|
||||
void ifq_destroy(struct ifqueue *);
|
||||
void ifq_add_data(struct ifqueue *, struct if_data *);
|
||||
int ifq_enqueue(struct ifqueue *, struct mbuf *);
|
||||
void ifq_start(struct ifqueue *);
|
||||
struct mbuf *ifq_deq_begin(struct ifqueue *);
|
||||
void ifq_deq_commit(struct ifqueue *, struct mbuf *);
|
||||
void ifq_deq_rollback(struct ifqueue *, struct mbuf *);
|
||||
struct mbuf *ifq_dequeue(struct ifqueue *);
|
||||
int ifq_hdatalen(struct ifqueue *);
|
||||
void ifq_init_maxlen(struct ifqueue *, unsigned int);
|
||||
void ifq_mfreem(struct ifqueue *, struct mbuf *);
|
||||
void ifq_mfreeml(struct ifqueue *, struct mbuf_list *);
|
||||
unsigned int ifq_purge(struct ifqueue *);
|
||||
void *ifq_q_enter(struct ifqueue *, const struct ifq_ops *);
|
||||
void ifq_q_leave(struct ifqueue *, void *);
|
||||
void ifq_serialize(struct ifqueue *, struct task *);
|
||||
void ifq_barrier(struct ifqueue *);
|
||||
void ifq_set_oactive(struct ifqueue *);
|
||||
void ifq_deq_set_oactive(struct ifqueue *);
|
||||
|
||||
int ifq_deq_sleep(struct ifqueue *, struct mbuf **, int, int,
|
||||
const char *, volatile unsigned int *,
|
||||
volatile unsigned int *);
|
||||
|
||||
#define ifq_len(_ifq) READ_ONCE((_ifq)->ifq_len)
|
||||
#define ifq_empty(_ifq) (ifq_len(_ifq) == 0)
|
||||
|
||||
static inline int
|
||||
ifq_is_priq(struct ifqueue *ifq)
|
||||
{
|
||||
return (ifq->ifq_ops == ifq_priq_ops);
|
||||
}
|
||||
|
||||
static inline void
|
||||
ifq_clr_oactive(struct ifqueue *ifq)
|
||||
{
|
||||
ifq->ifq_oactive = 0;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
ifq_is_oactive(struct ifqueue *ifq)
|
||||
{
|
||||
return (ifq->ifq_oactive);
|
||||
}
|
||||
|
||||
static inline void
|
||||
ifq_restart(struct ifqueue *ifq)
|
||||
{
|
||||
ifq_serialize(ifq, &ifq->ifq_restart);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
ifq_idx(struct ifqueue *ifq, unsigned int nifqs, const struct mbuf *m)
|
||||
{
|
||||
return ((*ifq->ifq_ops->ifqop_idx)(nifqs, m));
|
||||
}
|
||||
|
||||
/* ifiq */
|
||||
|
||||
void ifiq_init(struct ifiqueue *, struct ifnet *, unsigned int);
|
||||
void ifiq_destroy(struct ifiqueue *);
|
||||
int ifiq_input(struct ifiqueue *, struct mbuf_list *);
|
||||
int ifiq_enqueue_qlim(struct ifiqueue *, struct mbuf *,
|
||||
unsigned int);
|
||||
void ifiq_add_data(struct ifiqueue *, struct if_data *);
|
||||
|
||||
#define ifiq_len(_ifiq) READ_ONCE(ml_len(&(_ifiq)->ifiq_ml))
|
||||
#define ifiq_empty(_ifiq) (ifiq_len(_ifiq) == 0)
|
||||
|
||||
static inline int
|
||||
ifiq_enqueue(struct ifiqueue *ifiq, struct mbuf *m)
|
||||
{
|
||||
return ifiq_enqueue_qlim(ifiq, m, 0);
|
||||
}
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _NET_IFQ_H_ */
|
||||
@@ -0,0 +1,75 @@
|
||||
/* PFLINUX compat: <net/radix.h> — OpenBSD 8.0 radix structures/API
|
||||
* (rn_*), cleaned of BSD-only syntax. Implementation: compat/radix.c
|
||||
* (ported from OpenBSD 8.0 sys/net/radix.c, task T10). */
|
||||
#ifndef _PFK_RADIX_H
|
||||
#define _PFK_RADIX_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct radix_mask;
|
||||
|
||||
struct radix_node {
|
||||
struct radix_mask *rn_mklist;
|
||||
struct radix_node *rn_p;
|
||||
short rn_b;
|
||||
char rn_bmask;
|
||||
u_char rn_flags;
|
||||
#define RNF_NORMAL 1
|
||||
#define RNF_ROOT 2
|
||||
#define RNF_ACTIVE 4
|
||||
union {
|
||||
struct {
|
||||
caddr_t rn_Key;
|
||||
caddr_t rn_Mask;
|
||||
struct radix_node *rn_Dupedkey;
|
||||
} rn_leaf;
|
||||
struct {
|
||||
int rn_Off;
|
||||
struct radix_node *rn_L;
|
||||
struct radix_node *rn_R;
|
||||
} rn_node;
|
||||
} rn_u;
|
||||
};
|
||||
|
||||
#define rn_dupedkey rn_u.rn_leaf.rn_Dupedkey
|
||||
#define rn_key rn_u.rn_leaf.rn_Key
|
||||
#define rn_mask rn_u.rn_leaf.rn_Mask
|
||||
#define rn_off rn_u.rn_node.rn_Off
|
||||
#define rn_l rn_u.rn_node.rn_L
|
||||
#define rn_r rn_u.rn_node.rn_R
|
||||
|
||||
struct radix_mask {
|
||||
short rm_b;
|
||||
char rm_unused;
|
||||
u_char rm_flags;
|
||||
struct radix_mask *rm_mklist;
|
||||
union {
|
||||
caddr_t rmu_mask;
|
||||
struct radix_node *rmu_leaf;
|
||||
} rm_rmu;
|
||||
int rm_refs;
|
||||
};
|
||||
|
||||
#define rm_mask rm_rmu.rmu_mask
|
||||
#define rm_leaf rm_rmu.rmu_leaf
|
||||
|
||||
struct radix_node_head {
|
||||
struct radix_node *rnh_treetop;
|
||||
int rnh_addrsize;
|
||||
int rnh_pktsize;
|
||||
struct radix_node rnh_nodes[3];
|
||||
u_int rnh_rtableid;
|
||||
};
|
||||
|
||||
void rn_init(unsigned int);
|
||||
int rn_inithead(void **, int);
|
||||
int rn_walktree(struct radix_node_head *,
|
||||
int (*)(struct radix_node *, void *, u_int), void *);
|
||||
struct radix_node *rn_addroute(void *, void *, struct radix_node_head *,
|
||||
struct radix_node [2], u_int8_t);
|
||||
struct radix_node *rn_delete(void *, void *, struct radix_node_head *,
|
||||
struct radix_node *);
|
||||
struct radix_node *rn_lookup(void *, void *, struct radix_node_head *);
|
||||
struct radix_node *rn_match(void *, struct radix_node_head *);
|
||||
|
||||
#endif /* _PFK_RADIX_H_ */
|
||||
@@ -0,0 +1,82 @@
|
||||
/* $OpenBSD: rtable.h,v 1.36 2025/07/15 09:55:49 dlg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2016 Martin Pieuchot
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _NET_RTABLE_H_
|
||||
#define _NET_RTABLE_H_
|
||||
|
||||
#include <sys/rwlock.h>
|
||||
|
||||
struct art;
|
||||
|
||||
/*
|
||||
* Locks used to protect struct members in this file:
|
||||
* I immutable after creation
|
||||
* N net lock
|
||||
*/
|
||||
|
||||
struct rtable {
|
||||
struct rwlock r_lock;
|
||||
struct art *r_art; /* [I] */
|
||||
unsigned int r_off; /* [I] Offset of key in bytes */
|
||||
|
||||
struct sockaddr *r_source; /* [N] use optional src addr */
|
||||
};
|
||||
|
||||
/*
|
||||
* Newer routing table implementation based on ART (Allotment Routing
|
||||
* Table).
|
||||
*/
|
||||
|
||||
#define rt_key(rt) ((rt)->rt_dest)
|
||||
#define rt_plen(rt) ((rt)->rt_plen)
|
||||
#define RT_ROOT(rt) (0)
|
||||
|
||||
int rtable_satoplen(sa_family_t, const struct sockaddr *);
|
||||
|
||||
void rtable_init(void);
|
||||
int rtable_exists(unsigned int);
|
||||
int rtable_empty(unsigned int);
|
||||
int rtable_add(unsigned int);
|
||||
unsigned int rtable_l2(unsigned int);
|
||||
unsigned int rtable_loindex(unsigned int);
|
||||
void rtable_l2set(unsigned int, unsigned int, unsigned int);
|
||||
|
||||
int rtable_setsource(unsigned int, int, struct sockaddr *);
|
||||
struct sockaddr *rtable_getsource(unsigned int, int);
|
||||
void rtable_clearsource(unsigned int, struct sockaddr *);
|
||||
struct rtentry *rtable_lookup(unsigned int, const struct sockaddr *,
|
||||
const struct sockaddr *, const struct sockaddr *, uint8_t);
|
||||
struct rtentry *rtable_match(unsigned int, const struct sockaddr *,
|
||||
uint32_t *);
|
||||
struct rtentry *rtable_iterate(struct rtentry *);
|
||||
int rtable_insert(unsigned int, struct sockaddr *,
|
||||
const struct sockaddr *, const struct sockaddr *, uint8_t,
|
||||
struct rtentry *);
|
||||
int rtable_delete(unsigned int, const struct sockaddr *,
|
||||
const struct sockaddr *, struct rtentry *);
|
||||
int rtable_walk(unsigned int, sa_family_t, struct rtentry **,
|
||||
int (*)(struct rtentry *, void *, unsigned int), void *);
|
||||
int rtable_read(unsigned int, sa_family_t,
|
||||
int (*)(const struct rtentry *, void *, unsigned int),
|
||||
void *);
|
||||
|
||||
int rtable_mpath_capable(unsigned int, sa_family_t);
|
||||
int rtable_mpath_reprio(unsigned int, struct sockaddr *, int,
|
||||
uint8_t, struct rtentry *);
|
||||
|
||||
#endif /* _NET_RTABLE_H_ */
|
||||
@@ -0,0 +1,53 @@
|
||||
/* PFLINUX compat: <net/toeplitz.h> — software Toeplitz hash (RFC 3305)
|
||||
* with the OpenBSD API shape used by PF (global cache + stoeplitz_* macros).
|
||||
* Implementation: compat/toeplitz.c (uses kernel crypto_shash "sha256"). */
|
||||
#ifndef _PFK_TOEPLITZ_H
|
||||
#define _PFK_TOEPLITZ_H
|
||||
#include <linux/types.h>
|
||||
|
||||
#define TOEPLITZ_KEY_LEN 40
|
||||
|
||||
struct stoeplitz_cache {
|
||||
u8 key[TOEPLITZ_KEY_LEN];
|
||||
u8 keyhash[32]; /* SHA256(key) */
|
||||
int initialized;
|
||||
};
|
||||
|
||||
extern struct stoeplitz_cache *stoeplitz_cache;
|
||||
|
||||
void stoeplitz_init(void);
|
||||
void stoeplitz_cache_init(struct stoeplitz_cache *, const u8 *key);
|
||||
uint16_t stoeplitz_hash_ip4(const struct stoeplitz_cache *,
|
||||
const struct in_addr *, const struct in_addr *);
|
||||
uint16_t stoeplitz_hash_ip4port(const struct stoeplitz_cache *,
|
||||
const struct in_addr *, const struct in_addr *,
|
||||
u16, u16);
|
||||
uint16_t stoeplitz_hash_ip6(const struct stoeplitz_cache *,
|
||||
const struct in6_addr *, const struct in6_addr *);
|
||||
uint16_t stoeplitz_hash_ip6port(const struct stoeplitz_cache *,
|
||||
const struct in6_addr *, const struct in6_addr *,
|
||||
u16, u16);
|
||||
uint16_t stoeplitz_hash_eaddr(const struct stoeplitz_cache *,
|
||||
const u8 *);
|
||||
uint16_t stoeplitz_hash_n16(const struct stoeplitz_cache *, u16);
|
||||
uint16_t stoeplitz_hash_n32(const struct stoeplitz_cache *, u32);
|
||||
uint16_t stoeplitz_hash_h16(const struct stoeplitz_cache *, u16);
|
||||
uint16_t stoeplitz_hash_h32(const struct stoeplitz_cache *, u32);
|
||||
uint16_t stoeplitz_hash_h64(const struct stoeplitz_cache *, u64);
|
||||
|
||||
#define stoeplitz_n32(_n32) stoeplitz_hash_n32(stoeplitz_cache, (_n32))
|
||||
#define stoeplitz_h16(_h16) stoeplitz_hash_h16(stoeplitz_cache, (_h16))
|
||||
#define stoeplitz_h32(_h32) stoeplitz_hash_h32(stoeplitz_cache, (_h32))
|
||||
#define stoeplitz_h64(_h64) stoeplitz_hash_h64(stoeplitz_cache, (_h64))
|
||||
#define stoeplitz_ip4(_sa4, _da4) \
|
||||
stoeplitz_hash_ip4(stoeplitz_cache, (_sa4), (_da4))
|
||||
#define stoeplitz_ip4port(_sa4, _da4, _sp, _dp) \
|
||||
stoeplitz_hash_ip4port(stoeplitz_cache, (_sa4), (_da4), (_sp), (_dp))
|
||||
#define stoeplitz_ip6(_sa6, _da6) \
|
||||
stoeplitz_hash_ip6(stoeplitz_cache, (_sa6), (_da6))
|
||||
#define stoeplitz_ip6port(_sa6, _da6, _sp, _dp) \
|
||||
stoeplitz_hash_ip6port(stoeplitz_cache, (_sa6), (_da6), (_sp), (_dp))
|
||||
#define stoeplitz_eaddr(_ea) \
|
||||
stoeplitz_hash_eaddr(stoeplitz_cache, (_ea))
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
/* PFLINUX compat: <netinet/in.h> */
|
||||
#ifndef _PFK_NETINET_IN_H
|
||||
#define _PFK_NETINET_IN_H
|
||||
#include <linux/in.h>
|
||||
#include <linux/in6.h>
|
||||
/* BSD IP-level option numbers (Linux uapi uses different values) */
|
||||
#define PF_IP_OPTIONS 1
|
||||
#define PF_IP_RECORD_ROUTE 7
|
||||
#define PF_IP_TIMESTAMP 68
|
||||
#ifndef INADDR_MULTICAST
|
||||
#define INADDR_MULTICAST 0xe0000000U
|
||||
#endif
|
||||
#endif
|
||||
@@ -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_ */
|
||||
@@ -0,0 +1,7 @@
|
||||
/* PFLINUX compat: <sys/_null.h> */
|
||||
#ifndef _SYS__NULL_H_
|
||||
#define _SYS__NULL_H_
|
||||
#ifndef NULL
|
||||
#define NULL 0L
|
||||
#endif
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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_ */
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
Reference in new issue
Block a user