logo
Free, unlimited AI code reviews that run on commit
git-lrc git-lrc GitHub Install Now We'd appreciate a star git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt

pedit - generic packet editor action

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.

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

Name

       pedit - generic packet editor action

Options

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

       offsetOFFSET { 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).

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

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

              srcdst    Source or destination MAC address in the standard format: XX:XX:XX:XX:XX:XX

              type   Ether-type in numeric value

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

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

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

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

       ipBEYOND_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:

              dportsport  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_typeicmp_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.

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

              ttlip6IP6HDR_FIELD
              The supported keywords for IP6HDR_FIELD are:

              srcdsttraffic_classflow_lblpayload_lennexthdrhoplimittcpTCPHDR_FIELD
              The supported keywords for TCPHDR_FIELD are:

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

              flagsudpUDPHDR_FIELD
              The supported keywords for UDPHDR_FIELD are:

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

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

       addVAL
              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 ipttl and ip6hoplimit.

       preserve
              Keep the addressed data as is.

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

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

See Also

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

iproute2                                           12 Jan 2015             Genericpacketeditoractionintc(8)

Synopsis

tc ... actionpedit[ex]munge { RAW_OP | LAYERED_OP | EXTENDED_LAYERED_OP } [ CONTROL ]

       RAW_OP := offsetOFFSET { u8 | u16 | u32 } [ AT_SPEC ] CMD_SPECAT_SPEC := atAToffmaskMASKshiftSHIFTLAYERED_OP := { ipIPHDR_FIELD | ipBEYOND_IPHDR_FIELD } CMD_SPECEXTENDED_LAYERED_OP  :=  { ethETHHDR_FIELD | ipIPHDR_FIELD | ipEX_IPHDR_FIELD | ip6IP6HDR_FIELD | tcpTCPHDR_FIELD | udpUDPHDR_FIELD } CMD_SPECETHHDR_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 | setVAL | addVAL | decrement | preserve } [ retainRVAL ]

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

See Also