tls: tlspicotls require version when building
[vpp.git] / src / vnet / flow / flow_api.c
1 /*
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>
28 #include <vnet/udp/udp_local.h>
29 #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
55 static inline void
56 ipv4_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
62 static inline void
63 ipv6_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
69 static inline void
70 protocol_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
77 static inline void
78 port_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
85 static inline void
86 ipv4_n_tuple_flow_convert (vl_api_flow_ip4_n_tuple_t * vl_api_flow,
87                            vnet_flow_ip4_n_tuple_t * f)
88 {
89   ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
90   ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
91   protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
92
93   port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
94   port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
95 }
96
97 static void
98 ipv6_n_tuple_flow_convert (vl_api_flow_ip6_n_tuple_t * vl_api_flow,
99                            vnet_flow_ip6_n_tuple_t * f)
100 {
101   ipv6_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
102   ipv6_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
103   protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
104
105   port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
106   port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
107 }
108
109 static inline void
110 ipv4_n_tuple_tagged_flow_convert (vl_api_flow_ip4_n_tuple_tagged_t *
111                                   vl_api_flow,
112                                   vnet_flow_ip4_n_tuple_tagged_t * f)
113 {
114   return ipv4_n_tuple_flow_convert ((vl_api_flow_ip4_n_tuple_t *) vl_api_flow,
115                                     (vnet_flow_ip4_n_tuple_t *) f);
116 }
117
118 static inline void
119 ipv6_n_tuple_tagged_flow_convert (vl_api_flow_ip6_n_tuple_tagged_t *
120                                   vl_api_flow,
121                                   vnet_flow_ip6_n_tuple_tagged_t * f)
122 {
123   return ipv6_n_tuple_flow_convert ((vl_api_flow_ip6_n_tuple_t *) vl_api_flow,
124                                     (vnet_flow_ip6_n_tuple_t *) f);
125 }
126
127 static inline void
128 ipv4_l2tpv3oip_flow_convert (vl_api_flow_ip4_l2tpv3oip_t * vl_api_flow,
129                              vnet_flow_ip4_l2tpv3oip_t * f)
130 {
131   ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
132   ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
133
134   protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
135   f->session_id = ntohl (vl_api_flow->session_id);
136 }
137
138 static inline void
139 ipv4_ipsec_esp_flow_convert (vl_api_flow_ip4_ipsec_esp_t * vl_api_flow,
140                              vnet_flow_ip4_ipsec_esp_t * f)
141 {
142   ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
143   ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
144
145   protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
146   f->spi = ntohl (vl_api_flow->spi);
147 }
148
149 static inline void
150 ipv4_ipsec_ah_flow_convert (vl_api_flow_ip4_ipsec_ah_t * vl_api_flow,
151                             vnet_flow_ip4_ipsec_ah_t * f)
152 {
153   ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
154   ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
155
156   protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
157   f->spi = ntohl (vl_api_flow->spi);
158 }
159
160 static inline void
161 ipv4_gtpu_flow_convert (vl_api_flow_ip4_gtpu_t * vl_api_flow,
162                         vnet_flow_ip4_gtpu_t * f)
163 {
164   ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
165   ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
166
167   port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
168   port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
169
170   protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
171   f->teid = ntohl (vl_api_flow->teid);
172 }
173
174 static inline void
175 ipv4_gtpc_flow_convert (vl_api_flow_ip4_gtpc_t * vl_api_flow,
176                         vnet_flow_ip4_gtpc_t * f)
177 {
178   ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
179   ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
180
181   port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
182   port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
183
184   protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
185   f->teid = ntohl (vl_api_flow->teid);
186 }
187
188 static void
189 vl_api_flow_add_t_handler (vl_api_flow_add_t * mp)
190 {
191   vl_api_flow_add_reply_t *rmp;
192   int rv = 0;
193   vnet_flow_t flow;
194   u32 flow_index = ~0;
195   vl_api_flow_rule_t *f = &mp->flow;
196
197   vnet_main_t *vnm = vnet_get_main ();
198
199   flow.type = ntohl (f->type);
200   flow.actions = ntohl (f->actions);
201   flow.mark_flow_id = ntohl (f->mark_flow_id);
202   flow.redirect_node_index = ntohl (f->redirect_node_index);
203   flow.redirect_device_input_next_index =
204     ntohl (f->redirect_device_input_next_index);
205   flow.redirect_queue = ntohl (f->redirect_queue);
206   flow.buffer_advance = ntohl (f->buffer_advance);
207
208   switch (flow.type)
209     {
210     case VNET_FLOW_TYPE_IP4_N_TUPLE:
211       ipv4_n_tuple_flow_convert (&f->flow.ip4_n_tuple, &flow.ip4_n_tuple);
212       break;
213     case VNET_FLOW_TYPE_IP6_N_TUPLE:
214       ipv6_n_tuple_flow_convert (&f->flow.ip6_n_tuple, &flow.ip6_n_tuple);
215       break;
216     case VNET_FLOW_TYPE_IP4_N_TUPLE_TAGGED:
217       ipv4_n_tuple_tagged_flow_convert (&f->flow.ip4_n_tuple_tagged,
218                                         &flow.ip4_n_tuple_tagged);
219       break;
220     case VNET_FLOW_TYPE_IP6_N_TUPLE_TAGGED:
221       ipv6_n_tuple_tagged_flow_convert (&f->flow.ip6_n_tuple_tagged,
222                                         &flow.ip6_n_tuple_tagged);
223       break;
224     case VNET_FLOW_TYPE_IP4_L2TPV3OIP:
225       ipv4_l2tpv3oip_flow_convert (&f->flow.ip4_l2tpv3oip,
226                                    &flow.ip4_l2tpv3oip);
227       break;
228     case VNET_FLOW_TYPE_IP4_IPSEC_ESP:
229       ipv4_ipsec_esp_flow_convert (&f->flow.ip4_ipsec_esp,
230                                    &flow.ip4_ipsec_esp);
231       break;
232     case VNET_FLOW_TYPE_IP4_IPSEC_AH:
233       ipv4_ipsec_ah_flow_convert (&f->flow.ip4_ipsec_ah, &flow.ip4_ipsec_ah);
234       break;
235     case VNET_FLOW_TYPE_IP4_GTPU:
236       ipv4_gtpu_flow_convert (&f->flow.ip4_gtpu, &flow.ip4_gtpu);
237       break;
238     case VNET_FLOW_TYPE_IP4_GTPC:
239       ipv4_gtpc_flow_convert (&f->flow.ip4_gtpc, &flow.ip4_gtpc);
240       break;
241     default:
242       rv = VNET_FLOW_ERROR_NOT_SUPPORTED;
243       goto out;
244       break;
245     }
246
247   rv = vnet_flow_add (vnm, &flow, &flow_index);
248
249 out:
250   /* *INDENT-OFF* */
251   REPLY_MACRO2(VL_API_FLOW_ADD_REPLY,
252   ({
253     rmp->flow_index = ntohl (flow_index);
254   }));
255   /* *INDENT-ON* */
256 }
257
258 static void
259 vl_api_flow_del_t_handler (vl_api_flow_del_t * mp)
260 {
261   vl_api_flow_add_reply_t *rmp;
262   int rv = 0;
263
264   vnet_main_t *vnm = vnet_get_main ();
265   rv = vnet_flow_del (vnm, ntohl (mp->flow_index));
266
267   REPLY_MACRO (VL_API_FLOW_DEL_REPLY);
268 }
269
270 static void
271 vl_api_flow_enable_t_handler (vl_api_flow_enable_t * mp)
272 {
273   vl_api_flow_add_reply_t *rmp;
274   int rv = 0;
275
276   vnet_main_t *vnm = vnet_get_main ();
277   rv =
278     vnet_flow_enable (vnm, ntohl (mp->flow_index), ntohl (mp->hw_if_index));
279
280   REPLY_MACRO (VL_API_FLOW_ENABLE_REPLY);
281 }
282
283 static void
284 vl_api_flow_disable_t_handler (vl_api_flow_disable_t * mp)
285 {
286   vl_api_flow_add_reply_t *rmp;
287   int rv = 0;
288
289   vnet_main_t *vnm = vnet_get_main ();
290   rv =
291     vnet_flow_disable (vnm, ntohl (mp->flow_index), ntohl (mp->hw_if_index));
292
293   REPLY_MACRO (VL_API_FLOW_DISABLE_REPLY);
294 }
295
296 #define vl_msg_name_crc_list
297 #include <vnet/flow/flow.api.h>
298 #undef vl_msg_name_crc_list
299
300 /*
301  * flow_api_hookup
302  * Add vpe's API message handlers to the table.
303  * vlib has already mapped shared memory and
304  * added the client registration handlers.
305  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
306  */
307
308
309 static void
310 setup_message_id_table (api_main_t * am)
311 {
312 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
313   foreach_vl_msg_name_crc_flow;
314 #undef _
315 }
316
317 static clib_error_t *
318 hw_flow_api_hookup (vlib_main_t * vm)
319 {
320   api_main_t *am = vlibapi_get_main ();
321
322 #define _(N,n)                                                  \
323     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
324                            vl_api_##n##_t_handler,              \
325                            vl_noop_handler,                     \
326                            vl_api_##n##_t_endian,               \
327                            vl_api_##n##_t_print,                \
328                            sizeof(vl_api_##n##_t), 1);
329   foreach_vpe_api_msg;
330 #undef _
331
332   /*
333    * Set up the (msg_name, crc, message-id) table
334    */
335   setup_message_id_table (am);
336
337   return 0;
338 }
339
340 VLIB_API_INIT_FUNCTION (hw_flow_api_hookup);
341
342 /*
343  * fd.io coding-style-patch-verification: ON
344  *
345  * Local Variables:
346  * eval: (c-set-style "gnu")
347  * End:
348  */