]>
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 | |
75e1e6fd MD |
110 | uint8_t icmp_code; |
111 | uint8_t icmp_type; | |
112 | ||
f9885dc5 JL |
113 | uint16_t vlan_id[FLOW_MAX_VLAN_HEADERS]; |
114 | uint8_t vlan_prio[FLOW_MAX_VLAN_HEADERS]; | |
f98e418f | 115 | |
f9885dc5 | 116 | ovs_be16 encap_eth_type[FLOW_MAX_VLAN_HEADERS]; |
f98e418f | 117 | |
83e86606 | 118 | uint8_t flags; |
0b4b5203 | 119 | uint8_t ip_ttl; |
dfa2ccdb | 120 | uint8_t ip_tos; |
0b4b5203 | 121 | |
576126a9 PB |
122 | uint16_t ct_state; |
123 | uint16_t ct_zone; | |
9221c721 PB |
124 | uint32_t ct_mark; |
125 | ovs_u128 ct_label; | |
576126a9 | 126 | |
a3db6e47 TZ |
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 | ||
2b1d9fa9 PB |
135 | struct { |
136 | ovs_be32 ipv4_src; | |
137 | ovs_be32 ipv4_dst; | |
8ada482b | 138 | uint8_t rewrite_ttl; |
95431229 | 139 | uint8_t rewrite_tos; |
2b1d9fa9 PB |
140 | } ipv4; |
141 | struct { | |
142 | struct in6_addr ipv6_src; | |
143 | struct in6_addr ipv6_dst; | |
46df7fac | 144 | uint8_t rewrite_hlimit; |
dbcb014d | 145 | uint8_t rewrite_tclass; |
2b1d9fa9 | 146 | } ipv6; |
105e8179 OG |
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; | |
a468645c | 162 | struct tun_metadata metadata; |
105e8179 | 163 | } tunnel; |
f98e418f RD |
164 | }; |
165 | ||
0c70132c CM |
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, | |
55412eac | 172 | TC_ACT_MPLS_POP, |
283dcf85 | 173 | TC_ACT_MPLS_PUSH, |
a8f005cf | 174 | TC_ACT_MPLS_SET, |
b2ae4069 | 175 | TC_ACT_GOTO, |
576126a9 | 176 | TC_ACT_CT, |
0c70132c CM |
177 | }; |
178 | ||
2bf6ffb7 PB |
179 | enum nat_type { |
180 | TC_NO_NAT = 0, | |
181 | TC_NAT_SRC, | |
182 | TC_NAT_DST, | |
183 | TC_NAT_RESTORE, | |
184 | }; | |
185 | ||
0c70132c CM |
186 | struct tc_action { |
187 | union { | |
b2ae4069 PB |
188 | int chain; |
189 | ||
4aa2dc04 JH |
190 | struct { |
191 | int ifindex_out; | |
192 | bool ingress; | |
193 | } out; | |
0c70132c CM |
194 | |
195 | struct { | |
61e8655c | 196 | ovs_be16 vlan_push_tpid; |
0c70132c CM |
197 | uint16_t vlan_push_id; |
198 | uint8_t vlan_push_prio; | |
199 | } vlan; | |
200 | ||
55412eac JH |
201 | struct { |
202 | ovs_be16 proto; | |
283dcf85 JH |
203 | uint32_t label; |
204 | uint8_t tc; | |
205 | uint8_t ttl; | |
206 | uint8_t bos; | |
55412eac JH |
207 | } mpls; |
208 | ||
0c70132c | 209 | struct { |
0227bf09 | 210 | bool id_present; |
0c70132c CM |
211 | ovs_be64 id; |
212 | ovs_be16 tp_src; | |
213 | ovs_be16 tp_dst; | |
4b12e454 OG |
214 | uint8_t tos; |
215 | uint8_t ttl; | |
d9677a1f | 216 | uint8_t no_csum; |
0c70132c CM |
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; | |
202469aa | 225 | struct tun_metadata data; |
0c70132c | 226 | } encap; |
576126a9 PB |
227 | |
228 | struct { | |
229 | uint16_t zone; | |
9221c721 PB |
230 | uint32_t mark; |
231 | uint32_t mark_mask; | |
232 | ovs_u128 label; | |
233 | ovs_u128 label_mask; | |
2bf6ffb7 PB |
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 | ||
6f370784 | 249 | struct { |
2bf6ffb7 PB |
250 | ovs_be16 min; |
251 | ovs_be16 max; | |
252 | } port; | |
253 | ||
254 | } range; | |
576126a9 PB |
255 | bool clear; |
256 | bool force; | |
257 | bool commit; | |
258 | } ct; | |
0c70132c CM |
259 | }; |
260 | ||
261 | enum tc_action_type type; | |
262 | }; | |
263 | ||
d63ca532 GT |
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 | ||
d0fbb09f CM |
270 | #define TCA_ACT_MAX_NUM 16 |
271 | ||
acdd544c PB |
272 | struct tcf_id { |
273 | enum tc_qdisc_hook hook; | |
274 | uint32_t block_id; | |
275 | int ifindex; | |
b2ae4069 | 276 | uint32_t chain; |
acdd544c | 277 | uint16_t prio; |
f98e418f | 278 | uint32_t handle; |
acdd544c PB |
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 | { | |
e64fe4e4 IM |
285 | struct tcf_id id = { |
286 | .hook = hook, | |
287 | .block_id = block_id, | |
288 | .ifindex = ifindex, | |
289 | .prio = prio, | |
290 | }; | |
f98e418f | 291 | |
acdd544c PB |
292 | return id; |
293 | } | |
294 | ||
b2ae4069 PB |
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 | ||
acdd544c PB |
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 | |
b2ae4069 PB |
314 | && id1->ifindex == id2->ifindex |
315 | && id1->chain == id2->chain; | |
acdd544c PB |
316 | } |
317 | ||
d5659751 RD |
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 | ||
acdd544c | 326 | struct tc_flower { |
f98e418f RD |
327 | struct tc_flower_key key; |
328 | struct tc_flower_key mask; | |
329 | ||
0c70132c | 330 | int action_count; |
d0fbb09f | 331 | struct tc_action actions[TCA_ACT_MAX_NUM]; |
f98e418f RD |
332 | |
333 | struct ovs_flow_stats stats; | |
334 | uint64_t lastused; | |
335 | ||
8ada482b PB |
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 | ||
105e8179 | 344 | bool tunnel; |
f98e418f RD |
345 | |
346 | struct tc_cookie act_cookie; | |
d6118e62 PB |
347 | |
348 | bool needs_full_ip_proto_mask; | |
d63ca532 GT |
349 | |
350 | enum tc_offloaded_state offloaded_state; | |
d5659751 RD |
351 | /* Used to force skip_hw when probing tc features. */ |
352 | enum tc_offload_policy tc_policy; | |
f98e418f RD |
353 | }; |
354 | ||
8ada482b PB |
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 | ||
acdd544c PB |
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); | |
5db012c4 | 365 | int tc_dump_flower_start(struct tcf_id *id, struct nl_dump *dump, bool terse); |
f98e418f | 366 | int parse_netlink_to_tc_flower(struct ofpbuf *reply, |
acdd544c | 367 | struct tcf_id *id, |
5db012c4 VB |
368 | struct tc_flower *flower, |
369 | bool terse); | |
691d20cb | 370 | void tc_set_policy(const char *policy); |
f98e418f | 371 | |
c1c5c723 | 372 | #endif /* tc.h */ |