man: Add a man page for the pedit action
Signed-off-by: Phil Sutter <phil@nwl.cc>
This commit is contained in:
parent
ec0bab1e02
commit
448800026f
|
|
@ -0,0 +1,230 @@
|
|||
.TH "Generic packet editor action in tc" 8 "12 Jan 2015" "iproute2" "Linux"
|
||||
|
||||
.SH NAME
|
||||
pedit - generic packet editor action
|
||||
.SH SYNOPSIS
|
||||
.in +8
|
||||
.ti -8
|
||||
.BR tc " ... " "action pedit munge " {
|
||||
.IR RAW_OP " | " LAYERED_OP " } [ " BRANCH " ]"
|
||||
|
||||
.ti -8
|
||||
.IR RAW_OP " := "
|
||||
.BI offset " OFFSET"
|
||||
.RB "{ " u8 " | " u16 " | " u32 " } ["
|
||||
.IR AT_SPEC " ] " CMD_SPEC
|
||||
|
||||
.ti -8
|
||||
.IR AT_SPEC " := "
|
||||
.BI at " AT " offmask " MASK " shift " SHIFT"
|
||||
|
||||
.ti -8
|
||||
.IR LAYERED_OP " := { "
|
||||
.BI ip " IPHDR_FIELD"
|
||||
|
|
||||
.BI ip6 " IP6HDR_FIELD"
|
||||
|
|
||||
.BI udp " UDPHDR_FIELD"
|
||||
|
|
||||
.BI tcp " TCPHDR_FIELD"
|
||||
|
|
||||
.BI icmp " ICMPHDR_FIELD"
|
||||
.RI } " CMD_SPEC"
|
||||
|
||||
.ti -8
|
||||
.IR IPHDR_FIELD " := { "
|
||||
.BR src " | " dst " | " tos " | " dsfield " | " ihl " | " protocol " |"
|
||||
.BR precedence " | " nofrag " | " firstfrag " | " ce " | " df " |"
|
||||
.BR mf " | " dport " | " sport " | " icmp_type " | " icmp_code " }"
|
||||
|
||||
.ti -8
|
||||
.IR CMD_SPEC " := {"
|
||||
.BR clear " | " invert " | " set
|
||||
.IR VAL " | "
|
||||
.BR preserve " } [ " retain
|
||||
.IR RVAL " ]"
|
||||
|
||||
.ti -8
|
||||
.IR BRANCH " := {"
|
||||
.BR reclassify " | " pipe " | " drop " | " shot " | " continue " | " pass " }"
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B pedit
|
||||
action can be used to change arbitrary packet data. The location of data to
|
||||
change can either be specified by giving an offset and size as in
|
||||
.IR RAW_OP ,
|
||||
or for header values by naming the header and field to edit the size is then
|
||||
chosen automatically based on the header field size. Currently this is supported
|
||||
only for IPv4 headers.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI offset " OFFSET " "\fR{ \fBu32 \fR| \fBu16 \fR| \fBu8 \fR}"
|
||||
Specify the offset at which to change data.
|
||||
.I OFFSET
|
||||
is a signed integer, it's base is automatically chosen (e.g. hex if prefixed by
|
||||
.B 0x
|
||||
or octal if prefixed by
|
||||
.BR 0 ).
|
||||
The second argument specifies the length of data to change, that is four bytes
|
||||
.RB ( u32 ),
|
||||
two bytes
|
||||
.RB ( u16 )
|
||||
or a single byte
|
||||
.RB ( u8 ).
|
||||
.TP
|
||||
.BI at " AT " offmask " MASK " shift " SHIFT"
|
||||
This is an optional part of
|
||||
.IR RAW_OP
|
||||
which allows to have a variable
|
||||
.I OFFSET
|
||||
depending on packet data at offset
|
||||
.IR AT ,
|
||||
which is binary ANDed with
|
||||
.I MASK
|
||||
and right-shifted by
|
||||
.I SHIFT
|
||||
before adding it to
|
||||
.IR OFFSET .
|
||||
.TP
|
||||
.BI ip " IPHDR_FIELD"
|
||||
Change an IPv4 header field. The supported keywords for
|
||||
.I IPHDR_FIELD
|
||||
are:
|
||||
.RS
|
||||
.TP
|
||||
.B src
|
||||
.TQ
|
||||
.B dst
|
||||
Source or destination IP address, a four-byte value.
|
||||
.TP
|
||||
.B tos
|
||||
.TQ
|
||||
.B dsfield
|
||||
.TQ
|
||||
.B precedence
|
||||
Type Of Service field, an eight-bit value.
|
||||
.TP
|
||||
.B ihl
|
||||
Change the IP Header Length field, a four-bit value.
|
||||
.TP
|
||||
.B protocol
|
||||
Next-layer Protocol field, an eight-bit value.
|
||||
.TP
|
||||
.B nofrag
|
||||
.TQ
|
||||
.B firstfrag
|
||||
.TQ
|
||||
.B ce
|
||||
.TQ
|
||||
.B df
|
||||
.TQ
|
||||
.B mf
|
||||
Change IP header flags. Note that the value to pass to the
|
||||
.B set
|
||||
command is not just a bit value, but the full byte including the flags field.
|
||||
Though only the relevant bits of that value are respected, the rest ignored.
|
||||
.TP
|
||||
.B dport
|
||||
.TQ
|
||||
.B sport
|
||||
Destination or source port numbers, a 16-bit value. Indeed, IPv4 headers don't
|
||||
contain this information. Instead, this will set an offset which suits at least
|
||||
TCP and UDP if the IP header is of minimum size (20 bytes). If not, this will do
|
||||
unexpected things.
|
||||
.TP
|
||||
.B icmp_type
|
||||
.TQ
|
||||
.B icmp_code
|
||||
Again, this allows to change data past the actual IP header itself. It assumes
|
||||
an ICMP header is present immediately following the (minimal sized) IP header.
|
||||
If it is not or the latter is bigger than the minimum of 20 bytes, this will do
|
||||
unexpected things. These fields are eight-bit values.
|
||||
.RE
|
||||
.TP
|
||||
.B clear
|
||||
Clear the addressed data (i.e., set it to zero).
|
||||
.TP
|
||||
.B invert
|
||||
Swap every bit in the addressed data.
|
||||
.TP
|
||||
.BI set " VAL"
|
||||
Set the addressed data to a specific value. The size of
|
||||
.I VAL
|
||||
is defined by either one of the
|
||||
.BR u32 ", " u16 " or " u8
|
||||
keywords in
|
||||
.IR RAW_OP ,
|
||||
or the size of the addressed header field in
|
||||
.IR LAYERED_OP .
|
||||
.TP
|
||||
.B preserve
|
||||
Keep the addressed data as is.
|
||||
.TP
|
||||
.BI retain " RVAL"
|
||||
This optional extra part of
|
||||
.I CMD_SPEC
|
||||
allows to exclude bits from being changed.
|
||||
.TP
|
||||
.I BRANCH
|
||||
The following keywords allow to control how the tree of qdisc, classes,
|
||||
filters and actions is further traversed after this action.
|
||||
.RS
|
||||
.TP
|
||||
.B reclassify
|
||||
Restart with the first filter in the current list.
|
||||
.TP
|
||||
.B pipe
|
||||
Continue with the next action attached to the same filter.
|
||||
.TP
|
||||
.B drop
|
||||
.TQ
|
||||
.B shot
|
||||
Drop the packet.
|
||||
.TP
|
||||
.B continue
|
||||
Continue classification with the next filter in line.
|
||||
.TP
|
||||
.B pass
|
||||
Finish classification process and return to calling qdisc for further packet
|
||||
processing. This is the default.
|
||||
.RE
|
||||
.SH EXAMPLES
|
||||
Being able to edit packet data, one could do all kinds of things, such as e.g.
|
||||
implementing port redirection. Certainly not the most useful application, but
|
||||
as an example it should do:
|
||||
|
||||
First, qdiscs need to be set up to attach filters to. For the receive path, a simple
|
||||
.B ingress
|
||||
qdisc will do, for transmit path a classful qdisc
|
||||
.RB ( HTB
|
||||
in this case) is necessary:
|
||||
|
||||
.RS
|
||||
.EX
|
||||
tc qdisc replace dev eth0 root handle 1: htb
|
||||
tc qdisc add dev eth0 ingress handle ffff:
|
||||
.EE
|
||||
.RE
|
||||
|
||||
Finally, a filter with
|
||||
.B pedit
|
||||
action can be added for each direction. In this case,
|
||||
.B u32
|
||||
is used matching on the port number to redirect from, while
|
||||
.B pedit
|
||||
then does the actual rewriting:
|
||||
|
||||
.RS
|
||||
.EX
|
||||
tc filter add dev eth0 parent 1: u32 \\
|
||||
match ip dport 23 0xffff \\
|
||||
action pedit pedit munge ip dport set 22
|
||||
tc filter add dev eth0 parent ffff: u32 \\
|
||||
match ip sport 22 0xffff \\
|
||||
action pedit pedit munge ip sport set 23
|
||||
.EE
|
||||
.RE
|
||||
.SH SEE ALSO
|
||||
.BR tc (8),
|
||||
.BR tc-htb (8),
|
||||
.BR tc-u32 (8)
|
||||
Loading…
Reference in New Issue