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