Provided by: iproute2_6.1.0-1ubuntu2_amd64 bug

NAME

       pedit - generic packet editor action

SYNOPSIS

       tc ... action pedit [ex] munge { RAW_OP | LAYERED_OP | EXTENDED_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 | ip BEYOND_IPHDR_FIELD } CMD_SPEC

       EXTENDED_LAYERED_OP  :=  {  eth  ETHHDR_FIELD  |  ip IPHDR_FIELD | ip EX_IPHDR_FIELD | ip6
               IP6HDR_FIELD | tcp TCPHDR_FIELD | udp UDPHDR_FIELD } CMD_SPEC

       ETHHDR_FIELD := { src | dst | type }

       IPHDR_FIELD := { src | dst | tos | dsfield | ihl  |  protocol  |  precedence  |  nofrag  |
               firstfrag | ce | df }

       BEYOND_IPHDR_FIELD := { dport | sport | icmp_type | icmp_code }

       EX_IPHDR_FIELD := { ttl }

       IP6HDR_FIELD  := { src | dst | traffic_class | flow_lbl | payload_len | nexthdr | hoplimit
               }

       TCPHDR_FIELD := { sport | dport | flags }

       UDPHDR_FIELD := { sport | dport }

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

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

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.

OPTIONS

       ex     Use extended pedit.  EXTENDED_LAYERED_OP and the add/decrement CMD_SPEC are allowed
              only in this mode.

       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 one 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.

       eth ETHHDR_FIELD
              Change an ETH header field. The supported keywords for ETHHDR_FIELD are:

              src
              dst    Source or destination MAC address in the standard format: XX:XX:XX:XX:XX:XX

              type   Ether-type in numeric value

       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
              mf     Change  IP  header  flags. Note that the value to pass to the 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.

       ip BEYOND_IPHDR_FIELD
              Supported  only  for non-extended layered op. It is passed to the kernel as offsets
              relative to the beginning of the IP header and assumes the IP header is of  minimum
              size (20 bytes). The supported keywords for BEYOND_IPHDR_FIELD are:

              dport
              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.

              icmp_type
              icmp_code
                     Again, this allows one 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.

       ip EX_IPHDR_FIELD
              Supported only when ex is used. The supported keywords for EX_IPHDR_FIELD are:

              ttl

       ip6 IP6HDR_FIELD
              The supported keywords for IP6HDR_FIELD are:

              src
              dst
              traffic_class
              flow_lbl
              payload_len
              nexthdr
              hoplimit

       tcp TCPHDR_FIELD
              The supported keywords for TCPHDR_FIELD are:

              sport
              dport  Source or destination TCP port number, a 16-bit value.

              flags

       udp UDPHDR_FIELD
              The supported keywords for UDPHDR_FIELD are:

              sport
              dport  Source or destination TCP port number, a 16-bit value.

       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.

       add VAL
              Add  the addressed data by a specific value. The size of VAL is defined by the size
              of the addressed header field in EXTENDED_LAYERED_OP.  This operation is  supported
              only for extended layered op.

       decrement
              Decrease  the  addressed  data by one.  This operation is supported only for ip ttl
              and ip6 hoplimit.

       preserve
              Keep the addressed data as is.

       retain RVAL
              This optional extra part of CMD_SPEC allows one to exclude bits from being changed.
              Supported only for 32 bits fields or smaller.

       CONTROL
              The following keywords allow one 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 \
                   action pedit pedit munge ip sport set 23
              tc filter add dev eth0 parent ffff: u32 \
                   match ip sport 22 0xffff \
                   action pedit ex munge ip dst set 192.168.1.199
              tc filter add dev eth0 parent ffff: u32 \
                   match ip sport 22 0xffff \
                   action pedit ex munge ip6 dst set fe80::dacb:8aff:fec7:320e
              tc filter add dev eth0 parent ffff: u32 \
                   match ip sport 22 0xffff \
                   action pedit ex munge eth dst set 11:22:33:44:55:66
              tc filter add dev eth0 parent ffff: u32 \
                   match ip dport 23 0xffff \
                   action pedit ex munge tcp dport set 22

       To rewrite just part of a field, use the retain directive. E.g. to overwrite the DSCP part
       of a dsfield with $DSCP, without touching ECN:

              tc filter add dev eth0 ingress flower ... \
                   action pedit ex munge ip dsfield set $((DSCP << 2)) retain 0xfc

       And vice versa, to set ECN to e.g. 1 without impacting DSCP:

              tc filter add dev eth0 ingress flower ... \
                   action pedit ex munge ip dsfield set 1 retain 0x3

SEE ALSO

       tc(8), tc-htb(8), tc-u32(8)