| PKTQUEUE(9) | Kernel Developer's Manual | PKTQUEUE(9) |
pktqueue, pktq_create,
pktq_destroy, pktq_enqueue,
pktq_dequeue, pktq_barrier,
pktq_ifdetach, pktq_flush,
pktq_set_maxlen,
pktq_rps_hash,
pktq_sysctl_setup,
sysctl_pktq_rps_hash_handler —
#include <net/pktqueue.h>
pktqueue_t *
pktq_create(size_t
maxlen, void
(*intrh)(void *), void
*arg);
void
pktq_destroy(pktqueue_t
*pq);
bool
pktq_enqueue(pktqueue_t
*pq, struct mbuf
*m, u_int
hash);
struct mbuf *
pktq_dequeue(pktqueue_t
*pq);
void
pktq_barrier(pktqueue_t
*pq);
void
pktq_ifdetach(void);
void
pktq_flush(pktqueue_t
*pq);
int
pktq_set_maxlen(pktqueue_t
*pq, size_t
maxlen);
uint32_t
pktq_rps_hash(const
pktq_rps_hash_func_t *funcp,
const struct mbuf
*m);
int
pktq_sysctl_setup(pktqueue_t
*pq, struct sysctllog
**clog, const struct
sysctlnode *parent_node,
int qid);
int
sysctl_pktq_rps_hash_handler(SYSCTLFN_ARGS);
pktqueue functions provide a lockless network
protocol input queue interface with integrated software interrupt scheduling
and support for receiver-side packet steering (RPS). The implementation is
based around per-CPU producer-consumer queues; multiple CPUs may enqueue
packets into a CPU's queue, but only the owning CPU will dequeue packets from
any given queue.
pktq_create(maxlen,
intrh, arg)PCQ_MAXLEN. The software interrupt handler
intrh with argument arg will
be established at SOFTINT_NET.pktq_destroy(pq)pktq_enqueue(pq,
m, hash)pktq_dequeue(pq)NULL is returned. This function must be called
with kernel preemption disabled, which is always the case when running in
a software interrupt handler.pktq_barrier(pq)pktq_ifdetach()pktq_barrier() operation on
all packet queues.pktq_flush(pq)pktq_enqueue() or
pktq_dequeue() run concurrently with
pktq_flush().pktq_set_maxlen(pq,
maxlen)pktq_rps_hash(funcp,
m)pktq_rps_hash_default. The default routine is
guaranteed to be safe to use for any network protocol. The behavior of
“toeplitz” and “toeplitz-othercpus” is
undefined if used with protocols other than IPv4 or IPv6.pktq_sysctl_setup(pq,
clog, parent_node,
qid)CTL_CREATE
to dynamically assign a node ID. The clog argument
is passed directly to sysctl_createv().sysctl_pktq_rps_hash_handler()pktq_rps_hash()
via sysctl(8). When calling
sysctl_createv() to create the sysctl node, pass
sysctl_pktq_rps_hash_handler() as the
func argument and the pointer to the RPS hash
function reference variable as the newp argument
(cast to ‘void *’).pktqueue interface is implemented within the file
net/pktqueue.c.
An example of how to use pktq_rps_hash()
can be found in the ether_input() function. An
example of how to use sysctl_pktq_rps_hash_handler()
can be found in the ether_sysctl_setup() function.
Both reside within the file net/if_ethersubr.c.
An example of how to use
pktq_sysctl_setup() can be found in the
sysctl_net_inet_ip_setup() function within the file
netinet/ip_input.c.
pktq_create() specifies the maximum number of packets
that can be stored in each per-CPU queue. This means that, in theory, the
maximum number of packets that can be enqueued is ‘maxlen *
ncpu’. However, as a practical matter, the number will be smaller
because the distribution of packets across the per-CPU queues is not perfectly
uniform.
Calls to pktq_set_maxlen() may result in
re-ordering the delivery of packets currently in the queue.
pktqueue interface first appeared in
NetBSD 7.0.
| September 3, 2022 | NetBSD 10.0 |