]>
Commit | Line | Data |
---|---|---|
c1c5c723 PB |
1 | /* |
2 | * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc. | |
f98e418f | 3 | * Copyright (c) 2016 Mellanox Technologies, Ltd. |
c1c5c723 PB |
4 | * |
5 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | * you may not use this file except in compliance with the License. | |
7 | * You may obtain a copy of the License at: | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, software | |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | * See the License for the specific language governing permissions and | |
15 | * limitations under the License. | |
16 | */ | |
17 | ||
18 | #ifndef TC_H | |
19 | #define TC_H 1 | |
20 | ||
b2befd5b | 21 | #include <sys/types.h> |
de4a611f | 22 | #include <netinet/in.h> /* Must happen before linux/pkt_cls.h - Glibc #20215 */ |
c1c5c723 PB |
23 | #include <linux/pkt_cls.h> |
24 | #include <linux/pkt_sched.h> | |
ef3767f5 JS |
25 | |
26 | #include "netlink-socket.h" | |
f98e418f | 27 | #include "odp-netlink.h" |
c1c5c723 | 28 | #include "openvswitch/ofpbuf.h" |
f9885dc5 | 29 | #include "openvswitch/flow.h" |
202469aa | 30 | #include "openvswitch/tun-metadata.h" |
c1c5c723 | 31 | |
f98e418f RD |
32 | /* For backwards compatability with older kernels */ |
33 | #ifndef TC_H_CLSACT | |
34 | #define TC_H_CLSACT TC_H_INGRESS | |
35 | #endif | |
36 | #ifndef TC_H_MIN_INGRESS | |
37 | #define TC_H_MIN_INGRESS 0xFFF2U | |
38 | #endif | |
95255018 JH |
39 | #ifndef TC_H_MIN_EGRESS |
40 | #define TC_H_MIN_EGRESS 0xFFF3U | |
41 | #endif | |
f98e418f RD |
42 | |
43 | #define TC_INGRESS_PARENT TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_INGRESS) | |
95255018 | 44 | #define TC_EGRESS_PARENT TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_EGRESS) |
f98e418f | 45 | |
691d20cb PB |
46 | #define TC_POLICY_DEFAULT "none" |
47 | ||
e7f6ba22 PJV |
48 | enum tc_flower_reserved_prio { |
49 | TC_RESERVED_PRIORITY_NONE, | |
50 | TC_RESERVED_PRIORITY_POLICE, | |
51 | __TC_RESERVED_PRIORITY_MAX | |
52 | }; | |
53 | #define TC_RESERVED_PRIORITY_MAX (__TC_RESERVED_PRIORITY_MAX -1) | |
54 | ||
95255018 JH |
55 | enum tc_qdisc_hook { |
56 | TC_INGRESS, | |
57 | TC_EGRESS, | |
58 | }; | |
59 | ||
837f5250 RD |
60 | /* Returns tc handle 'major':'minor'. */ |
61 | static inline unsigned int | |
62 | tc_make_handle(unsigned int major, unsigned int minor) | |
63 | { | |
64 | return TC_H_MAKE(major << 16, minor); | |
65 | } | |
66 | ||
67 | /* Returns the major number from 'handle'. */ | |
68 | static inline unsigned int | |
69 | tc_get_major(unsigned int handle) | |
70 | { | |
71 | return TC_H_MAJ(handle) >> 16; | |
72 | } | |
73 | ||
74 | /* Returns the minor number from 'handle'. */ | |
75 | static inline unsigned int | |
76 | tc_get_minor(unsigned int handle) | |
77 | { | |
78 | return TC_H_MIN(handle); | |
79 | } | |
80 | ||
c1c5c723 PB |
81 | struct tcmsg *tc_make_request(int ifindex, int type, |
82 | unsigned int flags, struct ofpbuf *); | |
83 | int tc_transact(struct ofpbuf *request, struct ofpbuf **replyp); | |
95255018 JH |
84 | int tc_add_del_qdisc(int ifindex, bool add, uint32_t block_id, |
85 | enum tc_qdisc_hook hook); | |
c1c5c723 | 86 | |
f98e418f RD |
87 | struct tc_cookie { |
88 | const void *data; | |
89 | size_t len; | |
90 | }; | |
91 | ||
92 | struct tc_flower_key { | |
93 | ovs_be16 eth_type; | |
94 | uint8_t ip_proto; | |
95 | ||
96 | struct eth_addr dst_mac; | |
97 | struct eth_addr src_mac; | |
98 | ||
34b16955 | 99 | ovs_be32 mpls_lse; |
2b1d9fa9 PB |
100 | ovs_be16 tcp_src; |
101 | ovs_be16 tcp_dst; | |
cd081043 | 102 | ovs_be16 tcp_flags; |
2b1d9fa9 PB |
103 | |
104 | ovs_be16 udp_src; | |
105 | ovs_be16 udp_dst; | |
106 | ||
107 | ovs_be16 sctp_src; | |
108 | ovs_be16 sctp_dst; | |
f98e418f | 109 | |
f9885dc5 JL |
110 | uint16_t vlan_id[FLOW_MAX_VLAN_HEADERS]; |
111 | uint8_t vlan_prio[FLOW_MAX_VLAN_HEADERS]; | |
f98e418f | 112 | |
f9885dc5 | 113 | ovs_be16 encap_eth_type[FLOW_MAX_VLAN_HEADERS]; |
f98e418f | 114 | |
83e86606 | 115 | uint8_t flags; |
0b4b5203 | 116 | uint8_t ip_ttl; |
dfa2ccdb | 117 | uint8_t ip_tos; |
0b4b5203 | 118 | |
576126a9 PB |
119 | uint16_t ct_state; |
120 | uint16_t ct_zone; | |
9221c721 PB |
121 | uint32_t ct_mark; |
122 | ovs_u128 ct_label; | |
576126a9 | 123 | |
a3db6e47 TZ |
124 | struct { |
125 | ovs_be32 spa; | |
126 | ovs_be32 tpa; | |
127 | struct eth_addr sha; | |
128 | struct eth_addr tha; | |
129 | uint8_t opcode; | |
130 | } arp; | |
131 | ||
2b1d9fa9 PB |
132 | struct { |
133 | ovs_be32 ipv4_src; | |
134 | ovs_be32 ipv4_dst; | |
8ada482b | 135 | uint8_t rewrite_ttl; |
95431229 | 136 | uint8_t rewrite_tos; |
2b1d9fa9 PB |
137 | } ipv4; |
138 | struct { | |
139 | struct in6_addr ipv6_src; | |
140 | struct in6_addr ipv6_dst; | |
46df7fac | 141 | uint8_t rewrite_hlimit; |
dbcb014d | 142 | uint8_t rewrite_tclass; |
2b1d9fa9 | 143 | } ipv6; |
105e8179 OG |
144 | |
145 | struct { | |
146 | struct { | |
147 | ovs_be32 ipv4_src; | |
148 | ovs_be32 ipv4_dst; | |
149 | } ipv4; | |
150 | struct { | |
151 | struct in6_addr ipv6_src; | |
152 | struct in6_addr ipv6_dst; | |
153 | } ipv6; | |
154 | uint8_t tos; | |
155 | uint8_t ttl; | |
156 | ovs_be16 tp_src; | |
157 | ovs_be16 tp_dst; | |
158 | ovs_be64 id; | |
a468645c | 159 | struct tun_metadata metadata; |
105e8179 | 160 | } tunnel; |
f98e418f RD |
161 | }; |
162 | ||
0c70132c CM |
163 | enum tc_action_type { |
164 | TC_ACT_OUTPUT, | |
165 | TC_ACT_ENCAP, | |
166 | TC_ACT_PEDIT, | |
167 | TC_ACT_VLAN_POP, | |
168 | TC_ACT_VLAN_PUSH, | |
55412eac | 169 | TC_ACT_MPLS_POP, |
283dcf85 | 170 | TC_ACT_MPLS_PUSH, |
a8f005cf | 171 | TC_ACT_MPLS_SET, |
b2ae4069 | 172 | TC_ACT_GOTO, |
576126a9 | 173 | TC_ACT_CT, |
0c70132c CM |
174 | }; |
175 | ||
2bf6ffb7 PB |
176 | enum nat_type { |
177 | TC_NO_NAT = 0, | |
178 | TC_NAT_SRC, | |
179 | TC_NAT_DST, | |
180 | TC_NAT_RESTORE, | |
181 | }; | |
182 | ||
0c70132c CM |
183 | struct tc_action { |
184 | union { | |
b2ae4069 PB |
185 | int chain; |
186 | ||
4aa2dc04 JH |
187 | struct { |
188 | int ifindex_out; | |
189 | bool ingress; | |
190 | } out; | |
0c70132c CM |
191 | |
192 | struct { | |
61e8655c | 193 | ovs_be16 vlan_push_tpid; |
0c70132c CM |
194 | uint16_t vlan_push_id; |
195 | uint8_t vlan_push_prio; | |
196 | } vlan; | |
197 | ||
55412eac JH |
198 | struct { |
199 | ovs_be16 proto; | |
283dcf85 JH |
200 | uint32_t label; |
201 | uint8_t tc; | |
202 | uint8_t ttl; | |
203 | uint8_t bos; | |
55412eac JH |
204 | } mpls; |
205 | ||
0c70132c | 206 | struct { |
0227bf09 | 207 | bool id_present; |
0c70132c CM |
208 | ovs_be64 id; |
209 | ovs_be16 tp_src; | |
210 | ovs_be16 tp_dst; | |
4b12e454 OG |
211 | uint8_t tos; |
212 | uint8_t ttl; | |
d9677a1f | 213 | uint8_t no_csum; |
0c70132c CM |
214 | struct { |
215 | ovs_be32 ipv4_src; | |
216 | ovs_be32 ipv4_dst; | |
217 | } ipv4; | |
218 | struct { | |
219 | struct in6_addr ipv6_src; | |
220 | struct in6_addr ipv6_dst; | |
221 | } ipv6; | |
202469aa | 222 | struct tun_metadata data; |
0c70132c | 223 | } encap; |
576126a9 PB |
224 | |
225 | struct { | |
226 | uint16_t zone; | |
9221c721 PB |
227 | uint32_t mark; |
228 | uint32_t mark_mask; | |
229 | ovs_u128 label; | |
230 | ovs_u128 label_mask; | |
2bf6ffb7 PB |
231 | uint8_t nat_type; |
232 | struct { | |
233 | uint8_t ip_family; | |
234 | ||
235 | union { | |
236 | struct { | |
237 | ovs_be32 min; | |
238 | ovs_be32 max; | |
239 | } ipv4; | |
240 | struct { | |
241 | struct in6_addr min; | |
242 | struct in6_addr max; | |
243 | } ipv6; | |
244 | }; | |
245 | ||
6f370784 | 246 | struct { |
2bf6ffb7 PB |
247 | ovs_be16 min; |
248 | ovs_be16 max; | |
249 | } port; | |
250 | ||
251 | } range; | |
576126a9 PB |
252 | bool clear; |
253 | bool force; | |
254 | bool commit; | |
255 | } ct; | |
0c70132c CM |
256 | }; |
257 | ||
258 | enum tc_action_type type; | |
259 | }; | |
260 | ||
d63ca532 GT |
261 | enum tc_offloaded_state { |
262 | TC_OFFLOADED_STATE_UNDEFINED, | |
263 | TC_OFFLOADED_STATE_IN_HW, | |
264 | TC_OFFLOADED_STATE_NOT_IN_HW, | |
265 | }; | |
266 | ||
d0fbb09f CM |
267 | #define TCA_ACT_MAX_NUM 16 |
268 | ||
acdd544c PB |
269 | struct tcf_id { |
270 | enum tc_qdisc_hook hook; | |
271 | uint32_t block_id; | |
272 | int ifindex; | |
b2ae4069 | 273 | uint32_t chain; |
acdd544c | 274 | uint16_t prio; |
f98e418f | 275 | uint32_t handle; |
acdd544c PB |
276 | }; |
277 | ||
278 | static inline struct tcf_id | |
279 | tc_make_tcf_id(int ifindex, uint32_t block_id, uint16_t prio, | |
280 | enum tc_qdisc_hook hook) | |
281 | { | |
e64fe4e4 IM |
282 | struct tcf_id id = { |
283 | .hook = hook, | |
284 | .block_id = block_id, | |
285 | .ifindex = ifindex, | |
286 | .prio = prio, | |
287 | }; | |
f98e418f | 288 | |
acdd544c PB |
289 | return id; |
290 | } | |
291 | ||
b2ae4069 PB |
292 | static inline struct tcf_id |
293 | tc_make_tcf_id_chain(int ifindex, uint32_t block_id, uint32_t chain, | |
294 | uint16_t prio, enum tc_qdisc_hook hook) | |
295 | { | |
296 | struct tcf_id id = tc_make_tcf_id(ifindex, block_id, prio, hook); | |
297 | ||
298 | id.chain = chain; | |
299 | ||
300 | return id; | |
301 | } | |
302 | ||
acdd544c PB |
303 | static inline bool |
304 | is_tcf_id_eq(struct tcf_id *id1, struct tcf_id *id2) | |
305 | { | |
306 | return id1->prio == id2->prio | |
307 | && id1->handle == id2->handle | |
308 | && id1->handle == id2->handle | |
309 | && id1->hook == id2->hook | |
310 | && id1->block_id == id2->block_id | |
b2ae4069 PB |
311 | && id1->ifindex == id2->ifindex |
312 | && id1->chain == id2->chain; | |
acdd544c PB |
313 | } |
314 | ||
d5659751 RD |
315 | enum tc_offload_policy { |
316 | TC_POLICY_NONE = 0, | |
317 | TC_POLICY_SKIP_SW, | |
318 | TC_POLICY_SKIP_HW | |
319 | }; | |
320 | ||
321 | BUILD_ASSERT_DECL(TC_POLICY_NONE == 0); | |
322 | ||
acdd544c | 323 | struct tc_flower { |
f98e418f RD |
324 | struct tc_flower_key key; |
325 | struct tc_flower_key mask; | |
326 | ||
0c70132c | 327 | int action_count; |
d0fbb09f | 328 | struct tc_action actions[TCA_ACT_MAX_NUM]; |
f98e418f RD |
329 | |
330 | struct ovs_flow_stats stats; | |
331 | uint64_t lastused; | |
332 | ||
8ada482b PB |
333 | struct { |
334 | bool rewrite; | |
335 | struct tc_flower_key key; | |
336 | struct tc_flower_key mask; | |
337 | } rewrite; | |
338 | ||
339 | uint32_t csum_update_flags; | |
340 | ||
105e8179 | 341 | bool tunnel; |
f98e418f RD |
342 | |
343 | struct tc_cookie act_cookie; | |
d6118e62 PB |
344 | |
345 | bool needs_full_ip_proto_mask; | |
d63ca532 GT |
346 | |
347 | enum tc_offloaded_state offloaded_state; | |
d5659751 RD |
348 | /* Used to force skip_hw when probing tc features. */ |
349 | enum tc_offload_policy tc_policy; | |
f98e418f RD |
350 | }; |
351 | ||
8ada482b PB |
352 | /* assert that if we overflow with a masked write of uint32_t to the last byte |
353 | * of flower.rewrite we overflow inside struct flower. | |
354 | * shouldn't happen unless someone moves rewrite to the end of flower */ | |
355 | BUILD_ASSERT_DECL(offsetof(struct tc_flower, rewrite) | |
356 | + MEMBER_SIZEOF(struct tc_flower, rewrite) | |
357 | + sizeof(uint32_t) - 2 < sizeof(struct tc_flower)); | |
358 | ||
acdd544c PB |
359 | int tc_replace_flower(struct tcf_id *id, struct tc_flower *flower); |
360 | int tc_del_filter(struct tcf_id *id); | |
361 | int tc_get_flower(struct tcf_id *id, struct tc_flower *flower); | |
5db012c4 | 362 | int tc_dump_flower_start(struct tcf_id *id, struct nl_dump *dump, bool terse); |
f98e418f | 363 | int parse_netlink_to_tc_flower(struct ofpbuf *reply, |
acdd544c | 364 | struct tcf_id *id, |
5db012c4 VB |
365 | struct tc_flower *flower, |
366 | bool terse); | |
691d20cb | 367 | void tc_set_policy(const char *policy); |
f98e418f | 368 | |
c1c5c723 | 369 | #endif /* tc.h */ |