SIFTR(4) | Device Drivers Manual | SIFTR(4) |
SIFTR
—
Statistical Information For TCP Research
To load the driver as a module at run-time, run the following command as root:
kldload siftr
Alternatively, to load the driver as a module at boot time, add the following line into the loader.conf(5) file:
siftr_load="YES"
The SIFTR
(Statistical
Information
For
TCP
Research) kernel
module logs a range of statistics on active TCP connections to a log file.
It provides the ability to make highly granular measurements of TCP
connection state, aimed at system administrators, developers and
researchers.
The default operation of SIFTR
is to
capture IPv4 TCP/IP packets. SIFTR
can be configured
to support IPv4 and IPv6 by uncommenting:
CFLAGS+=-DSIFTR_IPV6
in ⟨sys/modules/siftr/Makefile⟩ and recompiling.
In the IPv4-only (default) mode, standard dotted decimal notation (e.g. "136.186.229.95") is used to format IPv4 addresses for logging. In IPv6 mode, standard dotted decimal notation is used to format IPv4 addresses, and standard colon-separated hex notation (see RFC 4291) is used to format IPv6 addresses for logging. Note that SIFTR uses uncompressed notation to format IPv6 addresses. For example, the address "fe80::20f:feff:fea2:531b" would be logged as "fe80:0:0:0:20f:feff:fea2:531b".
SIFTR
utilises the
sysctl(8) interface to export its configuration variables
to user-space. The following variables are available:
SIFTR
. By default, the value is set to 0, which
means no hashes are generated. The hashes are useful to correlate which
TCP packet triggered the generation of a particular log message, but
calculating them adds additional computational overhead into the fast
path.A typical SIFTR
log file will contain 3
different types of log message. All messages are written in plain ASCII
text.
Note: The "\" present in the example log messages in this section indicates a line continuation and is not part of the actual log message.
The first type of log message is written to the file when the module is enabled and starts collecting data from the running kernel. The text below shows an example module enable log. The fields are tab delimited key-value pairs which describe some basic information about the system.
enable_time_secs=1238556193 enable_time_usecs=462104 \ siftrver=1.2.2 hz=1000 tcp_rtt_scale=32 \ sysname=FreeBSD sysver=604000 ipmode=4
Field descriptions are as follows:
SIFTR
.The second type of log message is written to the file when a data log message is generated. The text below shows an example data log triggered by an IPv4 TCP/IP packet. The data is CSV formatted.
o,0xbec491a5,1238556193.463551,172.16.7.28,22,172.16.2.5,55931, \ 1073725440,172312,6144,66560,66608,8,1,4,1448,936,1,996,255, \ 33304,208,66608,0,208,0
Field descriptions are as follows:
M_HASHTYPE_*
.The third type of log message is written to the file when the module is disabled and ceases collecting data from the running kernel. The text below shows an example module disable log. The fields are tab delimited key-value pairs which provide statistics about operations since the module was most recently enabled.
disable_time_secs=1238556197 disable_time_usecs=933607 \ num_inbound_tcp_pkts=356 num_outbound_tcp_pkts=627 \ total_tcp_pkts=983 num_inbound_skipped_pkts_malloc=0 \ num_outbound_skipped_pkts_malloc=0 num_inbound_skipped_pkts_mtx=0 \ num_outbound_skipped_pkts_mtx=0 num_inbound_skipped_pkts_tcb=0 \ num_outbound_skipped_pkts_tcb=0 num_inbound_skipped_pkts_icb=0 \ num_outbound_skipped_pkts_icb=0 total_skipped_tcp_pkts=0 \ flow_list=172.16.7.28;22-172.16.2.5;55931,
Field descriptions are as follows:
SIFTR
was enabled.SIFTR
was enabled.The total number of data log messages found in the log file for a module enable/disable cycle should equate to total_tcp_pkts - total_skipped_tcp_pkts.
SIFTR
hooks into the network stack using
the pfil(9) interface. In its current incarnation, it
hooks into the AF_INET/AF_INET6 (IPv4/IPv6) pfil(9)
filtering points, which means it sees packets at the IP layer of the network
stack. This means that TCP packets inbound to the stack are intercepted
before they have been processed by the TCP layer. Packets outbound from the
stack are intercepted after they have been processed by the TCP layer.
The diagram below illustrates how SIFTR
inserts itself into the stack.
---------------------------------- Upper Layers ---------------------------------- ^ | | | | | | v TCP in TCP out ---------------------------------- ^ | |________ _________| | | | v --------- | SIFTR | --------- ^ | ________| |__________ | | | v IPv{4/6} in IPv{4/6} out ---------------------------------- ^ | | | | v Layer 2 in Layer 2 out ---------------------------------- Physical Layer ----------------------------------
SIFTR
uses the alq(9)
interface to manage writing data to disk.
At first glance, you might mistakenly think that
SIFTR
extracts information from individual TCP
packets. This is not the case. SIFTR
uses TCP packet
events (inbound and outbound) for each TCP flow originating from the system
to trigger a dump of the state of the TCP control block for that flow. With
the PPL set to 1, we are in effect sampling each TCP flow's control block
state as frequently as flow packets enter/leave the system. For example,
setting PPL to 2 halves the sampling rate i.e., every second flow packet
(inbound OR outbound) causes a dump of the control block state.
The distinction between interrogating individual packets versus
interrogating the control block is important, because
SIFTR
does not remove the need for packet capturing
tools like tcpdump(1). SIFTR
allows you to correlate and observe the cause-and-affect relationship
between what you see on the wire (captured using a tool like
tcpdump(1)) and changes in the TCP control block
corresponding to the flow of interest. It is therefore useful to use
SIFTR
and a tool like tcpdump(1)
to gather the necessary data to piece together the complete picture. Use of
either tool on its own will not be able to provide all of the necessary
data.
As a result of needing to interrogate the TCP control block,
certain packets during the lifecycle of a connection are unable to trigger a
SIFTR
log message. The initial handshake takes place
without the existence of a control block and the final ACK is exchanged when
the connection is in the TIMEWAIT state.
SIFTR
was designed to minimise the delay
introduced to packets traversing the network stack. This design called for a
highly optimised and minimal hook function that extracted the minimal
details necessary whilst holding the packet up, and passing these details to
another thread for actual processing and logging.
This multithreaded design does introduce some contention issues when accessing the data structure shared between the threads of operation. When the hook function tries to place details in the structure, it must first acquire an exclusive lock. Likewise, when the processing thread tries to read details from the structure, it must also acquire an exclusive lock to do so. If one thread holds the lock, the other must wait before it can obtain it. This does introduce some additional bounded delay into the kernel's packet processing code path.
In some cases (e.g., low memory, connection termination), TCP
packets that enter the SIFTR
pfil(9) hook function will not trigger a log message to be
generated. SIFTR
refers to this outcome as a
"skipped packet". Note that SIFTR
always
ensures that packets are allowed to continue through the stack, even if they
could not successfully trigger a data log message.
SIFTR
will therefore not introduce any packet loss
for TCP/IP packets traversing the network stack.
The behaviour of a log file path change whilst the module is enabled is as follows:
During the time between the flush of pending log messages to the old file and commencing logging to the new file, new log messages will still be generated and buffered. As soon as the new file path is ready for writing, the accumulated log messages will be written out to the file.
To enable the module's operations, run the following command as root: sysctl net.inet.siftr.enabled=1
To change the granularity of log messages such that 1 log message is generated for every 10 TCP packets per connection, run the following command as root: sysctl net.inet.siftr.ppl=10
To change the log file location to /tmp/siftr.log, run the following command as root: sysctl net.inet.siftr.logfile=/tmp/siftr.log
Development of this software was made possible in part by grants from the Cisco University Research Program Fund at Community Foundation Silicon Valley, and the FreeBSD Foundation.
SIFTR
first appeared in
FreeBSD 7.4 and FreeBSD
8.2.
SIFTR
was first released in 2007 by
Lawrence Stewart and James Healy whilst working on the NewTCP research
project at Swinburne University of Technology's Centre for Advanced Internet
Architectures, Melbourne, Australia, which was made possible in part by a
grant from the Cisco University Research Program Fund at Community
Foundation Silicon Valley. More details are available at:
http://caia.swin.edu.au/urp/newtcp/
Work on SIFTR
v1.2.x was sponsored by the
FreeBSD Foundation as part of the "Enhancing the FreeBSD TCP
Implementation" project 2008-2009. More details are available at:
http://www.freebsdfoundation.org/
http://caia.swin.edu.au/freebsd/etcp09/
SIFTR
was written by
Lawrence Stewart
<lstewart@FreeBSD.org>
and James Healy
<jimmy@deefa.com>.
This manual page was written by Lawrence Stewart <lstewart@FreeBSD.org>.
Current known limitations and any relevant workarounds are outlined below:
SIFTR
to cope with bursty network traffic, but
sustained high packet-per-second traffic can cause exhaustion of kernel
memory if the processing thread cannot keep up with the packet rate.SIFTR
on a machine that is also running
other modules utilising the pfil(9) framework e.g.
dummynet(4), ipfw(8),
pf(4), the order in which you load the modules is
important. You should kldload the other modules first, as this will ensure
TCP packets undergo any necessary manipulations before
SIFTR
"sees" and processes them.SIFTR
is enabled
in a kernel compiled with witness(4) support.SIFTR
is deleted whilst the module is set to use
the file. Switching to a new log file using the
net.inet.siftr.logfile variable will create the new file
and allow log messages to begin being written to disk again. The new log
file path must differ from the path to the deleted file.SIFTR
.SIFTR
's use of IP layer hook
points means all IP traffic will be processed by the
SIFTR
pfil(9) hook function,
which introduces minor, but nonetheless unnecessary packet delay and
processing overhead on the system for non-TCP packets as well. Hooking in
at the IP layer is also not ideal from the data gathering point of view.
Packets traversing up the stack will be intercepted and cause a log
message generation BEFORE they have been processed by the TCP layer, which
means we cannot observe the cause-and-affect relationship between inbound
events and the corresponding TCP control block as precisely as could be.
Ideally, SIFTR
should intercept packets after they
have been processed by the TCP layer i.e. intercept packets coming up the
stack after they have been processed by tcp_input(), and intercept packets
coming down the stack after they have been processed by tcp_output(). The
current code still gives satisfactory granularity though, as inbound
events tend to trigger outbound events, allowing the cause-and-effect to
be observed indirectly by capturing the state on outbound events as
well.SIFTR
does not take into account bytes that have
been SACK'ed by the receiving host.March 18, 2015 | Debian |