/*
 * 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.
 */
#include <stddef.h>

#include <vnet/vnet.h>
#include <vnet/devices/devices.h>
#include <vnet/ip/ip.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/ethernet/packet.h>
#include <vnet/flow/flow.h>

static format_function_t format_flow;

uword
unformat_ip_port_and_mask (unformat_input_t * input, va_list * args)
{
  ip_port_and_mask_t *pm = va_arg (*args, ip_port_and_mask_t *);
  u32 port = 0, mask = 0;

  if (unformat (input, "any"))
    ;
  else if (unformat (input, "%u/%u", &port, &mask))
    ;
  else if (unformat (input, "%u/0x%x", &port, &mask))
    ;
  else if (unformat (input, "%u", &port))
    mask = 0xffff;
  else
    return 0;

  if (port > 0xffff || mask > 0xffff)
    return 0;

  pm->port = port;
  pm->mask = mask;
  return 1;
}

u8 *
format_ip_port_and_mask (u8 * s, va_list * args)
{
  ip_port_and_mask_t *pm = va_arg (*args, ip_port_and_mask_t *);

  if (pm->port == 0 && pm->mask == 0)
    return format (s, "any");

  if (pm->mask == 0xffff)
    return format (s, "%u", pm->port);

  return format (s, "%u/0x%x", pm->port, pm->mask);
}

uword
unformat_ip_protocol_and_mask (unformat_input_t * input, va_list * args)
{
  ip_prot_and_mask_t *pm = va_arg (*args, ip_prot_and_mask_t *);
  u32 prot = 0, mask = 0;

  if (unformat (input, "any"))
    ;
  else if (unformat (input, "%U", unformat_ip_protocol, &prot))
    mask = 0xFF;
  else if (unformat (input, "%u", &prot))
    mask = 0xFF;
  else
    return 0;

  if (prot > 0XFF || mask > 0xFF)
    return 0;

  pm->prot = prot;
  pm->mask = mask;
  return 1;
}

u8 *
format_ip_protocol_and_mask (u8 * s, va_list * args)
{
  ip_prot_and_mask_t *pm = va_arg (*args, ip_prot_and_mask_t *);

  if (pm->prot == 0 && pm->mask == 0)
    return format (s, "any");

  return format (s, "%U", format_ip_protocol, pm->prot);
}

u8 *
format_flow_error (u8 * s, va_list * args)
{
  int error = va_arg (*args, int);

  if (error == 0)
    return format (s, "no error");

#define _(v,n,str) if (error == v) return format (s, #str);
  foreach_flow_error;
#undef _

  return format (s, "unknown error (%d)", error);
}

u8 *
format_flow_actions (u8 * s, va_list * args)
{
  u32 actions = va_arg (*args, u32);
  u8 *t = 0;

#define _(a, b, c) if (actions & (1 << a)) \
  t = format (t, "%s%s", t ? " ":"", c);
  foreach_flow_action
#undef _
    s = format (s, "%v", t);
  vec_free (t);
  return s;
}

u8 *
format_flow_enabled_hw (u8 * s, va_list * args)
{
  u32 flow_index = va_arg (*args, u32);
  vnet_flow_t *f = vnet_get_flow (flow_index);
  if (f == 0)
    return format (s, "not found");

  u8 *t = 0;
  u32 hw_if_index;
  uword private_data;
  vnet_main_t *vnm = vnet_get_main ();
  /* *INDENT-OFF* */
  hash_foreach (hw_if_index, private_data, f->private_data,
    ({
     t = format (t, "%s%U", t ? ", " : "",
                 format_vnet_hw_if_index_name, vnm, hw_if_index);
     }));
  /* *INDENT-ON* */
  s = format (s, "%v", t);
  vec_free (t);
  return s;
}

