summaryrefslogtreecommitdiffstats
path: root/src/vlib/log.c
AgeCommit message (Expand)AuthorFilesLines
2024-03-12misc: remove GNU Indent directivesDamjan Marion1-18/+0
2023-07-26vlib: rename vnet_log_get_class_dataVratko Polak1-1/+1
2023-05-27vlib: add vlib_log_is_enabledDamjan Marion1-20/+6
2023-04-12vlib dhcp: default to logging without elogsFlorin Coras1-1/+1
2023-03-06vlib: fix vlib_log for elogluoyaozu1-8/+8
2022-07-06misc: pass NULL instead of 0 for pointer in variadic functionsAndreas Schultz1-4/+3
2022-03-10vlib: init logging eearlierDamjan Marion1-5/+2
2021-12-22vlib: null terminate elog stringDamjan Marion1-1/+1
2021-03-26vlib: introduce vlib_get_elog_main()Damjan Marion1-2/+3
2020-11-26vlib: fix vlib log elog vector overrunBenoƮt Ganne1-1/+1
2020-11-25vlib: add elog events for vlib log entriesDave Barach1-0/+34
2020-10-26vlib: add VLIB_REGISTER_LOG_CLASS macroDamjan Marion1-24/+43
2020-10-23vlib: log: fix non-null terminated stringsjiangxiaoming1-0/+1
2020-10-21vlib: per-class logging configuration in startup.confDamjan Marion1-3/+86
2020-10-21vlib: print logs to stderr if interactive or nosyslog setDamjan Marion1-46/+98
2020-02-06vlib: add plugin override supportDave Barach1-3/+17
2019-10-30vlib: fix subclass name being truncated in outputPaul Vinciguerra1-1/+1
2019-10-30vlib: Trivial - fix typo in short helpPaul Vinciguerra1-1/+1
2019-07-08api: Implement log_dump/log_detailsPaul Vinciguerra1-52/+1
2019-01-20log: bug fix register class compare mismatchSu Wang1-1/+3
2018-10-03fix format error in show logging config outputJerome Tollet1-3/+6
2018-09-27"show log": print wall-clock timeDave Barach1-1/+14
2018-08-25Add int cast to fit '.*' printf expectationsPierre Pfister1-4/+5
2018-05-19log: Validate the size of vec in vlib_logMohsin Kazmi1-0/+1
2018-04-26vlib: set log tap level <level> does not work for some keywordsSteven1-2/+2
2018-04-18vlib: logging improvementsDamjan Marion1-31/+72
2018-04-17Add logging supportDamjan Marion1-0/+673
.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
/*
 * Copyright (c) 2016 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <vnet/ipfix-export/flow_report.h>
#include <ioam/analyse/ioam_summary_export.h>
#include <vnet/api_errno.h>
#include <ioam/udp-ping/udp_ping.h>

#define UDP_PING_EXPORT_RECORD_SIZE 400

static u8 *
udp_ping_template_rewrite (flow_report_main_t * frm, flow_report_t * fr,
			   ip4_address_t * collector_address,
			   ip4_address_t * src_address, u16 collector_port,
			   ipfix_report_element_t * elts,
			   u32 n_elts, u32 * stream_index)
{
  return ioam_template_rewrite (frm, fr, collector_address,
				src_address, collector_port, elts, n_elts,
				stream_index);
}

static vlib_frame_t *
udp_ping_send_flows (flow_report_main_t * frm, flow_report_t * fr,
		     vlib_frame_t * f, u32 * to_next, u32 node_index)
{
  vlib_buffer_t *b0 = NULL;
  u32 next_offset = 0;
  u32 bi0 = ~0;
  int i, j;
  ip4_ipfix_template_packet_t *tp;
  ipfix_message_header_t *h;
  ipfix_set_header_t *s = NULL;
  ip4_header_t *ip;
  udp_header_t *udp;
  u32 records_this_buffer;
  u16 new_l0, old_l0;
  ip_csum_t sum0;
  vlib_main_t *vm = frm->vlib_main;
  flow_report_stream_t *stream;
  udp_ping_flow_data *stats;
  ip46_udp_ping_flow *ip46_flow;
  u16 src_port, dst_port;
  u16 data_len;

  stream = &frm->streams[fr->stream_index];
  data_len = vec_len (udp_ping_main.ip46_flow);

  for (i = 0; i < data_len; i++)
    {
      if (pool_is_free_index (udp_ping_main.ip46_flow, i))
	continue;

      ip46_flow = pool_elt_at_index (udp_ping_main.ip46_flow, i);
      j = 0;
      for (src_port = ip46_flow->udp_data.start_src_port;
	   src_port <= ip46_flow->udp_data.end_src_port; src_port++)
	{
	  for (dst_port = ip46_flow->udp_data.start_dst_port;
	       dst_port <= ip46_flow->udp_data.end_dst_port; dst_port++, j++)
	    {
	      stats = ip46_flow->udp_data.stats + j;
	      if (PREDICT_FALSE (b0 == NULL))
		{
		  if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
		    break;


		  b0 = vlib_get_buffer (vm, bi0);
		  memcpy (b0->data, fr->rewrite, vec_len (fr->rewrite));
		  b0->current_data = 0;
		  b0->current_length = vec_len (fr->rewrite);
		  b0->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
		  vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0;
		  vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;

		  tp = vlib_buffer_get_current (b0);
		  ip = &tp->ip4;
		  h = &tp->ipfix.h;
		  s = &tp->ipfix.s;

		  /* FIXUP: message header export_time */
		  h->export_time = clib_host_to_net_u32 (((u32) time (NULL)));

		  /* FIXUP: message header sequence_number */
		  h->sequence_number = stream->sequence_number++;
		  h->sequence_number =
		    clib_host_to_net_u32 (h->sequence_number);
		  next_offset = (u32) (((u8 *) (s + 1)) - (u8 *) tp);
		  records_this_buffer = 0;
		}

	      next_offset = ioam_analyse_add_ipfix_record (fr,
							   &stats->analyse_data,
							   b0, next_offset,
							   &ip46_flow->
							   src.ip6,
							   &ip46_flow->
							   dst.ip6, src_port,
							   dst_port);

	      //u32 pak_sent = clib_host_to_net_u32(stats->pak_sent);
	      //memcpy (b0->data + next_offset, &pak_sent, sizeof(u32));
	      //next_offset += sizeof(u32);

	      records_this_buffer++;

	      /* Flush data if packet len is about to reach path mtu */
	      if (next_offset > (frm->path_mtu - UDP_PING_EXPORT_RECORD_SIZE))
		{
		  b0->current_length = next_offset;
		  b0->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
		  tp = vlib_buffer_get_current (b0);
		  ip = (ip4_header_t *) & tp->ip4;
		  udp = (udp_header_t *) (ip + 1);
		  h = &tp->ipfix.h;
		  s = &tp->ipfix.s;

		  s->set_id_length =
		    ipfix_set_id_length (IOAM_FLOW_TEMPLATE_ID,
					 next_offset - (sizeof (*ip) +
							sizeof (*udp) +
							sizeof (*h)));
		  h->version_length =
		    version_length (next_offset -
				    (sizeof (*ip) + sizeof (*udp)));

		  sum0 = ip->checksum;
		  old_l0 = ip->length;
		  new_l0 = clib_host_to_net_u16 ((u16) next_offset);
		  sum0 = ip_csum_update (sum0, old_l0, new_l0, ip4_header_t,
					 length /* changed member */ );

		  ip->checksum = ip_csum_fold (sum0);
		  ip->length = new_l0;
		  udp->length =
		    clib_host_to_net_u16 (b0->current_length - sizeof (*ip));

		  udp->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ip);
		  if (udp->checksum == 0)
		    udp->checksum = 0xffff;

		  ASSERT (ip->checksum == ip4_header_checksum (ip));

		  to_next[0] = bi0;
		  f->n_vectors++;
		  to_next++;

		  if (f->n_vectors == VLIB_FRAME_SIZE)
		    {
		      vlib_put_frame_to_node (vm, node_index, f);
		      f = vlib_get_frame_to_node (vm, node_index);
		      f->n_vectors = 0;
		      to_next = vlib_frame_vector_args (f);
		    }
		  b0 = 0;
		  bi0 = ~0;
		}
	    }
	}
    }

  if (b0)
    {
      b0->current_length = next_offset;
      b0->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
      tp = vlib_buffer_get_current (b0);
      ip = (ip4_header_t *) & tp->ip4;
      udp = (udp_header_t *) (ip + 1);
      h = &tp->ipfix.h;
      s = &tp->ipfix.s;

      s->set_id_length = ipfix_set_id_length (IOAM_FLOW_TEMPLATE_ID,
					      next_offset - (sizeof (*ip) +
							     sizeof (*udp) +
							     sizeof (*h)));
      h->version_length =
	version_length (next_offset - (sizeof (*ip) + sizeof (*udp)));

      sum0 = ip->checksum;
      old_l0 = ip->length;
      new_l0 = clib_host_to_net_u16 ((u16) next_offset);
      sum0 = ip_csum_update (sum0, old_l0, new_l0, ip4_header_t,
			     length /* changed member */ );

      ip->checksum = ip_csum_fold (sum0);
      ip->length = new_l0;
      udp->length = clib_host_to_net_u16 (b0->current_length - sizeof (*ip));

      udp->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ip);
      if (udp->checksum == 0)
	udp->checksum = 0xffff;

      ASSERT (ip->checksum == ip4_header_checksum (ip));

      to_next[0] = bi0;
      f->n_vectors++;
      to_next++;

      if (f->n_vectors == VLIB_FRAME_SIZE)
	{
	  vlib_put_frame_to_node (vm, node_index, f);
	  f = vlib_get_frame_to_node (vm, node_index);
	  f->n_vectors = 0;
	  to_next = vlib_frame_vector_args (f);
	}
      b0 = 0;
      bi0 = ~0;
    }
  return f;
}

