]>
Commit | Line | Data |
---|---|---|
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-socket.h" | |
27 | #include "odp-netlink.h" | |
28 | #include "openvswitch/ofpbuf.h" | |
29 | #include "openvswitch/flow.h" | |
30 | #include "openvswitch/tun-metadata.h" | |
31 | ||
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 | |
39 | #ifndef TC_H_MIN_EGRESS | |
40 | #define TC_H_MIN_EGRESS 0xFFF3U | |
41 | #endif | |
42 | ||
43 | #define TC_INGRESS_PARENT TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_INGRESS) | |
44 | #define TC_EGRESS_PARENT TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_EGRESS) | |
45 | ||
46 | #define TC_POLICY_DEFAULT "none" | |
47 | ||
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 | ||
55 | enum tc_qdisc_hook { | |
56 | TC_INGRESS, | |
57 | TC_EGRESS, | |
58 | }; | |
59 | ||
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 | ||
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); | |
84 | int tc_add_del_qdisc(int ifindex, bool add, uint32_t block_id, | |
85 | enum tc_qdisc_hook hook); | |
86 | ||
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 | ||
99 | ovs_be32 mpls_lse; | |
100 | ovs_be16 tcp_src; | |
101 | ovs_be16 tcp_dst; | |
102 | ovs_be16 tcp_flags; | |
103 | ||
104 | ovs_be16 udp_src; | |
105 | ovs_be16 udp_dst; | |
106 | ||
107 | ovs_be16 sctp_src; | |
108 | ovs_be16 sctp_dst; | |
109 | ||
110 | uint8_t icmp_code; | |
111 | uint8_t icmp_type; | |
112 | ||
113 | uint16_t vlan_id[FLOW_MAX_VLAN_HEADERS]; | |
114 | uint8_t vlan_prio[FLOW_MAX_VLAN_HEADERS]; | |
115 | ||
116 | ovs_be16 encap_eth_type[FLOW_MAX_VLAN_HEADERS]; | |
117 | ||
118 | uint8_t flags; | |
119 | uint8_t ip_ttl; | |
120 | uint8_t ip_tos; | |
121 | ||
122 | uint16_t ct_state; | |
123 | uint16_t ct_zone; | |
124 | uint32_t ct_mark; | |
125 | ovs_u128 ct_label; | |
126 | ||
127 | struct { | |
128 | ovs_be32 spa; | |
129 | ovs_be32 tpa; | |
130 | struct eth_addr sha; | |
131 | struct eth_addr tha; | |
132 | uint8_t opcode; | |
133 | } arp; | |
134 | ||
135 | struct { | |
136 | ovs_be32 ipv4_src; | |
137 | ovs_be32 ipv4_dst; | |
138 | uint8_t rewrite_ttl; | |
139 | uint8_t rewrite_tos; | |
140 | } ipv4; | |
141 | struct { | |
142 | struct in6_addr ipv6_src; | |
143 | struct in6_addr ipv6_dst; | |
144 | uint8_t rewrite_hlimit; | |
145 | uint8_t rewrite_tclass; | |
146 | } ipv6; | |
147 | ||
148 | struct { | |
149 | struct { | |
150 | ovs_be32 ipv4_src; | |
151 | ovs_be32 ipv4_dst; | |
152 | } ipv4; | |
153 | struct { | |
154 | struct in6_addr ipv6_src; | |
155 | struct in6_addr ipv6_dst; | |
156 | } ipv6; | |
157 | uint8_t tos; | |
158 | uint8_t ttl; | |
159 | ovs_be16 tp_src; | |
160 | ovs_be16 tp_dst; | |
161 | ovs_be64 id; | |
162 | struct tun_metadata metadata; | |
163 | } tunnel; | |
164 | }; | |
165 | ||
166 | enum tc_action_type { | |
167 | TC_ACT_OUTPUT, | |
168 | TC_ACT_ENCAP, | |
169 | TC_ACT_PEDIT, | |
170 | TC_ACT_VLAN_POP, | |
171 | TC_ACT_VLAN_PUSH, | |
172 | TC_ACT_MPLS_POP, | |
173 | TC_ACT_MPLS_PUSH, | |
174 | TC_ACT_MPLS_SET, | |
175 | TC_ACT_GOTO, | |
176 | TC_ACT_CT, | |
177 | }; | |
178 | ||
179 | enum nat_type { | |
180 | TC_NO_NAT = 0, | |
181 | TC_NAT_SRC, | |
182 | TC_NAT_DST, | |
183 | TC_NAT_RESTORE, | |
184 | }; | |
185 | ||
186 | struct tc_action { | |
187 | union { | |
188 | int chain; | |
189 | ||
190 | struct { | |
191 | int ifindex_out; | |
192 | bool ingress; | |
193 | } out; | |
194 | ||
195 | struct { | |
196 | ovs_be16 vlan_push_tpid; | |
197 | uint16_t vlan_push_id; | |
198 | uint8_t vlan_push_prio; | |
199 | } vlan; | |
200 | ||
201 | struct { | |
202 | ovs_be16 proto; | |
203 | uint32_t label; | |
204 | uint8_t tc; | |
205 | uint8_t ttl; | |
206 | uint8_t bos; | |
207 | } mpls; | |
208 | ||
209 | struct { | |
210 | bool id_present; | |
211 | ovs_be64 id; | |
212 | ovs_be16 tp_src; | |
213 | ovs_be16 tp_dst; | |
214 | uint8_t tos; | |
215 | uint8_t ttl; | |
216 | uint8_t no_csum; | |
217 | struct { | |
218 | ovs_be32 ipv4_src; | |
219 | ovs_be32 ipv4_dst; | |
220 | } ipv4; | |
221 | struct { | |
222 | struct in6_addr ipv6_src; | |
223 | struct in6_addr ipv6_dst; | |
224 | } ipv6; | |
225 | struct tun_metadata data; | |
226 | } encap; | |
227 | ||
228 | struct { | |
229 | uint16_t zone; | |
230 | uint32_t mark; | |
231 | uint32_t mark_mask; | |
232 | ovs_u128 label; | |
233 | ovs_u128 label_mask; | |
234 | uint8_t nat_type; | |
235 | struct { | |
236 | uint8_t ip_family; | |
237 | ||
238 | union { | |
239 | struct { | |
240 | ovs_be32 min; | |
241 | ovs_be32 max; | |
242 | } ipv4; | |
243 | struct { | |
244 | struct in6_addr min; | |
245 | struct in6_addr max; | |
246 | } ipv6; | |
247 | }; | |
248 | ||
249 | struct { | |
250 | ovs_be16 min; | |
251 | ovs_be16 max; | |
252 | } port; | |
253 | ||
254 | } range; | |
255 | bool clear; | |
256 | bool force; | |
257 | bool commit; | |
258 | } ct; | |
259 | }; | |
260 | ||
261 | enum tc_action_type type; | |
262 | }; | |
263 | ||
264 | enum tc_offloaded_state { | |
265 | TC_OFFLOADED_STATE_UNDEFINED, | |
266 | TC_OFFLOADED_STATE_IN_HW, | |
267 | TC_OFFLOADED_STATE_NOT_IN_HW, | |
268 | }; | |
269 | ||
270 | #define TCA_ACT_MAX_NUM 16 | |
271 | ||
272 | struct tcf_id { | |
273 | enum tc_qdisc_hook hook; | |
274 | uint32_t block_id; | |
275 | int ifindex; | |
276 | uint32_t chain; | |
277 | uint16_t prio; | |
278 | uint32_t handle; | |
279 | }; | |
280 | ||
281 | static inline struct tcf_id | |
282 | tc_make_tcf_id(int ifindex, uint32_t block_id, uint16_t prio, | |
283 | enum tc_qdisc_hook hook) | |
284 | { | |
285 | struct tcf_id id = { | |
286 | .hook = hook, | |
287 | .block_id = block_id, | |
288 | .ifindex = ifindex, | |
289 | .prio = prio, | |
290 | }; | |
291 | ||
292 | return id; | |
293 | } | |
294 | ||
295 | static inline struct tcf_id | |
296 | tc_make_tcf_id_chain(int ifindex, uint32_t block_id, uint32_t chain, | |
297 | uint16_t prio, enum tc_qdisc_hook hook) | |
298 | { | |
299 | struct tcf_id id = tc_make_tcf_id(ifindex, block_id, prio, hook); | |
300 | ||
301 | id.chain = chain; | |
302 | ||
303 | return id; | |
304 | } | |
305 | ||
306 | static inline bool | |
307 | is_tcf_id_eq(struct tcf_id *id1, struct tcf_id *id2) | |
308 | { | |
309 | return id1->prio == id2->prio | |
310 | && id1->handle == id2->handle | |
311 | && id1->handle == id2->handle | |
312 | && id1->hook == id2->hook | |
313 | && id1->block_id == id2->block_id | |
314 | && id1->ifindex == id2->ifindex | |
315 | && id1->chain == id2->chain; | |
316 | } | |
317 | ||
318 | enum tc_offload_policy { | |
319 | TC_POLICY_NONE = 0, | |
320 | TC_POLICY_SKIP_SW, | |
321 | TC_POLICY_SKIP_HW | |
322 | }; | |
323 | ||
324 | BUILD_ASSERT_DECL(TC_POLICY_NONE == 0); | |
325 | ||
326 | struct tc_flower { | |
327 | struct tc_flower_key key; | |
328 | struct tc_flower_key mask; | |
329 | ||
330 | int action_count; | |
331 | struct tc_action actions[TCA_ACT_MAX_NUM]; | |
332 | ||
333 | struct ovs_flow_stats stats; | |
334 | uint64_t lastused; | |
335 | ||
336 | struct { | |
337 | bool rewrite; | |
338 | struct tc_flower_key key; | |
339 | struct tc_flower_key mask; | |
340 | } rewrite; | |
341 | ||
342 | uint32_t csum_update_flags; | |
343 | ||
344 | bool tunnel; | |
345 | ||
346 | struct tc_cookie act_cookie; | |
347 | ||
348 | bool needs_full_ip_proto_mask; | |
349 | ||
350 | enum tc_offloaded_state offloaded_state; | |
351 | /* Used to force skip_hw when probing tc features. */ | |
352 | enum tc_offload_policy tc_policy; | |
353 | }; | |
354 | ||
355 | /* assert that if we overflow with a masked write of uint32_t to the last byte | |
356 | * of flower.rewrite we overflow inside struct flower. | |
357 | * shouldn't happen unless someone moves rewrite to the end of flower */ | |
358 | BUILD_ASSERT_DECL(offsetof(struct tc_flower, rewrite) | |
359 | + MEMBER_SIZEOF(struct tc_flower, rewrite) | |
360 | + sizeof(uint32_t) - 2 < sizeof(struct tc_flower)); | |
361 | ||
362 | int tc_replace_flower(struct tcf_id *id, struct tc_flower *flower); | |
363 | int tc_del_filter(struct tcf_id *id); | |
364 | int tc_get_flower(struct tcf_id *id, struct tc_flower *flower); | |
365 | int tc_dump_flower_start(struct tcf_id *id, struct nl_dump *dump, bool terse); | |
366 | int parse_netlink_to_tc_flower(struct ofpbuf *reply, | |
367 | struct tcf_id *id, | |
368 | struct tc_flower *flower, | |
369 | bool terse); | |
370 | void tc_set_policy(const char *policy); | |
371 | ||
372 | #endif /* tc.h */ |