Back to main site | Back to man page index

Generic packet editor action in tc(8)                   Linux                   Generic packet editor action in tc(8)



NAME
       pedit - generic packet editor action

SYNOPSIS
       tc ... action pedit munge { RAW_OP | LAYERED_OP } [ CONTROL ]

       RAW_OP := offset OFFSET { u8 | u16 | u32 } [ AT_SPEC ] CMD_SPEC

       AT_SPEC := at AT offmask MASK shift SHIFT

       LAYERED_OP := { ip IPHDR_FIELD | ip6 IP6HDR_FIELD | udp UDPHDR_FIELD | tcp TCPHDR_FIELD | icmp ICMPHDR_FIELD }
               CMD_SPEC

       IPHDR_FIELD := { src | dst | tos | dsfield | ihl | protocol | precedence | nofrag | firstfrag | ce | df | mf |
               dport | sport | icmp_type | icmp_code }

       CMD_SPEC := { clear | invert | set VAL | preserve } [ retain RVAL ]

       CONTROL := { reclassify | pipe | drop | shot | continue | pass }

DESCRIPTION
       The  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 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.

OPTIONS
       offset OFFSET { u32 | u16 | u8 }
              Specify the offset at which to change data.  OFFSET is a signed integer,  it's  base  is  automatically
              chosen  (e.g.  hex  if  prefixed  by  0x or octal if prefixed by 0).  The second argument specifies the
              length of data to change, that is four bytes (u32), two bytes (u16) or a single byte (u8).

       at AT offmask MASK shift SHIFT
              This is an optional part of RAW_OP which allows to have a variable OFFSET depending on packet  data  at
              offset AT, which is binary ANDed with MASK and right-shifted by SHIFT before adding it to OFFSET.

       ip IPHDR_FIELD
              Change an IPv4 header field. The supported keywords for IPHDR_FIELD are:

              src
              dst    Source or destination IP address, a four-byte value.

              tos
              dsfield
              precedence
                     Type Of Service field, an eight-bit value.

              ihl    Change the IP Header Length field, a four-bit value.

              protocol
                     Next-layer Protocol field, an eight-bit value.

              nofrag
              firstfrag
              ce
              df

                     present immediately following the (minimal sized) IP header.  If it is not or the latter is big‐
                     ger  than  the  minimum  of 20 bytes, this will do unexpected things. These fields are eight-bit
                     values.

       clear  Clear the addressed data (i.e., set it to zero).

       invert Swap every bit in the addressed data.

       set VAL
              Set the addressed data to a specific value. The size of VAL is defined by either one of the u32, u16 or
              u8 keywords in RAW_OP, or the size of the addressed header field in LAYERED_OP.

       preserve
              Keep the addressed data as is.

       retain RVAL
              This optional extra part of CMD_SPEC allows to exclude bits from being changed.

       CONTROL
              The  following keywords allow to control how the tree of qdisc, classes, filters and actions is further
              traversed after this action.

              reclassify
                     Restart with the first filter in the current list.

              pipe   Continue with the next action attached to the same filter.

              drop
              shot   Drop the packet.

              continue
                     Continue classification with the next filter in line.

              pass   Finish classification process and return to calling qdisc for further packet processing. This is
                     the default.

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 ingress  qdisc  will  do,
       for transmit path a classful qdisc (HTB in this case) is necessary:

              tc qdisc replace dev eth0 root handle 1: htb
              tc qdisc add dev eth0 ingress handle ffff:

       Finally, a filter with pedit action can be added for each direction. In this case, u32 is used matching on the
       port number to redirect from, while pedit then does the actual rewriting:

              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 \