Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions xdp-trafficgen/README.org
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ Enable dynamic port mode where the destination port is varied over a range of
Number of packets to send before exiting. If not supplied, =xdp-trafficgen= will
keep sending packets until interrupted.

** -D, --duration <seconds>
Number of seconds to send packets before exiting. A value of 0 (the default)
disables the time limit. If both =--duration= and =--num-packets= are supplied,
transmission stops when either limit is reached.

** -s, --pkt-size <bytes>
Size of each UDP packet being sent, including the Ethernet header and checksum.
Since =xdp-trafficgen= generates IPv6 traffic, the minimum size, which is also
Expand Down Expand Up @@ -308,6 +313,11 @@ Load ingress XDP program in <mode>; default native (valid values: native,skb,hw)
Number of packets to send before exiting. If not supplied, =xdp-trafficgen= will
keep sending packets until interrupted.

** -D, --duration <seconds>
Number of seconds to send packets before exiting. A value of 0 (the default)
disables the time limit. If both =--duration= and =--num-packets= are supplied,
transmission stops when either limit is reached.

** -I, --interval <s>
Output transmission statistics with this interval (in seconds).

Expand Down
10 changes: 10 additions & 0 deletions xdp-trafficgen/xdp-trafficgen.8
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ Enable dynamic port mode where the destination port is varied over a range of
.PP
Number of packets to send before exiting. If not supplied, \fIxdp\-trafficgen\fP will
keep sending packets until interrupted.
.SS "-D, --duration <seconds>"
.PP
Number of seconds to send packets before exiting. A value of 0 (the default)
disables the time limit. If both \fI\-\-duration\fP and \fI\-\-num\-packets\fP are supplied,
transmission stops when either limit is reached.
.SS "-s, --pkt-size <bytes>"
.PP
Size of each UDP packet being sent, including the Ethernet header and checksum.
Expand Down Expand Up @@ -299,6 +304,11 @@ Load ingress XDP program in <mode>; default native (valid values: native,skb,hw)
.PP
Number of packets to send before exiting. If not supplied, \fIxdp\-trafficgen\fP will
keep sending packets until interrupted.
.SS "-D, --duration <seconds>"
.PP
Number of seconds to send packets before exiting. A value of 0 (the default)
disables the time limit. If both \fI\-\-duration\fP and \fI\-\-num\-packets\fP are supplied,
transmission stops when either limit is reached.
.SS "-I, --interval <s>"
.PP
Output transmission statistics with this interval (in seconds).
Expand Down
48 changes: 46 additions & 2 deletions xdp-trafficgen/xdp-trafficgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <time.h>

#include <bpf/bpf.h>
#include <bpf/bpf_endian.h>
Expand Down Expand Up @@ -49,6 +50,7 @@

#define IFINDEX_LO 1
#define ETH_FCS_SIZE 4
#define TEST_RUN_BATCH_SIZE (1 << 20U)

static int mask = SAMPLE_DEVMAP_XMIT_CNT_MULTI | SAMPLE_DROP_OK;

Expand Down Expand Up @@ -164,6 +166,7 @@ struct thread_config {
size_t pkt_size;
__u32 cpu_core_id;
__u32 num_pkts;
__u32 duration;
__u32 batch_size;
struct xdp_program *prog;
};
Expand All @@ -174,27 +177,56 @@ static int run_prog(const struct thread_config *cfg, bool *status_var)
struct xdp_md ctx_in = {
.data_end = cfg->pkt_size,
};
int repeat = cfg->num_pkts && cfg->num_pkts < TEST_RUN_BATCH_SIZE ?
cfg->num_pkts : TEST_RUN_BATCH_SIZE;
DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts,
.data_in = cfg->pkt,
.data_size_in = cfg->pkt_size,
.ctx_in = &ctx_in,
.ctx_size_in = sizeof(ctx_in),
.repeat = cfg->num_pkts ?: 1 << 20,
.repeat = repeat,
.flags = BPF_F_TEST_XDP_LIVE_FRAMES,
.batch_size = cfg->batch_size,
);
__u64 iterations = 0;
struct timespec deadline = {}, now;
cpu_set_t cpu_cores;
__u64 iterations = 0;
int err;

