/src/openvswitch/lib/tc.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc. |
3 | | * Copyright (c) 2016 Mellanox Technologies, Ltd. |
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 | | |
21 | | #include <sys/types.h> |
22 | | #include <netinet/in.h> /* Must happen before linux/pkt_cls.h - Glibc #20215 */ |
23 | | #include <linux/pkt_cls.h> |
24 | | #include <linux/pkt_sched.h> |
25 | | |
26 | | #include "netlink.h" |
27 | | #include "netlink-socket.h" |
28 | | #include "odp-netlink.h" |
29 | | #include "openvswitch/ofpbuf.h" |
30 | | #include "openvswitch/flow.h" |
31 | | #include "openvswitch/tun-metadata.h" |
32 | | |
33 | | /* For backwards compatability with older kernels */ |
34 | | #ifndef TC_H_CLSACT |
35 | | #define TC_H_CLSACT TC_H_INGRESS |
36 | | #endif |
37 | | #ifndef TC_H_MIN_INGRESS |
38 | | #define TC_H_MIN_INGRESS 0xFFF2U |
39 | | #endif |
40 | | #ifndef TC_H_MIN_EGRESS |
41 | | #define TC_H_MIN_EGRESS 0xFFF3U |
42 | | #endif |
43 | | |
44 | 0 | #define TC_INGRESS_PARENT TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_INGRESS) |
45 | 0 | #define TC_EGRESS_PARENT TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_EGRESS) |
46 | | |
47 | 0 | #define TC_POLICY_DEFAULT "none" |
48 | | |
49 | | enum tc_flower_reserved_prio { |
50 | | TC_RESERVED_PRIORITY_NONE, |
51 | | TC_RESERVED_PRIORITY_POLICE, |
52 | | TC_RESERVED_PRIORITY_IPV4, |
53 | | TC_RESERVED_PRIORITY_IPV6, |
54 | | TC_RESERVED_PRIORITY_VLAN, |
55 | | __TC_RESERVED_PRIORITY_MAX, |
56 | | |
57 | | TC_MAX_PRIORITY = UINT16_MAX - 1, |
58 | | /* This priority is reserved solely for probing purposes. |
59 | | * Since it's not used in actual traffic flows, we assign it a high value |
60 | | * to avoid impacting vendor specific hardware offload implementations. */ |
61 | | TC_RESERVED_PRIORITY_FEATURE_PROBE |
62 | | }; |
63 | 0 | #define TC_RESERVED_PRIORITY_MAX (__TC_RESERVED_PRIORITY_MAX - 1) |
64 | | |
65 | | |
66 | | enum tc_qdisc_hook { |
67 | | TC_INGRESS, |
68 | | TC_EGRESS, |
69 | | }; |
70 | | |
71 | 0 | #define METER_POLICE_IDS_BASE 0x10000000 |
72 | 0 | #define METER_POLICE_IDS_MAX 0x1FFFFFFF |
73 | | |
74 | | static inline bool |
75 | 0 | tc_is_meter_index(uint32_t index) { |
76 | 0 | if (index >= METER_POLICE_IDS_BASE && index <= METER_POLICE_IDS_MAX) { |
77 | 0 | return true; |
78 | 0 | } |
79 | 0 | return false; |
80 | 0 | } Unexecuted instantiation: netdev.c:tc_is_meter_index Unexecuted instantiation: netdev-linux.c:tc_is_meter_index Unexecuted instantiation: netdev-offload-tc.c:tc_is_meter_index Unexecuted instantiation: tc.c:tc_is_meter_index Unexecuted instantiation: netdev-offload.c:tc_is_meter_index |
81 | | |
82 | | /* Returns tc handle 'major':'minor'. */ |
83 | | static inline unsigned int |
84 | | tc_make_handle(unsigned int major, unsigned int minor) |
85 | 0 | { |
86 | 0 | return TC_H_MAKE(major << 16, minor); |
87 | 0 | } Unexecuted instantiation: netdev.c:tc_make_handle Unexecuted instantiation: netdev-linux.c:tc_make_handle Unexecuted instantiation: netdev-offload-tc.c:tc_make_handle Unexecuted instantiation: tc.c:tc_make_handle Unexecuted instantiation: netdev-offload.c:tc_make_handle |
88 | | |
89 | | /* Returns the major number from 'handle'. */ |
90 | | static inline unsigned int |
91 | | tc_get_major(unsigned int handle) |
92 | 0 | { |
93 | 0 | return TC_H_MAJ(handle) >> 16; |
94 | 0 | } Unexecuted instantiation: netdev.c:tc_get_major Unexecuted instantiation: netdev-linux.c:tc_get_major Unexecuted instantiation: netdev-offload-tc.c:tc_get_major Unexecuted instantiation: tc.c:tc_get_major Unexecuted instantiation: netdev-offload.c:tc_get_major |
95 | | |
96 | | /* Returns the minor number from 'handle'. */ |
97 | | static inline unsigned int |
98 | | tc_get_minor(unsigned int handle) |
99 | 0 | { |
100 | 0 | return TC_H_MIN(handle); |
101 | 0 | } Unexecuted instantiation: netdev.c:tc_get_minor Unexecuted instantiation: netdev-linux.c:tc_get_minor Unexecuted instantiation: netdev-offload-tc.c:tc_get_minor Unexecuted instantiation: tc.c:tc_get_minor Unexecuted instantiation: netdev-offload.c:tc_get_minor |
102 | | |
103 | | struct tcmsg *tc_make_request(int ifindex, int type, |
104 | | unsigned int flags, struct ofpbuf *); |
105 | | struct tcamsg *tc_make_action_request(int type, unsigned int flags, |
106 | | struct ofpbuf *request); |
107 | | int tc_transact(struct ofpbuf *request, struct ofpbuf **replyp); |
108 | | int tc_add_del_qdisc(int ifindex, bool add, uint32_t block_id, |
109 | | enum tc_qdisc_hook hook); |
110 | | |
111 | | struct tc_cookie { |
112 | | const void *data; |
113 | | size_t len; |
114 | | }; |
115 | | |
116 | | struct tc_tunnel_gbp { |
117 | | ovs_be16 id; |
118 | | uint8_t flags; |
119 | | bool id_present; |
120 | | }; |
121 | | |
122 | | struct tc_flower_tunnel { |
123 | | struct { |
124 | | ovs_be32 ipv4_src; |
125 | | ovs_be32 ipv4_dst; |
126 | | } ipv4; |
127 | | struct { |
128 | | struct in6_addr ipv6_src; |
129 | | struct in6_addr ipv6_dst; |
130 | | } ipv6; |
131 | | uint8_t tos; |
132 | | uint8_t ttl; |
133 | | ovs_be16 tp_src; |
134 | | ovs_be16 tp_dst; |
135 | | uint32_t tc_enc_flags; |
136 | | struct tc_tunnel_gbp gbp; |
137 | | ovs_be64 id; |
138 | | struct tun_metadata metadata; |
139 | | }; |
140 | | |
141 | | struct tc_flower_key { |
142 | | ovs_be16 eth_type; |
143 | | uint8_t ip_proto; |
144 | | |
145 | | struct eth_addr dst_mac; |
146 | | struct eth_addr src_mac; |
147 | | |
148 | | ovs_be32 mpls_lse; |
149 | | ovs_be16 tcp_src; |
150 | | ovs_be16 tcp_dst; |
151 | | ovs_be16 tcp_flags; |
152 | | |
153 | | ovs_be16 udp_src; |
154 | | ovs_be16 udp_dst; |
155 | | |
156 | | ovs_be16 sctp_src; |
157 | | ovs_be16 sctp_dst; |
158 | | |
159 | | uint8_t icmp_code; |
160 | | uint8_t icmp_type; |
161 | | |
162 | | uint16_t vlan_id[FLOW_MAX_VLAN_HEADERS]; |
163 | | uint8_t vlan_prio[FLOW_MAX_VLAN_HEADERS]; |
164 | | |
165 | | ovs_be16 encap_eth_type[FLOW_MAX_VLAN_HEADERS]; |
166 | | |
167 | | uint8_t flags; |
168 | | uint8_t ip_ttl; |
169 | | uint8_t ip_tos; |
170 | | |
171 | | uint16_t ct_state; |
172 | | uint16_t ct_zone; |
173 | | uint32_t ct_mark; |
174 | | ovs_u128 ct_label; |
175 | | |
176 | | struct { |
177 | | ovs_be32 spa; |
178 | | ovs_be32 tpa; |
179 | | struct eth_addr sha; |
180 | | struct eth_addr tha; |
181 | | uint8_t opcode; |
182 | | } arp; |
183 | | |
184 | | struct { |
185 | | ovs_be32 ipv4_src; |
186 | | ovs_be32 ipv4_dst; |
187 | | uint8_t rewrite_ttl; |
188 | | uint8_t rewrite_tos; |
189 | | } ipv4; |
190 | | struct { |
191 | | struct in6_addr ipv6_src; |
192 | | struct in6_addr ipv6_dst; |
193 | | uint8_t rewrite_hlimit; |
194 | | uint8_t rewrite_tclass; |
195 | | } ipv6; |
196 | | |
197 | | struct tc_flower_tunnel tunnel; |
198 | | }; |
199 | | |
200 | | enum tc_action_type { |
201 | | TC_ACT_OUTPUT, |
202 | | TC_ACT_ENCAP, |
203 | | TC_ACT_PEDIT, |
204 | | TC_ACT_VLAN_POP, |
205 | | TC_ACT_VLAN_PUSH, |
206 | | TC_ACT_MPLS_POP, |
207 | | TC_ACT_MPLS_PUSH, |
208 | | TC_ACT_MPLS_SET, |
209 | | TC_ACT_GOTO, |
210 | | TC_ACT_CT, |
211 | | TC_ACT_POLICE, |
212 | | TC_ACT_POLICE_MTU, |
213 | | }; |
214 | | |
215 | | enum nat_type { |
216 | | TC_NO_NAT = 0, |
217 | | TC_NAT_SRC, |
218 | | TC_NAT_DST, |
219 | | TC_NAT_RESTORE, |
220 | | }; |
221 | | |
222 | | struct tc_action_encap { |
223 | | bool id_present; |
224 | | ovs_be64 id; |
225 | | /* ovs_be16 tp_src; Could have been here, but there is no |
226 | | * TCA_TUNNEL_KEY_ENC_ attribute for it in the kernel. */ |
227 | | ovs_be16 tp_dst; |
228 | | uint8_t tos; |
229 | | uint8_t ttl; |
230 | | uint8_t no_csum; |
231 | | bool dont_fragment; |
232 | | struct { |
233 | | ovs_be32 ipv4_src; |
234 | | ovs_be32 ipv4_dst; |
235 | | } ipv4; |
236 | | struct { |
237 | | struct in6_addr ipv6_src; |
238 | | struct in6_addr ipv6_dst; |
239 | | } ipv6; |
240 | | struct tun_metadata data; |
241 | | struct tc_tunnel_gbp gbp; |
242 | | }; |
243 | | |
244 | | struct tc_action { |
245 | | union { |
246 | | int chain; |
247 | | |
248 | | struct { |
249 | | int ifindex_out; |
250 | | bool ingress; |
251 | | } out; |
252 | | |
253 | | struct { |
254 | | ovs_be16 vlan_push_tpid; |
255 | | uint16_t vlan_push_id; |
256 | | uint8_t vlan_push_prio; |
257 | | } vlan; |
258 | | |
259 | | struct { |
260 | | ovs_be16 proto; |
261 | | uint32_t label; |
262 | | uint8_t tc; |
263 | | uint8_t ttl; |
264 | | uint8_t bos; |
265 | | } mpls; |
266 | | |
267 | | struct tc_action_encap encap; |
268 | | |
269 | | struct { |
270 | | uint16_t zone; |
271 | | uint32_t mark; |
272 | | uint32_t mark_mask; |
273 | | ovs_u128 label; |
274 | | ovs_u128 label_mask; |
275 | | uint8_t nat_type; |
276 | | struct { |
277 | | uint8_t ip_family; |
278 | | |
279 | | union { |
280 | | struct { |
281 | | ovs_be32 min; |
282 | | ovs_be32 max; |
283 | | } ipv4; |
284 | | struct { |
285 | | struct in6_addr min; |
286 | | struct in6_addr max; |
287 | | } ipv6; |
288 | | }; |
289 | | |
290 | | struct { |
291 | | ovs_be16 min; |
292 | | ovs_be16 max; |
293 | | } port; |
294 | | |
295 | | } range; |
296 | | bool clear; |
297 | | bool force; |
298 | | bool commit; |
299 | | } ct; |
300 | | struct { |
301 | | struct tc_flower_key key; |
302 | | struct tc_flower_key mask; |
303 | | } rewrite; |
304 | | struct { |
305 | | uint32_t index; |
306 | | uint32_t result_jump; |
307 | | uint16_t mtu; |
308 | | } police; |
309 | | }; |
310 | | |
311 | | enum tc_action_type type; |
312 | | uint32_t jump_action; |
313 | 0 | #define JUMP_ACTION_STOP 0xffffffff |
314 | | }; |
315 | | |
316 | | /* assert that if we overflow with a masked write of uint32_t to the last byte |
317 | | * of action.rewrite we overflow inside struct tc_action. |
318 | | * shouldn't happen unless someone moves rewrite to the end of action */ |
319 | | BUILD_ASSERT_DECL(offsetof(struct tc_action, rewrite) |
320 | | + MEMBER_SIZEOF(struct tc_action, rewrite) |
321 | | + sizeof(uint32_t) - 2 < sizeof(struct tc_action)); |
322 | | |
323 | | enum tc_offloaded_state { |
324 | | TC_OFFLOADED_STATE_UNDEFINED, |
325 | | TC_OFFLOADED_STATE_IN_HW, |
326 | | TC_OFFLOADED_STATE_NOT_IN_HW, |
327 | | }; |
328 | | |
329 | 0 | #define TCA_ACT_MAX_NUM 16 |
330 | | |
331 | | struct tcf_id { |
332 | | enum tc_qdisc_hook hook; |
333 | | uint32_t block_id; |
334 | | int ifindex; |
335 | | uint32_t chain; |
336 | | uint16_t prio; |
337 | | uint32_t handle; |
338 | | }; |
339 | | |
340 | | static inline struct tcf_id |
341 | | tc_make_tcf_id(int ifindex, uint32_t block_id, uint16_t prio, |
342 | | enum tc_qdisc_hook hook) |
343 | 0 | { |
344 | 0 | struct tcf_id id = { |
345 | 0 | .hook = hook, |
346 | 0 | .block_id = block_id, |
347 | 0 | .ifindex = ifindex, |
348 | 0 | .prio = prio, |
349 | 0 | }; |
350 | |
|
351 | 0 | return id; |
352 | 0 | } Unexecuted instantiation: netdev.c:tc_make_tcf_id Unexecuted instantiation: netdev-linux.c:tc_make_tcf_id Unexecuted instantiation: netdev-offload-tc.c:tc_make_tcf_id Unexecuted instantiation: tc.c:tc_make_tcf_id Unexecuted instantiation: netdev-offload.c:tc_make_tcf_id |
353 | | |
354 | | static inline struct tcf_id |
355 | | tc_make_tcf_id_chain(int ifindex, uint32_t block_id, uint32_t chain, |
356 | | uint16_t prio, enum tc_qdisc_hook hook) |
357 | 0 | { |
358 | 0 | struct tcf_id id = tc_make_tcf_id(ifindex, block_id, prio, hook); |
359 | |
|
360 | 0 | id.chain = chain; |
361 | |
|
362 | 0 | return id; |
363 | 0 | } Unexecuted instantiation: netdev.c:tc_make_tcf_id_chain Unexecuted instantiation: netdev-linux.c:tc_make_tcf_id_chain Unexecuted instantiation: netdev-offload-tc.c:tc_make_tcf_id_chain Unexecuted instantiation: tc.c:tc_make_tcf_id_chain Unexecuted instantiation: netdev-offload.c:tc_make_tcf_id_chain |
364 | | |
365 | | static inline bool |
366 | | is_tcf_id_eq(struct tcf_id *id1, struct tcf_id *id2) |
367 | 0 | { |
368 | 0 | return id1->prio == id2->prio |
369 | 0 | && id1->handle == id2->handle |
370 | 0 | && id1->hook == id2->hook |
371 | 0 | && id1->block_id == id2->block_id |
372 | 0 | && id1->ifindex == id2->ifindex |
373 | 0 | && id1->chain == id2->chain; |
374 | 0 | } Unexecuted instantiation: netdev.c:is_tcf_id_eq Unexecuted instantiation: netdev-linux.c:is_tcf_id_eq Unexecuted instantiation: netdev-offload-tc.c:is_tcf_id_eq Unexecuted instantiation: tc.c:is_tcf_id_eq Unexecuted instantiation: netdev-offload.c:is_tcf_id_eq |
375 | | |
376 | | enum tc_offload_policy { |
377 | | TC_POLICY_NONE = 0, |
378 | | TC_POLICY_SKIP_SW, |
379 | | TC_POLICY_SKIP_HW |
380 | | }; |
381 | | |
382 | | BUILD_ASSERT_DECL(TC_POLICY_NONE == 0); |
383 | | |
384 | | struct tc_flower { |
385 | | struct tc_flower_key key; |
386 | | struct tc_flower_key mask; |
387 | | |
388 | | int action_count; |
389 | | struct tc_action actions[TCA_ACT_MAX_NUM]; |
390 | | |
391 | | struct ovs_flow_stats stats_sw; |
392 | | struct ovs_flow_stats stats_hw; |
393 | | uint64_t lastused; |
394 | | |
395 | | uint32_t csum_update_flags; |
396 | | |
397 | | bool tunnel; |
398 | | |
399 | | struct tc_cookie act_cookie; |
400 | | |
401 | | bool needs_full_ip_proto_mask; |
402 | | |
403 | | enum tc_offloaded_state offloaded_state; |
404 | | /* Used to force skip_hw when probing tc features. */ |
405 | | enum tc_offload_policy tc_policy; |
406 | | }; |
407 | | |
408 | | int tc_replace_flower(struct tcf_id *id, struct tc_flower *flower); |
409 | | int tc_del_filter(struct tcf_id *id, const char *kind); |
410 | | int tc_del_flower_filter(struct tcf_id *id); |
411 | | int tc_get_flower(struct tcf_id *id, struct tc_flower *flower); |
412 | | int tc_dump_flower_start(struct tcf_id *id, struct nl_dump *dump, bool terse); |
413 | | int tc_dump_tc_chain_start(struct tcf_id *id, struct nl_dump *dump); |
414 | | int parse_netlink_to_tc_flower(struct ofpbuf *reply, |
415 | | struct tcf_id *id, |
416 | | struct tc_flower *flower, |
417 | | bool terse); |
418 | | int parse_netlink_to_tc_chain(struct ofpbuf *reply, uint32_t *chain); |
419 | | void tc_set_policy(const char *policy); |
420 | | int tc_parse_action_stats(struct nlattr *action, |
421 | | struct ovs_flow_stats *stats_sw, |
422 | | struct ovs_flow_stats *stats_hw, |
423 | | struct ovs_flow_stats *stats_dropped); |
424 | | int tc_dump_tc_action_start(char *name, struct nl_dump *dump); |
425 | | int parse_netlink_to_tc_policer(struct ofpbuf *reply, uint32_t police_idx[]); |
426 | | |
427 | | void nl_msg_put_act_tc_policy_flag(struct ofpbuf *request); |
428 | | |
429 | | #endif /* tc.h */ |