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 UD‐
20 PHDR_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 | traffic_class | flow_lbl | payload_len |
33 nexthdr | hoplimit }
34
35 TCPHDR_FIELD := { sport | dport | flags }
36
37 UDPHDR_FIELD := { sport | dport }
38
39 CMD_SPEC := { clear | invert | set VAL | add VAL | decrement | preserve
40 } [ retain 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.
51
53 ex Use extended pedit. EXTENDED_LAYERED_OP and the add/decrement
54 CMD_SPEC 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 one to have a
65 variable 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. In‐
113 deed, IPv4 headers don't contain this information. In‐
114 stead, 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 one 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 traffic_class
139 flow_lbl
140 payload_len
141 nexthdr
142 hoplimit
143
144 tcp TCPHDR_FIELD
145 The supported keywords for TCPHDR_FIELD are:
146
147 sport
148 dport Source or destination TCP port number, a 16-bit value.
149
150 flags
151
152 udp UDPHDR_FIELD
153 The supported keywords for UDPHDR_FIELD are:
154
155 sport
156 dport Source or destination TCP port number, a 16-bit value.
157
158 clear Clear the addressed data (i.e., set it to zero).
159
160 invert Swap every bit in the addressed data.
161
162 set VAL
163 Set the addressed data to a specific value. The size of VAL is
164 defined by either one of the u32, u16 or u8 keywords in RAW_OP,
165 or the size of the addressed header field in LAYERED_OP.
166
167 add VAL
168 Add the addressed data by a specific value. The size of VAL is
169 defined by the size of the addressed header field in EX‐
170 TENDED_LAYERED_OP. This operation is supported only for ex‐
171 tended layered op.
172
173 decrement
174 Decrease the addressed data by one. This operation is supported
175 only for ip ttl and ip6 hoplimit.
176
177 preserve
178 Keep the addressed data as is.
179
180 retain RVAL
181 This optional extra part of CMD_SPEC allows one to exclude bits
182 from being changed. Supported only for 32 bits fields or
183 smaller.
184
185 CONTROL
186 The following keywords allow one to control how the tree of
187 qdisc, classes, filters and actions is further traversed after
188 this action.
189
190 reclassify
191 Restart with the first filter in the current list.
192
193 pipe Continue with the next action attached to the same fil‐
194 ter.
195
196 drop
197 shot Drop the packet.
198
199 continue
200 Continue classification with the next filter in line.
201
202 pass Finish classification process and return to calling qdisc
203 for further packet processing. This is the default.
204
206 Being able to edit packet data, one could do all kinds of things, such
207 as e.g. implementing port redirection. Certainly not the most useful
208 application, but as an example it should do:
209
210 First, qdiscs need to be set up to attach filters to. For the receive
211 path, a simple ingress qdisc will do, for transmit path a classful
212 qdisc (HTB in this case) is necessary:
213
214 tc qdisc replace dev eth0 root handle 1: htb
215 tc qdisc add dev eth0 ingress handle ffff:
216
217 Finally, a filter with pedit action can be added for each direction. In
218 this case, u32 is used matching on the port number to redirect from,
219 while pedit then does the actual rewriting:
220
221 tc filter add dev eth0 parent 1: u32 \
222 match ip dport 23 0xffff \
223 action pedit pedit munge ip dport set 22
224 tc filter add dev eth0 parent ffff: u32 \
225 match ip sport 22 0xffff \
226 action pedit pedit munge ip sport set 23
227 tc filter add dev eth0 parent ffff: u32 \
228 match ip sport 22 0xffff \
229 action pedit ex munge ip dst set 192.168.1.199
230 tc filter add dev eth0 parent ffff: u32 \
231 match ip sport 22 0xffff \
232 action pedit ex munge ip6 dst set fe80::dacb:8aff:fec7:320e
233 tc filter add dev eth0 parent ffff: u32 \
234 match ip sport 22 0xffff \
235 action pedit ex munge eth dst set 11:22:33:44:55:66
236 tc filter add dev eth0 parent ffff: u32 \
237 match ip dport 23 0xffff \
238 action pedit ex munge tcp dport set 22
239
240 To rewrite just part of a field, use the retain directive. E.g. to
241 overwrite the DSCP part of a dsfield with $DSCP, without touching ECN:
242
243 tc filter add dev eth0 ingress flower ... \
244 action pedit ex munge ip dsfield set $((DSCP << 2)) retain 0xfc
245
246 And vice versa, to set ECN to e.g. 1 without impacting DSCP:
247
248 tc filter add dev eth0 ingress flower ... \
249 action pedit ex munge ip dsfield set 1 retain 0x3
250
251
253 tc(8), tc-htb(8), tc-u32(8)
254
255
256
257iproute2 12 Jan 2G0e1n5eric packet editor action in tc(8)