CPU_ZERO(&cpu_cores);
CPU_SET(cfg->cpu_core_id, &cpu_cores);
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpu_cores);

if (cfg->duration) {
err = clock_gettime(CLOCK_MONOTONIC, &deadline);
if (err)
return -errno;

deadline.tv_sec += cfg->duration;
}

do {
if (cfg->num_pkts) {
__u64 remaining = cfg->num_pkts - iterations;

if (remaining < (__u64)opts.repeat)
opts.repeat = (int)remaining;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a separate fix, let's split it out to its own commit. And there's something wrong with the indentation (spaces instead of tabs)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separated into another commit.

err = xdp_program__test_run(cfg->prog, &opts, 0);
if (err)
return -errno;
iterations += opts.repeat;

if (cfg->duration) {
if (clock_gettime(CLOCK_MONOTONIC, &now))
return -errno;

if (now.tv_sec > deadline.tv_sec ||
(now.tv_sec == deadline.tv_sec &&
now.tv_nsec >= deadline.tv_nsec))
break;
}
} while (!*status_var && (!cfg->num_pkts || cfg->num_pkts > iterations));

return 0;
Expand Down Expand Up @@ -348,6 +380,7 @@ static __be16 calc_udp_cksum(const struct udp_packet *pkt)

static const struct udpopt {
__u32 num_pkts;
__u32 duration;
struct iface iface;
struct mac_addr dst_mac;
struct mac_addr src_mac;
Expand Down Expand Up @@ -471,6 +504,10 @@ static struct prog_option udp_options[] = {
.short_opt = 'n',
.metavar = "<port>",
.help = "Number of packets to send"),
DEFINE_OPTION("duration", OPT_U32, struct udpopt, duration,
.short_opt = 'D',
.metavar = "<seconds>",
.help = "Duration to run; default 0 (forever)"),
DEFINE_OPTION("pkt-size", OPT_U16, struct udpopt, pkt_size,
.short_opt = 's',
.metavar = "<bytes>",
Expand Down Expand Up @@ -503,6 +540,7 @@ int do_udp(const void *opt, __unused const char *pin_root_path)
DECLARE_LIBXDP_OPTS(xdp_program_opts, opts);
struct thread_config *t = NULL, tcfg = {
.num_pkts = cfg->num_pkts,
.duration = cfg->duration,
};
struct trafficgen_state bpf_state = {};
struct xdp_trafficgen *skel = NULL;
Expand Down Expand Up @@ -919,6 +957,7 @@ static void prepare_tcp_pkt(const struct tcp_flowkey *fkey,

static const struct tcpopt {
__u32 num_pkts;
__u32 duration;
struct iface iface;
char *dst_addr;
__u16 dst_port;
Expand All @@ -941,6 +980,10 @@ static struct prog_option tcp_options[] = {
.short_opt = 'n',
.metavar = "<port>",
.help = "Number of packets to send"),
DEFINE_OPTION("duration", OPT_U32, struct tcpopt, duration,
.short_opt = 'D',
.metavar = "<seconds>",
.help = "Duration to run; default 0 (forever)"),
DEFINE_OPTION("interval", OPT_U16, struct tcpopt, interval,
.short_opt = 'I',
.metavar = "<s>",
Expand Down Expand Up @@ -986,6 +1029,7 @@ int do_tcp(const void *opt, __unused const char *pin_root_path)
.pkt = &pkt_tcp,
.pkt_size = sizeof(pkt_tcp),
.num_pkts = cfg->num_pkts,
.duration = cfg->duration,
};
struct trafficgen_state bpf_state = {};
struct xdp_trafficgen *skel = NULL;
Expand Down