summaryrefslogtreecommitdiffstats
path: root/src/vnet/ipsec/ipsec_output.c
AgeCommit message (Collapse)AuthorFilesLines
2019-02-22IPSEC: header exportsNeale Ranns1-0/+1
Change-Id: I7d48a4e236c6e7b11b0c9750a30fb68e829d64a5 Signed-off-by: Neale Ranns <nranns@cisco.com>
2019-02-05IPSEC: SPD counters in the stats sgementNeale Ranns1-42/+35
- return the stats_index of each SPD in the create API call - no ip_any in the API as this creates 2 SPD entries. client must add both v4 and v6 explicitly - only one pool of SPD entries (rhter than one per-SPD) to support this - no packets/bytes in the dump API. Polling the stats segment is much more efficient (if the SA lifetime is based on packet/bytes) - emit the policy index in the packet trace and CLI commands. Change-Id: I7eaf52c9d0495fa24450facf55229941279b8569 Signed-off-by: Neale Ranns <nranns@cisco.com>
2018-12-12Change ipsec feature node namesPierre Pfister1-4/+4
ipsec4-output and ipsec6-output were conflicting with ipsec interface names ("ipsec<id>") and vnet/interface.c autogenerated output node ("<ifname>-output"). Changing feature names seems to be the less invasive option. This patch also changes "input" feature names for consistency. Change-Id: I4ba10d07e9ba09df20aa2500104252b06b55f8f7 Signed-off-by: Pierre Pfister <ppfister@cisco.com>
2018-10-29migrate ipsec to new multiarch infraKlement Sekera1-13/+8
Change-Id: Ibef46e068cd72415af28920b0146adf48105bf68 Signed-off-by: Klement Sekera <ksekera@cisco.com>
2018-10-25buffer trace is broken in ipsec-output. copy it from node->flags to ↵Kingwel Xie1-0/+5
frame->frame_flags Change-Id: I56b573b5da04a27766bcbcafbd5438555424f2e7 Signed-off-by: Kingwel Xie <kingwel.xie@ericsson.com>
2018-10-22ipsec: split ipsec nodes into ip4/ip6 nodesKlement Sekera1-33/+35
Change-Id: Ic6b27659f1fe9e8df39e80a0441305e4e952195a Signed-off-by: Klement Sekera <ksekera@cisco.com>
2018-06-24Revert "Revert "ipsec: VPP-1316 calculate IP/TCP/UDP inner checksums""Klement Sekera1-1/+39
This reverts commit e0d2bd6bd7fc59c0c6ac48195d7f825dc99bfd91. Change-Id: If491e16f9ea66b2493a6a7c7f3c684ed585f8f51 Signed-off-by: Klement Sekera <ksekera@cisco.com>
2018-06-22Revert "ipsec: VPP-1316 calculate IP/TCP/UDP inner checksums"Ole Troan1-39/+1
This reverts commit a98346f664aae148d26a8e158008b773d73db96f. Change-Id: Iee5b3a5ddff0e8fd3a30fe5973cee24de434fe12 Signed-off-by: Ole Troan <ot@cisco.com>
2018-06-21ipsec: VPP-1316 calculate IP/TCP/UDP inner checksumsKlement Sekera1-1/+39
Calculate IP/TCP/UDP checksums in software before adding authentication. Change-Id: I3e121cb00aeba667764f39ade8d62170f18f8b6b Signed-off-by: Klement Sekera <ksekera@cisco.com>
2018-05-22CSIT-928 dpdk/ipsec: performance improvementRadu Nicolau1-7/+5
Replace hash with a vector to improve performance. Plus other minor performance improvements. Change-Id: I3f0ebd909782ce3727f6360ce5ff5ddd131f8574 Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
2018-01-24SCTP stack (RFC4960)Marco Varlese1-2/+6
== CONTENT == * SCTP chunks definition as per RFC4960; * Helper functions to set/get values to/from the corresponding chunks; * Hooks to the session/application layers; * Complete state-machine handling; * Implementation for unexpected chunk received in a certain state (state-machine error handling) * Support for 1-single connection; * Sample application to test receive/transmit data-path; * Test to validate SCTP stack; Change-Id: I1b55c455ab400be9513f4e094dadfc3181d2ebc9 Signed-off-by: Marco Varlese <marco.varlese@suse.com>
2017-11-28IPSec AH protocol enhancement in VPP native core“mukeshyadav1984”1-1/+8
Change-Id: Iec5804d768485f4015bbf732d8d19ef2f24e6939 Signed-off-by: “mukeshyadav1984” <mukyadav@cisco.com>
2017-01-27dpdk: rework cryptodev ipsec build and setupSergio Gonzalez Monroy1-20/+0
Build Cryptodev IPsec support by default when DPDK is enabled but only build hardware Cryptodev PMDs. To enable Cryptodev support, a new startup.conf option for dpdk has been introduced 'enable-cryptodev'. During VPP init, if Cryptodev support is not enabled or not enough cryptodev resources are available then default to OpenSSL ipsec implementation. Change-Id: I5aa7e0d5c2676bdb41d775ef40364536a081956d Signed-off-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
2017-01-16Add --without-libssl configure parameterDamjan Marion1-1/+1
This replaces --without-ipsec and --without-ipv6sr and allows other parts of the code to be disabled if libssl is not available. Change-Id: Id97ff3685a7924d7f86622952e0405d94ceb5957 Signed-off-by: Damjan Marion <damarion@cisco.com>
2016-12-28Reorganize source tree to use single autotools instanceDamjan Marion1-0/+478
Change-Id: I7b51f88292e057c6443b12224486f2d0c9f8ae23 Signed-off-by: Damjan Marion <damarion@cisco.com>
font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.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 */ }
/*
 *------------------------------------------------------------------
 * flow_api.c - flow api
 *
 * Copyright (c) 2020 Intel 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 <stddef.h>

#include <vnet/vnet.h>
#include <vlibmemory/api.h>
#include <vnet/interface.h>
#include <vnet/api_errno.h>
#include <vnet/flow/flow.h>
#include <vnet/fib/fib_table.h>
#include <vnet/udp/udp_local.h>
#include <vnet/tunnel/tunnel_types_api.h>
#include <vnet/ip/ip_types_api.h>
#include <vnet/vnet_msg_enum.h>

#define vl_typedefs		/* define message structures */
#include <vnet/vnet_all_api_h.h>
#undef vl_typedefs

