1Generic packet editor action in tc(8)LinuxGeneric packet editor action in tc(8)
2
3
4
6 pedit - generic packet editor action
7
9 tc ... action pedit [ex] munge { RAW_OP | LAYERED_OP | EXTENDED_LAY‐
10 ERED_OP } [ CONTROL ]
11
12 RAW_OP := offset OFFSET { u8 | u16 | u32 } [ AT_SPEC ] CMD_SPEC
13
14 AT_SPEC := at AT offmask MASK shift SHIFT
15
16 LAYERED_OP := { ip IPHDR_FIELD | ip BEYOND_IPHDR_FIELD } CMD_SPEC
17
18 EXTENDED_LAYERED_OP := { eth ETHHDR_FIELD | ip IPHDR_FIELD | ip
19 EX_IPHDR_FIELD | ip6 IP6HDR_FIELD | tcp TCPHDR_FIELD | udp
20 UDPHDR_FIELD } CMD_SPEC
21
22 ETHHDR_FIELD := { src | dst | type }
23
24 IPHDR_FIELD := { src | dst | tos | dsfield | ihl | protocol | prece‐
25 dence | nofrag | firstfrag | ce | df }
26
27 BEYOND_IPHDR_FIELD := { dport | sport | icmp_type | icmp_code }
28
29 EX_IPHDR_FIELD := { ttl }
30
31
32 IP6HDR_FIELD := { src | dst | flow_lbl | payload_len | nexthdr |
33 hoplimit }
34
35 TCPHDR_FIELD := { sport | dport | flags }
36
37 UDPHDR_FIELD := { sport | dport }
38
39 CMD_SPEC := { clear | invert | set VAL | add VAL | preserve } [ retain
40 RVAL ]
41
42 CONTROL := { reclassify | pipe | drop | shot | continue | pass | goto
43 chain CHAIN_INDEX }
44
46 The pedit action can be used to change arbitrary packet data. The loca‐
47 tion of data to change can either be specified by giving an offset and
48 size as in RAW_OP, or for header values by naming the header and field
49 to edit the size is then chosen automatically based on the header field
50 size. Currently this is supported only for IPv4 headers.
51
53 ex Use extended pedit. EXTENDED_LAYERED_OP and the add CMD_SPEC
54 are allowed only in this mode.
55
56 offset OFFSET { u32 | u16 | u8 }
57 Specify the offset at which to change data. OFFSET is a signed
58 integer, it's base is automatically chosen (e.g. hex if prefixed
59 by 0x or octal if prefixed by 0). The second argument specifies
60 the length of data to change, that is four bytes (u32), two
61 bytes (u16) or a single byte (u8).
62
63 at AT offmask MASK shift SHIFT
64 This is an optional part of RAW_OP which allows to have a vari‐
65 able OFFSET depending on packet data at offset AT, which is
66 binary ANDed with MASK and right-shifted by SHIFT before adding
67 it to OFFSET.
68
69 eth ETHHDR_FIELD
70 Change an ETH header field. The supported keywords for ETH‐
71 HDR_FIELD are:
72
73 src
74 dst Source or destination MAC address in the standard format:
75 XX:XX:XX:XX:XX:XX
76
77 type Ether-type in numeric value
78
79 ip IPHDR_FIELD
80 Change an IPv4 header field. The supported keywords for
81 IPHDR_FIELD are:
82
83 src
84 dst Source or destination IP address, a four-byte value.
85
86 tos
87 dsfield
88 precedence
89 Type Of Service field, an eight-bit value.
90
91 ihl Change the IP Header Length field, a four-bit value.
92
93 protocol
94 Next-layer Protocol field, an eight-bit value.
95
96 nofrag
97 firstfrag
98 ce
99 df
100 mf Change IP header flags. Note that the value to pass to
101 the set command is not just a bit value, but the full
102 byte including the flags field. Though only the relevant
103 bits of that value are respected, the rest ignored.
104
105 ip BEYOND_IPHDR_FIELD
106 Supported only for non-extended layered op. It is passed to the
107 kernel as offsets relative to the beginning of the IP header and
108 assumes the IP header is of minimum size (20 bytes). The sup‐
109 ported keywords for BEYOND_IPHDR_FIELD are:
110
111 dport
112 sport Destination or source port numbers, a 16-bit value.
113 Indeed, IPv4 headers don't contain this information.
114 Instead, this will set an offset which suits at least TCP
115 and UDP if the IP header is of minimum size (20 bytes).
116 If not, this will do unexpected things.
117
118 icmp_type
119 icmp_code
120 Again, this allows to change data past the actual IP
121 header itself. It assumes an ICMP header is present imme‐
122 diately following the (minimal sized) IP header. If it
123 is not or the latter is bigger than the minimum of 20
124 bytes, this will do unexpected things. These fields are
125 eight-bit values.
126
127 ip EX_IPHDR_FIELD
128 Supported only when ex is used. The supported keywords for
129 EX_IPHDR_FIELD are:
130
131 ttl
132
133 ip6 IP6HDR_FIELD
134 The supported keywords for IP6HDR_FIELD are:
135
136 src
137 dst
138 flow_lbl
139 payload_len
140 nexthdr
141 hoplimit
142
143 tcp TCPHDR_FIELD
144 The supported keywords for TCPHDR_FIELD are:
145
146 sport
147 dport Source or destination TCP port number, a 16-bit value.
148
149 flags
150
151 udp UDPHDR_FIELD
152 The supported keywords for UDPHDR_FIELD are:
153
154 sport
155 dport Source or destination TCP port number, a 16-bit value.
156
157 clear Clear the addressed data (i.e., set it to zero).
158
159 invert Swap every bit in the addressed data.
160
161 set VAL
162 Set the addressed data to a specific value. The size of VAL is
163 defined by either one of the u32, u16 or u8 keywords in RAW_OP,
164 or the size of the addressed header field in LAYERED_OP.
165
166 add VAL
167 Add the addressed data by a specific value. The size of VAL is
168 defined by the size of the addressed header field in
169 EXTENDED_LAYERED_OP. This operation is supported only for
170 extended layered op.
171
172 preserve
173 Keep the addressed data as is.
174
175 retain RVAL
176 This optional extra part of CMD_SPEC allows to exclude bits from
177 being changed. Supported only for 32 bits fields or smaller.
178
179 CONTROL
180 The following keywords allow to control how the tree of qdisc,
181 classes, filters and actions is further traversed after this
182 action.
183
184 reclassify
185 Restart with the first filter in the current list.
186
187 pipe Continue with the next action attached to the same fil‐
188 ter.
189
190 drop
191 shot Drop the packet.
192
193 continue
194 Continue classification with the next filter in line.
195
196 pass Finish classification process and return to calling qdisc
197 for further packet processing. This is the default.
198
200 Being able to edit packet data, one could do all kinds of things, such
201 as e.g. implementing port redirection. Certainly not the most useful
202 application, but as an example it should do:
203
204 First, qdiscs need to be set up to attach filters to. For the receive
205 path, a simple ingress qdisc will do, for transmit path a classful
206 qdisc (HTB in this case) is necessary:
207
208 tc qdisc replace dev eth0 root handle 1: htb
209 tc qdisc add dev eth0 ingress handle ffff:
210
211 Finally, a filter with pedit action can be added for each direction. In
212 this case, u32 is used matching on the port number to redirect from,
213 while pedit then does the actual rewriting:
214
215 tc filter add dev eth0 parent 1: u32 \
216 match ip dport 23 0xffff \
217 action pedit pedit munge ip dport set 22
218 tc filter add dev eth0 parent ffff: u32 \
219 match ip sport 22 0xffff \
220 action pedit pedit munge ip sport set 23
221 tc filter add dev eth0 parent ffff: u32 \
222 match ip sport 22 0xffff \
223 action pedit ex munge ip dst set 192.168.1.199
224 tc filter add dev eth0 parent ffff: u32 \
225 match ip sport 22 0xffff \
226 action pedit ex munge ip6 dst set fe80::dacb:8aff:fec7:320e
227 tc filter add dev eth0 parent ffff: u32 \
228 match ip sport 22 0xffff \
229 action pedit ex munge eth dst set 11:22:33:44:55:66
230 tc filter add dev eth0 parent ffff: u32 \
231 match ip dport 23 0xffff \
232 action pedit ex munge tcp dport set 22
233
235 tc(8), tc-htb(8), tc-u32(8)
236
237
238
239iproute2 12 Jan 2G0e1n5eric packet editor action in tc(8)