u8 *
format_rss_function (u8 * s, va_list * args)
{
  vnet_rss_function_t func = va_arg (*args, vnet_rss_function_t);

  if (0)
    ;
#undef _
#define _(f, n) \
      else if (func == VNET_RSS_FUNC_##f) \
        return format (s, n);

  foreach_rss_function
#undef _
    return format (s, "unknown");
}

u8 *
format_rss_types (u8 * s, va_list * args)
{
  u64 type = va_arg (*args, u64);

#undef _
#define _(a,b,c)     \
  if (type & (1UL<<a)) \
    s = format (s, "%s ", c);

  foreach_flow_rss_types
#undef _
    return s;
}

static const char *flow_type_strings[] = { 0,
#define _(a,b,c) c,
  foreach_flow_type
#undef _
};

static clib_error_t *
show_flow_entry (vlib_main_t * vm, unformat_input_t * input,
		 vlib_cli_command_t * cmd_arg)
{
  vnet_main_t *vnm = vnet_get_main ();
  vnet_flow_main_t *fm = &flow_main;
  unformat_input_t _line_input, *line_input = &_line_input;
  vnet_hw_interface_t *hi;
  vnet_device_class_t *dev_class;
  vnet_flow_t *f;
  uword private_data;
  u32 index = ~0, hw_if_index;

  if (!unformat_user (input, unformat_line_input, line_input))
    goto no_args;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "index %u", &index))
	;
      else
	return clib_error_return (0, "parse error: '%U'",
				  format_unformat_error, line_input);
    }

  unformat_free (line_input);

  if (index != ~0)
    {
      if ((f = vnet_get_flow (index)) == 0)
	return clib_error_return (0, "no such flow");

      vlib_cli_output (vm, "%-10s: %u", "index", f->index);
      vlib_cli_output (vm, "%-10s: %s", "type", flow_type_strings[f->type]);
      vlib_cli_output (vm, "%-10s: %U", "match", format_flow, f);
      /* *INDENT-OFF* */
      hash_foreach (hw_if_index, private_data, f->private_data,
        ({
	 hi = vnet_get_hw_interface (vnm, hw_if_index);
	  dev_class = vnet_get_device_class (vnm, hi->dev_class_index);
	  vlib_cli_output (vm,  "interface %U\n",
			   format_vnet_hw_if_index_name, vnm, hw_if_index);
	  if (dev_class->format_flow)
	    vlib_cli_output (vm,  "  %U\n", dev_class->format_flow,
			     hi->dev_instance, f->index, private_data);
         }));
      /* *INDENT-ON* */
      return 0;
    }

no_args:
  /* *INDENT-OFF* */
  pool_foreach (f, fm->global_flow_pool)
    {
      vlib_cli_output (vm, "%U\n", format_flow, f);
    }
  /* *INDENT-ON* */

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_flow_entry_command, static) = {
    .path = "show flow entry",
    .short_help = "show flow entry [index <index>]",
    .function = show_flow_entry,
};
/* *INDENT-ON* */

static clib_error_t *
show_flow_ranges (vlib_main_t * vm, unformat_input_t * input,
		  vlib_cli_command_t * cmd_arg)
{
  vnet_flow_main_t *fm = &flow_main;
  vnet_flow_range_t *r = 0;

  vlib_cli_output (vm, "%8s  %8s  %s", "Start", "Count", "Owner");

  /* *INDENT-OFF* */
  vec_foreach (r, fm->ranges)
    {
      vlib_cli_output (vm, "%8u  %8u  %s", r->start, r->count, r->owner);
    };
  /* *INDENT-ON* */
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_flow_ranges_command, static) = {
    .path = "show flow ranges",
    .short_help = "show flow ranges",
    .function = show_flow_ranges,
};
/* *INDENT-ON* */

static clib_error_t *
show_flow_interface (vlib_main_t * vm, unformat_input_t * input,
		     vlib_cli_command_t * cmd_arg)
{
  vnet_main_t *vnm = vnet_get_main ();
  vnet_hw_interface_t *hi;
  vnet_device_class_t *dev_class;
  unformat_input_t _line_input, *line_input = &_line_input;
  u32 hw_if_index = ~0;

  if (unformat_user (input, unformat_line_input, line_input))
    {
      while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
	{
	  if (unformat (line_input, "%U",
			unformat_vnet_hw_interface, vnm, &hw_if_index))
	    ;
	  else
	    return clib_error_return (0, "parse error: '%U'",
				      format_unformat_error, line_input);
	}
      unformat_free (line_input);
    }

  if (hw_if_index == ~0)
    return clib_error_return (0, "please specify interface");

  hi = vnet_get_hw_interface (vnm, hw_if_index);
  dev_class = vnet_get_device_class (vnm, hi->dev_class_index);
  if (dev_class->format_flow == 0)
    return clib_error_return (0, "not supported");

  vlib_cli_output (vm, "%U", dev_class->format_flow, hi->dev_instance, ~0, 0);
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_flow_interface_command, static) = {
    .path = "show flow interface",
    .short_help = "show flow interface <interface name>",
    .function = show_flow_interface,
};
/* *INDENT-ON* */

