mirror of
				https://git.proxmox.com/git/mirror_iproute2
				synced 2025-10-31 12:00:02 +00:00 
			
		
		
		
	 1672f42195
			
		
	
	
		1672f42195
		
	
	
	
	
		
			
			As Jamal suggested, BRANCH is the wrong name, as these keywords go beyond simple branch control - e.g. loops are possible, too. Therefore rename the non-terminal to CONTROL instead which should be more appropriate. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
		
			
				
	
	
		
			231 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
			
		
		
	
	
			231 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
| .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 " } [ " CONTROL " ]"
 | |
| 
 | |
| .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 CONTROL " := {"
 | |
| .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 CONTROL
 | |
| 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)
 |