Age | Commit message (Collapse) | Author | Files | Lines |
|
Add basic infrastructure for update proto field value at runtime by
dynamic field function.
Extended 'struct packet_dyn' with proto fields which has dynamically
changing values at runtime.
Added 'field_changed' callback for proto header which may be used for
check if csum updating is needed. This callback is called after field
was changed at runtime.
Added 'packet_update' callback to let proto header know when to apply
final proto header changes at runtime (e.g. - csum update).
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
The same code for applying dynamic elements to a packet is used for both
slow & fast path modes, so let's move it into one inlined function.
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Use the mkostemp_or_die() wrapper introduced in commit a87f181bd836
("ioops: Add mkostemp_or_die") to safely create a unique temporary file
instead of using rand() to manually create a (potentially unsafe)
temporary filename.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Add new trafgen_proto.c module with basic protocol header fields
generation logic. This will allow to support protocol specific keywords
in the trafgen configuration language.
Each protocol must implement struct proto_hdr and register it to the
global proto list.
Protocol headers consist of a set of fields, and each field must be
described via struct proto_field by specifying unique id, length and
offset (relative to the header start). Fields smaller than 8 bits can be
described via left shift & mask.
The following callbacks are invoked to perform special actions to build
the header during parsing:
1) header_init - required fields must be added to the packet and
initialized with default values.
2) header_finish - it is invoked when header is specified, all user
specified fields are set.
3) packet_finish - callback is invoked from upper to lower header
to calculate fields depending on upper layers such as total
length or checksum.
The protocol generation API provides convenience protocol field
setters/getters to to be used in the parser while crafting the packet.
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
[tk: wordsmithing on commit message, minor variable type changes]
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Lets strtoul(...) func set pointer of unit name for ring size option,
instead of check each character by isdigit(...).
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
It is not needed to parse each character to find
unit name in the option string but just let to do it
via strtoul providing the pointer which will keep non numeric
value.
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Move gap feature into rate shaper, as these features
means the same - delay the packet sending.
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Use 'kbit' instead of kBit in usage and manpage to actually reflect what
trafgen expects.
Fixes: 9ece0fe02096 ("trafgen: Add option to specify packets sending rate")
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Added -b,--rate option in units of:
pps/B/kB/MB/kBit/Mbit/Gbit/KiB/MiB/GiB
to specify rate at which packets will be sent.
Similarly to -t,--gap option the packets will be sent
in slow mode with 1 CPU.
Tested with ifpps.
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Add -D,--define option which allows to pass multiple
macro/defines which can be used in trafgen script
(e.g. by #ifdef ).
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
No need to duplicate the call to preprocess_packets(), just call it
directly after compile_packets()/compile_packets_str().
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
The `ccsum' parameter to calc_csum() is never used and is set to 0 by
all callers. There's no reason to keep it, so remove it.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Craft packet directly from command line with same syntax as for conf file.
It might be as first step to extend current syntax with specific proto fields.
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Just add a newline before notes.
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
|
Let AF_PACKET do this job to fail in case boundaries are too small or
too large. I found it quite useful for testing the kernel.
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
|
Spell out "resolve" properly.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
The TCP/UDP checksums cannot be calculated in the parser as the packet
payload following the TCP/UDP header is not yet know. However, we can
calculate these checksums before the send loop if the only dynamic
elements of the packet are checksums.
This change avoids the overhead of recalculating the checksums for every
iteration the send loop in these cases.
Suggested-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Replace bugs@netsniff-ng.com with netsniff-ng@googlegroups.com
which is used in REPORTING-BUGS file.
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Move has_dynamic_elems() to to trafgen_conf.h, rename it to
packet_dyn_has_elems() and use it to check whether dynamic
packet elements are present.
Also change the return type to bool and use || instead of + to
potentially make use of short-circuit evaluation.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
The return value of xmit_packet_precheck() is always 0 and it calls
panic() in any error cases, so its return value isn't of any use.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Add the csumudp6 and csumtcp6 helper functions in order to simplify
checksum generation for TCP/UDP packets sent over IPv6.
trafgen example for TCP over IPv6:
{
/* MAC Destination */
fill(0xff, 6),
/* MAC Source */
0x00, 0x02, 0xb3, drnd(3),
/* IPv6 Protocol */
c16(0x86DD),
/* Version, Traffic Class, Flow Label */
0b01100000, c8(0), c16(0),
/* Payload Length */
c16(54),
/* Next Header (TCP) */
c8(6),
/* Hop Limit */
c8(64),
/* Source IPv6 */
0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xba, 0xac, 0x6f, 0xff, 0xfe, 0xa4, 0x12, 0xe3,
/* Destination IPv6 */
0xfe, 0x80, 0x82, 0x2e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xde, 0xff, 0xfe, 0x00, 0x06, 0xde,
/* TCP Source Port */
c16(55042),
/* TCP Destination Port */
c16(55043),
/* TCP Sequence Number */
drnd(4),
/* TCP Ackn. Number */
c32(0),
/* TCP Header length + TCP SYN/ECN Flag */
c16((8 << 12) | (1 << 1) | (1 << 6))
/* Window Size */
c16(16),
/* TCP Checksum (offset IPv6, offset TCP) */
csumtcp6(14, 54),
/* TCP Options */
0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x06,
0x91, 0x68, 0x7d, 0x06, 0x91, 0x68, 0x6f,
/* Data blob */
"foobar!",
}
Suggested-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Print minimum needed packet size in case if validation error.
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Create PF_PACKET socket with proto=0 which does not setup packet handler
and will not capture packets until bind() will be invoked.
Also replaced pf_tx_socket by pf_socket as these funcs became the same,
as proto arg is set to 0.
Suggested-by: Daniel Borkmann <borkmann@iogearbox.net>
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Rename xxx_panic_func(s) to xxx_panic_handler(s) which is more
understandable than 'func'.
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Fixed case when rfmon mac80211 created device remains after trafgen
failed (for ex. - incorrect cfg file), so just delete it when panic
occured.
Also made panic handlers invoking per process and only once.
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Trafgen uses all the online CPUs even if the number of packets specified
by -n is less than the number of selected CPUs. Such behaviour leads to
issues:
- trafgen re-calculates number of packets per CPU which
leads to rounding it to 0 then no packets will be sent.
- trafgen might send more packets than specified by -n because
of using all the online cpus.
Fixed by taking min(#CPUs, #packets) as the number of CPUs if a number
of packets is specified by -n.
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
[tklauser: moved code and added explanatory comment]
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
We no longer ship example trafgen config files. Instead, mention the
netsniff-ng conversion facility.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
linux has default time slack of 50 usec, which means that trafgen
'gap' option is unable to precisely control delays.
Set the process timer slack to the minimum of 1 nsec.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
|
|
No need for some of the empty lines, remove them to make the output a
bit denser.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Move the copyright/bug report/license string to an own constant and use
it for the output of help() and version() to avoid duplication and
prevent the strings from getting out of sync. This makes the text
section of trafgen.o slightly smaller:
before:
text data bss dec hex filename
18512 0 104 18616 48b8 trafgen/trafgen.o
after:
text data bss dec hex filename
18240 0 104 18344 47a8 trafgen/trafgen.o
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
The number of CPUs is stored in ctx.cpus which is unsigned int, so use
unsigned int consistently when using CPU number. Negative CPU numbers
wont occur anyhow.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Use zmalloc()'ed buffer or statically sized array to replace usage of
variable sized arrays. Found by the sparse static checker.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Pushed last commit a bit too fast. The help text described that
the single letter option for "--no-sock-mem" were "-m", which is
wrong the right option is "-A" (only help txt, correct in the code
and manual).
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
|
|
The default behavior of trafgen is to boost the systems default
socket memory limits during a testrun. This behaviour does not
always result in improved performance, because this will stress
the kernels SLAB allocators unnecessary.
Introducing an option "--no-sock-mem" that instruct trafgen
to not perform any socket memory adjustments.
Fixes: #130
Acked-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
|
|
Instead of having to perform the individual steps to initialize a ring
and open coding them in multiple places, provide convenience functions
to do all at once. This has the nice side effect of allowing to make
most of these *_{rx,tx}_ring() functions static in their respective
module.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
It will be set later on depending on command line option (or panic()
out) and it is initialized to 0 by a memset() before anyways.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
The mm_len member of struct ring is of type size_t, but in the code
paths leading to set it, unsigned int is used. In circumstances where
unsigned int is 32 bit and size_t is 64 bit, this could lead to an
integer overflow, which causes an improper ring size being mmap()'ed in
mmap_ring_generic().
In order to prevent this, consistently use size_t to store the ring
size, since this is also what mmap() takes as its `length' parameter.
This now allows to specify ring sizes larger than 4 GiB for both
netsniff-ng and trafgen (fixes #90).
Reported-by: Jon Schipp <jonschipp@gmail.com>
Reported-by: Michał Purzyński <michalpurzynski1@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
The -k/--kernel-pull option got useless with commit c139e80 ("trafgen:
remove timer-based trigger model"). Instead of entirely removing it and
thus possibly breaking people's scripts, still accept it as an option,
but warn the user about it. We might want to remove the option in a
future release.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
If setting an unsigned long variable, use strtoul() instead of strtol().
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
commit c10621e ("trafgen: keep a small initial ring buffer size to
reduce cache-misses") reduced default ring buffer size to 196KiB,
but on my big machines with 10Gbit/s this size is too small.
Increase default ring-size to 512 KiB, yield the best results,
without increasing ring buffer size too much, this fixes #120.
Single CPU results from my E5-2630 CPU with intel ixgbe/82599.
(Cmd: trafgen --cpp --dev eth8 --conf udp_example01.trafgen --cpu 1)
* 769,440 pkts/sec -- default ring-size 196 KiB
* 1,417,908 pkts/sec -- ring-size 500 KiB
Going above CPUs L3 cache size which is (15Mb)
* 1,236,580 pkts/sec -- ring-size 20000KiB
The mmap'ed ring buffer is now faster than using sendto().
For comparison, not using the ring-buffer, by using option "-t0":
* 1,381,364 (with qdisc bypass)
And using the qdisc code path in the kernel (enable via
parameter "--qdisc-path")
* 1,227,772 pkts/sec (with --qdisc-path)
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
|
|
Heavily reduce the initial ring buffer size for trafgen to just 196KiB,
so that we can heavily reduce the number of cache-misses related to
cache references. People can still overwrite this setting later on via
command line option for their specific architecture if they wish.
Perhaps the RX_RING should be checked as well in netsniff-ng though the
use case there is slightly different.
Before:
Performance counter stats for 'trafgen -i blub -o dummy0 -n100000000':
137,765,493,346 instructions:k # 0.82 insns per cycle
167,438,826,578 cycles:k # 0.000 GHz
59,508,315 branch-misses:k
361 context-switches:k
6 cpu-migrations:k
134,751,541 cache-misses:k # 85.019 % of all cache refs
158,495,358 cache-references:k
755 kmem:kmem_cache_alloc
15.139458202 seconds time elapsed
After:
Performance counter stats for 'trafgen -i blub -o dummy0 -n100000000':
137,889,782,650 instructions:k # 0.92 insns per cycle
150,239,185,971 cycles:k # 0.000 GHz
71,583,573 branch-misses:k
423 context-switches:k
7 cpu-migrations:k
60,239 cache-misses:k # 0.073 % of all cache refs
82,502,468 cache-references:k
740 kmem:kmem_cache_alloc
12.028787964 seconds time elapsed
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
|
|
perf reports in mmap case a huge number of kmem_cache_alloc's
which seem to stem from triggering signals from kernel to user
application, against dummy device:
Performance counter stats for 'trafgen -i blub -o dummy0 -n100000000 -k100': <-- mmap case
175,837 kmem:kmem_cache_alloc
14.758900522 seconds time elapsed
Performance counter stats for 'trafgen -i blub -o dummy0 -n100000000 -k100 -t0': <-- non-mmap case
707 kmem:kmem_cache_alloc
15.591667364 seconds time elapsed
It seems not to case significant number of cache-misses, but
it's better to switch to a direct trigger when we cannot fill
new frames anymore. After this patch, we see a similar number
of kmem_cache_alloc's as in the non-mmap case. This basically
renders the kpull interval useless, we can optionally remove
it if we don't care about people's scripts. ;-)
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
|
|
Handle all termination signals that we're allowed to handle (SIGKILL
can't be handled) in order to exit gracefully in any regular termination
case.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Follow commit bed9b6bb ("netsniff-ng: Don't modify optarg/argv").
We shouldn't modify optarg (and thus argv) since it's e.g. used to
display the commandline string in `ps'. Since strtoul() reads until it
encounters the first non-numeric character and ignores the rest, we can
just revert from setting a NULL byte after the numeric part of the
string.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
|
Since Linux 3.14, the kernel supports a socket option PACKET_QDISC_BYPASS,
which trafgen enables by default. That allow us to bypass the kernels
normal qdisc (traffic control) layer.
An option -q, --qdisc-path is added to allow enabling the qdisc path
explicity, useful for testing purposes.
This will be avail in kernels >= 3.14 via
commit d346a3fae3 (packet: introduce PACKET_QDISC_BYPASS socket option).
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
|
|
The tool trafgen is used in a pktgen style transmit only scenario.
We discovered a performance bottleneck in the kernel, when
running trafgen, where the kernel stalled on a lock in
packet_rcv(). This call is unnecessary for trafgen given its
transmit only nature.
This packet_rcv() call can, easily be avoided by instructing the
RAW/PF_PACKET socket, to not listen to any protocols (by passing
protocol argument zero, when creating the socket).
The performance gain is huge, increasing performance from approx
max 2Mpps to 12Mpps, basically causing trafgen to scale with
the number of CPUs.
Following tests were run on a 2xCPU E5-2650 with Intel 10Gbit/s ixgbe:
Trafgen using sendto() syscall via parameter -t0:
* # CPUs -- *with* -- *without* packet_rcv() call
* 1 CPU == 1,232,244 -- 1,236,144 pkts/sec
* 2 CPUs == 1,592,720 -- 2,593,620 pkts/sec
* 3 CPUs == 1,635,623 -- 3,692,216 pkts/sec
* 4 CPUs == 1,567,768 -- 4,102,866 pkts/sec
* 5 CPUs == 1,700,270 -- 5,151,489 pkts/sec
* 6 CPUs == 1,762,392 -- 6,124,512 pkts/sec
* 7 CPUs == 1,850,139 -- 7,120,496 pkts/sec
* 8 CPUs == 1,770,909 -- 8,058,710 pkts/sec
* 9 CPUs == 1,721,072 -- 8,963,192 pkts/sec
* 10 CPUs == 1,359,157 -- 9,584,535 pkts/sec
* 11 CPUs == 1,175,520 -- 10,498,038 pkts/sec
* 12 CPUs == 1,075,867 -- 11,189,292 pkts/sec
* 13 CPUs == 1,012,602 -- 12,048,836 pkts/sec
* [...]
* 20 CPUs == 1,030,446 -- 11,202,449 pkts/sec
Trafgen using mmap() TX tpacket_v2 (default)
* # CPUs -- *with* -- *without* packet_rcv() call
* 1 CPU == 920,682 -- 927,984 pkts/sec
* 2 CPUs == 1,607,940 -- 2,061,406 pkts/sec
* 3 CPUs == 1,668,488 -- 2,979,463 pkts/sec
* 4 CPUs == 1,423,066 -- 3,169,565 pkts/sec
* 5 CPUs == 1,507,708 -- 3,910,756 pkts/sec
* 6 CPUs == 1,555,616 -- 4,625,844 pkts/sec
* 7 CPUs == 1,560,961 -- 5,298,441 pkts/sec
* 8 CPUs == 1,596,092 -- 6,000,465 pkts/sec
* 9 CPUs == 1,575,139 -- 6,722,130 pkts/sec
* 10 CPUs == 1,311,676 -- 7,114,202 pkts/sec
* 11 CPUs == 1,157,650 -- 7,859,399 pkts/sec
* 12 CPUs == 1,060,366 -- 8,491,004 pkts/sec
* 13 CPUs == 1,012,956 -- 9,269,761 pkts/sec
* [...]
* 20 CPUs == 955,716 -- 8,653,947 pkts/sec
It is fairly strange that the mmap() version runs slower than the
sendto() version. This is likely another performance problem related
to mmap() which seems worth fixing.
Note, that the mmap() version speed can be improved by reducing the
default --ring-size to around 1-2 MiB. But this does not fix general
trend with mmap() performance.
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
|
|
Also make these options available to trafgen.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
|
|
If we loose carrier, don't bother about panic'ing, but continue sending!
Only exit in case we're doing a smoke test.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
|
|
Add ability to set IGP in time units in seconds, milliseconds,
microseconds, and nanoseconds by appending a postfix to --gap e.g. --gap
100ms. Also, update the man page and trafgen.zsh to reflect the
changes.
[Fix whitespaces, coding style and minor wording changes -- tklauser]
Signed-off-by: Jon Schipp <jonschipp@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|