static clib_error_t *
test_flow (vlib_main_t * vm, unformat_input_t * input,
	   vlib_cli_command_t * cmd_arg)
{
  vnet_flow_t flow;
  vnet_main_t *vnm = vnet_get_main ();
  unformat_input_t _line_input, *line_input = &_line_input;
  enum
  {
    FLOW_UNKNOWN_ACTION,
    FLOW_ADD,
    FLOW_DEL,
    FLOW_ENABLE,
    FLOW_DISABLE
  } action = FLOW_UNKNOWN_ACTION;
  enum
  {
    FLOW_UNKNOWN_CLASS,
    FLOW_ETHERNET_CLASS,
    FLOW_IPV4_CLASS,
    FLOW_IPV6_CLASS,
  } flow_class = FLOW_UNKNOWN_CLASS;

  u32 hw_if_index = ~0, flow_index = ~0;
  int rv;
  u32 teid = 0, session_id = 0, spi = 0;
  u32 vni = 0;
  vnet_flow_type_t type = VNET_FLOW_TYPE_UNKNOWN;
  ip4_address_and_mask_t ip4s = { };
  ip4_address_and_mask_t ip4d = { };
  ip6_address_and_mask_t ip6s = { };
  ip6_address_and_mask_t ip6d = { };
  ip_port_and_mask_t sport = { };
  ip_port_and_mask_t dport = { };
  ip_prot_and_mask_t protocol = { };
  u16 eth_type;
  bool tcp_udp_port_set = false;
  bool gtpc_set = false;
  bool gtpu_set = false;
  bool vni_set = false;
  bool l2tpv3oip_set = false;
  bool ipsec_esp_set = false, ipsec_ah_set = false;
  u8 *rss_type[3] = { };
  u8 *type_str = NULL;

  clib_memset (&flow, 0, sizeof (vnet_flow_t));
  flow.index = ~0;
  flow.actions = 0;

  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "add"))
	action = FLOW_ADD;
      else if (unformat (line_input, "del"))
	action = FLOW_DEL;
      else if (unformat (line_input, "enable"))
	action = FLOW_ENABLE;
      else if (unformat (line_input, "disable"))
	action = FLOW_DISABLE;
      else if (unformat (line_input, "eth-type %U",
			 unformat_ethernet_type_host_byte_order, &eth_type))
	flow_class = FLOW_ETHERNET_CLASS;
      else if (unformat (line_input, "src-ip %U",
			 unformat_ip4_address_and_mask, &ip4s))
	flow_class = FLOW_IPV4_CLASS;
      else if (unformat (line_input, "dst-ip %U",
			 unformat_ip4_address_and_mask, &ip4d))
	flow_class = FLOW_IPV4_CLASS;
      else if (unformat (line_input, "ip6-src-ip %U",
			 unformat_ip6_address_and_mask, &ip6s))
	flow_class = FLOW_IPV6_CLASS;
      else if (unformat (line_input, "ip6-dst-ip %U",
			 unformat_ip6_address_and_mask, &ip6d))
	flow_class = FLOW_IPV6_CLASS;
      else if (unformat (line_input, "src-port %U", unformat_ip_port_and_mask,
			 &sport))
	tcp_udp_port_set = true;
      else if (unformat (line_input, "dst-port %U", unformat_ip_port_and_mask,
			 &dport))
	tcp_udp_port_set = true;
      else
	if (unformat
	    (line_input, "proto %U", unformat_ip_protocol_and_mask,
	     &protocol))
	;
      else if (unformat (line_input, "gtpc teid %u", &teid))
	gtpc_set = true;
      else if (unformat (line_input, "gtpu teid %u", &teid))
	gtpu_set = true;
      else if (unformat (line_input, "vxlan vni %u", &vni))
	vni_set = true;
      else if (unformat (line_input, "session id %u", &session_id))
	{
	  if (protocol.prot == IP_PROTOCOL_L2TP)
	    l2tpv3oip_set = true;
	}
      else if (unformat (line_input, "spi %u", &spi))
	{
	  if (protocol.prot == IP_PROTOCOL_IPSEC_ESP)
	    ipsec_esp_set = true;
	  else if (protocol.prot == IP_PROTOCOL_IPSEC_AH)
	    ipsec_ah_set = true;
	}
      else if (unformat (line_input, "index %u", &flow_index))
	;
      else if (unformat (line_input, "next-node %U", unformat_vlib_node, vm,
			 &flow.redirect_node_index))
	flow.actions |= VNET_FLOW_ACTION_REDIRECT_TO_NODE;
      else if (unformat (line_input, "mark %d", &flow.mark_flow_id))
	flow.actions |= VNET_FLOW_ACTION_MARK;
      else if (unformat (line_input, "buffer-advance %d",
			 &flow.buffer_advance))
	flow.actions |= VNET_FLOW_ACTION_BUFFER_ADVANCE;
      else if (unformat (line_input, "redirect-to-queue %d",
			 &flow.redirect_queue))
	flow.actions |= VNET_FLOW_ACTION_REDIRECT_TO_QUEUE;
      else if (unformat (line_input, "drop"))
	flow.actions |= VNET_FLOW_ACTION_DROP;
      else if (unformat (line_input, "rss function"))
	{
	  if (0)
	    ;
#undef _
#define _(f, s) \
      else if (unformat (line_input, s)) \
      flow.rss_fun = VNET_RSS_FUNC_##f;

	  foreach_rss_function
#undef _
	    else
	    {
	      return clib_error_return (0, "unknown input `%U'",
					format_unformat_error, line_input);
	    }

	  flow.actions |= VNET_FLOW_ACTION_RSS;
	}
      else if (unformat (line_input, "rss types"))
	{
	  rss_type[0] = NULL;
	  rss_type[1] = NULL;
	  rss_type[2] = NULL;
	  type_str = NULL;

	  if (unformat (line_input, "%s use %s and %s",
			&rss_type[0], &rss_type[1], &rss_type[2]))
	    ;
	  else if (unformat
		   (line_input, "%s use %s", &rss_type[0], &rss_type[1]))
	    ;
	  else if (unformat (line_input, "%s", &rss_type[0]))
	    ;

#undef _
#define _(a,b,c)     \
      else if (!clib_strcmp(c, (const char *)type_str)) \
        flow.rss_types |= (1ULL<<a);

#define check_rss_types(_str)     \
      if (_str != NULL) {\
        type_str = _str;\
        if (0) \
          ; \
        foreach_flow_rss_types \
        else \
        { \
          return clib_error_return (0, "parse error: '%U'", \
          format_unformat_error, line_input); \
        } \
      }

	  check_rss_types (rss_type[0])
	    check_rss_types (rss_type[1]) check_rss_types (rss_type[2])
#undef _
	    flow.actions |= VNET_FLOW_ACTION_RSS;
	}
      else if (unformat (line_input, "%U", unformat_vnet_hw_interface, vnm,
			 &hw_if_index))
	;
      else
	return clib_error_return (0, "parse error: '%U'",
				  format_unformat_error, line_input);
    }

  unformat_free (line_input);

  if (hw_if_index == ~0 && (action == FLOW_ENABLE || action == FLOW_DISABLE))
    return clib_error_return (0, "Please specify interface name");

  if (flow_index == ~0 && (action == FLOW_ENABLE || action == FLOW_DISABLE ||
			   action == FLOW_DEL))
    return clib_error_return (0, "Please specify flow index");

  switch (action)
    {
    case FLOW_ADD:
      if (flow.actions == 0)
	return clib_error_return (0, "Please specify at least one action");

      /* Adjust the flow type */
      switch (flow_class)
	{
	case FLOW_ETHERNET_CLASS:
	  type = VNET_FLOW_TYPE_ETHERNET;
	  break;

	case FLOW_IPV4_CLASS:
	  if (gtpc_set)
	    {
	      type = VNET_FLOW_TYPE_IP4_GTPC;
	      protocol.prot = IP_PROTOCOL_UDP;
	    }
	  else if (gtpu_set)
	    {
	      type = VNET_FLOW_TYPE_IP4_GTPU;
	      protocol.prot = IP_PROTOCOL_UDP;
	    }
	  else if (vni_set)
	    {
	      type = VNET_FLOW_TYPE_IP4_VXLAN;
	      protocol.prot = IP_PROTOCOL_UDP;
	    }
	  else if (l2tpv3oip_set)
	    type = VNET_FLOW_TYPE_IP4_L2TPV3OIP;
	  else if (ipsec_esp_set)
	    type = VNET_FLOW_TYPE_IP4_IPSEC_ESP;
	  else if (ipsec_ah_set)
	    type = VNET_FLOW_TYPE_IP4_IPSEC_AH;
	  else if (tcp_udp_port_set)
	    type = VNET_FLOW_TYPE_IP4_N_TUPLE;
	  else
	    type = VNET_FLOW_TYPE_IP4;
	  break;
	case FLOW_IPV6_CLASS:
	  if (tcp_udp_port_set)
	    type = VNET_FLOW_TYPE_IP6_N_TUPLE;
	  else if (vni_set)
	    type = VNET_FLOW_TYPE_IP6_VXLAN;
	  else
	    type = VNET_FLOW_TYPE_IP6;
	  break;

	default:
	  return clib_error_return (0,
				    "Please specify a supported flow type");
	}

      /* Assign specific field values per flow type */
      if (flow_class == FLOW_ETHERNET_CLASS)
	{
	  flow.ethernet.eth_hdr.type = eth_type;
	}
      else if (flow_class == FLOW_IPV4_CLASS)
	{
	  vnet_flow_ip4_t *ip4_ptr = &flow.ip4;

	  clib_memcpy (&ip4_ptr->src_addr, &ip4s,
		       sizeof (ip4_address_and_mask_t));
	  clib_memcpy (&ip4_ptr->dst_addr, &ip4d,
		       sizeof (ip4_address_and_mask_t));
	  ip4_ptr->protocol.prot = protocol.prot;

	  /* In this cli, we use the protocol.mask only when the flow type is
	   * VNET_FLOW_TYPE_IP4/IP6. For other cases, the IP protocol is just
	   * used to identify the next layer type: e.g. UDP/TCP or IPSEC_ESP
	   */
	  if (type == VNET_FLOW_TYPE_IP4)
	    ip4_ptr->protocol.mask = protocol.mask;

	  switch (protocol.prot)
	    {
	      /* ip4-n-tuple */
	    case IP_PROTOCOL_TCP:
	    case IP_PROTOCOL_UDP:
	      flow.ip4_n_tuple.src_port = sport;
	      flow.ip4_n_tuple.dst_port = dport;

	      if (type == VNET_FLOW_TYPE_IP4_GTPC)
		flow.ip4_gtpc.teid = teid;
	      else if (type == VNET_FLOW_TYPE_IP4_GTPU)
		flow.ip4_gtpu.teid = teid;
	      else if (type == VNET_FLOW_TYPE_IP4_VXLAN)
		flow.ip4_vxlan.vni = vni;
	      break;
	    case IP_PROTOCOL_L2TP:
	      flow.ip4_l2tpv3oip.session_id = session_id;
	      break;
	    case IP_PROTOCOL_IPSEC_ESP:
	      flow.ip4_ipsec_esp.spi = spi;
	      break;
	    case IP_PROTOCOL_IPSEC_AH:
	      flow.ip4_ipsec_esp.spi = spi;
	      break;
	    default:
	      break;
	    }
	}
      else if (flow_class == FLOW_IPV6_CLASS)
	{
	  vnet_flow_ip6_t *ip6_ptr = &flow.ip6;

	  clib_memcpy (&flow.ip6_n_tuple.src_addr, &ip6s,
		       sizeof (ip6_address_and_mask_t));
	  clib_memcpy (&flow.ip6_n_tuple.dst_addr, &ip6d,
		       sizeof (ip6_address_and_mask_t));

	  ip6_ptr->protocol.prot = protocol.prot;

	  /* In this cli, we use the protocol.mask only when the flow type is
	   * VNET_FLOW_TYPE_IP4/IP6. For other cases, the IP protocol is just
	   * used to identify the next layer type: e.g. UDP/TCP or IPSEC_ESP
	   */
	  if (type == VNET_FLOW_TYPE_IP6)
	    ip6_ptr->protocol.mask = protocol.mask;

	  switch (protocol.prot)
	    {
	      /* ip6-n-tuple */
	    case IP_PROTOCOL_TCP:
	    case IP_PROTOCOL_UDP:
	      flow.ip6_n_tuple.src_port = sport;
	      flow.ip6_n_tuple.dst_port = dport;

	      if (type == VNET_FLOW_TYPE_IP6_VXLAN)
		flow.ip6_vxlan.vni = vni;
	      break;
	    default:
	      break;
	    }
	}

      flow.type = type;
      rv = vnet_flow_add (vnm, &flow, &flow_index);
      if (!rv)
	vlib_cli_output (vm, "flow %u added", flow_index);

      break;
    case FLOW_DEL:
      rv = vnet_flow_del (vnm, flow_index);
      break;
    case FLOW_ENABLE:
      rv = vnet_flow_enable (vnm, flow_index, hw_if_index);
      break;
    case FLOW_DISABLE:
      rv = vnet_flow_disable (vnm, flow_index, hw_if_index);
      break;
    default:
      return clib_error_return (0, "please specify action (add, del, enable,"
				" disable)");
    }

  if (rv < 0)
    return clib_error_return (0, "flow error: %U", format_flow_error, rv);

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (test_flow_command, static) = {
    .path = "test flow",
    .short_help = "test flow [add|del|enable|disable] [index <id>] "
        "[src-ip <ip-addr/mask>] [dst-ip <ip-addr/mask>] "
        "[ip6-src-ip <ip-addr/mask>] [ip6-dst-ip <ip-addr/mask>] "
        "[src-port <port/mask>] [dst-port <port/mask>] "
        "[proto <ip-proto>] "
        "[gtpc teid <teid>] [gtpu teid <teid>] [vxlan <vni>] "
        "[session id <session>] [spi <spi>]"
        "[next-node <node>] [mark <id>] [buffer-advance <len>] "
        "[redirect-to-queue <queue>] [drop] "
        "[rss function <name>] [rss types <flow type>]",
    .function = test_flow,
};
/* *INDENT-ON* */

