blob: 4b890728a8a28d0522b3c5ff2220882ca99a0c1d [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15/*
16 * flow_report.c
17 */
18#include <vnet/flow/flow_report.h>
19#include <vnet/api_errno.h>
20
Juraj Sloboda837fbb12016-07-06 23:11:47 -070021flow_report_main_t flow_report_main;
22
Swarup Nayak6bcac062017-11-26 23:11:40 +053023static_always_inline u8
24stream_index_valid (u32 index)
Juraj Slobodaffa652a2016-08-07 23:43:42 -070025{
Swarup Nayak6bcac062017-11-26 23:11:40 +053026 flow_report_main_t *frm = &flow_report_main;
27 return index < vec_len (frm->streams) &&
28 frm->streams[index].domain_id != ~0;
Juraj Slobodaffa652a2016-08-07 23:43:42 -070029}
30
Swarup Nayak6bcac062017-11-26 23:11:40 +053031static_always_inline flow_report_stream_t *
32add_stream (void)
Juraj Slobodaffa652a2016-08-07 23:43:42 -070033{
Swarup Nayak6bcac062017-11-26 23:11:40 +053034 flow_report_main_t *frm = &flow_report_main;
Juraj Slobodaffa652a2016-08-07 23:43:42 -070035 u32 i;
Swarup Nayak6bcac062017-11-26 23:11:40 +053036 for (i = 0; i < vec_len (frm->streams); i++)
37 if (!stream_index_valid (i))
Juraj Slobodaffa652a2016-08-07 23:43:42 -070038 return &frm->streams[i];
Swarup Nayak6bcac062017-11-26 23:11:40 +053039 u32 index = vec_len (frm->streams);
40 vec_validate (frm->streams, index);
Juraj Slobodaffa652a2016-08-07 23:43:42 -070041 return &frm->streams[index];
42}
43
Swarup Nayak6bcac062017-11-26 23:11:40 +053044static_always_inline void
45delete_stream (u32 index)
Juraj Slobodaffa652a2016-08-07 23:43:42 -070046{
Swarup Nayak6bcac062017-11-26 23:11:40 +053047 flow_report_main_t *frm = &flow_report_main;
48 ASSERT (index < vec_len (frm->streams));
Juraj Slobodaffa652a2016-08-07 23:43:42 -070049 ASSERT (frm->streams[index].domain_id != ~0);
50 frm->streams[index].domain_id = ~0;
51}
52
Swarup Nayak6bcac062017-11-26 23:11:40 +053053static i32
54find_stream (u32 domain_id, u16 src_port)
Juraj Slobodaffa652a2016-08-07 23:43:42 -070055{
Swarup Nayak6bcac062017-11-26 23:11:40 +053056 flow_report_main_t *frm = &flow_report_main;
57 flow_report_stream_t *stream;
Juraj Slobodaffa652a2016-08-07 23:43:42 -070058 u32 i;
Swarup Nayak6bcac062017-11-26 23:11:40 +053059 for (i = 0; i < vec_len (frm->streams); i++)
60 if (stream_index_valid (i))
61 {
62 stream = &frm->streams[i];
63 if (domain_id == stream->domain_id)
64 {
65 if (src_port != stream->src_port)
66 return -2;
67 return i;
68 }
69 else if (src_port == stream->src_port)
70 {
71 return -2;
72 }
Juraj Slobodaffa652a2016-08-07 23:43:42 -070073 }
Juraj Slobodaffa652a2016-08-07 23:43:42 -070074 return -1;
75}
76
Swarup Nayak6bcac062017-11-26 23:11:40 +053077int
78send_template_packet (flow_report_main_t * frm,
79 flow_report_t * fr, u32 * buffer_indexp)
Ed Warnickecb9cada2015-12-08 15:45:58 -070080{
81 u32 bi0;
Swarup Nayak6bcac062017-11-26 23:11:40 +053082 vlib_buffer_t *b0;
83 ip4_ipfix_template_packet_t *tp;
84 ipfix_message_header_t *h;
85 ip4_header_t *ip;
86 udp_header_t *udp;
87 vlib_main_t *vm = frm->vlib_main;
88 flow_report_stream_t *stream;
Dave Barach393252a2016-11-02 18:37:56 -040089 vlib_buffer_free_list_t *fl;
Ed Warnickecb9cada2015-12-08 15:45:58 -070090
91 ASSERT (buffer_indexp);
92
93 if (fr->update_rewrite || fr->rewrite == 0)
94 {
Swarup Nayak6bcac062017-11-26 23:11:40 +053095 if (frm->ipfix_collector.as_u32 == 0 || frm->src_address.as_u32 == 0)
96 {
97 vlib_node_set_state (frm->vlib_main, flow_report_process_node.index,
98 VLIB_NODE_STATE_DISABLED);
99 return -1;
100 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700101 vec_free (fr->rewrite);
102 fr->update_rewrite = 1;
103 }
104
105 if (fr->update_rewrite)
106 {
107 fr->rewrite = fr->rewrite_callback (frm, fr,
Swarup Nayak6bcac062017-11-26 23:11:40 +0530108 &frm->ipfix_collector,
109 &frm->src_address,
110 frm->collector_port);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700111 fr->update_rewrite = 0;
112 }
113
114 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
115 return -1;
Swarup Nayak6bcac062017-11-26 23:11:40 +0530116
Ed Warnickecb9cada2015-12-08 15:45:58 -0700117 b0 = vlib_get_buffer (vm, bi0);
118
Dave Barach393252a2016-11-02 18:37:56 -0400119 /* Initialize the buffer */
120 fl = vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
121 vlib_buffer_init_for_free_list (b0, fl);
122 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
123
Ed Warnickecb9cada2015-12-08 15:45:58 -0700124 ASSERT (vec_len (fr->rewrite) < VLIB_BUFFER_DEFAULT_FREE_LIST_BYTES);
Swarup Nayak6bcac062017-11-26 23:11:40 +0530125
Damjan Marionf1213b82016-03-13 02:22:06 +0100126 clib_memcpy (b0->data, fr->rewrite, vec_len (fr->rewrite));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700127 b0->current_data = 0;
128 b0->current_length = vec_len (fr->rewrite);
Damjan Mariondac03522018-02-01 15:30:13 +0100129 b0->flags |= (VLIB_BUFFER_TOTAL_LENGTH_VALID | VNET_BUFFER_F_FLOW_REPORT);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700130 vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0;
Juraj Sloboda86634f02016-07-01 06:12:58 -0700131 vnet_buffer (b0)->sw_if_index[VLIB_TX] = frm->fib_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700132
133 tp = vlib_buffer_get_current (b0);
Swarup Nayak6bcac062017-11-26 23:11:40 +0530134 ip = (ip4_header_t *) & tp->ip4;
135 udp = (udp_header_t *) (ip + 1);
136 h = (ipfix_message_header_t *) (udp + 1);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700137
Swarup Nayak6bcac062017-11-26 23:11:40 +0530138 /* FIXUP: message header export_time */
139 h->export_time = (u32)
140 (((f64) frm->unix_time_0) +
141 (vlib_time_now (frm->vlib_main) - frm->vlib_time_0));
142 h->export_time = clib_host_to_net_u32 (h->export_time);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700143
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700144 stream = &frm->streams[fr->stream_index];
145
Ed Warnickecb9cada2015-12-08 15:45:58 -0700146 /* FIXUP: message header sequence_number. Templates do not increase it */
Swarup Nayak6bcac062017-11-26 23:11:40 +0530147 h->sequence_number = clib_host_to_net_u32 (stream->sequence_number);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700148
149 /* FIXUP: udp length */
150 udp->length = clib_host_to_net_u16 (b0->current_length - sizeof (*ip));
151
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700152 if (frm->udp_checksum)
153 {
154 /* RFC 7011 section 10.3.2. */
155 udp->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ip);
156 if (udp->checksum == 0)
Swarup Nayak6bcac062017-11-26 23:11:40 +0530157 udp->checksum = 0xffff;
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700158 }
159
Ed Warnickecb9cada2015-12-08 15:45:58 -0700160 *buffer_indexp = bi0;
Juraj Sloboda0d2a8e72016-07-07 02:59:28 -0700161
162 fr->last_template_sent = vlib_time_now (vm);
163
Ed Warnickecb9cada2015-12-08 15:45:58 -0700164 return 0;
165}
166
167static uword
168flow_report_process (vlib_main_t * vm,
Swarup Nayak6bcac062017-11-26 23:11:40 +0530169 vlib_node_runtime_t * rt, vlib_frame_t * f)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700170{
Swarup Nayak6bcac062017-11-26 23:11:40 +0530171 flow_report_main_t *frm = &flow_report_main;
172 flow_report_t *fr;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700173 u32 ip4_lookup_node_index;
Swarup Nayak6bcac062017-11-26 23:11:40 +0530174 vlib_node_t *ip4_lookup_node;
175 vlib_frame_t *nf = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700176 u32 template_bi;
Swarup Nayak6bcac062017-11-26 23:11:40 +0530177 u32 *to_next;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700178 int send_template;
179 f64 now;
180 int rv;
181 uword event_type;
182 uword *event_data = 0;
183
184 /* Wait for Godot... */
185 vlib_process_wait_for_event_or_clock (vm, 1e9);
186 event_type = vlib_process_get_events (vm, &event_data);
187 if (event_type != 1)
Swarup Nayak6bcac062017-11-26 23:11:40 +0530188 clib_warning ("bogus kickoff event received, %d", event_type);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700189 vec_reset_length (event_data);
190
191 /* Enqueue pkts to ip4-lookup */
192 ip4_lookup_node = vlib_get_node_by_name (vm, (u8 *) "ip4-lookup");
193 ip4_lookup_node_index = ip4_lookup_node->index;
194
Swarup Nayak6bcac062017-11-26 23:11:40 +0530195 while (1)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700196 {
Dave Barach0f3b6802016-12-23 15:15:48 -0500197 vlib_process_wait_for_event_or_clock (vm, 5.0);
198 event_type = vlib_process_get_events (vm, &event_data);
199 vec_reset_length (event_data);
Swarup Nayak6bcac062017-11-26 23:11:40 +0530200
Ed Warnickecb9cada2015-12-08 15:45:58 -0700201 vec_foreach (fr, frm->reports)
Swarup Nayak6bcac062017-11-26 23:11:40 +0530202 {
203 now = vlib_time_now (vm);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700204
Swarup Nayak6bcac062017-11-26 23:11:40 +0530205 /* Need to send a template packet? */
206 send_template =
207 now > (fr->last_template_sent + frm->template_interval);
208 send_template += fr->last_template_sent == 0;
209 template_bi = ~0;
210 rv = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700211
Swarup Nayak6bcac062017-11-26 23:11:40 +0530212 if (send_template)
213 rv = send_template_packet (frm, fr, &template_bi);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700214
Swarup Nayak6bcac062017-11-26 23:11:40 +0530215 if (rv < 0)
216 continue;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700217
Swarup Nayak6bcac062017-11-26 23:11:40 +0530218 nf = vlib_get_frame_to_node (vm, ip4_lookup_node_index);
219 nf->n_vectors = 0;
220 to_next = vlib_frame_vector_args (nf);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700221
Swarup Nayak6bcac062017-11-26 23:11:40 +0530222 if (template_bi != ~0)
223 {
224 to_next[0] = template_bi;
225 to_next++;
226 nf->n_vectors++;
227 }
228
229 nf = fr->flow_data_callback (frm, fr,
230 nf, to_next, ip4_lookup_node_index);
231 if (nf)
232 vlib_put_frame_to_node (vm, ip4_lookup_node_index, nf);
233 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700234 }
235
Swarup Nayak6bcac062017-11-26 23:11:40 +0530236 return 0; /* not so much */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700237}
238
Swarup Nayak6bcac062017-11-26 23:11:40 +0530239/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700240VLIB_REGISTER_NODE (flow_report_process_node) = {
241 .function = flow_report_process,
242 .type = VLIB_NODE_TYPE_PROCESS,
243 .name = "flow-report-process",
244};
Swarup Nayak6bcac062017-11-26 23:11:40 +0530245/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700246
Swarup Nayak6bcac062017-11-26 23:11:40 +0530247int
248vnet_flow_report_add_del (flow_report_main_t * frm,
249 vnet_flow_report_add_del_args_t * a,
250 u16 * template_id)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700251{
252 int i;
253 int found_index = ~0;
254 flow_report_t *fr;
Swarup Nayak6bcac062017-11-26 23:11:40 +0530255 flow_report_stream_t *stream;
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700256 u32 si;
Swarup Nayak6bcac062017-11-26 23:11:40 +0530257
258 si = find_stream (a->domain_id, a->src_port);
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700259 if (si == -2)
260 return VNET_API_ERROR_INVALID_VALUE;
261 if (si == -1 && a->is_add == 0)
262 return VNET_API_ERROR_NO_SUCH_ENTRY;
263
Swarup Nayak6bcac062017-11-26 23:11:40 +0530264 for (i = 0; i < vec_len (frm->reports); i++)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700265 {
266 fr = vec_elt_at_index (frm->reports, i);
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700267 if (fr->opaque.as_uword == a->opaque.as_uword
Swarup Nayak6bcac062017-11-26 23:11:40 +0530268 && fr->rewrite_callback == a->rewrite_callback
269 && fr->flow_data_callback == a->flow_data_callback)
270 {
271 found_index = i;
272 if (template_id)
273 *template_id = fr->template_id;
274 break;
275 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700276 }
277
278 if (a->is_add == 0)
279 {
280 if (found_index != ~0)
Swarup Nayak6bcac062017-11-26 23:11:40 +0530281 {
282 vec_delete (frm->reports, 1, found_index);
283 stream = &frm->streams[si];
284 stream->n_reports--;
285 if (stream->n_reports == 0)
286 delete_stream (si);
287 return 0;
288 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700289 return VNET_API_ERROR_NO_SUCH_ENTRY;
290 }
291
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700292 if (found_index != ~0)
293 return VNET_API_ERROR_VALUE_EXIST;
294
295 if (si == -1)
296 {
Swarup Nayak6bcac062017-11-26 23:11:40 +0530297 stream = add_stream ();
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700298 stream->domain_id = a->domain_id;
299 stream->src_port = a->src_port;
300 stream->sequence_number = 0;
301 stream->n_reports = 0;
302 si = stream - frm->streams;
303 }
304 else
305 stream = &frm->streams[si];
306
307 stream->n_reports++;
308
Ed Warnickecb9cada2015-12-08 15:45:58 -0700309 vec_add2 (frm->reports, fr, 1);
310
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700311 fr->stream_index = si;
312 fr->template_id = 256 + stream->next_template_no;
313 stream->next_template_no = (stream->next_template_no + 1) % (65536 - 256);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700314 fr->update_rewrite = 1;
315 fr->opaque = a->opaque;
316 fr->rewrite_callback = a->rewrite_callback;
317 fr->flow_data_callback = a->flow_data_callback;
Ole Troan5c749732017-03-13 13:39:52 +0100318
319 if (template_id)
320 *template_id = fr->template_id;
321
Ed Warnickecb9cada2015-12-08 15:45:58 -0700322 return 0;
323}
324
Swarup Nayak6bcac062017-11-26 23:11:40 +0530325clib_error_t *
326flow_report_add_del_error_to_clib_error (int error)
Juraj Sloboda24648ad2016-09-06 04:43:52 -0700327{
Swarup Nayak6bcac062017-11-26 23:11:40 +0530328 switch (error)
329 {
330 case 0:
331 return 0;
332 case VNET_API_ERROR_NO_SUCH_ENTRY:
333 return clib_error_return (0, "Flow report not found");
334 case VNET_API_ERROR_VALUE_EXIST:
335 return clib_error_return (0, "Flow report already exists");
336 case VNET_API_ERROR_INVALID_VALUE:
337 return clib_error_return (0, "Expecting either still unused values "
338 "for both domain_id and src_port "
339 "or already used values for both fields");
340 default:
341 return clib_error_return (0, "vnet_flow_report_add_del returned %d",
342 error);
343 }
Juraj Sloboda24648ad2016-09-06 04:43:52 -0700344}
345
Swarup Nayak6bcac062017-11-26 23:11:40 +0530346void
347vnet_flow_reports_reset (flow_report_main_t * frm)
Juraj Sloboda618ab082016-07-06 06:11:00 -0700348{
349 flow_report_t *fr;
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700350 u32 i;
351
Swarup Nayak6bcac062017-11-26 23:11:40 +0530352 for (i = 0; i < vec_len (frm->streams); i++)
353 if (stream_index_valid (i))
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700354 frm->streams[i].sequence_number = 0;
355
Juraj Sloboda618ab082016-07-06 06:11:00 -0700356 vec_foreach (fr, frm->reports)
Swarup Nayak6bcac062017-11-26 23:11:40 +0530357 {
358 fr->update_rewrite = 1;
359 fr->last_template_sent = 0;
360 }
Juraj Sloboda618ab082016-07-06 06:11:00 -0700361}
362
Swarup Nayak6bcac062017-11-26 23:11:40 +0530363void
364vnet_stream_reset (flow_report_main_t * frm, u32 stream_index)
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700365{
366 flow_report_t *fr;
367
368 frm->streams[stream_index].sequence_number = 0;
369
370 vec_foreach (fr, frm->reports)
Swarup Nayak6bcac062017-11-26 23:11:40 +0530371 if (frm->reports->stream_index == stream_index)
372 {
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700373 fr->update_rewrite = 1;
374 fr->last_template_sent = 0;
375 }
376}
377
Swarup Nayak6bcac062017-11-26 23:11:40 +0530378int
379vnet_stream_change (flow_report_main_t * frm,
380 u32 old_domain_id, u16 old_src_port,
381 u32 new_domain_id, u16 new_src_port)
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700382{
383 i32 stream_index = find_stream (old_domain_id, old_src_port);
384 if (stream_index < 0)
385 return 1;
Swarup Nayak6bcac062017-11-26 23:11:40 +0530386 flow_report_stream_t *stream = &frm->streams[stream_index];
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700387 stream->domain_id = new_domain_id;
388 stream->src_port = new_src_port;
389 if (old_domain_id != new_domain_id || old_src_port != new_src_port)
390 vnet_stream_reset (frm, stream_index);
391 return 0;
392}
393
Ed Warnickecb9cada2015-12-08 15:45:58 -0700394static clib_error_t *
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700395set_ipfix_exporter_command_fn (vlib_main_t * vm,
Swarup Nayak6bcac062017-11-26 23:11:40 +0530396 unformat_input_t * input,
397 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700398{
Swarup Nayak6bcac062017-11-26 23:11:40 +0530399 flow_report_main_t *frm = &flow_report_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700400 ip4_address_t collector, src;
Juraj Sloboda5a49bb92016-07-07 03:23:15 -0700401 u16 collector_port = UDP_DST_PORT_ipfix;
Juraj Sloboda86634f02016-07-01 06:12:58 -0700402 u32 fib_id;
403 u32 fib_index = ~0;
Swarup Nayak6bcac062017-11-26 23:11:40 +0530404
Ed Warnickecb9cada2015-12-08 15:45:58 -0700405 collector.as_u32 = 0;
406 src.as_u32 = 0;
Swarup Nayak6bcac062017-11-26 23:11:40 +0530407 u32 path_mtu = 512; // RFC 7011 section 10.3.3.
Juraj Sloboda5a49bb92016-07-07 03:23:15 -0700408 u32 template_interval = 20;
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700409 u8 udp_checksum = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700410
Swarup Nayak6bcac062017-11-26 23:11:40 +0530411 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
412 {
413 if (unformat (input, "collector %U", unformat_ip4_address, &collector))
414 ;
415 else if (unformat (input, "port %u", &collector_port))
416 ;
417 else if (unformat (input, "src %U", unformat_ip4_address, &src))
418 ;
419 else if (unformat (input, "fib-id %u", &fib_id))
420 {
421 ip4_main_t *im = &ip4_main;
422 uword *p = hash_get (im->fib_index_by_table_id, fib_id);
423 if (!p)
424 return clib_error_return (0, "fib ID %d doesn't exist\n", fib_id);
425 fib_index = p[0];
426 }
427 else if (unformat (input, "path-mtu %u", &path_mtu))
428 ;
429 else if (unformat (input, "template-interval %u", &template_interval))
430 ;
431 else if (unformat (input, "udp-checksum"))
432 udp_checksum = 1;
433 else
434 break;
435 }
436
Ole Troan5c749732017-03-13 13:39:52 +0100437 if (collector.as_u32 != 0 && src.as_u32 == 0)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700438 return clib_error_return (0, "src address required");
439
Swarup Nayak6bcac062017-11-26 23:11:40 +0530440 if (path_mtu > 1450 /* vpp does not support fragmentation */ )
441 return clib_error_return (0, "too big path-mtu value, maximum is 1450");
Juraj Sloboda5a49bb92016-07-07 03:23:15 -0700442
443 if (path_mtu < 68)
Swarup Nayak6bcac062017-11-26 23:11:40 +0530444 return clib_error_return (0, "too small path-mtu value, minimum is 68");
Juraj Sloboda5a49bb92016-07-07 03:23:15 -0700445
Juraj Sloboda618ab082016-07-06 06:11:00 -0700446 /* Reset report streams if we are reconfiguring IP addresses */
447 if (frm->ipfix_collector.as_u32 != collector.as_u32 ||
448 frm->src_address.as_u32 != src.as_u32 ||
449 frm->collector_port != collector_port)
Swarup Nayak6bcac062017-11-26 23:11:40 +0530450 vnet_flow_reports_reset (frm);
Juraj Sloboda618ab082016-07-06 06:11:00 -0700451
Ed Warnickecb9cada2015-12-08 15:45:58 -0700452 frm->ipfix_collector.as_u32 = collector.as_u32;
Juraj Sloboda5a49bb92016-07-07 03:23:15 -0700453 frm->collector_port = collector_port;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700454 frm->src_address.as_u32 = src.as_u32;
Juraj Sloboda86634f02016-07-01 06:12:58 -0700455 frm->fib_index = fib_index;
Juraj Sloboda5a49bb92016-07-07 03:23:15 -0700456 frm->path_mtu = path_mtu;
457 frm->template_interval = template_interval;
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700458 frm->udp_checksum = udp_checksum;
Swarup Nayak6bcac062017-11-26 23:11:40 +0530459
Ole Troan5c749732017-03-13 13:39:52 +0100460 if (collector.as_u32)
461 vlib_cli_output (vm, "Collector %U, src address %U, "
Swarup Nayak6bcac062017-11-26 23:11:40 +0530462 "fib index %d, path MTU %u, "
463 "template resend interval %us, "
464 "udp checksum %s",
465 format_ip4_address, &frm->ipfix_collector,
466 format_ip4_address, &frm->src_address,
467 fib_index, path_mtu, template_interval,
468 udp_checksum ? "enabled" : "disabled");
Ole Troan5c749732017-03-13 13:39:52 +0100469 else
470 vlib_cli_output (vm, "IPFIX Collector is disabled");
Juraj Sloboda5a49bb92016-07-07 03:23:15 -0700471
Ed Warnickecb9cada2015-12-08 15:45:58 -0700472 /* Turn on the flow reporting process */
Swarup Nayak6bcac062017-11-26 23:11:40 +0530473 vlib_process_signal_event (vm, flow_report_process_node.index, 1, 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700474 return 0;
475}
476
Swarup Nayak6bcac062017-11-26 23:11:40 +0530477/* *INDENT-OFF* */
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700478VLIB_CLI_COMMAND (set_ipfix_exporter_command, static) = {
479 .path = "set ipfix exporter",
480 .short_help = "set ipfix exporter "
481 "collector <ip4-address> [port <port>] "
Juraj Sloboda5a49bb92016-07-07 03:23:15 -0700482 "src <ip4-address> [fib-id <fib-id>] "
483 "[path-mtu <path-mtu>] "
484 "[template-interval <template-interval>]",
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700485 "[udp-checksum]",
486 .function = set_ipfix_exporter_command_fn,
Ed Warnickecb9cada2015-12-08 15:45:58 -0700487};
Swarup Nayak6bcac062017-11-26 23:11:40 +0530488/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700489
Dave Barach0f3b6802016-12-23 15:15:48 -0500490
491static clib_error_t *
492ipfix_flush_command_fn (vlib_main_t * vm,
Swarup Nayak6bcac062017-11-26 23:11:40 +0530493 unformat_input_t * input, vlib_cli_command_t * cmd)
Dave Barach0f3b6802016-12-23 15:15:48 -0500494{
495 /* poke the flow reporting process */
Swarup Nayak6bcac062017-11-26 23:11:40 +0530496 vlib_process_signal_event (vm, flow_report_process_node.index, 1, 0);
Dave Barach0f3b6802016-12-23 15:15:48 -0500497 return 0;
498}
499
Swarup Nayak6bcac062017-11-26 23:11:40 +0530500/* *INDENT-OFF* */
Dave Barach0f3b6802016-12-23 15:15:48 -0500501VLIB_CLI_COMMAND (ipfix_flush_command, static) = {
502 .path = "ipfix flush",
503 .short_help = "flush the current ipfix data [for make test]",
504 .function = ipfix_flush_command_fn,
505};
Swarup Nayak6bcac062017-11-26 23:11:40 +0530506/* *INDENT-ON* */
Dave Barach0f3b6802016-12-23 15:15:48 -0500507
Swarup Nayak6bcac062017-11-26 23:11:40 +0530508static clib_error_t *
509flow_report_init (vlib_main_t * vm)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700510{
Swarup Nayak6bcac062017-11-26 23:11:40 +0530511 flow_report_main_t *frm = &flow_report_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700512
513 frm->vlib_main = vm;
Swarup Nayak6bcac062017-11-26 23:11:40 +0530514 frm->vnet_main = vnet_get_main ();
515 frm->unix_time_0 = time (0);
516 frm->vlib_time_0 = vlib_time_now (frm->vlib_main);
Juraj Slobodaffa652a2016-08-07 23:43:42 -0700517 frm->fib_index = ~0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700518
519 return 0;
520}
521
522VLIB_INIT_FUNCTION (flow_report_init)
Swarup Nayak6bcac062017-11-26 23:11:40 +0530523/*
524 * fd.io coding-style-patch-verification: ON
525 *
526 * Local Variables:
527 * eval: (c-set-style "gnu")
528 * End:
529 */