#define vl_endianfun		/* define message structures */
#include <vnet/vnet_all_api_h.h>
#undef vl_endianfun

/* instantiate all the print functions we know about */
#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
#define vl_printfun
#include <vnet/vnet_all_api_h.h>
#undef vl_printfun

#include <vlibapi/api_helper_macros.h>

#define foreach_vpe_api_msg         \
_(FLOW_ADD, flow_add)               \
_(FLOW_DEL, flow_del)               \
_(FLOW_ENABLE, flow_enable)         \
_(FLOW_DISABLE, flow_disable)

static inline void
ipv4_addr_and_mask_convert (vl_api_ip4_address_and_mask_t * vl_api_addr,
			    ip4_address_and_mask_t * vnet_addr)
{
  clib_memcpy (vnet_addr, vl_api_addr, sizeof (*vnet_addr));
}

static inline void
ipv6_addr_and_mask_convert (vl_api_ip6_address_and_mask_t * vl_api_addr,
			    ip6_address_and_mask_t * vnet_addr)
{
  clib_memcpy (vnet_addr, vl_api_addr, sizeof (*vnet_addr));
}

static inline void
protocol_and_mask_convert (vl_api_ip_prot_and_mask_t * vl_api_protocol,
			   ip_prot_and_mask_t * vnet_protocol)
{
  vnet_protocol->prot = (ip_protocol_t) vl_api_protocol->prot;
  vnet_protocol->mask = vl_api_protocol->mask;
}

static inline void
port_and_mask_convert (vl_api_ip_port_and_mask_t * vl_api_port,
		       ip_port_and_mask_t * vnet_port)
{
  vnet_port->port = ntohs (vl_api_port->port);
  vnet_port->mask = ntohs (vl_api_port->mask);
}

static inline void
ipv4_n_tuple_flow_convert (vl_api_flow_ip4_n_tuple_t * vl_api_flow,
			   vnet_flow_ip4_n_tuple_t * f)
{
  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
  protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);

  port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
  port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
}

