blob: 62dc703d9a0e11ca93897fad7989624a09437170 [file] [log] [blame]
Pavel Kotucekeb9e6662017-01-24 13:40:26 +01001/*
2 *------------------------------------------------------------------
3 * flow_api.c - flow api
4 *
5 * Copyright (c) 2016 Cisco 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 <vnet/vnet.h>
21#include <vlibmemory/api.h>
Jakub Grajciar2f71a882019-10-10 14:21:22 +020022#include <vnet/ip/ip_types_api.h>
Florin Corasb040f982020-10-20 14:59:43 -070023#include <vnet/udp/udp_local.h>
Pavel Kotucekeb9e6662017-01-24 13:40:26 +010024
25#include <vnet/interface.h>
26#include <vnet/api_errno.h>
27
28#include <vnet/fib/fib_table.h>
Ole Troana9855ef2018-05-02 12:45:10 +020029#include <vnet/ipfix-export/flow_report.h>
30#include <vnet/ipfix-export/flow_report_classify.h>
Pavel Kotucekeb9e6662017-01-24 13:40:26 +010031
Filip Tehlar53dea272021-06-21 10:57:49 +000032#include <vnet/format_fns.h>
33#include <vnet/ipfix-export/ipfix_export.api_enum.h>
34#include <vnet/ipfix-export/ipfix_export.api_types.h>
Pavel Kotucekeb9e6662017-01-24 13:40:26 +010035
Filip Tehlar53dea272021-06-21 10:57:49 +000036#define REPLY_MSG_ID_BASE frm->msg_id_base
Pavel Kotucekeb9e6662017-01-24 13:40:26 +010037#include <vlibapi/api_helper_macros.h>
38
Paul Atkinsd747dd92021-09-22 14:56:17 +010039ipfix_exporter_t *
40vnet_ipfix_exporter_lookup (ip4_address_t *ipfix_collector)
41{
42 flow_report_main_t *frm = &flow_report_main;
43 ipfix_exporter_t *exp;
44
45 pool_foreach (exp, frm->exporters)
46 {
47 if (exp->ipfix_collector.as_u32 == ipfix_collector->as_u32)
48 return exp;
49 }
50
51 return NULL;
52}
53
54/*
55 * For backwards compatibility reasons index 0 in the set of exporters
56 * is alwyas used for the exporter created via the set_ipfix_exporter
57 * API.
58 */
59#define USE_INDEX_0 true
60#define USE_ANY_INDEX false
61
Paul Atkinsa6e131e2021-09-22 14:18:45 +010062static int
63vl_api_set_ipfix_exporter_t_internal (
64 u32 client_index, vl_api_address_t *mp_collector_address,
65 u16 mp_collector_port, vl_api_address_t *mp_src_address, u32 mp_vrf_id,
Paul Atkinsd747dd92021-09-22 14:56:17 +010066 u32 mp_path_mtu, u32 mp_template_interval, bool mp_udp_checksum,
67 bool use_index_0, bool is_create)
Pavel Kotucekeb9e6662017-01-24 13:40:26 +010068{
69 vlib_main_t *vm = vlib_get_main ();
70 flow_report_main_t *frm = &flow_report_main;
Paul Atkinsd747dd92021-09-22 14:56:17 +010071 ipfix_exporter_t *exp;
Paul Vinciguerra21b83e92019-06-24 09:55:46 -040072 vl_api_registration_t *reg;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +010073 ip4_address_t collector, src;
74 u16 collector_port = UDP_DST_PORT_ipfix;
75 u32 path_mtu;
76 u32 template_interval;
77 u8 udp_checksum;
78 u32 fib_id;
79 u32 fib_index = ~0;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +010080
Paul Atkinsa6e131e2021-09-22 14:18:45 +010081 reg = vl_api_client_index_to_registration (client_index);
Paul Vinciguerra21b83e92019-06-24 09:55:46 -040082 if (!reg)
Paul Atkinsa6e131e2021-09-22 14:18:45 +010083 return VNET_API_ERROR_UNIMPLEMENTED;
Paul Vinciguerra21b83e92019-06-24 09:55:46 -040084
Paul Atkinsd747dd92021-09-22 14:56:17 +010085 /* Collector address is the key for the exporter lookup */
86 ip4_address_decode (mp_collector_address->un.ip4, &collector);
87
88 if (use_index_0)
89 /*
90 * In this case we update the existing exporter. There is no delete
91 * for exp[0]
92 */
93 exp = &frm->exporters[0];
94 else
95 {
96 if (is_create)
97 {
98 exp = vnet_ipfix_exporter_lookup (&collector);
99 if (!exp)
100 {
101 /* Create a new exporter instead of updating an existing one */
102 if (pool_elts (frm->exporters) >= IPFIX_EXPORTERS_MAX)
103 return VNET_API_ERROR_INVALID_VALUE;
104 pool_get (frm->exporters, exp);
105 if (!exp)
106 return VNET_API_ERROR_INVALID_VALUE;
107 }
108 }
109 else
110 {
111 /* Delete the exporter */
112 exp = vnet_ipfix_exporter_lookup (&collector);
113 if (!exp)
114 return VNET_API_ERROR_NO_SUCH_ENTRY;
115
116 pool_put (frm->exporters, exp);
117 return 0;
118 }
119 }
120
Paul Atkinsa6e131e2021-09-22 14:18:45 +0100121 if (mp_src_address->af == ADDRESS_IP6 ||
122 mp_collector_address->af == ADDRESS_IP6)
Jakub Grajciar2f71a882019-10-10 14:21:22 +0200123 {
Paul Atkinsa6e131e2021-09-22 14:18:45 +0100124 return VNET_API_ERROR_UNIMPLEMENTED;
Jakub Grajciar2f71a882019-10-10 14:21:22 +0200125 }
126
Paul Atkinsa6e131e2021-09-22 14:18:45 +0100127 collector_port = ntohs (mp_collector_port);
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100128 if (collector_port == (u16) ~ 0)
129 collector_port = UDP_DST_PORT_ipfix;
Paul Atkinsa6e131e2021-09-22 14:18:45 +0100130 ip4_address_decode (mp_src_address->un.ip4, &src);
131 fib_id = ntohl (mp_vrf_id);
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100132
133 ip4_main_t *im = &ip4_main;
134 if (fib_id == ~0)
135 {
136 fib_index = ~0;
137 }
138 else
139 {
140 uword *p = hash_get (im->fib_index_by_table_id, fib_id);
141 if (!p)
Paul Atkinsa6e131e2021-09-22 14:18:45 +0100142 return VNET_API_ERROR_NO_SUCH_FIB;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100143 fib_index = p[0];
144 }
145
Paul Atkinsa6e131e2021-09-22 14:18:45 +0100146 path_mtu = ntohl (mp_path_mtu);
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100147 if (path_mtu == ~0)
148 path_mtu = 512; // RFC 7011 section 10.3.3.
Paul Atkinsa6e131e2021-09-22 14:18:45 +0100149 template_interval = ntohl (mp_template_interval);
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100150 if (template_interval == ~0)
151 template_interval = 20;
Paul Atkinsa6e131e2021-09-22 14:18:45 +0100152 udp_checksum = mp_udp_checksum;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100153
Alexander Chernavin67ec7522020-10-01 08:57:59 -0400154 if (collector.as_u32 != 0 && src.as_u32 == 0)
Paul Atkinsa6e131e2021-09-22 14:18:45 +0100155 return VNET_API_ERROR_INVALID_VALUE;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100156
157 if (path_mtu > 1450 /* vpp does not support fragmentation */ )
Paul Atkinsa6e131e2021-09-22 14:18:45 +0100158 return VNET_API_ERROR_INVALID_VALUE;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100159
160 if (path_mtu < 68)
Paul Atkinsa6e131e2021-09-22 14:18:45 +0100161 return VNET_API_ERROR_INVALID_VALUE;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100162
Paul Atkins19a5f232021-09-27 21:30:13 +0100163 /* Calculate how much header data we need. */
164 exp->all_headers_size = sizeof (ip4_header_t) + sizeof (udp_header_t) +
165 sizeof (ipfix_message_header_t) +
166 sizeof (ipfix_set_header_t);
167
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100168 /* Reset report streams if we are reconfiguring IP addresses */
Paul Atkins9ec64492021-09-21 20:49:12 +0100169 if (exp->ipfix_collector.as_u32 != collector.as_u32 ||
170 exp->src_address.as_u32 != src.as_u32 ||
171 exp->collector_port != collector_port)
Paul Atkins40f9a7a2021-09-22 10:06:23 +0100172 vnet_flow_reports_reset (exp);
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100173
Paul Atkins9ec64492021-09-21 20:49:12 +0100174 exp->ipfix_collector.as_u32 = collector.as_u32;
175 exp->collector_port = collector_port;
176 exp->src_address.as_u32 = src.as_u32;
177 exp->fib_index = fib_index;
178 exp->path_mtu = path_mtu;
179 exp->template_interval = template_interval;
180 exp->udp_checksum = udp_checksum;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100181
182 /* Turn on the flow reporting process */
183 vlib_process_signal_event (vm, flow_report_process_node.index, 1, 0);
184
Paul Atkinsa6e131e2021-09-22 14:18:45 +0100185 return 0;
186}
187
188static void
189vl_api_set_ipfix_exporter_t_handler (vl_api_set_ipfix_exporter_t *mp)
190{
191 vl_api_set_ipfix_exporter_reply_t *rmp;
192 flow_report_main_t *frm = &flow_report_main;
193 int rv = vl_api_set_ipfix_exporter_t_internal (
194 mp->client_index, &mp->collector_address, mp->collector_port,
195 &mp->src_address, mp->vrf_id, mp->path_mtu, mp->template_interval,
Paul Atkinsd747dd92021-09-22 14:56:17 +0100196 mp->udp_checksum, USE_INDEX_0, 0);
Paul Atkinsa6e131e2021-09-22 14:18:45 +0100197
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100198 REPLY_MACRO (VL_API_SET_IPFIX_EXPORTER_REPLY);
199}
200
201static void
Paul Atkinsd747dd92021-09-22 14:56:17 +0100202vl_api_ipfix_exporter_create_delete_t_handler (
203 vl_api_ipfix_exporter_create_delete_t *mp)
204{
205 vl_api_ipfix_exporter_create_delete_reply_t *rmp;
206 flow_report_main_t *frm = &flow_report_main;
207 int rv = vl_api_set_ipfix_exporter_t_internal (
208 mp->client_index, &mp->collector_address, mp->collector_port,
209 &mp->src_address, mp->vrf_id, mp->path_mtu, mp->template_interval,
210 mp->udp_checksum, USE_ANY_INDEX, mp->is_create);
211
212 REPLY_MACRO (VL_API_IPFIX_EXPORTER_CREATE_DELETE_REPLY);
213}
214
215static void
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100216vl_api_ipfix_exporter_dump_t_handler (vl_api_ipfix_exporter_dump_t * mp)
217{
218 flow_report_main_t *frm = &flow_report_main;
Paul Atkins9ec64492021-09-21 20:49:12 +0100219 ipfix_exporter_t *exp = pool_elt_at_index (flow_report_main.exporters, 0);
Florin Coras6c4dae22018-01-09 06:39:23 -0800220 vl_api_registration_t *reg;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100221 vl_api_ipfix_exporter_details_t *rmp;
222 ip4_main_t *im = &ip4_main;
Jakub Grajciar2f71a882019-10-10 14:21:22 +0200223 ip46_address_t collector = {.as_u64[0] = 0,.as_u64[1] = 0 };
224 ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100225 u32 vrf_id;
226
Florin Coras6c4dae22018-01-09 06:39:23 -0800227 reg = vl_api_client_index_to_registration (mp->client_index);
228 if (!reg)
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400229 return;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100230
231 rmp = vl_msg_api_alloc (sizeof (*rmp));
Dave Barachb7b92992018-10-17 10:38:51 -0400232 clib_memset (rmp, 0, sizeof (*rmp));
Paul Atkins5df0b342021-09-23 10:55:25 +0100233 rmp->_vl_msg_id =
234 ntohs ((REPLY_MSG_ID_BASE) + VL_API_IPFIX_EXPORTER_DETAILS);
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100235 rmp->context = mp->context;
Jakub Grajciar2f71a882019-10-10 14:21:22 +0200236
Paul Atkins9ec64492021-09-21 20:49:12 +0100237 memcpy (&collector.ip4, &exp->ipfix_collector, sizeof (ip4_address_t));
Jakub Grajciar2f71a882019-10-10 14:21:22 +0200238 ip_address_encode (&collector, IP46_TYPE_IP4, &rmp->collector_address);
239
Paul Atkins9ec64492021-09-21 20:49:12 +0100240 rmp->collector_port = htons (exp->collector_port);
Jakub Grajciar2f71a882019-10-10 14:21:22 +0200241
Paul Atkins9ec64492021-09-21 20:49:12 +0100242 memcpy (&src.ip4, &exp->src_address, sizeof (ip4_address_t));
Jakub Grajciar2f71a882019-10-10 14:21:22 +0200243 ip_address_encode (&src, IP46_TYPE_IP4, &rmp->src_address);
244
Paul Atkins9ec64492021-09-21 20:49:12 +0100245 if (exp->fib_index == ~0)
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100246 vrf_id = ~0;
247 else
Paul Atkins9ec64492021-09-21 20:49:12 +0100248 vrf_id = im->fibs[exp->fib_index].ft_table_id;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100249 rmp->vrf_id = htonl (vrf_id);
Paul Atkins9ec64492021-09-21 20:49:12 +0100250 rmp->path_mtu = htonl (exp->path_mtu);
251 rmp->template_interval = htonl (exp->template_interval);
252 rmp->udp_checksum = (exp->udp_checksum != 0);
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100253
Florin Coras6c4dae22018-01-09 06:39:23 -0800254 vl_api_send_msg (reg, (u8 *) rmp);
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100255}
256
257static void
Paul Atkinsacb0d2d2021-09-23 09:28:50 +0100258ipfix_all_fill_details (vl_api_ipfix_all_exporter_details_t *rmp,
259 ipfix_exporter_t *exp)
260{
261 ip4_main_t *im = &ip4_main;
262 ip46_address_t collector = { .as_u64[0] = 0, .as_u64[1] = 0 };
263 ip46_address_t src = { .as_u64[0] = 0, .as_u64[1] = 0 };
264 u32 vrf_id;
265
266 memcpy (&collector.ip4, &exp->ipfix_collector, sizeof (ip4_address_t));
267 ip_address_encode (&collector, IP46_TYPE_IP4, &rmp->collector_address);
268
269 rmp->collector_port = htons (exp->collector_port);
270
271 memcpy (&src.ip4, &exp->src_address, sizeof (ip4_address_t));
272 ip_address_encode (&src, IP46_TYPE_IP4, &rmp->src_address);
273
274 if (exp->fib_index == ~0)
275 vrf_id = ~0;
276 else
277 vrf_id = im->fibs[exp->fib_index].ft_table_id;
278 rmp->vrf_id = htonl (vrf_id);
279 rmp->path_mtu = htonl (exp->path_mtu);
280 rmp->template_interval = htonl (exp->template_interval);
281 rmp->udp_checksum = (exp->udp_checksum != 0);
282}
283
284static void
285ipfix_all_exporter_details (flow_report_main_t *frm, u32 index,
286 vl_api_registration_t *rp, u32 context)
287{
288 ipfix_exporter_t *exp = pool_elt_at_index (frm->exporters, index);
289
290 vl_api_ipfix_all_exporter_details_t *rmp;
291
292 REPLY_MACRO_DETAILS4 (VL_API_IPFIX_ALL_EXPORTER_DETAILS, rp, context,
293 ({ ipfix_all_fill_details (rmp, exp); }));
294}
295
296static void
297vl_api_ipfix_all_exporter_get_t_handler (vl_api_ipfix_all_exporter_get_t *mp)
298{
299 flow_report_main_t *frm = &flow_report_main;
300 vl_api_ipfix_all_exporter_get_reply_t *rmp;
301 int rv = 0;
302
303 REPLY_AND_DETAILS_MACRO (
304 VL_API_IPFIX_ALL_EXPORTER_GET_REPLY, frm->exporters,
305 ({ ipfix_all_exporter_details (frm, cursor, rp, mp->context); }));
306}
307
308static void
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100309 vl_api_set_ipfix_classify_stream_t_handler
310 (vl_api_set_ipfix_classify_stream_t * mp)
311{
312 vl_api_set_ipfix_classify_stream_reply_t *rmp;
313 flow_report_classify_main_t *fcm = &flow_report_classify_main;
314 flow_report_main_t *frm = &flow_report_main;
Paul Atkins40f9a7a2021-09-22 10:06:23 +0100315 ipfix_exporter_t *exp = &frm->exporters[0];
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100316 u32 domain_id = 0;
317 u32 src_port = UDP_DST_PORT_ipfix;
318 int rv = 0;
319
320 domain_id = ntohl (mp->domain_id);
321 src_port = ntohs (mp->src_port);
322
323 if (fcm->src_port != 0 &&
324 (fcm->domain_id != domain_id || fcm->src_port != (u16) src_port))
325 {
Paul Atkins40f9a7a2021-09-22 10:06:23 +0100326 int rv = vnet_stream_change (exp, fcm->domain_id, fcm->src_port,
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100327 domain_id, (u16) src_port);
328 ASSERT (rv == 0);
329 }
330
331 fcm->domain_id = domain_id;
332 fcm->src_port = (u16) src_port;
333
334 REPLY_MACRO (VL_API_SET_IPFIX_CLASSIFY_STREAM_REPLY);
335}
336
337static void
338 vl_api_ipfix_classify_stream_dump_t_handler
339 (vl_api_ipfix_classify_stream_dump_t * mp)
340{
341 flow_report_classify_main_t *fcm = &flow_report_classify_main;
Florin Coras6c4dae22018-01-09 06:39:23 -0800342 vl_api_registration_t *reg;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100343 vl_api_ipfix_classify_stream_details_t *rmp;
344
Florin Coras6c4dae22018-01-09 06:39:23 -0800345 reg = vl_api_client_index_to_registration (mp->client_index);
346 if (!reg)
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100347 return;
348
349 rmp = vl_msg_api_alloc (sizeof (*rmp));
Dave Barachb7b92992018-10-17 10:38:51 -0400350 clib_memset (rmp, 0, sizeof (*rmp));
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100351 rmp->_vl_msg_id = ntohs (VL_API_IPFIX_CLASSIFY_STREAM_DETAILS);
352 rmp->context = mp->context;
353 rmp->domain_id = htonl (fcm->domain_id);
354 rmp->src_port = htons (fcm->src_port);
355
Florin Coras6c4dae22018-01-09 06:39:23 -0800356 vl_api_send_msg (reg, (u8 *) rmp);
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100357}
358
359static void
360 vl_api_ipfix_classify_table_add_del_t_handler
361 (vl_api_ipfix_classify_table_add_del_t * mp)
362{
363 vl_api_ipfix_classify_table_add_del_reply_t *rmp;
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400364 vl_api_registration_t *reg;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100365 flow_report_classify_main_t *fcm = &flow_report_classify_main;
366 flow_report_main_t *frm = &flow_report_main;
Paul Atkins40f9a7a2021-09-22 10:06:23 +0100367 ipfix_exporter_t *exp = &frm->exporters[0];
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100368 vnet_flow_report_add_del_args_t args;
369 ipfix_classify_table_t *table;
370 int is_add;
371 u32 classify_table_index;
372 u8 ip_version;
373 u8 transport_protocol;
374 int rv = 0;
375
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400376 reg = vl_api_client_index_to_registration (mp->client_index);
377 if (!reg)
378 return;
379
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100380 classify_table_index = ntohl (mp->table_id);
Alexander Chernavinf6cf57c2020-09-30 10:36:10 -0400381 ip_version = (mp->ip_version == ADDRESS_IP4) ? 4 : 6;
382 transport_protocol = mp->transport_protocol;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100383 is_add = mp->is_add;
384
385 if (fcm->src_port == 0)
386 {
387 /* call set_ipfix_classify_stream first */
388 rv = VNET_API_ERROR_UNSPECIFIED;
389 goto out;
390 }
391
Dave Barachb7b92992018-10-17 10:38:51 -0400392 clib_memset (&args, 0, sizeof (args));
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100393
394 table = 0;
395 int i;
396 for (i = 0; i < vec_len (fcm->tables); i++)
397 if (ipfix_classify_table_index_valid (i))
398 if (fcm->tables[i].classify_table_index == classify_table_index)
399 {
400 table = &fcm->tables[i];
401 break;
402 }
403
404 if (is_add)
405 {
406 if (table)
407 {
408 rv = VNET_API_ERROR_VALUE_EXIST;
409 goto out;
410 }
411 table = ipfix_classify_add_table ();
412 table->classify_table_index = classify_table_index;
413 }
414 else
415 {
416 if (!table)
417 {
418 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
419 goto out;
420 }
421 }
422
423 table->ip_version = ip_version;
424 table->transport_protocol = transport_protocol;
425
426 args.opaque.as_uword = table - fcm->tables;
427 args.rewrite_callback = ipfix_classify_template_rewrite;
428 args.flow_data_callback = ipfix_classify_send_flows;
429 args.is_add = is_add;
430 args.domain_id = fcm->domain_id;
431 args.src_port = fcm->src_port;
432
Paul Atkins40f9a7a2021-09-22 10:06:23 +0100433 rv = vnet_flow_report_add_del (exp, &args, NULL);
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100434
435 /* If deleting, or add failed */
436 if (is_add == 0 || (rv && is_add))
437 ipfix_classify_delete_table (table - fcm->tables);
438
439out:
440 REPLY_MACRO (VL_API_SET_IPFIX_CLASSIFY_STREAM_REPLY);
441}
442
443static void
444send_ipfix_classify_table_details (u32 table_index,
Florin Coras6c4dae22018-01-09 06:39:23 -0800445 vl_api_registration_t * reg, u32 context)
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100446{
447 flow_report_classify_main_t *fcm = &flow_report_classify_main;
448 vl_api_ipfix_classify_table_details_t *mp;
449
450 ipfix_classify_table_t *table = &fcm->tables[table_index];
451
452 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400453 clib_memset (mp, 0, sizeof (*mp));
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100454 mp->_vl_msg_id = ntohs (VL_API_IPFIX_CLASSIFY_TABLE_DETAILS);
455 mp->context = context;
456 mp->table_id = htonl (table->classify_table_index);
Alexander Chernavinf6cf57c2020-09-30 10:36:10 -0400457 mp->ip_version = (table->ip_version == 4) ? ADDRESS_IP4 : ADDRESS_IP6;
458 mp->transport_protocol = table->transport_protocol;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100459
Florin Coras6c4dae22018-01-09 06:39:23 -0800460 vl_api_send_msg (reg, (u8 *) mp);
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100461}
462
463static void
464 vl_api_ipfix_classify_table_dump_t_handler
465 (vl_api_ipfix_classify_table_dump_t * mp)
466{
467 flow_report_classify_main_t *fcm = &flow_report_classify_main;
Florin Coras6c4dae22018-01-09 06:39:23 -0800468 vl_api_registration_t *reg;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100469 u32 i;
470
Florin Coras6c4dae22018-01-09 06:39:23 -0800471 reg = vl_api_client_index_to_registration (mp->client_index);
472 if (!reg)
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100473 return;
474
475 for (i = 0; i < vec_len (fcm->tables); i++)
476 if (ipfix_classify_table_index_valid (i))
Florin Coras6c4dae22018-01-09 06:39:23 -0800477 send_ipfix_classify_table_details (i, reg, mp->context);
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100478}
479
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400480static void
481vl_api_ipfix_flush_t_handler (vl_api_ipfix_flush_t * mp)
482{
Filip Tehlar53dea272021-06-21 10:57:49 +0000483 flow_report_main_t *frm = &flow_report_main;
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400484 vl_api_ipfix_flush_reply_t *rmp;
485 vl_api_registration_t *reg;
486 vlib_main_t *vm = vlib_get_main ();
487 int rv = 0;
488
489 reg = vl_api_client_index_to_registration (mp->client_index);
490 if (!reg)
491 return;
492
493 /* poke the flow reporting process */
494 vlib_process_signal_event (vm, flow_report_process_node.index,
495 1 /* type_opaque */ , 0 /* data */ );
496
497 REPLY_MACRO (VL_API_IPFIX_FLUSH_REPLY);
498}
499
Filip Tehlar53dea272021-06-21 10:57:49 +0000500#include <vnet/ipfix-export/ipfix_export.api.c>
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100501static clib_error_t *
502flow_api_hookup (vlib_main_t * vm)
503{
Filip Tehlar53dea272021-06-21 10:57:49 +0000504 flow_report_main_t *frm = &flow_report_main;
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100505 /*
506 * Set up the (msg_name, crc, message-id) table
507 */
Filip Tehlar53dea272021-06-21 10:57:49 +0000508 REPLY_MSG_ID_BASE = setup_message_id_table ();
Pavel Kotucekeb9e6662017-01-24 13:40:26 +0100509
510 return 0;
511}
512
513VLIB_API_INIT_FUNCTION (flow_api_hookup);
514
515/*
516 * fd.io coding-style-patch-verification: ON
517 *
518 * Local Variables:
519 * eval: (c-set-style "gnu")
520 * End:
521 */