blob: ce30582aaedc3e2ae657eb86de0484c40f42ddbb (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
/* Copyright (C) 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <bpf/xsk.h>
#include "libknot/xdp/xdp.h"
struct kxsk_iface {
/*! Interface name. */
const char *if_name;
/*! Interface name index (derived from ifname). */
int if_index;
/*! Network card queue id. */
int if_queue;
/*! Configuration BPF map file descriptor. */
int qidconf_map_fd;
/*! XSK BPF map file descriptor. */
int xsks_map_fd;
/*! BPF program object. */
struct bpf_object *prog_obj;
};
struct kxsk_umem {
/*! Fill queue: passing memory frames to kernel - ready to receive. */
struct xsk_ring_prod fq;
/*! Completion queue: passing memory frames from kernel - after send finishes. */
struct xsk_ring_cons cq;
/*! Handle internal to libbpf. */
struct xsk_umem *umem;
/*! The memory frames. */
struct umem_frame *frames;
/*! The number of free frames (for TX). */
uint32_t tx_free_count;
/*! Stack of indices of the free frames (for TX). */
uint16_t tx_free_indices[];
};
struct knot_xdp_socket {
/*! Receive queue: passing arrived packets from kernel. */
struct xsk_ring_cons rx;
/*! Transmit queue: passing packets to kernel for sending. */
struct xsk_ring_prod tx;
/*! Information about memory frames for all the passed packets. */
struct kxsk_umem *umem;
/*! Handle internal to libbpf. */
struct xsk_socket *xsk;
/*! Interface context. */
const struct kxsk_iface *iface;
/*! The kernel has to be woken up by a syscall indication. */
bool kernel_needs_wakeup;
};
/*!
* \brief Set up BPF program and map for one XDP socket.
*
* \param if_name Name of the net iface (e.g. eth0).
* \param if_queue Network card queue id.
* \param load_bpf Insert BPF program into packet processing.
* \param out_iface Output: created interface context.
*
* \return KNOT_E* or -errno
*/
int kxsk_iface_new(const char *if_name, int if_queue, knot_xdp_load_bpf_t load_bpf,
struct kxsk_iface **out_iface);
/*!
* \brief Unload BPF maps for a socket.
*
* \note This keeps the loaded BPF program. We don't care.
*
* \param iface Interface context to be freed.
*/
void kxsk_iface_free(struct kxsk_iface *iface);
/*!
* \brief Activate this AF_XDP socket through the BPF maps.
*
* \param iface Interface context.
* \param listen_port Port to listen on, or KNOT_XDP_LISTEN_PORT_* flag.
* \param xsk Socket ctx.
*
* \return KNOT_E* or -errno
*/
int kxsk_socket_start(const struct kxsk_iface *iface, uint32_t listen_port,
struct xsk_socket *xsk);
/*!
* \brief Deactivate this AF_XDP socket through the BPF maps.
*
* \param iface Interface context.
*/
void kxsk_socket_stop(const struct kxsk_iface *iface);
|