static void
ipv6_n_tuple_flow_convert (vl_api_flow_ip6_n_tuple_t * vl_api_flow,
			   vnet_flow_ip6_n_tuple_t * f)
{
  ipv6_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
  ipv6_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
  protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);

  port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
  port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
}

static inline void
ipv4_n_tuple_tagged_flow_convert (vl_api_flow_ip4_n_tuple_tagged_t *
				  vl_api_flow,
				  vnet_flow_ip4_n_tuple_tagged_t * f)
{
  return ipv4_n_tuple_flow_convert ((vl_api_flow_ip4_n_tuple_t *) vl_api_flow,
				    (vnet_flow_ip4_n_tuple_t *) f);
}

static inline void
ipv6_n_tuple_tagged_flow_convert (vl_api_flow_ip6_n_tuple_tagged_t *
				  vl_api_flow,
				  vnet_flow_ip6_n_tuple_tagged_t * f)
{
  return ipv6_n_tuple_flow_convert ((vl_api_flow_ip6_n_tuple_t *) vl_api_flow,
				    (vnet_flow_ip6_n_tuple_t *) f);
}

static inline void
ipv4_l2tpv3oip_flow_convert (vl_api_flow_ip4_l2tpv3oip_t * vl_api_flow,
			     vnet_flow_ip4_l2tpv3oip_t * f)
{
  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);

  protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
  f->session_id = ntohl (vl_api_flow->session_id);
}

static inline void
ipv4_ipsec_esp_flow_convert (vl_api_flow_ip4_ipsec_esp_t * vl_api_flow,
			     vnet_flow_ip4_ipsec_esp_t * f)
{
  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);

  protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
  f->spi = ntohl (vl_api_flow->spi);
}

static inline void
ipv4_ipsec_ah_flow_convert (vl_api_flow_ip4_ipsec_ah_t * vl_api_flow,
			    vnet_flow_ip4_ipsec_ah_t * f)
{
  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);

  protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
  f->spi = ntohl (vl_api_flow->spi);
}

static inline void
ipv4_gtpu_flow_convert (vl_api_flow_ip4_gtpu_t * vl_api_flow,
			vnet_flow_ip4_gtpu_t * f)
{
  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);

  port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
  port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);

  protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
  f->teid = ntohl (vl_api_flow->teid);
}

static inline void
ipv4_gtpc_flow_convert (vl_api_flow_ip4_gtpc_t * vl_api_flow,
			vnet_flow_ip4_gtpc_t * f)
{
  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);

  port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
  port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);

  protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
  f->teid = ntohl (vl_api_flow->teid);
}