static u8 *
format_flow_match_element (u8 * s, va_list * args)
{
  char *type = va_arg (*args, char *);
  void *ptr = va_arg (*args, void *);

  if (strncmp (type, "u8", 2) == 0)
    return format (s, "%d", *(u8 *) ptr);

  if (strncmp (type, "u16", 3) == 0)
    return format (s, "%d", *(u16 *) ptr);

  if (strncmp (type, "u32", 3) == 0)
    return format (s, "%d", *(u32 *) ptr);

  if (strncmp (type, "ethernet_header_t", 13) == 0)
    {
      ethernet_max_header_t m;
      memset (&m, 0, sizeof (m));
      m.ethernet = *(ethernet_header_t *) ptr;
      /* convert the ethernet type to net order */
      m.ethernet.type = clib_host_to_net_u16 (m.ethernet.type);
      return format (s, "%U", format_ethernet_header, &m);
    }

  if (strncmp (type, "ip4_address_t", 13) == 0)
    return format (s, "%U", format_ip4_address, ptr);

  if (strncmp (type, "ip4_address_and_mask_t", 13) == 0)
    return format (s, "%U", format_ip4_address_and_mask, ptr);

  if (strncmp (type, "ip6_address_t", 13) == 0)
    return format (s, "%U", format_ip6_address, ptr);

  if (strncmp (type, "ip6_address_and_mask_t", 13) == 0)
    return format (s, "%U", format_ip6_address_and_mask, ptr);

  if (strncmp (type, "ip_prot_and_mask_t", 13) == 0)
    return format (s, "%U", format_ip_protocol_and_mask, ptr);

  if (strncmp (type, "ip_port_and_mask_t", 18) == 0)
    return format (s, "%U", format_ip_port_and_mask, ptr);

  s = format (s, "unknown type '%s'", type);
  return s;
}

