summaryrefslogtreecommitdiffstats
path: root/src/vnet/ipsec/ipsec_test.c
blob: f14361936367e832edb1fbf5ea5f08b85fa89945 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

@media only all and (prefers-color-scheme: dark) {
.highlight .hll { background-color: #49483e }
.highlight .c { color: #75715e } /* Comment */
.highlight .err { color: #960050; background-color: #1e0010 } /* Error */
.highlight .k { color: #66d9ef } /* Keyword */
.highlight .l { color: #ae81ff } /* Literal */
.highlight .n { color: #f8f8f2 } /* Name */
.highlight .o { color: #f92672 } /* Operator */
.highlight .p { color: #f8f8f2 } /* Punctuation */
.highlight .ch { color: #75715e } /* Comment.Hashbang */
.highlight .cm { color: #75715e } /* Comment.Multiline */
.highlight .cp { color: #75715e } /* Comment.Preproc */
.highlight .cpf { color: #75715e } /* Comment.PreprocFile */
.highlight .c1 { color: #75715e } /* Comment.Single */
.highlight .cs { color: #75715e } /* Comment.Special */
.highlight .gd { color: #f92672 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gi { color: #a6e22e } /* Generic.Inserted */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #75715e } /* Generic.Subheading */
.highlight .kc { color: #66d9ef } /* Keyword.Constant */
.highlight .kd { color: #66d9ef } /* Keyword.Declaration */
.highlight .kn { color: #f92672 } /* Keyword.Namespace */
.highlight .kp { color: #66d9ef } /* Keyword.Pseudo */
.highlight .kr { color: #66d9ef } /* Keyword.Reserved */
.highlight .kt { color: #66d9ef } /* Keyword.Type */
.highlight .ld { color: #e6db74 } /* Literal.Date */
.highlight .m { color: #ae81ff } /* Literal.Number */
.highlight .s { color: #e6db74 } /* Literal.String */
.highlight .na { color: #a6e22e } /* Name.Attribute */
.highlight .nb { color: #f8f8f2 } /* Name.Builtin */
.highlight .nc { color: #a6e22e } /* Name.Class */
.highlight .no { color: #66d9ef } /* Name.Constant */
.highlight .nd { color: #a6e22e } /* Name.Decorator */
.highlight .ni { color: #f8f8f2 } /* Name.Entity */
.highlight .ne { color: #a6e22e } /* Name.Exception */
.highlight .nf { color: #a6e22e } /* Name.Function */
.highlight .nl { color: #f8f8f2 } /* Name.Label */
.highlight .nn { color: #f8f8f2 } /* Name.Namespace */
.highlight .nx { color: #a6e22e } /* Name.Other */
.highlight .py { color: #f8f8f2 } /* Name.Property */
.highlight .nt { color: #f92672 } /* Name.Tag */
.highlight .nv { color: #f8f8f2 } /* Name.Variable */
.highlight .ow { color: #f92672 } /* Operator.Word */
.highlight .w { color: #f8f8f2 } /* Text.Whitespace */
.highlight .mb { color: #ae81ff } /* Literal.Number.Bin */
.highlight .mf { color: #ae81ff } /* Literal.Number.Float */
.highlight .mh { color: #ae81ff } /* Literal.Number.Hex */
.highlight .mi { color: #ae81ff } /* Literal.Number.Integer */
.highlight .mo { color: #ae81ff } /* Literal.Number.Oct */
.highlight .sa { color: #e6db74 } /* Literal.String.Affix */
.highlight .sb { color: #e6db74 } /* Literal.String.Backtick */
.highlight .sc { color: #e6db74 } /* Literal.String.Char */
.highlight .dl { color: #e6db74 } /* Literal.String.Delimiter */
.highlight .sd { color: #e6db74 } /* Literal.String.Doc */
.highlight .s2 { color: #e6db74 } /* Literal.String.Double */
.highlight .se { color: #ae81ff } /* Literal.String.Escape */
.highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */
.highlight .si { color: #e6db74 } /* Literal.String.Interpol */
.highlight .sx { color: #e6db74 } /* Literal.String.Other */
.highlight .sr { color: #e6db74 } /* Literal.String.Regex */
.highlight .s1 { color: #e6db74 } /* Literal.String.Single */
.highlight .ss { color: #e6db74 } /* Literal.String.Symbol */
.highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #a6e22e } /* Name.Function.Magic */
.highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */
.highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */
.highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */
.highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */
.highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */
}
@media (prefers-color-scheme: light) {
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; 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 */
}
/*
 * Copyright (c) 2018 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.
 */

#ifndef __MFIB_API_H__
#define __MFIB_API_H__

#include <vnet/mfib/mfib_types.h>
#include <vnet/ip/ip.api_types.h>

/**
 * Forward declare the API type, no need to include the generated api headers
 */
struct _vl_api_mfib_path;

/**
 * Encode and decode functions from the API types to internal types
 */
extern void mfib_api_path_encode(const fib_route_path_t *in,
                                 vl_api_mfib_path_t *out);
extern int mfib_api_path_decode(vl_api_mfib_path_t *in,
                                fib_route_path_t *out);

extern mfib_entry_flags_t mfib_api_path_entry_flags_decode (vl_api_mfib_entry_flags_t in);

extern int mfib_api_table_id_decode(fib_protocol_t fproto,
                                    u32 table_id,
                                    u32 *fib_index);

#endif /* __MFIB_API_H__ */
ef='#n431'>431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703
/* SPDX-License-Identifier: Apache-2.0
 * Copyright(c) 2021 Cisco Systems, Inc.
 */

#include <vat/vat.h>
#include <vlibapi/api.h>
#include <vlibmemory/api.h>
#include <vppinfra/error.h>
#include <vpp/api/types.h>

#include <vnet/ipsec/ipsec.h>
#include <vnet/ip/ip_types_api.h>

#define __plugin_msg_base ipsec_test_main.msg_id_base
#include <vlibapi/vat_helper_macros.h>

#include <vlibmemory/vlib.api_enum.h>
#include <vlibmemory/vlib.api_types.h>

/* Declare message IDs */
#include <vnet/format_fns.h>
#include <vnet/ipsec/ipsec.api_enum.h>
#include <vnet/ipsec/ipsec.api_types.h>

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

#define vl_calcsizefun
#include <vnet/ipsec/ipsec.api.h>
#undef vl_calcsizefun

typedef struct
{
  /* API message ID base */
  u16 msg_id_base;
  u32 ping_id;
  vat_main_t *vat_main;
} ipsec_test_main_t;

static ipsec_test_main_t ipsec_test_main;

static void
vl_api_ipsec_spds_details_t_handler (vl_api_ipsec_spds_details_t *mp)
{
}

static void
vl_api_ipsec_itf_details_t_handler (vl_api_ipsec_itf_details_t *mp)
{
}

static int
api_ipsec_itf_delete (vat_main_t *vat)
{
  return -1;
}

static int
api_ipsec_itf_create (vat_main_t *vat)
{
  return -1;
}

static void
vl_api_ipsec_itf_create_reply_t_handler (vl_api_ipsec_itf_create_reply_t *vat)
{
}

static int
api_ipsec_spd_entry_add_del (vat_main_t *vam)
{
  unformat_input_t *i = vam->input;
  vl_api_ipsec_spd_entry_add_del_t *mp;
  u8 is_add = 1, is_outbound = 0;
  u32 spd_id = 0, sa_id = 0, protocol = IPSEC_POLICY_PROTOCOL_ANY, policy = 0;
  i32 priority = 0;
  u32 rport_start = 0, rport_stop = (u32) ~0;
  u32 lport_start = 0, lport_stop = (u32) ~0;
  vl_api_address_t laddr_start = {}, laddr_stop = {}, raddr_start = {},
		   raddr_stop = {};
  int ret;

  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (i, "del"))
	is_add = 0;
      if (unformat (i, "outbound"))
	is_outbound = 1;
      if (unformat (i, "inbound"))
	is_outbound = 0;
      else if (unformat (i, "spd_id %d", &spd_id))
	;
      else if (unformat (i, "sa_id %d", &sa_id))
	;
      else if (unformat (i, "priority %d", &priority))
	;
      else if (unformat (i, "protocol %d", &protocol))
	;
      else if (unformat (i, "lport_start %d", &lport_start))
	;
      else if (unformat (i, "lport_stop %d", &lport_stop))
	;
      else if (unformat (i, "rport_start %d", &rport_start))
	;
      else if (unformat (i, "rport_stop %d", &rport_stop))
	;
      else if (unformat (i, "laddr_start %U", unformat_vl_api_address,
			 &laddr_start))
	;
      else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
			 &laddr_stop))
	;
      else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
			 &raddr_start))
	;
      else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
			 &raddr_stop))
	;
      else if (unformat (i, "action %U", unformat_ipsec_policy_action,
			 &policy))
	{
	  if (policy == IPSEC_POLICY_ACTION_RESOLVE)
	    {
	      clib_warning ("unsupported action: 'resolve'");
	      return -99;
	    }
	}
      else
	{
	  clib_warning ("parse error '%U'", format_unformat_error, i);
	  return -99;
	}
    }

  M (IPSEC_SPD_ENTRY_ADD_DEL, mp);

  mp->is_add = is_add;

  mp->entry.spd_id = ntohl (spd_id);
  mp->entry.priority = ntohl (priority);
  mp->entry.is_outbound = is_outbound;

  clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
	       sizeof (vl_api_address_t));
  clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
	       sizeof (vl_api_address_t));
  clib_memcpy (&mp->entry.local_address_start, &laddr_start,
	       sizeof (vl_api_address_t));
  clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
	       sizeof (vl_api_address_t));

  mp->entry.protocol = protocol ? (u8) protocol : IPSEC_POLICY_PROTOCOL_ANY;
  mp->entry.local_port_start = ntohs ((u16) lport_start);
  mp->entry.local_port_stop = ntohs ((u16) lport_stop);
  mp->entry.remote_port_start = ntohs ((u16) rport_start);
  mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
  mp->entry.policy = (u8) policy;
  mp->entry.sa_id = ntohl (sa_id);

  S (mp);
  W (ret);
  return ret;
}

static int
api_ipsec_spd_entry_add_del_v2 (vat_main_t *vam)
{
  unformat_input_t *i = vam->input;
  vl_api_ipsec_spd_entry_add_del_t *mp;
  u8 is_add = 1, is_outbound = 0;
  u32 spd_id = 0, sa_id = 0, protocol = IPSEC_POLICY_PROTOCOL_ANY, policy = 0;
  i32 priority = 0;
  u32 rport_start = 0, rport_stop = (u32) ~0;
  u32 lport_start = 0, lport_stop = (u32) ~0;
  vl_api_address_t laddr_start = {}, laddr_stop = {}, raddr_start = {},
		   raddr_stop = {};
  int ret;

  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (i, "del"))
	is_add = 0;
      if (unformat (i, "outbound"))
	is_outbound = 1;
      if (unformat (i, "inbound"))
	is_outbound = 0;
      else if (unformat (i, "spd_id %d", &spd_id))
	;
      else if (unformat (i, "sa_id %d", &sa_id))
	;
      else if (unformat (i, "priority %d", &priority))
	;
      else if (unformat (i, "protocol %d", &protocol))
	;
      else if (unformat (i, "lport_start %d", &lport_start))
	;
      else if (unformat (i, "lport_stop %d", &lport_stop))
	;
      else if (unformat (i, "rport_start %d", &rport_start))
	;
      else if (unformat (i, "rport_stop %d", &rport_stop))
	;
      else if (unformat (i, "laddr_start %U", unformat_vl_api_address,
			 &laddr_start))
	;
      else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
			 &laddr_stop))
	;
      else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
			 &raddr_start))
	;
      else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
			 &raddr_stop))
	;
      else if (unformat (i, "action %U", unformat_ipsec_policy_action,
			 &policy))
	{
	  if (policy == IPSEC_POLICY_ACTION_RESOLVE)
	    {
	      clib_warning ("unsupported action: 'resolve'");
	      return -99;
	    }
	}
      else
	{
	  clib_warning ("parse error '%U'", format_unformat_error, i);
	  return -99;
	}
    }

  M (IPSEC_SPD_ENTRY_ADD_DEL, mp);

  mp->is_add = is_add;

  mp->entry.spd_id = ntohl (spd_id);
  mp->entry.priority = ntohl (priority);
  mp->entry.is_outbound = is_outbound;

  clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
	       sizeof (vl_api_address_t));
  clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
	       sizeof (vl_api_address_t));
  clib_memcpy (&mp->entry.local_address_start, &laddr_start,
	       sizeof (vl_api_address_t));
  clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
	       sizeof (vl_api_address_t));

  mp->entry.protocol = (u8) protocol;
  mp->entry.local_port_start = ntohs ((u16) lport_start);
  mp->entry.local_port_stop = ntohs ((u16) lport_stop);
  mp->entry.remote_port_start = ntohs ((u16) rport_start);
  mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
  mp->entry.policy = (u8) policy;
  mp->entry.sa_id = ntohl (sa_id);

  S (mp);
  W (ret);
  return ret;
}

static void
vl_api_ipsec_spd_details_t_handler (vl_api_ipsec_spd_details_t *mp)
{
}

static void
vl_api_ipsec_sad_entry_add_del_reply_t_handler (
  vl_api_ipsec_sad_entry_add_del_reply_t *mp)
{
}

static void
vl_api_ipsec_sad_entry_add_del_v3_reply_t_handler (
  vl_api_ipsec_sad_entry_add_del_v3_reply_t *mp)
{
}

static void
vl_api_ipsec_sad_entry_add_reply_t_handler (
  vl_api_ipsec_sad_entry_add_reply_t *mp)
{
}

static int
api_ipsec_sad_entry_del (vat_main_t *vat)
{
  return -1;
}

static void
vl_api_ipsec_sad_entry_add_del_v2_reply_t_handler (
  vl_api_ipsec_sad_entry_add_del_v2_reply_t *mp)
{
}

static void
vl_api_ipsec_spd_interface_details_t_handler (
  vl_api_ipsec_spd_interface_details_t *vat)
{
}

static int
api_ipsec_sad_entry_add_del_v3 (vat_main_t *vat)
{
  return -1;
}

static int
api_ipsec_tunnel_protect_update (vat_main_t *vat)
{
  return -1;
}

static void
vl_api_ipsec_backend_details_t_handler (vl_api_ipsec_backend_details_t *mp)
{
}

static int
api_ipsec_sa_v3_dump (vat_main_t *vat)
{
  return -1;
}

static int
api_ipsec_tunnel_protect_dump (vat_main_t *vat)
{
  return -1;
}

static int
api_ipsec_tunnel_protect_del (vat_main_t *vat)
{
  return -1;
}

static void
vl_api_ipsec_tunnel_protect_details_t_handler (
  vl_api_ipsec_tunnel_protect_details_t *mp)
{
}

static int
api_ipsec_sad_entry_add (vat_main_t *vat)
{
  return -1;
}

static void
vl_api_ipsec_spd_entry_add_del_reply_t_handler (
  vl_api_ipsec_spd_entry_add_del_reply_t *mp)
{
}

static void
vl_api_ipsec_spd_entry_add_del_v2_reply_t_handler (
  vl_api_ipsec_spd_entry_add_del_v2_reply_t *mp)
{
}

static int
api_ipsec_spds_dump (vat_main_t *vam)
{
  return -1;
}

static int
api_ipsec_itf_dump (vat_main_t *vam)
{
  return -1;
}

static void
vl_api_ipsec_sa_v3_details_t_handler (vl_api_ipsec_sa_v3_details_t *mp)
{
}

static int
api_ipsec_spd_interface_dump (vat_main_t *vat)
{
  return -1;
}

static void
vl_api_ipsec_sa_v2_details_t_handler (vl_api_ipsec_sa_v2_details_t *mp)
{
}

static int
api_ipsec_sa_v2_dump (vat_main_t *mp)
{
  return -1;
}

static int
api_ipsec_sa_dump (vat_main_t *vam)
{
  unformat_input_t *i = vam->input;
  vl_api_ipsec_sa_dump_t *mp;
  vl_api_control_ping_t *mp_ping;
  u32 sa_id = ~0;
  int ret;

  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (i, "sa_id %d", &sa_id))
	;
      else
	{
	  clib_warning ("parse error '%U'", format_unformat_error, i);
	  return -99;
	}
    }

  M (IPSEC_SA_DUMP, mp);

  mp->sa_id = ntohl (sa_id);

  S (mp);

  /* Use a control ping for synchronization */
  PING (&ipsec_test_main, mp_ping);
  S (mp_ping);

  W (ret);
  return ret;
}

static void
vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t *mp)
{
  vat_main_t *vam = &vat_main;

  print (vam->ofp,
	 "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
	 "crypto_key %U integ_alg %u integ_key %U flags %x "
	 "tunnel_src_addr %U tunnel_dst_addr %U "
	 "salt %u seq_outbound %lu last_seq_inbound %lu "
	 "replay_window %lu stat_index %u\n",
	 ntohl (mp->entry.sad_id), ntohl (mp->sw_if_index),
	 ntohl (mp->entry.spi), ntohl (mp->entry.protocol),
	 ntohl (mp->entry.crypto_algorithm), format_hex_bytes,
	 mp->entry.crypto_key.data, mp->entry.crypto_key.length,
	 ntohl (mp->entry.integrity_algorithm), format_hex_bytes,
	 mp->entry.integrity_key.data, mp->entry.integrity_key.length,
	 ntohl (mp->entry.flags), format_vl_api_address, &mp->entry.tunnel_src,
	 format_vl_api_address, &mp->entry.tunnel_dst, ntohl (mp->salt),
	 clib_net_to_host_u64 (mp->seq_outbound),
	 clib_net_to_host_u64 (mp->last_seq_inbound),
	 clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
}

static int
api_ipsec_spd_dump (vat_main_t *vam)
{
  return -1;
}

uword
unformat_ipsec_api_crypto_alg (unformat_input_t *input, va_list *args)
{
  u32 *r = va_arg (*args, u32 *);

  if (0)
    ;
#define _(v, f, s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
  foreach_ipsec_crypto_alg
#undef _
    else return 0;
  return 1;
}

uword
unformat_ipsec_api_integ_alg (unformat_input_t *input, va_list *args)
{
  u32 *r = va_arg (*args, u32 *);

  if (0)
    ;
#define _(v, f, s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
  foreach_ipsec_integ_alg
#undef _
    else return 0;
  return 1;
}

static int
api_ipsec_sad_entry_add_del (vat_main_t *vam)
{
  unformat_input_t *i = vam->input;
  vl_api_ipsec_sad_entry_add_del_t *mp;
  u32 sad_id = 0, spi = 0;
  u8 *ck = 0, *ik = 0;
  u8 is_add = 1;

  vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
  vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
  vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
  vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
  vl_api_address_t tun_src, tun_dst;
  int ret;

  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (i, "del"))
	is_add = 0;
      else if (unformat (i, "sad_id %d", &sad_id))
	;
      else if (unformat (i, "spi %d", &spi))
	;
      else if (unformat (i, "esp"))
	protocol = IPSEC_API_PROTO_ESP;
      else if (unformat (i, "tunnel_src %U", unformat_vl_api_address,
			 &tun_src))
	{
	  flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
	  if (ADDRESS_IP6 == tun_src.af)
	    flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
	}
      else if (unformat (i, "tunnel_dst %U", unformat_vl_api_address,
			 &tun_dst))
	{
	  flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
	  if (ADDRESS_IP6 == tun_src.af)
	    flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
	}
      else if (unformat (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg,
			 &crypto_alg))
	;
      else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
	;
      else if (unformat (i, "integ_alg %U", unformat_ipsec_api_integ_alg,
			 &integ_alg))
	;
      else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
	;
      else
	{
	  clib_warning ("parse error '%U'", format_unformat_error, i);
	  return -99;
	}
    }

  M (IPSEC_SAD_ENTRY_ADD_DEL, mp);

  mp->is_add = is_add;
  mp->entry.sad_id = ntohl (sad_id);
  mp->entry.protocol = protocol;
  mp->entry.spi = ntohl (spi);
  mp->entry.flags = flags;

  mp->entry.crypto_algorithm = crypto_alg;
  mp->entry.integrity_algorithm = integ_alg;
  mp->entry.crypto_key.length = vec_len (ck);
  mp->entry.integrity_key.length = vec_len (ik);

  if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
    mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);

  if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
    mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);

  if (ck)
    clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
  if (ik)
    clib_memcpy (mp->entry.integrity_key.data, ik,
		 mp->entry.integrity_key.length);

  if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
    {
      clib_memcpy (&mp->entry.tunnel_src, &tun_src,
		   sizeof (mp->entry.tunnel_src));
      clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
		   sizeof (mp->entry.tunnel_dst));
    }

  S (mp);
  W (ret);
  return ret;
}

static int
api_ipsec_sad_entry_add_del_v2 (vat_main_t *vam)
{
  return -1;
}

static int
api_ipsec_interface_add_del_spd (vat_main_t *vam)
{
  vnet_main_t *vnm = vnet_get_main ();
  unformat_input_t *i = vam->input;
  vl_api_ipsec_interface_add_del_spd_t *mp;
  u32 sw_if_index;
  u8 sw_if_index_set = 0;
  u32 spd_id = (u32) ~0;
  u8 is_add = 1;
  int ret;

  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (i, "del"))
	is_add = 0;
      else if (unformat (i, "spd_id %d", &spd_id))
	;
      else if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
			 &sw_if_index))
	sw_if_index_set = 1;
      else if (unformat (i, "sw_if_index %d", &sw_if_index))
	sw_if_index_set = 1;
      else
	{
	  clib_warning ("parse error '%U'", format_unformat_error, i);
	  return -99;
	}
    }

  if (spd_id == (u32) ~0)
    {
      errmsg ("spd_id must be set");
      return -99;
    }

  if (sw_if_index_set == 0)
    {
      errmsg ("missing interface name or sw_if_index");
      return -99;
    }

  M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);

  mp->spd_id = ntohl (spd_id);
  mp->sw_if_index = ntohl (sw_if_index);
  mp->is_add = is_add;

  S (mp);
  W (ret);
  return ret;
}

static int
api_ipsec_backend_dump (vat_main_t *vam)
{
  return -1;
}

static int
api_ipsec_select_backend (vat_main_t *vam)
{
  return -1;
}

static int
api_ipsec_set_async_mode (vat_main_t *vam)
{
  return -1;
}

static int
api_ipsec_spd_add_del (vat_main_t *vam)
{
  unformat_input_t *i = vam->input;
  vl_api_ipsec_spd_add_del_t *mp;
  u32 spd_id = ~0;
  u8 is_add = 1;
  int ret;

  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (i, "spd_id %d", &spd_id))
	;
      else if (unformat (i, "del"))
	is_add = 0;
      else
	{
	  clib_warning ("parse error '%U'", format_unformat_error, i);
	  return -99;
	}
    }
  if (spd_id == ~0)
    {
      errmsg ("spd_id must be set");
      return -99;
    }

  M (IPSEC_SPD_ADD_DEL, mp);

  mp->spd_id = ntohl (spd_id);
  mp->is_add = is_add;

  S (mp);
  W (ret);
  return ret;
}

#include <vnet/ipsec/ipsec.api_test.c>

/*
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */