Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
tsn-measures
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
tsn-measures
Commits
b1f3a35a
Commit
b1f3a35a
authored
Jun 16, 2020
by
Joanne Hugé
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP: start adding XDP sockets
parent
67101268
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
214 additions
and
1 deletion
+214
-1
packet-exchange/src/recv_packet.c
packet-exchange/src/recv_packet.c
+174
-1
packet-exchange/src/recv_packet.h
packet-exchange/src/recv_packet.h
+3
-0
packet-exchange/src/server.c
packet-exchange/src/server.c
+14
-0
packet-exchange/src/utilities.h
packet-exchange/src/utilities.h
+23
-0
No files found.
packet-exchange/src/recv_packet.c
View file @
b1f3a35a
...
...
@@ -29,6 +29,7 @@
#include "utilities.h"
static
void
fill_histograms
(
packet_info_t
*
packet_info
,
int64_t
histograms
[
NB_HISTOGRAMS
][
MAX_HIST_VAL
]);
static
void
open_xdp_socket
(
void
);
static
char
rx_buffer
[
MAX_BUFFER_SIZE
];
static
int
sock_fd
;
...
...
@@ -49,6 +50,9 @@ static int set_if(char *network_if) {
return
ifreq
.
ifr_ifindex
;
}
/*
* Init UDP socket
*/
int
init_udp_recv
(
int
use_timestamps
,
char
*
network_if
)
{
int
getaddrinfo_err
;
int
set_if_err
;
...
...
@@ -100,7 +104,7 @@ int init_udp_recv(int use_timestamps, char *network_if) {
}
/*
* Receive
s udp packets
* Receive
UDP packet
*/
packet_info_t
recv_udp_packet
(
int
use_timestamps
,
int
use_histograms
,
int64_t
histograms
[
NB_HISTOGRAMS
][
MAX_HIST_VAL
])
{
...
...
@@ -164,6 +168,175 @@ packet_info_t recv_udp_packet(int use_timestamps, int use_histograms, int64_t hi
return
packet_info
;
}
/*
* Init XDP socket
*/
void
setup_xdp_socket
(
void
)
{
#ifdef WITH_XDP
int
ret
,
prog_fd
,
xsks_map
=
0
;
struct
bpf_prog_load_attr
prog_load_attr
=
{
.
prog_type
=
BPF_PROG_TYPE_XDP
,
.
file
=
"xdp_kern.o"
,
};
struct
xsk_umem_config
cfg
=
{
.
fill_size
=
XSK_RING_PROD__DEFAULT_NUM_DESCS
,
.
comp_size
=
XSK_RING_CONS__DEFAULT_NUM_DESCS
,
.
frame_size
=
FRAME_SIZE
,
.
frame_headroom
=
XSK_UMEM__DEFAULT_FRAME_HEADROOM
,
.
flags
=
0
,
};
struct
bpf_object
*
obj
;
struct
bpf_map
*
map
;
void
*
buffer
=
NULL
;
ret
=
bpf_prog_load_xattr
(
&
prog_load_attr
,
&
obj
,
&
prog_fd
);
if
(
ret
||
prog_fd
<
0
)
err
(
"bpf_prog_load_xattr() failed"
);
map
=
bpf_object__find_map_by_name
(
obj
,
"xsks_map"
);
xsks_map
=
bpf_map__fd
(
map
);
if
(
xsks_map
<
0
)
err
(
"No xsks_map found!"
);
ifindex
=
if_nametoindex
(
interface
);
if
(
!
ifindex
)
err_errno
(
"if_nametoindex() failed"
);
/* Use XDP _only_ in conjuction with driver assisted mode */
ret
=
bpf_set_link_xdp_fd
(
ifindex
,
prog_fd
,
xdp_flags
());
if
(
ret
)
err
(
"bpf_set_link_xdp_fd() failed"
);
/* Allocate user space memory for xdp frames */
ret
=
posix_memalign
(
&
buffer
,
sysconf
(
_SC_PAGE_SIZE
),
NUM_FRAMES
*
FRAME_SIZE
);
if
(
ret
)
err_errno
(
"posix_memalign() failed"
);
ret
=
xsk_umem__create
(
&
xdp_socket
.
umem
.
umem
,
buffer
,
NUM_FRAMES
*
FRAME_SIZE
,
&
xdp_socket
.
umem
.
fq
,
&
xdp_socket
.
umem
.
cq
,
&
cfg
);
if
(
ret
)
err
(
"xsk_umem__create() failed"
);
xdp_socket
.
umem
.
buffer
=
buffer
;
/* Open and bind socket */
open_xdp_socket
();
#endif
}
/*
* Receive XDP socket
*/
void
recv_xdp_packet
(
void
)
{
#ifdef WITH_XDP
char
*
buffer
;
long
long
tx_time
,
diff
;
struct
timespec
ts
;
unsigned
int
received
;
uint64_t
addr
;
uint32_t
idx_rx
=
0
,
len
,
idx
;
int
ret
;
ret
=
poll
(
fds
,
1
,
-
1
);
if
(
ret
==
0
)
return
;
if
(
ret
<
0
)
error
(
EXIT_FAILURE
,
errno
,
"poll failed"
);
/*
* Process packets: One at a time is enough for cyclic apps. Just
* be sure, that the NIC queue is correctly confgured. ethtool can
* be used for that.
*/
received
=
xsk_ring_cons__peek
(
&
xdp_socket
.
rx
,
1
,
&
idx_rx
);
if
(
!
received
)
return
;
/* Get current time */
ret
=
clock_gettime
(
CLOCK_TAI
,
&
ts
);
if
(
received
!=
1
)
error
(
EXIT_FAILURE
,
errno
,
"Received more packets than expected"
);
/* Get the packet */
addr
=
xsk_ring_cons__rx_desc
(
&
xdp_socket
.
rx
,
idx_rx
)
->
addr
;
len
=
xsk_ring_cons__rx_desc
(
&
xdp_socket
.
rx
,
idx_rx
)
->
len
;
/* Parse it */
buffer
=
parse_raw_packet
(
xsk_umem__add_offset_to_addr
(
addr
),
len
);
if
(
!
buffer
)
return
;
/* Decode */
ret
=
sscanf
(
buffer
,
"KURT: %lld"
,
&
tx_time
);
if
(
ret
!=
1
)
{
log_err
(
"Failed to decode package"
);
return
;
}
/* Cleanup */
xsk_ring_cons__release
(
&
xdp_socket
.
rx
,
received
);
/* Add that particular buffer back to the fill queue */
if
(
xsk_prod_nb_free
(
&
xdp_socket
.
umem
.
fq
,
received
))
{
ret
=
xsk_ring_prod__reserve
(
&
xdp_socket
.
umem
.
fq
,
received
,
&
idx
);
if
(
ret
!=
received
)
err
(
"xsk_ring_prod__reserve() failed"
);
*
xsk_ring_prod__fill_addr
(
&
xdp_socket
.
umem
.
fq
,
idx
)
=
xsk_umem__extract_addr
(
addr
);
xsk_ring_prod__submit
(
&
xdp_socket
.
umem
.
fq
,
received
);
}
/* Update stats */
diff
=
update_stats
(
&
ts
,
tx_time
);
if
(
break_value_ns
&&
diff
>
break_value_ns
)
{
stop_tracing
();
stop
=
1
;
break
;
}
#endif
}
static
void
open_xdp_socket
(
void
)
{
struct
xsk_socket_config
xsk_cfg
;
uint32_t
idx
;
int
ret
,
i
;
/* Create XDP socket */
xsk_cfg
.
rx_size
=
XSK_RING_CONS__DEFAULT_NUM_DESCS
;
xsk_cfg
.
tx_size
=
XSK_RING_PROD__DEFAULT_NUM_DESCS
;
xsk_cfg
.
libbpf_flags
=
0
;
xsk_cfg
.
xdp_flags
=
xdp_flags
();
xsk_cfg
.
bind_flags
=
0
;
ret
=
xsk_socket__create
(
&
xdp_socket
.
xsk
,
interface
,
queue
,
xdp_socket
.
umem
.
umem
,
&
xdp_socket
.
rx
,
&
xdp_socket
.
tx
,
&
xsk_cfg
);
if
(
ret
)
err
(
"xsk_socket__create() failed"
);
/* Add some buffers */
ret
=
xsk_ring_prod__reserve
(
&
xdp_socket
.
umem
.
fq
,
XSK_RING_PROD__DEFAULT_NUM_DESCS
,
&
idx
);
if
(
ret
!=
XSK_RING_PROD__DEFAULT_NUM_DESCS
)
err
(
"xsk_ring_prod__reserve() failed"
);
for
(
i
=
0
;
i
<
XSK_RING_PROD__DEFAULT_NUM_DESCS
;
i
++
)
*
xsk_ring_prod__fill_addr
(
&
xdp_socket
.
umem
.
fq
,
idx
++
)
=
i
*
FRAME_SIZE
;
xsk_ring_prod__submit
(
&
xdp_socket
.
umem
.
fq
,
XSK_RING_PROD__DEFAULT_NUM_DESCS
);
}
static
void
fill_histograms
(
packet_info_t
*
packet_info
,
int64_t
histograms
[
NB_HISTOGRAMS
][
MAX_HIST_VAL
])
{
uint64_t
user_space_time
=
packet_info
->
userspace_exit_ts
-
packet_info
->
userspace_enter_ts
;
...
...
packet-exchange/src/recv_packet.h
View file @
b1f3a35a
...
...
@@ -6,4 +6,7 @@
int
init_udp_recv
(
int
use_timestamps
,
char
*
network_if
);
packet_info_t
recv_udp_packet
(
int
use_timestamps
,
int
use_histograms
,
int64_t
histograms
[
NB_HISTOGRAMS
][
MAX_HIST_VAL
]);
void
setup_xdp_socket
(
void
);
void
recv_xdp_packet
(
void
);
#endif
packet-exchange/src/server.c
View file @
b1f3a35a
...
...
@@ -28,6 +28,18 @@
#include "send_packet.h"
#include "utilities.h"
#ifdef WITH_XDP
#include <linux/if_link.h>
#include <linux/if_xdp.h>
#include <linux/if_ether.h>
#include <linux/udp.h>
#include <linux/ip.h>
#include <bpf/bpf.h>
#include <bpf/xsk.h>
#include <bpf/libbpf.h>
#endif
// Structs
typedef
struct
thread_stat
{
...
...
@@ -62,6 +74,8 @@ static void process_options(int argc, char *argv[]);
static
void
print_histograms
();
static
void
sighand
(
int
sig_num
);
static
void
setup_xdp_socket
(
void
);
// Static variables
static
int64_t
histograms
[
NB_HISTOGRAMS
][
MAX_HIST_VAL
];
...
...
packet-exchange/src/utilities.h
View file @
b1f3a35a
...
...
@@ -15,6 +15,29 @@
#define NB_HISTOGRAMS 3
#define MAX_BUFFER_SIZE 1024
// XDP
#ifdef WITH_XDP
#define NUM_FRAMES 4096
#define FRAME_SIZE XSK_UMEM__DEFAULT_FRAME_SIZE
unsigned
int
ifindex
;
struct
xsk_umem_info
{
struct
xsk_ring_prod
fq
;
struct
xsk_ring_cons
cq
;
struct
xsk_umem
*
umem
;
void
*
buffer
;
};
struct
xdpsock
{
struct
xsk_ring_cons
rx
;
struct
xsk_ring_prod
tx
;
struct
xsk_umem_info
umem
;
struct
xsk_socket
*
xsk
;
int
fd
;
};
static
struct
xdpsock
xdp_socket
;
#endif
typedef
struct
packet_info
{
uint64_t
userspace_enter_ts
;
uint64_t
userspace_exit_ts
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment