blob: 3aa4e0c5b75934368341806f2c54134d719eb6a9 [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
33#define vl_typedefs /* define message structures */
34#include <vnet/vnet_all_api_h.h>
35#undef vl_typedefs
36
37#define vl_endianfun /* define message structures */
38#include <vnet/vnet_all_api_h.h>
39#undef vl_endianfun
40
41/* instantiate all the print functions we know about */
42#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
43#define vl_printfun
44#include <vnet/vnet_all_api_h.h>
45#undef vl_printfun
46
47#include <vlibapi/api_helper_macros.h>
48
49#define foreach_vpe_api_msg \
50_(FLOW_ADD, flow_add) \
51_(FLOW_DEL, flow_del) \
52_(FLOW_ENABLE, flow_enable) \
53_(FLOW_DISABLE, flow_disable)
54
55static inline void
56ipv4_addr_and_mask_convert (vl_api_ip4_address_and_mask_t * vl_api_addr,
57 ip4_address_and_mask_t * vnet_addr)
58{
59 clib_memcpy (vnet_addr, vl_api_addr, sizeof (*vnet_addr));
60}
61
62static inline void
63ipv6_addr_and_mask_convert (vl_api_ip6_address_and_mask_t * vl_api_addr,
64 ip6_address_and_mask_t * vnet_addr)
65{
66 clib_memcpy (vnet_addr, vl_api_addr, sizeof (*vnet_addr));
67}
68
69static inline void
Chenmin Sun34bfa502020-07-27 17:40:17 +080070protocol_and_mask_convert (vl_api_ip_prot_and_mask_t * vl_api_protocol,
71 ip_prot_and_mask_t * vnet_protocol)
72{
73 vnet_protocol->prot = (ip_protocol_t) vl_api_protocol->prot;
74 vnet_protocol->mask = vl_api_protocol->mask;
75}
76
77static inline void
Chenmin Sund0236f72020-07-27 17:54:40 +080078port_and_mask_convert (vl_api_ip_port_and_mask_t * vl_api_port,
79 ip_port_and_mask_t * vnet_port)
80{
81 vnet_port->port = ntohs (vl_api_port->port);
82 vnet_port->mask = ntohs (vl_api_port->mask);
83}
84
85static inline void
Chenmin Sunc7e78192020-09-04 06:50:22 +080086ipv4_flow_convert (vl_api_flow_ip4_t *vl_api_flow, vnet_flow_ip4_t *f)
87{
88 ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
89 ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
90
91 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
92}
93
94static void
95ipv6_flow_convert (vl_api_flow_ip6_t *vl_api_flow, vnet_flow_ip6_t *f)
96{
97 ipv6_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
98 ipv6_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
99
100 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
101}
102
103static inline void
Chenmin Sund0236f72020-07-27 17:54:40 +0800104ipv4_n_tuple_flow_convert (vl_api_flow_ip4_n_tuple_t * vl_api_flow,
105 vnet_flow_ip4_n_tuple_t * f)
106{
107 ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
108 ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
Chenmin Sun34bfa502020-07-27 17:40:17 +0800109 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
Chenmin Sund0236f72020-07-27 17:54:40 +0800110
111 port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
112 port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
Chenmin Sund0236f72020-07-27 17:54:40 +0800113}
114
115static void
116ipv6_n_tuple_flow_convert (vl_api_flow_ip6_n_tuple_t * vl_api_flow,
117 vnet_flow_ip6_n_tuple_t * f)
118{
119 ipv6_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
120 ipv6_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
Chenmin Sun34bfa502020-07-27 17:40:17 +0800121 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
Chenmin Sund0236f72020-07-27 17:54:40 +0800122
123 port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
124 port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
Chenmin Sund0236f72020-07-27 17:54:40 +0800125}
126
127static inline void
128ipv4_n_tuple_tagged_flow_convert (vl_api_flow_ip4_n_tuple_tagged_t *
129 vl_api_flow,
130 vnet_flow_ip4_n_tuple_tagged_t * f)
131{
132 return ipv4_n_tuple_flow_convert ((vl_api_flow_ip4_n_tuple_t *) vl_api_flow,
133 (vnet_flow_ip4_n_tuple_t *) f);
134}
135
136static inline void
137ipv6_n_tuple_tagged_flow_convert (vl_api_flow_ip6_n_tuple_tagged_t *
138 vl_api_flow,
139 vnet_flow_ip6_n_tuple_tagged_t * f)
140{
141 return ipv6_n_tuple_flow_convert ((vl_api_flow_ip6_n_tuple_t *) vl_api_flow,
142 (vnet_flow_ip6_n_tuple_t *) f);
143}
144
145static inline void
146ipv4_l2tpv3oip_flow_convert (vl_api_flow_ip4_l2tpv3oip_t * vl_api_flow,
147 vnet_flow_ip4_l2tpv3oip_t * f)
148{
149 ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
150 ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
151
Chenmin Sun34bfa502020-07-27 17:40:17 +0800152 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
Chenmin Sund0236f72020-07-27 17:54:40 +0800153 f->session_id = ntohl (vl_api_flow->session_id);
154}
155
156static inline void
157ipv4_ipsec_esp_flow_convert (vl_api_flow_ip4_ipsec_esp_t * vl_api_flow,
158 vnet_flow_ip4_ipsec_esp_t * f)
159{
160 ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
161 ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
162
Chenmin Sun34bfa502020-07-27 17:40:17 +0800163 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
Chenmin Sund0236f72020-07-27 17:54:40 +0800164 f->spi = ntohl (vl_api_flow->spi);
165}
166
167static inline void
168ipv4_ipsec_ah_flow_convert (vl_api_flow_ip4_ipsec_ah_t * vl_api_flow,
169 vnet_flow_ip4_ipsec_ah_t * f)
170{
171 ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
172 ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
173
Chenmin Sun34bfa502020-07-27 17:40:17 +0800174 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
Chenmin Sund0236f72020-07-27 17:54:40 +0800175 f->spi = ntohl (vl_api_flow->spi);
176}
177
178static inline void
Chenmin Sunc7e78192020-09-04 06:50:22 +0800179ipv4_vxlan_flow_convert (vl_api_flow_ip4_vxlan_t *vl_api_flow,
180 vnet_flow_ip4_vxlan_t *f)
181{
182 ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
183 ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
184 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
185
186 port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
187 port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
188
Chenmin Sunee32d662021-05-10 20:11:49 +0800189 f->vni = ntohl (vl_api_flow->vni);
Chenmin Sunc7e78192020-09-04 06:50:22 +0800190}
191
192static inline void
193ipv6_vxlan_flow_convert (vl_api_flow_ip6_vxlan_t *vl_api_flow,
194 vnet_flow_ip6_vxlan_t *f)
195{
196 ipv6_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
197 ipv6_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
198 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
199
200 port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
201 port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
202
Chenmin Sunee32d662021-05-10 20:11:49 +0800203 f->vni = ntohl (vl_api_flow->vni);
Chenmin Sunc7e78192020-09-04 06:50:22 +0800204}
205
206static inline void
Chenmin Sund0236f72020-07-27 17:54:40 +0800207ipv4_gtpu_flow_convert (vl_api_flow_ip4_gtpu_t * vl_api_flow,
208 vnet_flow_ip4_gtpu_t * f)
209{
210 ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
211 ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
212
213 port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
214 port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
215
Chenmin Sun34bfa502020-07-27 17:40:17 +0800216 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
Chenmin Sund0236f72020-07-27 17:54:40 +0800217 f->teid = ntohl (vl_api_flow->teid);
218}
219
220static inline void
221ipv4_gtpc_flow_convert (vl_api_flow_ip4_gtpc_t * vl_api_flow,
222 vnet_flow_ip4_gtpc_t * f)
223{
224 ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
225 ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
226
227 port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
228 port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
229
Chenmin Sun34bfa502020-07-27 17:40:17 +0800230 protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
Chenmin Sund0236f72020-07-27 17:54:40 +0800231 f->teid = ntohl (vl_api_flow->teid);
232}
233
234static void
235vl_api_flow_add_t_handler (vl_api_flow_add_t * mp)
236{
237 vl_api_flow_add_reply_t *rmp;
238 int rv = 0;
239 vnet_flow_t flow;
240 u32 flow_index = ~0;
241 vl_api_flow_rule_t *f = &mp->flow;
242
243 vnet_main_t *vnm = vnet_get_main ();
244
245 flow.type = ntohl (f->type);
246 flow.actions = ntohl (f->actions);
247 flow.mark_flow_id = ntohl (f->mark_flow_id);
248 flow.redirect_node_index = ntohl (f->redirect_node_index);
249 flow.redirect_device_input_next_index =
250 ntohl (f->redirect_device_input_next_index);
251 flow.redirect_queue = ntohl (f->redirect_queue);
252 flow.buffer_advance = ntohl (f->buffer_advance);
253
254 switch (flow.type)
255 {
Chenmin Sunc7e78192020-09-04 06:50:22 +0800256 case VNET_FLOW_TYPE_IP4:
257 ipv4_flow_convert (&f->flow.ip4, &flow.ip4);
258 break;
259 case VNET_FLOW_TYPE_IP6:
260 ipv6_flow_convert (&f->flow.ip6, &flow.ip6);
261 break;
Chenmin Sund0236f72020-07-27 17:54:40 +0800262 case VNET_FLOW_TYPE_IP4_N_TUPLE:
263 ipv4_n_tuple_flow_convert (&f->flow.ip4_n_tuple, &flow.ip4_n_tuple);
264 break;
265 case VNET_FLOW_TYPE_IP6_N_TUPLE:
266 ipv6_n_tuple_flow_convert (&f->flow.ip6_n_tuple, &flow.ip6_n_tuple);
267 break;
268 case VNET_FLOW_TYPE_IP4_N_TUPLE_TAGGED:
269 ipv4_n_tuple_tagged_flow_convert (&f->flow.ip4_n_tuple_tagged,
270 &flow.ip4_n_tuple_tagged);
271 break;
272 case VNET_FLOW_TYPE_IP6_N_TUPLE_TAGGED:
273 ipv6_n_tuple_tagged_flow_convert (&f->flow.ip6_n_tuple_tagged,
274 &flow.ip6_n_tuple_tagged);
275 break;
276 case VNET_FLOW_TYPE_IP4_L2TPV3OIP:
277 ipv4_l2tpv3oip_flow_convert (&f->flow.ip4_l2tpv3oip,
278 &flow.ip4_l2tpv3oip);
279 break;
280 case VNET_FLOW_TYPE_IP4_IPSEC_ESP:
281 ipv4_ipsec_esp_flow_convert (&f->flow.ip4_ipsec_esp,
282 &flow.ip4_ipsec_esp);
283 break;
284 case VNET_FLOW_TYPE_IP4_IPSEC_AH:
285 ipv4_ipsec_ah_flow_convert (&f->flow.ip4_ipsec_ah, &flow.ip4_ipsec_ah);
286 break;
Chenmin Sunc7e78192020-09-04 06:50:22 +0800287 case VNET_FLOW_TYPE_IP4_VXLAN:
288 ipv4_vxlan_flow_convert (&f->flow.ip4_vxlan, &flow.ip4_vxlan);
289 break;
290 case VNET_FLOW_TYPE_IP6_VXLAN:
291 ipv6_vxlan_flow_convert (&f->flow.ip6_vxlan, &flow.ip6_vxlan);
292 break;
Chenmin Sund0236f72020-07-27 17:54:40 +0800293 case VNET_FLOW_TYPE_IP4_GTPU:
294 ipv4_gtpu_flow_convert (&f->flow.ip4_gtpu, &flow.ip4_gtpu);
295 break;
296 case VNET_FLOW_TYPE_IP4_GTPC:
297 ipv4_gtpc_flow_convert (&f->flow.ip4_gtpc, &flow.ip4_gtpc);
298 break;
299 default:
300 rv = VNET_FLOW_ERROR_NOT_SUPPORTED;
301 goto out;
302 break;
Chenmin Sund0236f72020-07-27 17:54:40 +0800303 }
304
305 rv = vnet_flow_add (vnm, &flow, &flow_index);
306
Chenmin Sund0236f72020-07-27 17:54:40 +0800307out:
308 /* *INDENT-OFF* */
309 REPLY_MACRO2(VL_API_FLOW_ADD_REPLY,
310 ({
311 rmp->flow_index = ntohl (flow_index);
312 }));
Florin Corasb040f982020-10-20 14:59:43 -0700313 /* *INDENT-ON* */
Chenmin Sund0236f72020-07-27 17:54:40 +0800314}
315
316static void
317vl_api_flow_del_t_handler (vl_api_flow_del_t * mp)
318{
319 vl_api_flow_add_reply_t *rmp;
320 int rv = 0;
321
Florin Corasb040f982020-10-20 14:59:43 -0700322 vnet_main_t *vnm = vnet_get_main ();
323 rv = vnet_flow_del (vnm, ntohl (mp->flow_index));
Chenmin Sund0236f72020-07-27 17:54:40 +0800324
325 REPLY_MACRO (VL_API_FLOW_DEL_REPLY);
326}
327
328static void
329vl_api_flow_enable_t_handler (vl_api_flow_enable_t * mp)
330{
331 vl_api_flow_add_reply_t *rmp;
332 int rv = 0;
333
Florin Corasb040f982020-10-20 14:59:43 -0700334 vnet_main_t *vnm = vnet_get_main ();
335 rv =
336 vnet_flow_enable (vnm, ntohl (mp->flow_index), ntohl (mp->hw_if_index));
Chenmin Sund0236f72020-07-27 17:54:40 +0800337
338 REPLY_MACRO (VL_API_FLOW_ENABLE_REPLY);
339}
340
341static void
342vl_api_flow_disable_t_handler (vl_api_flow_disable_t * mp)
343{
344 vl_api_flow_add_reply_t *rmp;
345 int rv = 0;
346
Florin Corasb040f982020-10-20 14:59:43 -0700347 vnet_main_t *vnm = vnet_get_main ();
348 rv =
349 vnet_flow_disable (vnm, ntohl (mp->flow_index), ntohl (mp->hw_if_index));
Chenmin Sund0236f72020-07-27 17:54:40 +0800350
351 REPLY_MACRO (VL_API_FLOW_DISABLE_REPLY);
352}
353
354#define vl_msg_name_crc_list
355#include <vnet/flow/flow.api.h>
356#undef vl_msg_name_crc_list
357
358/*
359 * flow_api_hookup
360 * Add vpe's API message handlers to the table.
361 * vlib has already mapped shared memory and
362 * added the client registration handlers.
363 * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
364 */
365
366
367static void
368setup_message_id_table (api_main_t * am)
369{
370#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
371 foreach_vl_msg_name_crc_flow;
372#undef _
373}
374
375static clib_error_t *
376hw_flow_api_hookup (vlib_main_t * vm)
377{
378 api_main_t *am = vlibapi_get_main ();
379
380#define _(N,n) \
381 vl_msg_api_set_handlers(VL_API_##N, #n, \
382 vl_api_##n##_t_handler, \
383 vl_noop_handler, \
384 vl_api_##n##_t_endian, \
385 vl_api_##n##_t_print, \
386 sizeof(vl_api_##n##_t), 1);
387 foreach_vpe_api_msg;
388#undef _
389
390 /*
391 * Set up the (msg_name, crc, message-id) table
392 */
393 setup_message_id_table (am);
394
395 return 0;
396}
397
398VLIB_API_INIT_FUNCTION (hw_flow_api_hookup);
399
400/*
401 * fd.io coding-style-patch-verification: ON
402 *
403 * Local Variables:
404 * eval: (c-set-style "gnu")
405 * End:
406 */