#define _fe(a,b) s2 = format (s2, "%s%s %U", s2 ? ", ":"", #b, \
			      format_flow_match_element, #a, &f->b);
#define _(a,b,c) \
u8 * format_flow_match_##b (u8 * s, va_list * args)			\
{									\
  vnet_flow_##b##_t *f = __builtin_va_arg (*args, vnet_flow_##b##_t *); \
  u8 *s2 = 0; \
foreach_flow_entry_##b \
  s = format (s, "%v", s2);; \
  vec_free (s2); \
return s; \
}
foreach_flow_type
#undef _
#undef _fe
static u8 *
format_flow_match (u8 * s, va_list * args)
{
  vnet_flow_t *f = va_arg (*args, vnet_flow_t *);

#define _(a,b,c) \
  if (f->type == VNET_FLOW_TYPE_##a) \
    return format (s, "%U", format_flow_match_##b, &f->b);
  foreach_flow_type;
#undef _

  return s;
}

static u8 *
format_flow (u8 * s, va_list * args)
{
  vlib_main_t *vm = vlib_get_main ();
  vnet_flow_t *f = va_arg (*args, vnet_flow_t *);
  u32 indent = format_get_indent (s);
  u8 *t = 0;

  s = format (s, "flow-index %u type %s active %u",
	      f->index, flow_type_strings[f->type],
	      hash_elts (f->private_data)),
    s = format (s, "\n%Umatch: %U", format_white_space, indent + 2,
		format_flow_match, f);
  s = format (s, "\n%Uaction: %U", format_white_space, indent + 2,
	      format_flow_actions, f->actions);

  if (f->actions & VNET_FLOW_ACTION_DROP)
    t = format (t, "%sdrop", t ? ", " : "");

  if (f->actions & VNET_FLOW_ACTION_MARK)
    t = format (t, "%smark %u", t ? ", " : "", f->mark_flow_id);

  if (f->actions & VNET_FLOW_ACTION_REDIRECT_TO_QUEUE)
    t =
      format (t, "%sredirect-to-queue %u", t ? ", " : "", f->redirect_queue);

  if (f->actions & VNET_FLOW_ACTION_REDIRECT_TO_NODE)
    t = format (t, "%snext-node %U", t ? ", " : "",
		format_vlib_node_name, vm, f->redirect_node_index);

  if (f->actions & VNET_FLOW_ACTION_BUFFER_ADVANCE)
    t = format (t, "%sbuffer-advance %d", t ? ", " : "", f->buffer_advance);

  if (f->actions & VNET_FLOW_ACTION_RSS)
    {
      t = format (t, "%srss function %U", t ? ", " : "",
		  format_rss_function, f->rss_fun);
      t = format (t, "%srss types %U", t ? ", " : "",
		  format_rss_types, f->rss_types);
    }

  if (t)
    {
      s = format (s, "\n%U%v", format_white_space, indent + 4, t);
      vec_free (t);
    }

  return s;
}

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