static void
vl_api_flow_add_t_handler (vl_api_flow_add_t * mp)
{
  vl_api_flow_add_reply_t *rmp;
  int rv = 0;
  vnet_flow_t flow;
  u32 flow_index = ~0;
  vl_api_flow_rule_t *f = &mp->flow;

  vnet_main_t *vnm = vnet_get_main ();

  flow.type = ntohl (f->type);
  flow.actions = ntohl (f->actions);
  flow.mark_flow_id = ntohl (f->mark_flow_id);
  flow.redirect_node_index = ntohl (f->redirect_node_index);
  flow.redirect_device_input_next_index =
    ntohl (f->redirect_device_input_next_index);
  flow.redirect_queue = ntohl (f->redirect_queue);
  flow.buffer_advance = ntohl (f->buffer_advance);

  switch (flow.type)
    {
    case VNET_FLOW_TYPE_IP4_N_TUPLE:
      ipv4_n_tuple_flow_convert (&f->flow.ip4_n_tuple, &flow.ip4_n_tuple);
      break;
    case VNET_FLOW_TYPE_IP6_N_TUPLE:
      ipv6_n_tuple_flow_convert (&f->flow.ip6_n_tuple, &flow.ip6_n_tuple);
      break;
    case VNET_FLOW_TYPE_IP4_N_TUPLE_TAGGED:
      ipv4_n_tuple_tagged_flow_convert (&f->flow.ip4_n_tuple_tagged,
					&flow.ip4_n_tuple_tagged);
      break;
    case VNET_FLOW_TYPE_IP6_N_TUPLE_TAGGED:
      ipv6_n_tuple_tagged_flow_convert (&f->flow.ip6_n_tuple_tagged,
					&flow.ip6_n_tuple_tagged);
      break;
    case VNET_FLOW_TYPE_IP4_L2TPV3OIP:
      ipv4_l2tpv3oip_flow_convert (&f->flow.ip4_l2tpv3oip,
				   &flow.ip4_l2tpv3oip);
      break;
    case VNET_FLOW_TYPE_IP4_IPSEC_ESP:
      ipv4_ipsec_esp_flow_convert (&f->flow.ip4_ipsec_esp,
				   &flow.ip4_ipsec_esp);
      break;
    case VNET_FLOW_TYPE_IP4_IPSEC_AH:
      ipv4_ipsec_ah_flow_convert (&f->flow.ip4_ipsec_ah, &flow.ip4_ipsec_ah);
      break;
    case VNET_FLOW_TYPE_IP4_GTPU:
      ipv4_gtpu_flow_convert (&f->flow.ip4_gtpu, &flow.ip4_gtpu);
      break;
    case VNET_FLOW_TYPE_IP4_GTPC:
      ipv4_gtpc_flow_convert (&f->flow.ip4_gtpc, &flow.ip4_gtpc);
      break;
    default:
      rv = VNET_FLOW_ERROR_NOT_SUPPORTED;
      goto out;
      break;
    }

  rv = vnet_flow_add (vnm, &flow, &flow_index);

out:
  /* *INDENT-OFF* */
  REPLY_MACRO2(VL_API_FLOW_ADD_REPLY,
  ({
    rmp->flow_index = ntohl (flow_index);
  }));
  /* *INDENT-ON* */
}

static void
vl_api_flow_del_t_handler (vl_api_flow_del_t * mp)
{
  vl_api_flow_add_reply_t *rmp;
  int rv = 0;

  vnet_main_t *vnm = vnet_get_main ();
  rv = vnet_flow_del (vnm, ntohl (mp->flow_index));

  REPLY_MACRO (VL_API_FLOW_DEL_REPLY);
}

static void
vl_api_flow_enable_t_handler (vl_api_flow_enable_t * mp)
{
  vl_api_flow_add_reply_t *rmp;
  int rv = 0;

  vnet_main_t *vnm = vnet_get_main ();
  rv =
    vnet_flow_enable (vnm, ntohl (mp->flow_index), ntohl (mp->hw_if_index));

  REPLY_MACRO (VL_API_FLOW_ENABLE_REPLY);
}

static void
vl_api_flow_disable_t_handler (vl_api_flow_disable_t * mp)
{
  vl_api_flow_add_reply_t *rmp;
  int rv = 0;

  vnet_main_t *vnm = vnet_get_main ();
  rv =
    vnet_flow_disable (vnm, ntohl (mp->flow_index), ntohl (mp->hw_if_index));

  REPLY_MACRO (VL_API_FLOW_DISABLE_REPLY);
}

#define vl_msg_name_crc_list
#include <vnet/flow/flow.api.h>
#undef vl_msg_name_crc_list

/*
 * flow_api_hookup
 * Add vpe's API message handlers to the table.
 * vlib has already mapped shared memory and
 * added the client registration handlers.
 * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
 */


static void
setup_message_id_table (api_main_t * am)
{
#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
  foreach_vl_msg_name_crc_flow;
#undef _
}

static clib_error_t *
hw_flow_api_hookup (vlib_main_t * vm)
{
  api_main_t *am = vlibapi_get_main ();

#define _(N,n)                                                  \
    vl_msg_api_set_handlers(VL_API_##N, #n,                     \
                           vl_api_##n##_t_handler,              \
                           vl_noop_handler,                     \
                           vl_api_##n##_t_endian,               \
                           vl_api_##n##_t_print,                \
                           sizeof(vl_api_##n##_t), 1);
  foreach_vpe_api_msg;
#undef _

  /*
   * Set up the (msg_name, crc, message-id) table
   */
  setup_message_id_table (am);

  return 0;
}

VLIB_API_INIT_FUNCTION (hw_flow_api_hookup);

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