- vlib_main_t *vm = vlib_get_main ();
- pcap_main_t *pm = &vm->dispatch_pcap_main;
- vlib_trace_main_t *tm;
- vlib_trace_node_t *tn;
-
- if (a->status)
- {
- if (vm->dispatch_pcap_enable)
- {
- int i;
- vlib_cli_output
- (vm, "pcap dispatch capture enabled: %d of %d pkts...",
- pm->n_packets_captured, pm->n_packets_to_capture);
- vlib_cli_output (vm, "capture to file %s", pm->file_name);
-
- for (i = 0; i < vec_len (vm->dispatch_buffer_trace_nodes); i++)
- {
- vlib_cli_output (vm,
- "Buffer trace of %d pkts from %U enabled...",
- a->buffer_traces_to_capture,
- format_vlib_node_name, vm,
- vm->dispatch_buffer_trace_nodes[i]);
- }
- }
- else
- vlib_cli_output (vm, "pcap dispatch capture disabled");
- return 0;
- }
-
- /* Consistency checks */
-
- /* Enable w/ capture already enabled not allowed */
- if (vm->dispatch_pcap_enable && a->enable)
- return -7; /* VNET_API_ERROR_INVALID_VALUE */
-
- /* Disable capture with capture already disabled, not interesting */
- if (vm->dispatch_pcap_enable == 0 && a->enable == 0)
- return -81; /* VNET_API_ERROR_VALUE_EXIST */
-
- /* Change number of packets to capture while capturing */
- if (vm->dispatch_pcap_enable
- && (pm->n_packets_to_capture != a->packets_to_capture))
- return -8; /* VNET_API_ERROR_INVALID_VALUE_2 */
-
- /* Independent of enable/disable, to allow buffer trace multi nodes */
- if (a->buffer_trace_node_index != ~0)
- {
- /* *INDENT-OFF* */
- foreach_vlib_main ((
- {
- tm = &this_vlib_main->trace_main;
- tm->verbose = 0; /* not sure this ever did anything... */
- vec_validate (tm->nodes, a->buffer_trace_node_index);
- tn = tm->nodes + a->buffer_trace_node_index;
- tn->limit += a->buffer_traces_to_capture;
- tm->trace_enable = 1;
- }));
- /* *INDENT-ON* */
- vec_add1 (vm->dispatch_buffer_trace_nodes, a->buffer_trace_node_index);
- }
-
- if (a->enable)
- {
- /* Clean up from previous run, if any */
- vec_free (pm->file_name);
- vec_free (pm->pcap_data);
- memset (pm, 0, sizeof (*pm));
-
- vec_validate_aligned (vnet_trace_dummy, 2048, CLIB_CACHE_LINE_BYTES);
- if (pm->lock == 0)
- clib_spinlock_init (&(pm->lock));
-
- if (a->filename == 0)
- a->filename = format (0, "/tmp/dispatch.pcap%c", 0);
-
- pm->file_name = (char *) a->filename;
- pm->n_packets_captured = 0;
- pm->packet_type = PCAP_PACKET_TYPE_vpp;
- vm->dispatch_pcap_enable = 1;
- pm->n_packets_to_capture = a->packets_to_capture;
- }
- else
- {
- vm->dispatch_pcap_enable = 0;
- vec_reset_length (vm->dispatch_buffer_trace_nodes);
- if (pm->n_packets_captured)
- {
- clib_error_t *error;
- pm->n_packets_to_capture = pm->n_packets_captured;
- vlib_cli_output (vm, "Write %d packets to %s, and stop capture...",
- pm->n_packets_captured, pm->file_name);
- error = pcap_write (pm);
- if (pm->file_descriptor >= 0)
- pcap_close (pm);
- /* Report I/O errors... */
- if (error)
- {
- clib_error_report (error);
- return -11; /* VNET_API_ERROR_SYSCALL_ERROR_1 */
- }
- return 0;
- }
- else
- return -6; /* VNET_API_ERROR_NO_SUCH_ENTRY */
- }
-
- return 0;