blob: 4fcff896f47a74f8960c3d21ad66614ca5413166 [file] [log] [blame]
Chenmin Sund0236f72020-07-27 17:54:40 +08001/*
2 *------------------------------------------------------------------
3 * flow_api.c - flow api
4 *
5 * Copyright (c) 2020 Intel and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
18 */
19
20#include <stddef.h>
21
22#include <vnet/vnet.h>
23#include <vlibmemory/api.h>
24#include <vnet/interface.h>
25#include <vnet/api_errno.h>
26#include <vnet/flow/flow.h>
27#include <vnet/fib/fib_table.h>
Florin Corasb040f982020-10-20 14:59:43 -070028#include <vnet/udp/udp_local.h>
Chenmin Sund0236f72020-07-27 17:54:40 +080029#include <vnet/tunnel/tunnel_types_api.h>
30#include <vnet/ip/ip_types_api.h>
31#include <vnet/vnet_msg_enum.h>
32
Filip Tehlar9597f082021-06-21 09:49:31 +000033#include <vnet/format_fns.h>
34#include <vnet/flow/flow.api_enum.h>
35#include <vnet/flow/flow.api_types.h>
Chenmin Sund0236f72020-07-27 17:54:40 +080036
Filip Tehlar9597f082021-06-21 09:49:31 +000037#define REPLY_MSG_ID_BASE flow_main.msg_id_base
Chenmin Sund0236f72020-07-27 17:54:40 +080038#include <vlibapi/api_helper_macros.h>
39
Chenmin Sund0236f72020-07-27 17:54:40 +080040static inline void
41ipv4_addr_and_mask_convert (vl_api_ip4_address_and_mask_t * vl_api_addr,
42 ip4_address_and_mask_t * vnet_addr)
43{
44 clib_memcpy (vnet_addr, vl_api_addr, sizeof (*vnet_addr));
45}
46
47static inline void
48ipv6_addr_and_mask_convert (vl_api_ip6_address_and_mask_t * vl_api_addr,
49 ip6_address_and_mask_t * vnet_addr)
50{
51 clib_memcpy (vnet_addr, vl_api_addr, sizeof (*vnet_addr));
52}
53
54static inline void
Chenmin Sun34bfa502020-07-27 17:40:17 +080055protocol_and_mask_convert (vl_api_ip_prot_and_mask_t * vl_api_protocol,
56 ip_prot_and_mask_t * vnet_protocol)
57{
58 vnet_protocol->prot = (ip_protocol_t) vl_api_protocol->prot;
59 vnet_protocol->mask = vl_api_protocol->mask;
60}
61
62static inline void
Chenmin Sund0236f72020-07-27 17:54:40 +080063port_and_mask_convert (vl_api_ip_port_and_mask_t * vl_api_port,
64 ip_port_and_mask_t * vnet_port)
65{
66 vnet_port->port = ntohs (vl_api_port->port);
67 vnet_port->mask = ntohs (vl_api_port->mask);
68}
69
70static inline void
Chenmin Sunc7e78192020-09-04 06:50:22 +080071ipv4_flow_convert (vl_api_flow_ip4_t *vl_api_flow, vnet_flow_ip4_t *f)
72{
73 ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
74 ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
75
76 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
77}
78
79static void
80ipv6_flow_convert (vl_api_flow_ip6_t *vl_api_flow, vnet_flow_ip6_t *f)
81{
82 ipv6_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
83 ipv6_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
84
85 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
86}
87
88static inline void
Chenmin Sund0236f72020-07-27 17:54:40 +080089ipv4_n_tuple_flow_convert (vl_api_flow_ip4_n_tuple_t * vl_api_flow,
90 vnet_flow_ip4_n_tuple_t * f)
91{
92 ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
93 ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
Chenmin Sun34bfa502020-07-27 17:40:17 +080094 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
Chenmin Sund0236f72020-07-27 17:54:40 +080095
96 port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
97 port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
Chenmin Sund0236f72020-07-27 17:54:40 +080098}
99
100static void
101ipv6_n_tuple_flow_convert (vl_api_flow_ip6_n_tuple_t * vl_api_flow,
102 vnet_flow_ip6_n_tuple_t * f)
103{
104 ipv6_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
105 ipv6_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
Chenmin Sun34bfa502020-07-27 17:40:17 +0800106 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
Chenmin Sund0236f72020-07-27 17:54:40 +0800107
108 port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
109 port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
Chenmin Sund0236f72020-07-27 17:54:40 +0800110}
111
112static inline void
113ipv4_n_tuple_tagged_flow_convert (vl_api_flow_ip4_n_tuple_tagged_t *
114 vl_api_flow,
115 vnet_flow_ip4_n_tuple_tagged_t * f)
116{
117 return ipv4_n_tuple_flow_convert ((vl_api_flow_ip4_n_tuple_t *) vl_api_flow,
118 (vnet_flow_ip4_n_tuple_t *) f);
119}
120
121static inline void
122ipv6_n_tuple_tagged_flow_convert (vl_api_flow_ip6_n_tuple_tagged_t *
123 vl_api_flow,
124 vnet_flow_ip6_n_tuple_tagged_t * f)
125{
126 return ipv6_n_tuple_flow_convert ((vl_api_flow_ip6_n_tuple_t *) vl_api_flow,
127 (vnet_flow_ip6_n_tuple_t *) f);
128}
129
130static inline void
131ipv4_l2tpv3oip_flow_convert (vl_api_flow_ip4_l2tpv3oip_t * vl_api_flow,
132 vnet_flow_ip4_l2tpv3oip_t * f)
133{
134 ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
135 ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
136
Chenmin Sun34bfa502020-07-27 17:40:17 +0800137 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
Chenmin Sund0236f72020-07-27 17:54:40 +0800138 f->session_id = ntohl (vl_api_flow->session_id);
139}
140
141static inline void
142ipv4_ipsec_esp_flow_convert (vl_api_flow_ip4_ipsec_esp_t * vl_api_flow,
143 vnet_flow_ip4_ipsec_esp_t * f)
144{
145 ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
146 ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
147
Chenmin Sun34bfa502020-07-27 17:40:17 +0800148 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
Chenmin Sund0236f72020-07-27 17:54:40 +0800149 f->spi = ntohl (vl_api_flow->spi);
150}
151
152static inline void
153ipv4_ipsec_ah_flow_convert (vl_api_flow_ip4_ipsec_ah_t * vl_api_flow,
154 vnet_flow_ip4_ipsec_ah_t * f)
155{
156 ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
157 ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
158
Chenmin Sun34bfa502020-07-27 17:40:17 +0800159 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
Chenmin Sund0236f72020-07-27 17:54:40 +0800160 f->spi = ntohl (vl_api_flow->spi);
161}
162
163static inline void
Chenmin Sunc7e78192020-09-04 06:50:22 +0800164ipv4_vxlan_flow_convert (vl_api_flow_ip4_vxlan_t *vl_api_flow,
165 vnet_flow_ip4_vxlan_t *f)
166{
167 ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
168 ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
169 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
170
171 port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
172 port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
173
Chenmin Sunee32d662021-05-10 20:11:49 +0800174 f->vni = ntohl (vl_api_flow->vni);
Chenmin Sunc7e78192020-09-04 06:50:22 +0800175}
176
177static inline void
178ipv6_vxlan_flow_convert (vl_api_flow_ip6_vxlan_t *vl_api_flow,
179 vnet_flow_ip6_vxlan_t *f)
180{
181 ipv6_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
182 ipv6_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
183 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
184
185 port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
186 port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
187
Chenmin Sunee32d662021-05-10 20:11:49 +0800188 f->vni = ntohl (vl_api_flow->vni);
Chenmin Sunc7e78192020-09-04 06:50:22 +0800189}
190
191static inline void
Chenmin Sund0236f72020-07-27 17:54:40 +0800192ipv4_gtpu_flow_convert (vl_api_flow_ip4_gtpu_t * vl_api_flow,
193 vnet_flow_ip4_gtpu_t * f)
194{
195 ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
196 ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
197
198 port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
199 port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
200
Chenmin Sun34bfa502020-07-27 17:40:17 +0800201 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
Chenmin Sund0236f72020-07-27 17:54:40 +0800202 f->teid = ntohl (vl_api_flow->teid);
203}
204
205static inline void
206ipv4_gtpc_flow_convert (vl_api_flow_ip4_gtpc_t * vl_api_flow,
207 vnet_flow_ip4_gtpc_t * f)
208{
209 ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
210 ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
211
212 port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
213 port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
214
Chenmin Sun34bfa502020-07-27 17:40:17 +0800215 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
Chenmin Sund0236f72020-07-27 17:54:40 +0800216 f->teid = ntohl (vl_api_flow->teid);
217}
218
219static void
220vl_api_flow_add_t_handler (vl_api_flow_add_t * mp)
221{
222 vl_api_flow_add_reply_t *rmp;
223 int rv = 0;
224 vnet_flow_t flow;
225 u32 flow_index = ~0;
226 vl_api_flow_rule_t *f = &mp->flow;
227
228 vnet_main_t *vnm = vnet_get_main ();
229
230 flow.type = ntohl (f->type);
231 flow.actions = ntohl (f->actions);
232 flow.mark_flow_id = ntohl (f->mark_flow_id);
233 flow.redirect_node_index = ntohl (f->redirect_node_index);
234 flow.redirect_device_input_next_index =
235 ntohl (f->redirect_device_input_next_index);
236 flow.redirect_queue = ntohl (f->redirect_queue);
237 flow.buffer_advance = ntohl (f->buffer_advance);
238
239 switch (flow.type)
240 {
Chenmin Sunc7e78192020-09-04 06:50:22 +0800241 case VNET_FLOW_TYPE_IP4:
242 ipv4_flow_convert (&f->flow.ip4, &flow.ip4);
243 break;
244 case VNET_FLOW_TYPE_IP6:
245 ipv6_flow_convert (&f->flow.ip6, &flow.ip6);
246 break;
Chenmin Sund0236f72020-07-27 17:54:40 +0800247 case VNET_FLOW_TYPE_IP4_N_TUPLE:
248 ipv4_n_tuple_flow_convert (&f->flow.ip4_n_tuple, &flow.ip4_n_tuple);
249 break;
250 case VNET_FLOW_TYPE_IP6_N_TUPLE:
251 ipv6_n_tuple_flow_convert (&f->flow.ip6_n_tuple, &flow.ip6_n_tuple);
252 break;
253 case VNET_FLOW_TYPE_IP4_N_TUPLE_TAGGED:
254 ipv4_n_tuple_tagged_flow_convert (&f->flow.ip4_n_tuple_tagged,
255 &flow.ip4_n_tuple_tagged);
256 break;
257 case VNET_FLOW_TYPE_IP6_N_TUPLE_TAGGED:
258 ipv6_n_tuple_tagged_flow_convert (&f->flow.ip6_n_tuple_tagged,
259 &flow.ip6_n_tuple_tagged);
260 break;
261 case VNET_FLOW_TYPE_IP4_L2TPV3OIP:
262 ipv4_l2tpv3oip_flow_convert (&f->flow.ip4_l2tpv3oip,
263 &flow.ip4_l2tpv3oip);
264 break;
265 case VNET_FLOW_TYPE_IP4_IPSEC_ESP:
266 ipv4_ipsec_esp_flow_convert (&f->flow.ip4_ipsec_esp,
267 &flow.ip4_ipsec_esp);
268 break;
269 case VNET_FLOW_TYPE_IP4_IPSEC_AH:
270 ipv4_ipsec_ah_flow_convert (&f->flow.ip4_ipsec_ah, &flow.ip4_ipsec_ah);
271 break;
Chenmin Sunc7e78192020-09-04 06:50:22 +0800272 case VNET_FLOW_TYPE_IP4_VXLAN:
273 ipv4_vxlan_flow_convert (&f->flow.ip4_vxlan, &flow.ip4_vxlan);
274 break;
275 case VNET_FLOW_TYPE_IP6_VXLAN:
276 ipv6_vxlan_flow_convert (&f->flow.ip6_vxlan, &flow.ip6_vxlan);
277 break;
Chenmin Sund0236f72020-07-27 17:54:40 +0800278 case VNET_FLOW_TYPE_IP4_GTPU:
279 ipv4_gtpu_flow_convert (&f->flow.ip4_gtpu, &flow.ip4_gtpu);
280 break;
281 case VNET_FLOW_TYPE_IP4_GTPC:
282 ipv4_gtpc_flow_convert (&f->flow.ip4_gtpc, &flow.ip4_gtpc);
283 break;
284 default:
285 rv = VNET_FLOW_ERROR_NOT_SUPPORTED;
286 goto out;
287 break;
Chenmin Sund0236f72020-07-27 17:54:40 +0800288 }
289
290 rv = vnet_flow_add (vnm, &flow, &flow_index);
291
Chenmin Sund0236f72020-07-27 17:54:40 +0800292out:
293 /* *INDENT-OFF* */
294 REPLY_MACRO2(VL_API_FLOW_ADD_REPLY,
295 ({
296 rmp->flow_index = ntohl (flow_index);
297 }));
Florin Corasb040f982020-10-20 14:59:43 -0700298 /* *INDENT-ON* */
Chenmin Sund0236f72020-07-27 17:54:40 +0800299}
300
301static void
302vl_api_flow_del_t_handler (vl_api_flow_del_t * mp)
303{
304 vl_api_flow_add_reply_t *rmp;
305 int rv = 0;
306
Florin Corasb040f982020-10-20 14:59:43 -0700307 vnet_main_t *vnm = vnet_get_main ();
308 rv = vnet_flow_del (vnm, ntohl (mp->flow_index));
Chenmin Sund0236f72020-07-27 17:54:40 +0800309
310 REPLY_MACRO (VL_API_FLOW_DEL_REPLY);
311}
312
313static void
314vl_api_flow_enable_t_handler (vl_api_flow_enable_t * mp)
315{
316 vl_api_flow_add_reply_t *rmp;
317 int rv = 0;
318
Florin Corasb040f982020-10-20 14:59:43 -0700319 vnet_main_t *vnm = vnet_get_main ();
320 rv =
321 vnet_flow_enable (vnm, ntohl (mp->flow_index), ntohl (mp->hw_if_index));
Chenmin Sund0236f72020-07-27 17:54:40 +0800322
323 REPLY_MACRO (VL_API_FLOW_ENABLE_REPLY);
324}
325
326static void
327vl_api_flow_disable_t_handler (vl_api_flow_disable_t * mp)
328{
329 vl_api_flow_add_reply_t *rmp;
330 int rv = 0;
331
Florin Corasb040f982020-10-20 14:59:43 -0700332 vnet_main_t *vnm = vnet_get_main ();
333 rv =
334 vnet_flow_disable (vnm, ntohl (mp->flow_index), ntohl (mp->hw_if_index));
Chenmin Sund0236f72020-07-27 17:54:40 +0800335
336 REPLY_MACRO (VL_API_FLOW_DISABLE_REPLY);
337}
338
Filip Tehlar9597f082021-06-21 09:49:31 +0000339#include <vnet/flow/flow.api.c>
Chenmin Sund0236f72020-07-27 17:54:40 +0800340static clib_error_t *
341hw_flow_api_hookup (vlib_main_t * vm)
342{
Filip Tehlar9597f082021-06-21 09:49:31 +0000343 flow_main.msg_id_base = setup_message_id_table ();
Chenmin Sund0236f72020-07-27 17:54:40 +0800344
345 return 0;
346}
347
348VLIB_API_INIT_FUNCTION (hw_flow_api_hookup);
349
350/*
351 * fd.io coding-style-patch-verification: ON
352 *
353 * Local Variables:
354 * eval: (c-set-style "gnu")
355 * End:
356 */