clib_error_t *
udp_ping_flow_create (u8 del)
{
  vnet_flow_report_add_del_args_t args;
  int rv;
  u32 domain_id = 0;
  flow_report_main_t *frm = &flow_report_main;
  u16 template_id;

  clib_memset (&args, 0, sizeof (args));
  args.rewrite_callback = udp_ping_template_rewrite;
  args.flow_data_callback = udp_ping_send_flows;
  del ? (args.is_add = 0) : (args.is_add = 1);
  args.domain_id = domain_id;
  args.src_port = UDP_DST_PORT_ipfix;

  rv = vnet_flow_report_add_del (frm, &args, &template_id);

  switch (rv)
    {
    case 0:
      break;
    case VNET_API_ERROR_NO_SUCH_ENTRY:
      return clib_error_return (0, "registration not found...");
    default:
      return clib_error_return (0, "vnet_flow_report_add_del returned %d",
				rv);
    }

  return 0;
}

static clib_error_t *
set_udp_ping_export_command_fn (vlib_main_t * vm, unformat_input_t * input,
				vlib_cli_command_t * cmd)
{
  //int rv;
  int is_add = 1;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "export-ipfix"))
	is_add = 1;
      else if (unformat (input, "disable"))
	is_add = 0;
      else
	break;
    }

  if (is_add)
    (void) udp_ping_flow_create (0);
  else
    (void) udp_ping_flow_create (1);

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (set_udp_ping_export_command, static) = {
    .path = "set udp-ping export-ipfix",
    .short_help = "set udp-ping export-ipfix [disable]",
    .function = set_udp_ping_export_command_fn,
};
/* *INDENT-ON* */

clib_error_t *
udp_ping_flow_report_init (vlib_main_t * vm)
{
  return 0;
}

/* *INDENT-OFF* */
VLIB_INIT_FUNCTION (udp_ping_flow_report_init) =
{
  .runs_after = VLIB_INITS ("flow_report_init"),
};
/* *INDENT-ON* */


/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */