File: tc-pedit.8

package info (click to toggle)
iproute2 5.10.0-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,880 kB
  • sloc: ansic: 107,211; sh: 1,338; cpp: 932; makefile: 654; yacc: 421; lex: 145
file content (396 lines) | stat: -rw-r--r-- 8,506 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
.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 [ex] munge " {
.IR RAW_OP " | " LAYERED_OP " | " EXTENDED_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 ip " BEYOND_IPHDR_FIELD"
.RI } " CMD_SPEC"

.ti -8
.IR EXTENDED_LAYERED_OP " := { "
.BI eth " ETHHDR_FIELD"
|
.BI ip " IPHDR_FIELD"
|
.BI ip " EX_IPHDR_FIELD"
|
.BI ip6 " IP6HDR_FIELD"
|
.BI tcp " TCPHDR_FIELD"
|
.BI udp " UDPHDR_FIELD"
.RI } " CMD_SPEC"

.ti -8
.IR ETHHDR_FIELD " := { "
.BR src " | " dst " | " type " }"

.ti -8
.IR IPHDR_FIELD " := { "
.BR src " | " dst " | " tos " | " dsfield " | " ihl " | " protocol " |"
.BR precedence " | " nofrag " | " firstfrag " | " ce " | " df " }"

.ti -8
.IR BEYOND_IPHDR_FIELD " := { "
.BR dport " | " sport " | " icmp_type " | " icmp_code " }"

.ti -8
.IR EX_IPHDR_FIELD " := { "
.BR ttl " }"


.ti -8
.IR IP6HDR_FIELD " := { "
.BR src " | " dst " | " traffic_class " | " flow_lbl " | " payload_len " | "
.BR nexthdr " | " hoplimit " }"

.ti -8
.IR TCPHDR_FIELD " := { "
.BR sport " | " dport " | " flags " }"

.ti -8
.IR UDPHDR_FIELD " := { "
.BR sport " | " dport " }"

.ti -8
.IR CMD_SPEC " := {"
.BR clear " | " invert " | " set
.IR VAL " | "
.BR add
.IR VAL " | "
.BR preserve " } [ " retain
.IR RVAL " ]"

.ti -8
.IR CONTROL " := {"
.BR reclassify " | " pipe " | " drop " | " shot " | " continue " | " pass " | " goto " " chain " " CHAIN_INDEX " }"
.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.
.SH OPTIONS
.TP
.B ex
Use extended pedit.
.I EXTENDED_LAYERED_OP
and the add
.I CMD_SPEC
are allowed only in this mode.
.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 eth " ETHHDR_FIELD"
Change an ETH header field. The supported keywords for
.I ETHHDR_FIELD
are:
.RS
.TP
.B src
.TQ
.B dst
Source or destination MAC address in the standard format: XX:XX:XX:XX:XX:XX
.TP
.B type
Ether-type in numeric value
.RE
.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.
.RE
.TP
.BI 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
.I BEYOND_IPHDR_FIELD
are:
.RS
.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
.BI ip " EX_IPHDR_FIELD"
Supported only when
.I ex
is used. The supported keywords for
.I EX_IPHDR_FIELD
are:
.RS
.TP
.B ttl
.RE
.TP
.BI ip6 " IP6HDR_FIELD"
The supported keywords for
.I IP6HDR_FIELD
are:
.RS
.TP
.B src
.TQ
.B dst
.TQ
.B traffic_class
.TQ
.B flow_lbl
.TQ
.B payload_len
.TQ
.B nexthdr
.TQ
.B hoplimit
.RE
.TP
.BI tcp " TCPHDR_FIELD"
The supported keywords for
.I TCPHDR_FIELD
are:
.RS
.TP
.B sport
.TQ
.B dport
Source or destination TCP port number, a 16-bit value.
.TP
.B flags
.RE
.TP
.BI udp " UDPHDR_FIELD"
The supported keywords for
.I UDPHDR_FIELD
are:
.RS
.TP
.B sport
.TQ
.B dport
Source or destination TCP port number, a 16-bit value.
.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
.BI add " VAL"
Add the addressed data by a specific value. The size of
.I VAL
is defined by the size of the addressed header field in
.IR EXTENDED_LAYERED_OP .
This operation is supported only for extended 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. Supported only for 32 bits fields
or smaller.
.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
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
.EE
.RE

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

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

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

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

.SH SEE ALSO
.BR tc (8),
.BR tc-htb (8),
.BR tc-u32 (8)