FLENT(1) | Flent: The FLExible Network Tester | FLENT(1) |
flent - Flent: The FLExible Network Tester
Flent is a wrapper around netperf and similar tools to run predefined tests and aggregate and plot the results. It defines several tests that can be run against one or more hosts, primarily targeted at testing for the presence of bufferbloat under various conditions.
The aggregated data is saved in (gzipped) JSON format for later processing and/or import into other tools. The JSON format is documented below.
Apart from the JSON format, the data can be output as csv values, emacs org mode tables or plots. Each test can specify several different plots, including time-series plots of the values against each other, as well as CDF plots of (e.g.) ping times.
Plots can be output to the formats supported by matplotlib by specifying the output filename with -o output.{png,ps,pdf,svg}. If no output file is specified, the plot is displayed using matplotlib’s interactive plot browser, which also allows saving of the output (in .png format).
Flent runs on Python, versions 2.7+ and 3.3+. Plotting requires a functional matplotlib installation (but everything else can run without matplotlib). For the interactive plot viewer, a graphical display (and suitably configured matplotlib) is required.
Most tests employ the netperf benchmarking tool to run the tests. Version 2.6 or higher is required, and netperf must be compiled with the --enable-demo option passed to ./configure. Some tests use iperf in addition to, or instead of netperf. Both tools must be available in the PATH.
For ICMP ping measurements, the version of ping employed must support output timestamping (the -D parameter to GNU ping). This is not supported by the BSD and OSX versions of ping. As an alternative to the regular ping command, the fping utility (see http://fping.org) can be employed. In that case fping must be version 3.5 or greater. Flent will attempt to detect the presence of fping in the PATH and check for support for the -D parameter. If this check is successful, fping will be employed for ping data, otherwise the system ping will be used.
The irtt tool is highly recommended for UDP measurements. See https://github.com/peteheist/irtt. Flent will automatically detect if irtt is available in the PATH and use it if it is detected. Note that the server component of irtt needs to be running on the target host(s) as well.
When run, flent must be supplied either (a) a test name and one or more host names to connect to, or (b) one or more input files containing data from previous runs to post-process.
Test names, hostnames and input file names can all be specified as unqualified arguments, and flent will do its best to guess which is which. For each argument, if it is an existing file, it is assumed to be an input file, if it is the name of an existing test configuration it’s assumed to be a test name, and if neither of those are true, it is assumed to be a host name. The -i and -H switches can be used to explicitly specify the interpretation of an argument.
flent [options] <host|test|input file ...>
This will attempt to find a data file in the resume directory and load the BATCH_TIME from the previous run from that and continue. The assumption is that the output directory and filenames are generated from the batch time, so that they will match with the previous run when the same time is used. Then, tests for which data files already exist will be skipped on this run. If the rest of the batch invocation is different from the one being resumed, results may not be what you want.
There's a check to ensure that the generated output path is a subdirectory of the resume directory, and the whole run will be aborted if it isn't.
These options affect the behaviour of the test being run and have no effect when parsing input files.
This works by simply prepending 'ssh HOSTNAME' to the runner command, so it relies on the same binaries being in the same places on both machines, and won't work for all runners.
This option can be specified multiple times to have multiple runners run on remote hosts.
For the default value, see the output of flent -h. The value of this parameter is an implicit upper bound on how long a round-trip time that can be measured. As such you may need to adjust it if you are experiencing latency above the default value. Set to 0 to disable.
Can be specified multiple times, with each value corresponding to a stream of a test. If only specified once, the same value will be applied to all flows.
In addition to serving as simple metadata, the test parameters can also affect the behaviour of some test configurations. See the tests section for information on these.
This option can be specified multiple times to set multiple test parameters.
The list of symbolic markings natively supported, along with their hex expansions, are:
AF11: 0x28 CS0: 0x00 AF12: 0x30 CS1: 0x20 AF13: 0x38 CS2: 0x40 AF21: 0x48 CS3: 0x60 AF22: 0x50 CS4: 0x80 AF23: 0x58 CS5: 0xa0 AF31: 0x68 CS6: 0xc0 AF32: 0x70 CS7: 0xe0 AF33: 0x78 EF: 0xb8 AF41: 0x88 AF42: 0x90 AF43: 0x98
Note that the hexadecimal values denote the value of the full ToS byte (including the two ECN bits), so they need to be right-shifted by two bits to get the corresponding diffserv code points.
These options are used to configure the appearance of plot output and only make sense combined with -f plot.
Like --override-title, this is applied at the time of plotting.
Say you're plotting nine datasets which are really testing two variables with three values each. In this case, it can be useful to have the box plot of the results be split into three parts (corresponding to the values of one variable) with each three boxes in each of them (corresponding to the values of the second variable). This option makes this possible; simply specify it three times with the labels to be used for the three groups.
A constraint on this option is that the number of datasets being plotted must be divisible by the number of groups.
Yes, this option uses British spelling. No, American spelling is not supported.
When running tests that uses D-ITG as a test tool (such as the voip-* tests), this switch controls where flent will look for the D-ITG control server (see section below on running tests with D-ITG). For Netperf-based tests, this option is passed to Netperf to control where to point the control connection. This is useful to, for instance, to run the control server communication over a separate control network so as to not interfere with test traffic.
There is also a per-flow setting for this for tests that connect to multiple hosts; see the control_hosts test parameter in tests. If both are set, the per-flow setting takes precedence for those tests that use it.
Flent will abort what it is currently doing on receiving a SIGINT -- this includes killing all runners, cleaning up temporary files and shutting down as gracefully as possible. Runners are killed with SIGTERM in this mode, and their output is discarded. If a batch run is in progress, the current test will be interrupted in this way, and the rest of the batch run is aborted. Previously completed tests and their results are not aborted. Post-commands marked as ’essential’ will be run after the test is interrupted. Additionally, flent converts SIGTERM into SIGINT internally and reacts accordingly.
Upon receiving a SIGUSR1, flent will try to gracefully abort the test it is currently running, and parse the output of the runners to the extent that any such output exists. That is, each runner will be killed by a SIGINT, which will cause a graceful shutdown for at least ping and netperf (although netperf running in TCP_MAERTS mode will bug out when interrupted like this, so end-of-tests statistics will be missing). Flent will only react once to a SIGUSR1, sending exactly one SIGINT to the active runners, then wait for them to exit. This may take several seconds in the case of netperf. If the runners for some reason fail to exit, flent will be stuck and will need to be killed with SIGINT. If running in batch mode, SIGUSR1 will only affect the currently running test; subsequent tests will still be run.
Test are supplied as Python files and can specify commands to run etc. For a full list of the tests supported by flent, see the --list-tests option.
This test exists in a couple of variants and is a partial implementation of the RRUL specification as written by Dave Taht (see https://github.com/dtaht/deBloat/blob/master/spec/rrule.doc?raw=true). It works by running RTT measurement using ICMP ping and UDP roundtrip time measurement, while loading up the link with eight TCP streams (four downloads, four uploads). This quite reliably saturates the measured link (wherever the bottleneck might be), and thus exposes bufferbloat when it is present.
These tests combine a TCP flow (either in one direction, or both) with an ICMP ping measurement. It’s a simpler test than RRUL, but in some cases the single TCP flow can be sufficient to saturate the link.
This test runs iperf configured to emit 100Mbps of UDP packets targeted at the test host, while measuring RTT using ICMP ping. It is useful for observing latency in the face of a completely unresponsive packet stream.
Some test parameters (set with --test-parameter) affect the way tests behave. These are:
If a congestion control is specified that is not available on the system running the test, setting it will simply fail. In addition, some tests override the congestion control for one or more flows. The actual congestion control used is stored in the CONG_CONTROL per-test metadata field.
When running multiple UDP streams use the plural versions of the options (udp_bandwidths and udp_pktsizes) to specify individual per-stream values (comma-separated per stream), or the singular versions to specify the same value for all streams.
CPU stats and netstat output is global to the machine being connected to. The qdisc and WiFi stats need extra parameters to work. These are qdisc_stats_interfaces, wifi_stats_interfaces and wifi_stats_stations. The two former specify which interfaces to gather statistics from. These are paired with the hostnames, and so must contain the same number of elements (also comma-separated) as the _hosts variables. To specify multiple interfaces on the same host, duplicate the hostname. The wifi_stats_stations parameter specifies MAC addresses of stations to gather statistics for. This list is the same for all hosts, but only stations present in debugfs on each host are actually captured.
The qdisc stats gather statistics output from tc -s, while the WiFi stats gather statistics from debugfs. These are gathered by looping in a shell script; however, for better performance, the tc_iterate and wifistats_iterate programmes available in the misc/ directory of the source code tarball can be installed. On low-powered systems this can be critical to get correct statistics. The helper programmes are packaged for LEDE/OpenWrt in the flent-tools package.
Flent comes equipped with a GUI to browse and plot previously captured datasets. The GUI requires PyQt4; if this is installed, it can be launched with the --gui parameter, or by launching the flent-gui binary. Additionally, if Flent is launched without parameters and without a controlling terminal, the GUI will be launched automatically.
The GUI can be used for interactively plotting previously captured datasets, and makes it easy to compare results from several test runs. It presents a tabbed interface to graphs of data files, allows dynamic configuration of plots, and includes a metadata browser. For each loaded data file, additional data files can be loaded and added to the plot, similar to what happens when specifying multiple input files for plotting on the command line. A checkbox controls whether the added data files are added as separate entries to the plot, or whether they are used for scaling the output (mirroring the --scale-mode) command line switch.
The GUI also incorporates matplotlib’s interactive browsing toolbar, enabling panning and zooming of the plot area, dynamic configuration of plot and axis parameters and labels and saving the plots to file. The exact dynamic features supported depends on the installed version of matplotlib.
Some of the command line options can be specified in an rc file. By default, flent looks for this in ~/.flentrc, but an alternative location can be specified with the --rcfile command line option.
The rc file allows options to be specified globally, an optionally overridden for specific tests. For an explanation of the options, refer to the annotated example rc file, by default installed to /usr/share/doc/flent/flentrc.example.
Flent supports reading batch files to automate running several tests and do setup/teardown of test environment etc. This greatly aids reproducibility of tests.
The batch file is parsed as an ini file, and can have three types of sections: batches, commands and args. Each section also has a name; type and name are separated with two colons. 'Batches' are named tests that can be selected from the command line, 'commands' are system commands to be run before or after each test run, and 'args' are used in the looping mechanism (which allows repeating tests multiple times with different parameters).
Variables in sections control the operation of Flent and can be modified in several ways: Sections of the same type can inherit from each other and the variables in an 'arg' section will be interpolated into the batch definition on each iteration of a loop. In addition, variable contents can be substituted into other variables by using the ${varname} syntax. These three operations are resolved in this order (inheritance, arg interpolation and variable substitution).
An annotated example batchfile is distributed with the source code, and is by default installed to /usr/share/doc/flent/batchfile.example.
The aggregated test data is saved in a file called <test_name>-<date>.<title>.flent.gz (the title part is omitted if no title is specified by the -t parameter). This file contains the data points generated during the test, as well as some metadata.
If the --remote-metadata is used, the extended metadata info is gathered for each of the hostnames specified. This is gathered under the REMOTE_METADATA key in the metadata object, keyed by the hostname values passed to --remote-metadata. Additionally, the REMOTE_METADATA object will contain an object called INGRESS_INFO which is a duplicate of EGRESS_INFO, but with the destination IP exchanged for the source address of the host running flent. The assumption here is that --remote-metadata is used to capture metadata of a router known to be in the test path, in which case INGRESS_INFO will contain information about the reverse path from the router (which is ingress from the point of view of the host running flent). If the host being queried for remote metadata is off the path, the contents of INGRESS_INFO will probably be the same as that of EGRESS_INFO .
If the --extended-metadata switch is turned on, the following additional values are collected and stored (to the extent they are available from the platform):
The following output formats are currently supported by Flent:
Output test data as one of a series of graphical plots of timeseries data or summarised as a CDF plot. Each test supplies a number of different plots; the list of plots for a given test is output by the --list-plots switch (which must be supplied along with a test name).
The plots are drawn by matplotlib, and can be displayed on the screen interactively (requires a graphical display), or output to a file in svg, pdf, ps and png formats. Using the -o switch turns out file output (the file format is inferred from the file name), while not supplying the switch turns on the interactive plot viewer.
These formats output the numeric data in a tabulated format to be consumed by other applications. The csv output format is a comma-separated output that can be imported into e.g. spreadsheets, while org_table outputs a tabulated output in the table format supported by Emacs org mode. The data is output in text format to standard output, or written to a file if invoked with the -o parameter.
This output format outputs various statistics about the test data, such as total bandwidth consumed, and various statistical measures (min/max/mean/median/std dev/variance) for each data source specified in the relevant test (this can include some data sources not includes on plots). The data is output in text format to standard output, or written to a file if invoked with the -o parameter.
This output format outputs the test metadata as pretty-printed JSON (also suitable for human consumption). It is output as a list of objects, where each object corresponds to the metadata of one test. Mostly useful for inspecting metadata of stored data files.
This version of flent has experimental support for running and parsing the output of the D-ITG test tool (see http://traffic.comics.unina.it/software/ITG/). Flent supports parsing the one-way delay as measured by D-ITG. However, in order to do so, the data needs to be collected at the receiver end, statistics extracted, and the result passed back to flent on the sending side.
To perform this function, flent supports a control server which will listen to XML-RPC requests, spawn an appropriate ITGRecv instance and, after the test is done, parse its output and make it available for flent to retrieve. This control server is available as a Python file that by default is installed in /usr/share/doc/flent/misc. It currently requires a patched version of D-ITG v2.8.1. The patch is also included in the same directory.
Note that the D-ITG server is finicky and not designed with security in mind. For this reason, the control server includes HMAC authentication to only allow authenticated clients to run a test against the server; however there is currently no support for enforcement of this in e.g. firewall rules. Please bear this in mind when running a publicly reachable ITGRecv instance (with or without the control server). Another security issue with the control server is that the Python XML-RPC library by default is vulnerable to XML entity expansion attacks. For this reason, it is highly recommended to install the defusedxml library (available at https://pypi.python.org/pypi/defusedxml/) on the host running the control server. The server will try to find the library on startup and refuse to run if it is not available, unless explicitly told otherwise.
Due to the hassle of using D-ITG, it is recommended to install irtt instead and use that for VoIP tests.
Under some conditions (such as severe bufferbloat), the UDP RTT measurements done by netperf can experience packet loss to the extent that the test aborts completely, which can cause missing data points for some measurement series. The --socket-timeout feature can alleviate this, but requires a recent SVN version of netperf to work. Flent tries to detect if netperf supports this option and enables it for the UDP measurements if it does. Using irtt for UDP measurements is a way to alleviate this; Flent will automatically detect the availability of irtt and use it if available.
Probably many other bugs. Please report any found to https://github.com/tohojo/flent/issues and include the output of flent --version in the report. A debug log (as obtained with flent --log-file) is also often useful.
Toke Høiland-Jørgensen
2012-2017, Toke Høiland-Jørgensen and contributors. Source code is GPLv3. Documentation is CC-BY-SA
January 14, 2021 | 2.0.0 |