コード例 #1
0
ファイル: ip_types_api.c プロジェクト: chrisy/vpp
static ip46_type_t
ip_address_union_decode (const vl_api_address_union_t * in,
			 vl_api_address_family_t af, ip46_address_t * out)
{
  ip46_type_t type;

  switch (clib_net_to_host_u32 (af))
    {
    case ADDRESS_IP4:
      clib_memset (out, 0, sizeof (*out));
      clib_memcpy (&out->ip4, &in->ip4, sizeof (out->ip4));
      type = IP46_TYPE_IP4;
      break;
    case ADDRESS_IP6:
      clib_memcpy (&out->ip6, &in->ip6, sizeof (out->ip6));
      type = IP46_TYPE_IP6;
      break;
    default:
      ASSERT (!"Unkown address family in API address type");
      type = IP46_TYPE_ANY;
      break;
    }

  return type;
}
コード例 #2
0
ファイル: error.c プロジェクト: Venkattk/vpp
/* Reserves given number of error codes for given node. */
void
vlib_register_errors (vlib_main_t * vm,
		      u32 node_index, u32 n_errors, char *error_strings[])
{
  vlib_error_main_t *em = &vm->error_main;
  vlib_node_t *n = vlib_get_node (vm, node_index);
  uword l;

  ASSERT (os_get_cpu_number () == 0);

  /* Free up any previous error strings. */
  if (n->n_errors > 0)
    heap_dealloc (em->error_strings_heap, n->error_heap_handle);

  n->n_errors = n_errors;
  n->error_strings = error_strings;

  if (n_errors == 0)
    return;

  n->error_heap_index =
    heap_alloc (em->error_strings_heap, n_errors, n->error_heap_handle);

  l = vec_len (em->error_strings_heap);

  clib_memcpy (vec_elt_at_index (em->error_strings_heap, n->error_heap_index),
	       error_strings, n_errors * sizeof (error_strings[0]));

  /* Allocate a counter/elog type for each error. */
  vec_validate (em->counters, l - 1);
  vec_validate (vm->error_elog_event_types, l - 1);

  /* Zero counters for re-registrations of errors. */
  if (n->error_heap_index + n_errors <= vec_len (em->counters_last_clear))
    clib_memcpy (em->counters + n->error_heap_index,
		 em->counters_last_clear + n->error_heap_index,
		 n_errors * sizeof (em->counters[0]));
  else
    memset (em->counters + n->error_heap_index,
	    0, n_errors * sizeof (em->counters[0]));

  {
    elog_event_type_t t;
    uword i;

    memset (&t, 0, sizeof (t));
    for (i = 0; i < n_errors; i++)
      {
	t.format = (char *) format (0, "%v %s: %%d",
				    n->name, error_strings[i]);
	vm->error_elog_event_types[n->error_heap_index + i] = t;
      }
  }
}
コード例 #3
0
ファイル: udp_api.c プロジェクト: vpp-dev/vpp
static void
send_udp_encap_details (const udp_encap_t * ue, vl_api_registration_t * reg,
			u32 context)
{
  vl_api_udp_encap_details_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (VL_API_UDP_ENCAP_DETAILS);
  mp->context = context;

  if (FIB_PROTOCOL_IP4 == ue->ue_ip_proto)
    {
      clib_memcpy (&mp->udp_encap.src_ip.un.ip4,
		   &ue->ue_hdrs.ip4.ue_ip4.src_address, 4);
      clib_memcpy (&mp->udp_encap.dst_ip.un.ip4,
		   &ue->ue_hdrs.ip4.ue_ip4.dst_address, 4);
      mp->udp_encap.dst_ip.af = clib_host_to_net_u32 (ADDRESS_IP4);
      mp->udp_encap.src_ip.af = clib_host_to_net_u32 (ADDRESS_IP4);

      /* ports aren't byte swapped because they are stored in network
       * byte order */
      mp->udp_encap.src_port = ue->ue_hdrs.ip4.ue_udp.src_port;
      mp->udp_encap.dst_port = ue->ue_hdrs.ip4.ue_udp.dst_port;
    }
  else
    {
      clib_memcpy (&mp->udp_encap.src_ip.un.ip6,
		   &ue->ue_hdrs.ip6.ue_ip6.src_address, 16);
      clib_memcpy (&mp->udp_encap.dst_ip.un.ip6,
		   &ue->ue_hdrs.ip6.ue_ip6.dst_address, 16);
      mp->udp_encap.dst_ip.af = clib_host_to_net_u32 (ADDRESS_IP6);
      mp->udp_encap.src_ip.af = clib_host_to_net_u32 (ADDRESS_IP6);

      /* ports aren't byte swapped because they are stored in network
       * byte order */
      mp->udp_encap.src_port = ue->ue_hdrs.ip6.ue_udp.src_port;
      mp->udp_encap.dst_port = ue->ue_hdrs.ip6.ue_udp.dst_port;
    }

  mp->udp_encap.table_id =
    htonl (fib_table_get_table_id (ue->ue_fib_index, ue->ue_ip_proto));
  mp->udp_encap.id = htonl (ue - udp_encap_pool);

  vl_api_send_msg (reg, (u8 *) mp);
}
コード例 #4
0
ファイル: ipip_api.c プロジェクト: vpp-dev/vpp
static void
vl_api_ipip_add_tunnel_t_handler (vl_api_ipip_add_tunnel_t * mp)
{
  vl_api_ipip_add_tunnel_reply_t *rmp;
  int rv = 0;
  u32 fib_index, sw_if_index = ~0;
  ip46_address_t src = ip46_address_initializer, dst =
    ip46_address_initializer;

  /* ip addresses sent in network byte order */
  if (mp->is_ipv6)
    {
      clib_memcpy (&src.ip6, mp->src_address, 16);
      clib_memcpy (&dst.ip6, mp->dst_address, 16);
    }
  else
    {
      clib_memcpy (&src.ip4, mp->src_address, 4);
      clib_memcpy (&dst.ip4, mp->dst_address, 4);
    }

  fib_index =
    fib_table_find (fib_ip_proto (mp->is_ipv6), ntohl (mp->table_id));

  if (~0 == fib_index)
    {
      rv = VNET_API_ERROR_NO_SUCH_FIB;
    }
  else
    {
      rv = ipip_add_tunnel ((mp->is_ipv6 ?
			     IPIP_TRANSPORT_IP6 :
			     IPIP_TRANSPORT_IP4),
			    ntohl (mp->instance), &src, &dst,
			    fib_index, mp->tc_tos, &sw_if_index);
    }

  /* *INDENT-OFF* */
  REPLY_MACRO2(VL_API_IPIP_ADD_TUNNEL_REPLY,
  ({
    rmp->sw_if_index = ntohl(sw_if_index);
  }));
コード例 #5
0
ファイル: application_local.c プロジェクト: chrisy/vpp
static u32
ct_start_listen (u32 app_listener_index, transport_endpoint_t * tep)
{
  session_endpoint_cfg_t *sep;
  ct_connection_t *ct;

  sep = (session_endpoint_cfg_t *) tep;
  ct = ct_connection_alloc ();
  ct->server_wrk = sep->app_wrk_index;
  ct->c_is_ip4 = sep->is_ip4;
  clib_memcpy (&ct->c_lcl_ip, &sep->ip, sizeof (sep->ip));
  ct->c_lcl_port = sep->port;
  ct->actual_tp = sep->transport_proto;
  ct_enable_disable_main_pre_input_node (1 /* is_add */ );
  return ct->c_c_index;
}
コード例 #6
0
ファイル: api_shared.c プロジェクト: Venkattk/vpp
/*
 * vl_msg_api_trace
 */
void
vl_msg_api_trace (api_main_t * am, vl_api_trace_t * tp, void *msg)
{
  u8 **this_trace;
  u8 **old_trace;
  u8 *msg_copy;
  trace_cfg_t *cfgp;
  u16 msg_id = ntohs (*((u16 *) msg));

  cfgp = am->api_trace_cfg + msg_id;

  if (!cfgp || !cfgp->trace_enable)
    return;

  msg_copy = 0;

  if (tp->nitems == 0)
    {
      clib_warning ("tp->nitems is 0");
      return;
    }

  if (vec_len (tp->traces) < tp->nitems)
    {
      vec_add1 (tp->traces, 0);
      this_trace = tp->traces + vec_len (tp->traces) - 1;
    }
  else
    {
      tp->wrapped = 1;
      old_trace = tp->traces + tp->curindex++;
      if (tp->curindex == tp->nitems)
	tp->curindex = 0;
      vec_free (*old_trace);
      this_trace = old_trace;
    }

  vec_validate (msg_copy, cfgp->size - 1);
  clib_memcpy (msg_copy, msg, cfgp->size);
  *this_trace = msg_copy;
}
コード例 #7
0
ファイル: api_shared.c プロジェクト: Venkattk/vpp
static void
vl_msg_api_process_file (vlib_main_t * vm, u8 * filename,
			 u32 first_index, u32 last_index,
			 vl_api_replay_t which)
{
  vl_api_trace_file_header_t *hp;
  int i, fd;
  struct stat statb;
  size_t file_size;
  u8 *msg;
  u8 endian_swap_needed = 0;
  api_main_t *am = &api_main;
  static u8 *tmpbuf;
  u32 nitems;
  void **saved_print_handlers = 0;

  fd = open ((char *) filename, O_RDONLY);

  if (fd < 0)
    {
      vlib_cli_output (vm, "Couldn't open %s\n", filename);
      return;
    }

  if (fstat (fd, &statb) < 0)
    {
      vlib_cli_output (vm, "Couldn't stat %s\n", filename);
      return;
    }

  if (!(statb.st_mode & S_IFREG) || (statb.st_size < sizeof (*hp)))
    {
      vlib_cli_output (vm, "File not plausible: %s\n", filename);
      close(fd);
      return;
    }

  file_size = statb.st_size;
  file_size = (file_size + 4095) & ~(4096);

  hp = mmap (0, file_size, PROT_READ, MAP_PRIVATE, fd, 0);

  if (hp == (vl_api_trace_file_header_t *) MAP_FAILED)
    {
      vlib_cli_output (vm, "mmap failed: %s\n", filename);
      close (fd);
      return;
    }
  close (fd);

  if ((clib_arch_is_little_endian && hp->endian == VL_API_BIG_ENDIAN)
      || (clib_arch_is_big_endian && hp->endian == VL_API_LITTLE_ENDIAN))
    endian_swap_needed = 1;

  if (endian_swap_needed)
    nitems = ntohl (hp->nitems);
  else
    nitems = hp->nitems;

  if (last_index == (u32) ~ 0)
    {
      last_index = nitems - 1;
    }

  if (first_index >= nitems || last_index >= nitems)
    {
      vlib_cli_output (vm, "Range (%d, %d) outside file range (0, %d)\n",
		       first_index, last_index, nitems - 1);
      munmap (hp, file_size);
      return;
    }
  if (hp->wrapped)
    vlib_cli_output (vm,
		     "Note: wrapped/incomplete trace, results may vary\n");

  if (which == CUSTOM_DUMP)
    {
      saved_print_handlers = (void **) vec_dup (am->msg_print_handlers);
      vl_msg_api_custom_dump_configure (am);
    }


  msg = (u8 *) (hp + 1);

  for (i = 0; i < first_index; i++)
    {
      trace_cfg_t *cfgp;
      int size;
      u16 msg_id;

      if (clib_arch_is_little_endian)
	msg_id = ntohs (*((u16 *) msg));
      else
	msg_id = *((u16 *) msg);

      cfgp = am->api_trace_cfg + msg_id;
      if (!cfgp)
	{
	  vlib_cli_output (vm, "Ugh: msg id %d no trace config\n", msg_id);
	  return;
	}
      size = cfgp->size;
      msg += size;
    }

  for (; i <= last_index; i++)
    {
      trace_cfg_t *cfgp;
      u16 *msg_idp;
      u16 msg_id;
      int size;

      if (which == DUMP)
	vlib_cli_output (vm, "---------- trace %d -----------\n", i);

      if (clib_arch_is_little_endian)
	msg_id = ntohs (*((u16 *) msg));
      else
	msg_id = *((u16 *) msg);

      cfgp = am->api_trace_cfg + msg_id;
      if (!cfgp)
	{
	  vlib_cli_output (vm, "Ugh: msg id %d no trace config\n", msg_id);
	  return;
	}
      size = cfgp->size;

      /* Copy the buffer (from the read-only mmap'ed file) */
      vec_validate (tmpbuf, size - 1 + sizeof (uword));
      clib_memcpy (tmpbuf + sizeof (uword), msg, size);
      memset (tmpbuf, 0xf, sizeof (uword));

      /*
       * Endian swap if needed. All msg data is supposed to be
       * in network byte order. All msg handlers are supposed to
       * know that. The generic message dumpers don't know that.
       * One could fix apigen, I suppose.
       */
      if ((which == DUMP && clib_arch_is_little_endian) || endian_swap_needed)
	{
	  void (*endian_fp) (void *);
	  if (msg_id >= vec_len (am->msg_endian_handlers)
	      || (am->msg_endian_handlers[msg_id] == 0))
	    {
	      vlib_cli_output (vm, "Ugh: msg id %d no endian swap\n", msg_id);
	      return;
	    }
	  endian_fp = am->msg_endian_handlers[msg_id];
	  (*endian_fp) (tmpbuf + sizeof (uword));
	}

      /* msg_id always in network byte order */
      if (clib_arch_is_little_endian)
	{
	  msg_idp = (u16 *) (tmpbuf + sizeof (uword));
	  *msg_idp = msg_id;
	}

      switch (which)
	{
	case CUSTOM_DUMP:
	case DUMP:
	  if (msg_id < vec_len (am->msg_print_handlers) &&
	      am->msg_print_handlers[msg_id])
	    {
	      u8 *(*print_fp) (void *, void *);

	      print_fp = (void *) am->msg_print_handlers[msg_id];
	      (*print_fp) (tmpbuf + sizeof (uword), vm);
	    }
	  else
	    {
	      vlib_cli_output (vm, "Skipping msg id %d: no print fcn\n",
			       msg_id);
	      break;
	    }
	  break;

	case INITIALIZERS:
	  if (msg_id < vec_len (am->msg_print_handlers) &&
	      am->msg_print_handlers[msg_id])
	    {
	      u8 *s;
	      int j;
	      u8 *(*print_fp) (void *, void *);

	      print_fp = (void *) am->msg_print_handlers[msg_id];

	      vlib_cli_output (vm, "/*");

	      (*print_fp) (tmpbuf + sizeof (uword), vm);
	      vlib_cli_output (vm, "*/\n");

	      s = format (0, "static u8 * vl_api_%s_%d[%d] = {",
			  am->msg_names[msg_id], i,
			  am->api_trace_cfg[msg_id].size);

	      for (j = 0; j < am->api_trace_cfg[msg_id].size; j++)
		{
		  if ((j & 7) == 0)
		    s = format (s, "\n    ");
		  s = format (s, "0x%02x,", tmpbuf[sizeof (uword) + j]);
		}
	      s = format (s, "\n};\n%c", 0);
	      vlib_cli_output (vm, (char *) s);
	      vec_free (s);
	    }
	  break;

	case REPLAY:
	  if (msg_id < vec_len (am->msg_print_handlers) &&
	      am->msg_print_handlers[msg_id] && cfgp->replay_enable)
	    {
	      void (*handler) (void *);

	      handler = (void *) am->msg_handlers[msg_id];

	      if (!am->is_mp_safe[msg_id])
		vl_msg_api_barrier_sync ();
	      (*handler) (tmpbuf + sizeof (uword));
	      if (!am->is_mp_safe[msg_id])
		vl_msg_api_barrier_release ();
	    }
	  else
	    {
	      if (cfgp->replay_enable)
		vlib_cli_output (vm, "Skipping msg id %d: no handler\n",
				 msg_id);
	      break;
	    }
	  break;
	}

      _vec_len (tmpbuf) = 0;
      msg += size;
    }

  if (saved_print_handlers)
    {
      clib_memcpy (am->msg_print_handlers, saved_print_handlers,
		   vec_len (am->msg_print_handlers) * sizeof (void *));
      vec_free (saved_print_handlers);
    }

  munmap (hp, file_size);
}
コード例 #8
0
ファイル: ip_types_api.c プロジェクト: chrisy/vpp
void
ip4_address_decode (const vl_api_ip4_address_t in, ip4_address_t * out)
{
  clib_memcpy (out, in, sizeof (*out));
}
コード例 #9
0
ファイル: ip_types_api.c プロジェクト: chrisy/vpp
void
ip4_address_encode (const ip4_address_t * in, vl_api_ip4_address_t out)
{
  clib_memcpy (out, in, sizeof (*in));
}
コード例 #10
0
ファイル: dhcp6_pd_client_dp.c プロジェクト: chrisy/vpp
static vlib_buffer_t *
create_buffer_for_client_message (vlib_main_t * vm,
				  u32 sw_if_index,
				  dhcp6_pd_client_state_t
				  * client_state, u32 type)
{
  dhcp6_client_common_main_t *ccm = &dhcp6_client_common_main;
  vnet_main_t *vnm = vnet_get_main ();

  vlib_buffer_t *b;
  u32 bi;
  ip6_header_t *ip;
  udp_header_t *udp;
  dhcpv6_header_t *dhcp;
  ip6_address_t src_addr;
  u32 dhcp_opt_len = 0;
  client_state->transaction_start = vlib_time_now (vm);
  u32 n_prefixes;
  u32 i;

  vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
  vnet_sw_interface_t *sup_sw = vnet_get_sup_sw_interface (vnm, sw_if_index);
  vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, sw_if_index);

  /* Interface(s) down? */
  if ((hw->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) == 0)
    return NULL;
  if ((sup_sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0)
    return NULL;
  if ((sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0)
    return NULL;

  /* Get a link-local address */
  src_addr = ip6_neighbor_get_link_local_address (sw_if_index);

  if (src_addr.as_u8[0] != 0xfe)
    {
      clib_warning ("Could not find source address to send DHCPv6 packet");
      return NULL;
    }

  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
    {
      clib_warning ("Buffer allocation failed");
      return NULL;
    }

  b = vlib_get_buffer (vm, bi);
  vnet_buffer (b)->sw_if_index[VLIB_RX] = sw_if_index;
  vnet_buffer (b)->sw_if_index[VLIB_TX] = sw_if_index;
  client_state->adj_index = adj_mcast_add_or_lock (FIB_PROTOCOL_IP6,
						   VNET_LINK_IP6,
						   sw_if_index);
  vnet_buffer (b)->ip.adj_index[VLIB_TX] = client_state->adj_index;
  b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;

  ip = (ip6_header_t *) vlib_buffer_get_current (b);
  udp = (udp_header_t *) (ip + 1);
  dhcp = (dhcpv6_header_t *) (udp + 1);

  ip->src_address = src_addr;
  ip->hop_limit = 255;
  ip->ip_version_traffic_class_and_flow_label =
    clib_host_to_net_u32 (0x6 << 28);
  ip->payload_length = 0;
  ip->protocol = IP_PROTOCOL_UDP;

  udp->src_port = clib_host_to_net_u16 (DHCPV6_CLIENT_PORT);
  udp->dst_port = clib_host_to_net_u16 (DHCPV6_SERVER_PORT);
  udp->checksum = 0;
  udp->length = 0;

  dhcp->msg_type = type;
  dhcp->xid[0] = (client_state->transaction_id & 0x00ff0000) >> 16;
  dhcp->xid[1] = (client_state->transaction_id & 0x0000ff00) >> 8;
  dhcp->xid[2] = (client_state->transaction_id & 0x000000ff) >> 0;

  void *d = (void *) dhcp->data;
  dhcpv6_option_t *duid;
  dhcpv6_elapsed_t *elapsed;
  dhcpv6_ia_header_t *ia_hdr;
  dhcpv6_ia_opt_pd_t *opt_pd;
  if (type == DHCPV6_MSG_SOLICIT || type == DHCPV6_MSG_REQUEST ||
      type == DHCPV6_MSG_RENEW || type == DHCPV6_MSG_REBIND ||
      type == DHCPV6_MSG_RELEASE)
    {
      duid = (dhcpv6_option_t *) d;
      duid->option = clib_host_to_net_u16 (DHCPV6_OPTION_CLIENTID);
      duid->length = clib_host_to_net_u16 (CLIENT_DUID_LENGTH);
      clib_memcpy (duid + 1, client_duid.bin_string, CLIENT_DUID_LENGTH);
      d += sizeof (*duid) + CLIENT_DUID_LENGTH;

      if (client_state->params.server_index != ~0)
	{
	  server_id_t *se =
	    &ccm->server_ids[client_state->params.server_index];

	  duid = (dhcpv6_option_t *) d;
	  duid->option = clib_host_to_net_u16 (DHCPV6_OPTION_SERVERID);
	  duid->length = clib_host_to_net_u16 (se->len);
	  clib_memcpy (duid + 1, se->data, se->len);
	  d += sizeof (*duid) + se->len;
	}

      elapsed = (dhcpv6_elapsed_t *) d;
      elapsed->opt.option = clib_host_to_net_u16 (DHCPV6_OPTION_ELAPSED_TIME);
      elapsed->opt.length =
	clib_host_to_net_u16 (sizeof (*elapsed) - sizeof (elapsed->opt));
      elapsed->elapsed_10ms = 0;
      client_state->elapsed_pos =
	(char *) &elapsed->elapsed_10ms -
	(char *) vlib_buffer_get_current (b);
      d += sizeof (*elapsed);

      ia_hdr = (dhcpv6_ia_header_t *) d;
      ia_hdr->opt.option = clib_host_to_net_u16 (DHCPV6_OPTION_IA_PD);
      ia_hdr->iaid = clib_host_to_net_u32 (DHCPV6_CLIENT_IAID);
      ia_hdr->t1 = clib_host_to_net_u32 (client_state->params.T1);
      ia_hdr->t2 = clib_host_to_net_u32 (client_state->params.T2);
      d += sizeof (*ia_hdr);

      n_prefixes = vec_len (client_state->params.prefixes);

      ia_hdr->opt.length =
	clib_host_to_net_u16 (sizeof (*ia_hdr) +
			      n_prefixes * sizeof (*opt_pd) -
			      sizeof (ia_hdr->opt));

      for (i = 0; i < n_prefixes; i++)
	{
	  dhcp6_pd_send_client_message_params_prefix_t *pref =
	    &client_state->params.prefixes[i];
	  opt_pd = (dhcpv6_ia_opt_pd_t *) d;
	  opt_pd->opt.option = clib_host_to_net_u16 (DHCPV6_OPTION_IAPREFIX);
	  opt_pd->opt.length =
	    clib_host_to_net_u16 (sizeof (*opt_pd) - sizeof (opt_pd->opt));
	  opt_pd->addr = pref->prefix;
	  opt_pd->prefix = pref->prefix_length;
	  opt_pd->valid = clib_host_to_net_u32 (pref->valid_lt);
	  opt_pd->preferred = clib_host_to_net_u32 (pref->preferred_lt);
	  d += sizeof (*opt_pd);
	}
    }
  else
    {
      clib_warning ("State not implemented");
    }

  dhcp_opt_len = ((u8 *) d) - dhcp->data;
  udp->length =
    clib_host_to_net_u16 (sizeof (*udp) + sizeof (*dhcp) + dhcp_opt_len);
  ip->payload_length = udp->length;
  b->current_length =
    sizeof (*ip) + sizeof (*udp) + sizeof (*dhcp) + dhcp_opt_len;

  ip->dst_address = all_dhcp6_relay_agents_and_servers;

  return b;
}
コード例 #11
0
ファイル: dhcp6_pd_client_dp.c プロジェクト: chrisy/vpp
static uword
dhcp6_pd_reply_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
			vlib_frame_t * f)
{
  /* These cross the longjmp  boundary (vlib_process_wait_for_event)
   * and need to be volatile - to prevent them from being optimized into
   * a register - which could change during suspension */

  while (1)
    {
      vlib_process_wait_for_event (vm);
      uword event_type = DHCP6_PD_DP_REPLY_REPORT;
      void *event_data = vlib_process_get_event_data (vm, &event_type);

      int i;
      if (event_type == DHCP6_PD_DP_REPLY_REPORT)
	{
	  prefix_report_t *events = event_data;
	  for (i = 0; i < vec_len (events); i++)
	    {
	      u32 event_size =
		sizeof (vl_api_dhcp6_pd_reply_event_t) +
		vec_len (events[i].prefixes) *
		sizeof (vl_api_dhcp6_pd_prefix_info_t);
	      vl_api_dhcp6_pd_reply_event_t *event =
		clib_mem_alloc (event_size);
	      clib_memset (event, 0, event_size);

	      event->sw_if_index = htonl (events[i].body.sw_if_index);
	      event->server_index = htonl (events[i].body.server_index);
	      event->msg_type = events[i].body.msg_type;
	      event->T1 = htonl (events[i].body.T1);
	      event->T2 = htonl (events[i].body.T2);
	      event->inner_status_code =
		htons (events[i].body.inner_status_code);
	      event->status_code = htons (events[i].body.status_code);
	      event->preference = events[i].body.preference;

	      event->n_prefixes = htonl (vec_len (events[i].prefixes));
	      vl_api_dhcp6_pd_prefix_info_t *prefix =
		(typeof (prefix)) event->prefixes;
	      u32 j;
	      for (j = 0; j < vec_len (events[i].prefixes); j++)
		{
		  dhcp6_prefix_info_t *info = &events[i].prefixes[j];
		  memcpy (prefix->prefix, &info->prefix, 16);
		  prefix->prefix_length = info->prefix_length;
		  prefix->valid_time = htonl (info->valid_time);
		  prefix->preferred_time = htonl (info->preferred_time);
		  prefix++;
		}
	      vec_free (events[i].prefixes);

	      dhcp6_pd_client_public_main_t *dpcpm =
		&dhcp6_pd_client_public_main;
	      call_dhcp6_pd_reply_event_callbacks (event, dpcpm->functions);

	      vpe_client_registration_t *reg;
              /* *INDENT-OFF* */
              pool_foreach(reg, vpe_api_main.dhcp6_pd_reply_events_registrations,
              ({
                vl_api_registration_t *vl_reg;
                vl_reg =
                  vl_api_client_index_to_registration (reg->client_index);
                if (vl_reg && vl_api_can_send_msg (vl_reg))
                  {
                    vl_api_dhcp6_pd_reply_event_t *msg =
                      vl_msg_api_alloc (event_size);
                    clib_memcpy (msg, event, event_size);
                    msg->_vl_msg_id = htons (VL_API_DHCP6_PD_REPLY_EVENT);
                    msg->client_index = reg->client_index;
                    msg->pid = reg->client_pid;
                    vl_api_send_msg (vl_reg, (u8 *) msg);
                  }
              }));
              /* *INDENT-ON* */

	      clib_mem_free (event);
	    }
	}
コード例 #12
0
ファイル: vpe_cli.c プロジェクト: Venkattk/vpp
static clib_error_t *
virtual_ip_cmd_fn_command_fn (vlib_main_t * vm,
		 unformat_input_t * input,
		 vlib_cli_command_t * cmd)
{
    unformat_input_t _line_input, * line_input = &_line_input;
    vnet_main_t * vnm = vnet_get_main();
    ip4_main_t * im = &ip4_main;
    ip_lookup_main_t * lm = &im->lookup_main;
    ip4_address_t ip_addr, next_hop;
    u8 mac_addr[6];
    mac_addr_t *mac_addrs = 0;
    u32 sw_if_index;
    u32 i, f;

    /* Get a line of input. */
    if (! unformat_user (input, unformat_line_input, line_input))
        return 0;

    if (!unformat(line_input, "%U %U", 
                  unformat_ip4_address, &ip_addr,
                  unformat_vnet_sw_interface, vnm, &sw_if_index))
        goto barf;

    while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
	if (unformat (line_input, "mac %U", 
                      unformat_ethernet_address, 
                      &mac_addr))
        {
            mac_addr_t *ma;
            vec_add2 (mac_addrs, ma, 1);
            clib_memcpy(ma, mac_addr, sizeof (mac_addr));
        } else {
        barf:
	    return clib_error_return (0, "unknown input `%U'",
				      format_unformat_error, input);
        }
    }
    if (vec_len (mac_addrs) == 0)
        goto barf;

    /* Create / delete special interface route /32's */
    next_hop.as_u32 = 0;

    for (i = 0; i < vec_len(mac_addrs); i++) {
        ip_adjacency_t adj;
        u32 adj_index;
        
        adj.lookup_next_index = IP_LOOKUP_NEXT_REWRITE;
        
        vnet_rewrite_for_sw_interface
            (vnm,
             VNET_L3_PACKET_TYPE_IP4,
             sw_if_index,
             ip4_rewrite_node.index,
             &mac_addrs[i],     /* destination address */
             &adj.rewrite_header,
             sizeof (adj.rewrite_data));

        ip_add_adjacency (lm, &adj, 1 /* one adj */,
                          &adj_index);
        
        f = (i + 1 < vec_len(mac_addrs)) ? IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP : 0;
        ip4_add_del_route_next_hop (im,
                                    IP4_ROUTE_FLAG_ADD | f,
                                    &ip_addr,
                                    32 /* insert /32's */,
                                    &next_hop,
                                    sw_if_index,
                                    1 /* weight */, 
                                    adj_index, 
                                    (u32)~0 /* explicit fib index */);
    }

    vec_free (mac_addrs);

    return 0;
}
コード例 #13
0
ファイル: policer.c プロジェクト: Venkattk/vpp
clib_error_t *
policer_add_del (vlib_main_t *vm,
                 u8 * name,
                 sse2_qos_pol_cfg_params_st * cfg,
                 u32 * policer_index,
                 u8 is_add)
{
  vnet_policer_main_t *pm = &vnet_policer_main;
  policer_read_response_type_st test_policer;
  policer_read_response_type_st * policer;
  uword * p;
  u32 pi;
  int rv;

  p = hash_get_mem (pm->policer_config_by_name, name);

  if (is_add == 0)
    {
      if (p == 0)
        {
          vec_free(name);
          return clib_error_return (0, "No such policer configuration");
        }
      hash_unset_mem (pm->policer_config_by_name, name);
      hash_unset_mem (pm->policer_index_by_name, name);
      vec_free(name);
      return 0;
    }

  if (p != 0)
    {
      vec_free(name);
      return clib_error_return (0, "Policer already exists");
    }

  /* Vet the configuration before adding it to the table */
  rv = sse2_pol_logical_2_physical (cfg, &test_policer);

  if (rv == 0)
    {
      policer_read_response_type_st *pp;
      sse2_qos_pol_cfg_params_st *cp;

      pool_get (pm->configs, cp);
      pool_get (pm->policer_templates, pp);

      ASSERT (cp - pm->configs == pp - pm->policer_templates);

      clib_memcpy (cp, cfg, sizeof (*cp));
      clib_memcpy (pp, &test_policer, sizeof (*pp));

      hash_set_mem (pm->policer_config_by_name, name, cp - pm->configs);
      pool_get_aligned (pm->policers, policer, CLIB_CACHE_LINE_BYTES);
      policer[0] = pp[0];
      pi = policer - pm->policers;
      hash_set_mem (pm->policer_index_by_name, name, pi);
      *policer_index = pi;
    }
  else
    {
      vec_free (name);
      return clib_error_return (0, "Config failed sanity check");
    }

  return 0;
}
コード例 #14
0
ファイル: application_local.c プロジェクト: chrisy/vpp
static int
ct_connect (app_worker_t * client_wrk, session_t * ll,
	    session_endpoint_cfg_t * sep)
{
  u32 cct_index, ll_index, ll_ct_index;
  ct_connection_t *sct, *cct, *ll_ct;
  app_worker_t *server_wrk;
  session_t *ss;

  ll_index = ll->session_index;
  ll_ct_index = ll->connection_index;

  cct = ct_connection_alloc ();
  cct_index = cct->c_c_index;
  sct = ct_connection_alloc ();
  ll_ct = ct_connection_get (ll_ct_index);

  /*
   * Alloc and init client transport
   */
  cct = ct_connection_get (cct_index);
  cct->c_thread_index = 0;
  cct->c_rmt_port = sep->port;
  cct->c_lcl_port = 0;
  cct->c_is_ip4 = sep->is_ip4;
  clib_memcpy (&cct->c_rmt_ip, &sep->ip, sizeof (sep->ip));
  cct->actual_tp = ll_ct->actual_tp;
  cct->is_client = 1;

  /*
   * Init server transport
   */
  sct->c_thread_index = 0;
  sct->c_rmt_port = 0;
  sct->c_lcl_port = ll_ct->c_lcl_port;
  sct->c_is_ip4 = sep->is_ip4;
  clib_memcpy (&sct->c_lcl_ip, &ll_ct->c_lcl_ip, sizeof (ll_ct->c_lcl_ip));
  sct->client_wrk = client_wrk->wrk_index;
  sct->c_proto = TRANSPORT_PROTO_NONE;
  sct->client_opaque = sep->opaque;
  sct->actual_tp = ll_ct->actual_tp;

  sct->peer_index = cct->c_c_index;
  cct->peer_index = sct->c_c_index;

  /*
   * Accept server session. Client session is created only after
   * server confirms accept.
   */
  ss = session_alloc (0);
  ll = listen_session_get (ll_index);
  ss->session_type = session_type_from_proto_and_ip (TRANSPORT_PROTO_NONE,
						     sct->c_is_ip4);
  ss->connection_index = sct->c_c_index;
  ss->listener_index = ll->session_index;
  ss->session_state = SESSION_STATE_CREATED;

  server_wrk = application_listener_select_worker (ll);
  ss->app_wrk_index = server_wrk->wrk_index;

  sct->c_s_index = ss->session_index;
  sct->server_wrk = ss->app_wrk_index;

  if (ct_init_local_session (client_wrk, server_wrk, sct, ss, ll))
    {
      clib_warning ("failed");
      ct_connection_free (sct);
      session_free (ss);
      return -1;
    }

  ss->session_state = SESSION_STATE_ACCEPTING;
  if (app_worker_accept_notify (server_wrk, ss))
    {
      clib_warning ("failed");
      ct_connection_free (sct);
      session_free_w_fifos (ss);
      return -1;
    }

  cct->segment_handle = sct->segment_handle;
  ct_enable_disable_main_pre_input_node (1 /* is_add */ );
  return 0;
}