/*
 * Copyright (c) 2017 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.
 */

/**
 * @file
 * @brief IPv6 Reassembly.
 *
 * This file contains the source code for IPv6 reassembly.
 */

#include <vppinfra/vec.h>
#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
#include <vppinfra/bihash_48_8.h>
#include <vnet/ip/ip6_reassembly.h>

#define MSEC_PER_SEC 1000
#define IP6_REASS_TIMEOUT_DEFAULT_MS 100
#define IP6_REASS_EXPIRE_WALK_INTERVAL_DEFAULT_MS 10000	// 10 seconds default
#define IP6_REASS_MAX_REASSEMBLIES_DEAFULT 1024
#define IP6_REASS_HT_LOAD_FACTOR (0.75)

static vlib_node_registration_t ip6_reass_node;

typedef struct
{
  union
  {
    struct
    {
      ip6_address_t src;
      ip6_address_t dst;
      // align by making this 4 octets even though its a 2 octets field
      u32 xx_id;
      // align by making this 4 octets even though its a 2 octets field
      u32 frag_id;
      // align by making this 4 octets even though its a 1 octet field
      u32 proto;
      u32 unused;
    };
    u64 as_u64[6];
  };
} ip6_reass_key_t;

always_inline u32
ip6_reass_buffer_get_data_offset_no_check (vlib_buffer_t * b)
{
  vnet_buffer_opaque_t *vnb = vnet_buffer (b);
  return vnb->ip.reass.range_first - vnb->ip.reass.fragment_first;
}

always_inline u32
ip6_reass_buffer_get_data_offset (vlib_buffer_t * b)
{
  vnet_buffer_opaque_t *vnb = vnet_buffer (b);
  ASSERT (vnb->ip.reass.range_first >= vnb->ip.reass.fragment_first);
  return ip6_reass_buffer_get_data_offset_no_check (b);
}

always_inline u16
ip6_reass_buffer_get_data_len_no_check (vlib_buffer_t * b)
{
  vnet_buffer_opaque_t *vnb = vnet_buffer (b);
  return clib_min (vnb->ip.reass.range_last, vnb->ip.reass.fragment_last) -
    (vnb->ip.reass.fragment_first + ip6_reass_buffer_get_data_offset (b)) + 1;
}

always_inline u16
ip6_reass_buffer_get_data_len (vlib_buffer_t * b)
{
  vnet_buffer_opaque_t *vnb = vnet_buffer (b);
  ASSERT (vnb->ip.reass.range_last > vnb->ip.reass.fragment_first);
  return ip6_reass_buffer_get_data_len_no_check (b);
}

typedef struct
{
  // hash table key
  ip6_reass_key_t key;
  // time when first packet was received
  f64 first_heard;
  // time when last packet was received
  f64 last_heard;
  // internal id of this reassembly
  u32 id;
  // buffer index of first buffer in this reassembly context
  u32 first_bi;
  // last octet of packet, ~0 until fragment without more_fragments arrives
  u32 last_packet_octet;
  // length of data collected so far
  u32 data_len;
  // trace operation counter
  u32 trace_op_counter;
} ip6_reass_t;

typedef struct
{
  // IPv6 config
  u32 timeout_ms;
  f64 timeout;
  u32 expire_walk_interval_ms;
  u32 max_reass_n;

  // IPv6 runtime
  ip6_reass_t *pool;
  clib_bihash_48_8_t hash;
  u32 reass_n;
  u32 id_counter;
  u32 buffers_n;

  // convenience
  vlib_main_t *vlib_main;
  vnet_main_t *vnet_main;

  // node index of ip6-drop node
  u32 ip6_drop_idx;
  u32 ip6_icmp_error_idx;
  u32 ip6_reass_expire_node_idx;

} ip6_reass_main_t;

ip6_reass_main_t ip6_reass_main;

typedef enum
{
  IP6_REASSEMBLY_NEXT_INPUT,
  IP6_REASSEMBLY_NEXT_DROP,
  IP6_REASSEMBLY_NEXT_ICMP_ERROR,
  IP6_REASSEMBLY_N_NEXT,
} ip6_reass_next_t;

typedef enum
{
  RANGE_NEW,
  RANGE_OVERLAP,
  ICMP_ERROR_RT_EXCEEDED,
  ICMP_ERROR_FL_TOO_BIG,
  ICMP_ERROR_FL_NOT_MULT_8,
  FINALIZE,
} ip6_reass_trace_operation_e;

typedef struct
{
  u16 range_first;
  u16 range_last;
  u32 range_bi;
  i32 data_offset;
  u32 data_len;
  u32 first_bi;
} ip6_reass_range_trace_t;

typedef struct
{
  ip6_reass_trace_operation_e action;
  u32 pool_index;
  u32 reass_id;
  ip6_reass_range_trace_t trace_range;
  u32 size_diff;
  u32 op_id;
  u32 fragment_first;
  u32 fragment_last;
  u32 total_data_len;
} ip6_reass_trace_t;

static void
ip6_reass_trace_details (vlib_main_t * vm, u32 bi,
			 ip6_reass_range_trace_t * trace)
{
  vlib_buffer_t *b = vlib_get_buffer (vm, bi);
  vnet_buffer_opaque_t *vnb = vnet_buffer (b);
  trace->range_first = vnb->ip.reass.range_first;
  trace->range_last = vnb->ip.reass.range_last;
  trace->data_offset = ip6_reass_buffer_get_data_offset_no_check (b);
  trace->data_len = ip6_reass_buffer_get_data_len_no_check (b);
  trace->range_bi = bi;
}

u8 *
format_ip6_reass_range_trace (u8 * s, va_list * args)
{
  ip6_reass_range_trace_t *trace = va_arg (*args, ip6_reass_range_trace_t *);
  s = format (s, "range: [%u, %u], off %d, len %u, bi %u", trace->range_first,
	      trace->range_last, trace->data_offset, trace->data_len,
	      trace->range_bi);
  return s;
}

u8 *
format_ip6_reass_trace (u8 * s, va_list * args)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
  ip6_reass_trace_t *t = va_arg (*args, ip6_reass_trace_t *);
  s = format (s, "reass id: %u, op id: %u ", t->reass_id, t->op_id);
  u32 indent = format_get_indent (s);
  s = format (s, "first bi: %u, data len: %u, ip/fragment[%u, %u]",
	      t->trace_range.first_bi, t->total_data_len, t->fragment_first,
	      t->fragment_last);
  switch (t->action)
    {
    case RANGE_NEW:
      s = format (s, "\n%Unew %U", format_white_space, indent,
		  format_ip6_reass_range_trace, &t->trace_range);
      break;
    case RANGE_OVERLAP:
      s = format (s, "\n%Uoverlap %U", format_white_space, indent,
		  format_ip6_reass_range_trace, &t->trace_range);
      break;
    case ICMP_ERROR_FL_TOO_BIG:
      s = format (s, "\n%Uicmp-error - frag_len > 65535 %U",
		  format_white_space, indent, format_ip6_reass_range_trace,
		  &t->trace_range);
      break;
    case ICMP_ERROR_FL_NOT_MULT_8:
      s = format (s, "\n%Uicmp-error - frag_len mod 8 != 0 %U",
		  format_white_space, indent, format_ip6_reass_range_trace,
		  &t->trace_range);
      break;
    case ICMP_ERROR_RT_EXCEEDED:
      s = format (s, "\n%Uicmp-error - reassembly time exceeded",
		  format_white_space, indent);
      break;
    case FINALIZE:
      s = format (s, "\n%Ufinalize reassembly", format_white_space, indent);
      break;
    }
  return s;
}

static void
ip6_reass_add_trace (vlib_main_t * vm, vlib_node_runtime_t * node,
		     ip6_reass_main_t * rm, ip6_reass_t * reass,
		     u32 bi, ip6_reass_trace_operation_e action,
		     u32 size_diff)
{
  vlib_buffer_t *b = vlib_get_buffer (vm, bi);
  vnet_buffer_opaque_t *vnb = vnet_buffer (b);
  ip6_reass_trace_t *t = vlib_add_trace (vm, node, b, sizeof (t[0]));
  t->pool_index = reass - rm->pool;
  t->reass_id = reass->id;
  t->action = action;
  ip6_reass_trace_details (vm, bi, &t->trace_range);
  t->size_diff = size_diff;
  t->op_id = reass->trace_op_counter;
  ++reass->trace_op_counter;
  t->fragment_first = vnb->ip.reass.fragment_first;
  t->fragment_last = vnb->ip.reass.fragment_last;
  t->trace_range.first_bi = reass->first_bi;
  t->total_data_len = reass->data_len;
#if 0
  static u8 *s = NULL;
  s = format (s, "%U", format_ip6_reass_trace, NULL, NULL, t);
  printf ("%.*s\n", vec_len (s), s);
  fflush (stdout);
  vec_reset_length (s);
#endif
}

static void
ip6_reass_free (ip6_reass_main_t * rm, ip6_reass_t * reass)
{
  clib_bihash_kv_48_8_t kv;
  kv.key[0] = reass->key.as_u64[0];
  kv.key[1] = reass->key.as_u64[1];
  kv.key[2] = reass->key.as_u64[2];
  kv.key[3] = reass->key.as_u64[3];
  kv.key[4] = reass->key.as_u64[4];
  kv.key[5] = reass->key.as_u64[5];
  clib_bihash_add_del_48_8 (&rm->hash, &kv, 0);
  pool_put (rm->pool, reass);
  --rm->reass_n;
}

static void
ip6_reass_drop_all (vlib_main_t * vm, ip6_reass_main_t * rm,
		    ip6_reass_t * reass, u32 ** vec_drop_bi)
{
  u32 range_bi = reass->first_bi;
  vlib_buffer_t *range_b;
  vnet_buffer_opaque_t *range_vnb;
  while (~0 != range_bi)
    {
      range_b = vlib_get_buffer (vm, range_bi);
      range_vnb = vnet_buffer (range_b);
      u32 bi = range_bi;
      while (~0 != bi)
	{
	  vec_add1 (*vec_drop_bi, bi);
	  vlib_buffer_t *b = vlib_get_buffer (vm, bi);
	  if (b->flags & VLIB_BUFFER_NEXT_PRESENT)
	    {
	      bi = b->next_buffer;
	      b->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
	    }
	  else
	    {
	      bi = ~0;
	    }
	}
      range_bi = range_vnb->ip.reass.next_range_bi;
    }
}

static void
ip6_reass_on_timeout (vlib_main_t * vm, vlib_node_runtime_t * node,
		      ip6_reass_main_t * rm, ip6_reass_t * reass,
		      u32 * icmp_bi, u32 ** vec_timeout)
{
  if (~0 == reass->first_bi)
    {
      return;
    }
  vlib_buffer_t *b = vlib_get_buffer (vm, reass->first_bi);
  if (0 == vnet_buffer (b)->ip.reass.fragment_first)
    {
      *icmp_bi = reass->first_bi;
      if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
	{
	  ip6_reass_add_trace (vm, node, rm, reass, reass->first_bi,
			       ICMP_ERROR_RT_EXCEEDED, 0);
	}
      // fragment with offset zero received - send icmp message back
      if (b->flags & VLIB_BUFFER_NEXT_PRESENT)
	{
	  // separate first buffer from chain and steer it towards icmp node
	  b->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
	  reass->first_bi = b->next_buffer;
	}
      else
	{
	  reass->first_bi = vnet_buffer (b)->ip.reass.next_range_bi;
	}
      icmp6_error_set_vnet_buffer (b, ICMP6_time_exceeded,
				   ICMP6_time_exceeded_fragment_reassembly_time_exceeded,
				   0);
    }
  ip6_reass_drop_all (vm, rm, reass, vec_timeout);
}

static ip6_reass_t *
ip6_reass_find_or_create (vlib_main_t * vm,
			  vlib_node_runtime_t * node,
			  ip6_reass_main_t * rm,
			  ip6_reass_key_t * k, u32 * icmp_bi,
			  u32 ** vec_timeout)
{
  ip6_reass_t *reass = NULL;
  f64 now = vlib_time_now (rm->vlib_main);
  clib_bihash_kv_48_8_t kv, value;
  kv.key[0] = k->as_u64[0];
  kv.key[1] = k->as_u64[1];
  kv.key[2] = k->as_u64[2];
  kv.key[3] = k->as_u64[3];
  kv.key[4] = k->as_u64[4];
  kv.key[5] = k->as_u64[5];

  if (!clib_bihash_search_48_8 (&rm->hash, &kv, &value))
    {
      reass = pool_elt_at_index (rm->pool, value.value);
      if (now > reass->last_heard + rm->timeout)
	{
	  ip6_reass_on_timeout (vm, node, rm, reass, icmp_bi, vec_timeout);
	  ip6_reass_free (rm, reass);
	  reass = NULL;
	}
    }

  if (reass)
    {
      reass->last_heard = now;
      return reass;
    }

  if (rm->reass_n >= rm->max_reass_n)
    {
      reass = NULL;
      return reass;
    }
  else
    {
      pool_get (rm->pool, reass);
      memset (reass, 0, sizeof (*reass));
      reass->id = rm->id_counter;
      ++rm->id_counter;
      reass->first_bi = ~0;
      reass->last_packet_octet = ~0;
      reass->data_len = 0;
      ++rm->reass_n;
    }

  reass->key.as_u64[0] = kv.key[0] = k->as_u64[0];
  reass->key.as_u64[1] = kv.key[1] = k->as_u64[1];
  reass->key.as_u64[2] = kv.key[2] = k->as_u64[2];
  reass->key.as_u64[3] = kv.key[3] = k->as_u64[3];
  reass->key.as_u64[4] = kv.key[4] = k->as_u64[4];
  reass->key.as_u64[5] = kv.key[5] = k->as_u64[5];
  kv.value = reass - rm->pool;
  reass->last_heard = now;

  if (clib_bihash_add_del_48_8 (&rm->hash, &kv, 1))
    {
      ip6_reass_free (rm, reass);
      reass = NULL;
    }

  return reass;
}

void
ip6_reass_finalize (vlib_main_t * vm, vlib_node_runtime_t * node,
		    ip6_reass_main_t * rm, ip6_reass_t * reass, u32 * bi0,
		    u32 * next0, vlib_error_t * error0, u32 next_input,
		    u32 ** vec_drop_compress)
{
  ASSERT (~0 != reass->first_bi);
  *bi0 = reass->first_bi;
  *next0 = next_input;
  *error0 = IP6_ERROR_NONE;
  ip6_frag_hdr_t *frag_hdr;
  vlib_buffer_t *last_b = NULL;
  u32 sub_chain_bi = reass->first_bi;
  u32 total_length = 0;
  u32 buf_cnt = 0;
  u32 dropped_cnt = 0;
  do
    {
      u32 tmp_bi = sub_chain_bi;
      vlib_buffer_t *tmp = vlib_get_buffer (vm, tmp_bi);
      u32 data_len = ip6_reass_buffer_get_data_len (tmp);
      u32 trim_front = vnet_buffer (tmp)->ip.reass.ip6_frag_hdr_offset +
	sizeof (*frag_hdr) + ip6_reass_buffer_get_data_offset (tmp);
      u32 trim_end =
	vlib_buffer_length_in_chain (vm, tmp) - trim_front - data_len;
      if (tmp_bi == reass->first_bi)
	{
	  /* first buffer - keep ip6 header */
	  ASSERT (0 == ip6_reass_buffer_get_data_offset (tmp));
	  trim_front = 0;
	  trim_end = vlib_buffer_length_in_chain (vm, tmp) - data_len -
	    (vnet_buffer (tmp)->ip.reass.ip6_frag_hdr_offset +
	     sizeof (*frag_hdr));
	  ASSERT (vlib_buffer_length_in_chain (vm, tmp) - trim_end > 0);
	}
      u32 keep_data =
	vlib_buffer_length_in_chain (vm, tmp) - trim_front - trim_end;
      while (1)
	{
	  ++buf_cnt;
	  if (trim_front)
	    {
	      if (trim_front > tmp->current_length)
		{
		  /* drop whole buffer */
		  vec_add1 (*vec_drop_compress, tmp_bi);
		  ++dropped_cnt;
		  trim_front -= tmp->current_length;
		  ASSERT (tmp->flags & VLIB_BUFFER_NEXT_PRESENT);
		  tmp->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
		  tmp_bi = tmp->next_buffer;
		  tmp = vlib_get_buffer (vm, tmp_bi);
		  continue;
		}
	      else
		{
		  vlib_buffer_advance (tmp, trim_front);
		  trim_front = 0;
		}
	    }
	  if (keep_data)
	    {
	      if (last_b)
		{
		  last_b->flags |= VLIB_BUFFER_NEXT_PRESENT;
		  last_b->next_buffer = tmp_bi;
		}
	      last_b = tmp;
	      if (keep_data <= tmp->current_length)
		{
		  tmp->current_length = keep_data;
		  keep_data = 0;
		}
	      else
		{
		  keep_data -= tmp->current_length;
		  ASSERT (tmp->flags & VLIB_BUFFER_NEXT_PRESENT);
		}
	      total_length += tmp->current_length;
	    }
	  else
	    {
	      vec_add1 (*vec_drop_compress, tmp_bi);
	      ASSERT (reass->first_bi != tmp_bi);
	      ++dropped_cnt;
	    }
	  if (tmp->flags & VLIB_BUFFER_NEXT_PRESENT)
	    {
	      tmp_bi = tmp->next_buffer;
	      tmp = vlib_get_buffer (vm, tmp->next_buffer);
	    }
	  else
	    {
	      break;
	    }
	}
      sub_chain_bi =
	vnet_buffer (vlib_get_buffer (vm, sub_chain_bi))->ip.
	reass.next_range_bi;
    }
  while (~0 != sub_chain_bi);
  last_b->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
  vlib_buffer_t *first_b = vlib_get_buffer (vm, reass->first_bi);
  ASSERT (total_length >= first_b->current_length);
  total_length -= first_b->current_length;
  first_b->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
  first_b->total_length_not_including_first_buffer = total_length;
  // drop fragment header
  vnet_buffer_opaque_t *first_b_vnb = vnet_buffer (first_b);
  ip6_header_t *ip = vlib_buffer_get_current (first_b);
  u16 ip6_frag_hdr_offset = first_b_vnb->ip.reass.ip6_frag_hdr_offset;
  ip6_ext_header_t *prev_hdr;
  ip6_ext_header_find_t (ip, prev_hdr, frag_hdr,
			 IP_PROTOCOL_IPV6_FRAGMENTATION);
  if (prev_hdr)
    {
      prev_hdr->next_hdr = frag_hdr->next_hdr;
    }
  else
    {
      ip->protocol = frag_hdr->next_hdr;
    }
  ASSERT ((u8 *) frag_hdr - (u8 *) ip == ip6_frag_hdr_offset);
  memmove (frag_hdr, (u8 *) frag_hdr + sizeof (*frag_hdr),
	   first_b->current_length - ip6_frag_hdr_offset -
	   sizeof (ip6_frag_hdr_t));
  first_b->current_length -= sizeof (*frag_hdr);
  ip->payload_length =
    clib_host_to_net_u16 (total_length + first_b->current_length -
			  sizeof (*ip));
  ip6_reass_free (rm, reass);
  vlib_buffer_chain_compress (vm, first_b, vec_drop_compress);
  if (PREDICT_FALSE (first_b->flags & VLIB_BUFFER_IS_TRACED))
    {
      ip6_reass_add_trace (vm, node, rm, reass, reass->first_bi, FINALIZE, 0);
#if 0
      // following code does a hexdump of packet fragments to stdout ...
      do
	{
	  u32 bi = reass->first_bi;
	  u8 *s = NULL;
	  while (~0 != bi)
	    {
	      vlib_buffer_t *b = vlib_get_buffer (vm, bi);
	      s = format (s, "%u: %U\n", bi, format_hexdump,
			  vlib_buffer_get_current (b), b->current_length);
	      if (b->flags & VLIB_BUFFER_NEXT_PRESENT)
		{
		  bi = b->next_buffer;
		}
	      else
		{
		  break;
		}
	    }
	  printf ("%.*s\n", vec_len (s), s);
	  fflush (stdout);
	  vec_free (s);
	}
      while (0);
#endif
    }
  reass = NULL;
}

static u32
ip6_reass_get_buffer_chain_length (vlib_main_t * vm, vlib_buffer_t * b)
{
  u32 len = 0;
  while (b)
    {
      ++len;
      if (PREDICT_FALSE (b->flags & VLIB_BUFFER_NEXT_PRESENT))
	{
	  b = vlib_get_buffer (vm, b->next_buffer);
	}
      else
	{
	  break;
	}
    }
  return len;
}

static void
ip6_reass_insert_range_in_chain (vlib_main_t * vm,
				 ip6_reass_main_t * rm,
				 ip6_reass_t * reass,
				 u32 prev_range_bi, u32 new_next_bi)
{

  vlib_buffer_t *new_next_b = vlib_get_buffer (vm, new_next_bi);
  vnet_buffer_opaque_t *new_next_vnb = vnet_buffer (new_next_b);
  if (~0 != prev_range_bi)
    {
      vlib_buffer_t *prev_b = vlib_get_buffer (vm, prev_range_bi);
      vnet_buffer_opaque_t *prev_vnb = vnet_buffer (prev_b);
      new_next_vnb->ip.reass.next_range_bi = prev_vnb->ip.reass.next_range_bi;
      prev_vnb->ip.reass.next_range_bi = new_next_bi;
    }
  else
    {
      if (~0 != reass->first_bi)
	{
	  new_next_vnb->ip.reass.next_range_bi = reass->first_bi;
	}
      reass->first_bi = new_next_bi;
    }
  reass->data_len += ip6_reass_buffer_get_data_len (new_next_b);
  rm->buffers_n += ip6_reass_get_buffer_chain_length (vm, new_next_b);
}

void
ip6_reass_update (vlib_main_t * vm, vlib_node_runtime_t * node,
		  ip6_reass_main_t * rm, ip6_reass_t * reass, u32 * bi0,
		  u32 * next0, vlib_error_t * error0,
		  ip6_frag_hdr_t * frag_hdr, u32 ** vec_drop_overlap,
		  u32 ** vec_drop_compress, u32 next_input, u32 next_drop,
		  u32 next_icmp_error)
{
  int consumed = 0;
  vlib_buffer_t *fb = vlib_get_buffer (vm, *bi0);
  vnet_buffer_opaque_t *fvnb = vnet_buffer (fb);
  fvnb->ip.reass.ip6_frag_hdr_offset =
    (u8 *) frag_hdr - (u8 *) vlib_buffer_get_current (fb);
  ip6_header_t *fip = vlib_buffer_get_current (fb);
  ASSERT (fb->current_length > sizeof (*fip));
  ASSERT (fvnb->ip.reass.ip6_frag_hdr_offset > 0 &&
	  fvnb->ip.reass.ip6_frag_hdr_offset < fb->current_length);
  u32 fragment_first = fvnb->ip.reass.fragment_first =
    ip6_frag_hdr_offset_bytes (frag_hdr);
  u32 fragment_length =
    vlib_buffer_length_in_chain (vm, fb) -
    (fvnb->ip.reass.ip6_frag_hdr_offset + sizeof (*frag_hdr));
  u32 fragment_last = fvnb->ip.reass.fragment_last =
    fragment_first + fragment_length - 1;
  int more_fragments = ip6_frag_hdr_more (frag_hdr);
  u32 candidate_range_bi = reass->first_bi;
  u32 prev_range_bi = ~0;
  fvnb->ip.reass.range_first = fragment_first;
  fvnb->ip.reass.range_last = fragment_last;
  fvnb->ip.reass.next_range_bi = ~0;
  if (more_fragments && 0 != fragment_length % 8)
    {
      if (PREDICT_FALSE (fb->flags & VLIB_BUFFER_IS_TRACED))
	{
	  ip6_reass_add_trace (vm, node, rm, reass, *bi0,
			       ICMP_ERROR_FL_NOT_MULT_8, 0);
	}
      *next0 = next_icmp_error;
      icmp6_error_set_vnet_buffer (fb, ICMP6_parameter_problem,
				   ICMP6_parameter_problem_erroneous_header_field,
				   (u8 *) & fip->payload_length - (u8 *) fip);
      return;
    }
  if (fragment_first + fragment_length > 65535)
    {
      if (PREDICT_FALSE (fb->flags & VLIB_BUFFER_IS_TRACED))
	{
	  ip6_reass_add_trace (vm, node, rm, reass, *bi0,
			       ICMP_ERROR_FL_TOO_BIG, 0);
	}
      *next0 = next_icmp_error;
      ip6_header_t *ip0 = vlib_buffer_get_current (fb);
      icmp6_error_set_vnet_buffer (fb, ICMP6_parameter_problem,
				   ICMP6_parameter_problem_erroneous_header_field,
				   (u8 *) & frag_hdr->fragment_offset_and_more
				   - (u8 *) ip0);
      return;
    }
  if (!more_fragments)
    {
      reass->last_packet_octet = fragment_last;
    }
  if (~0 == reass->first_bi)
    {
      // starting a new reassembly
      ip6_reass_insert_range_in_chain (vm, rm, reass, prev_range_bi, *bi0);
      if (PREDICT_FALSE (fb->flags & VLIB_BUFFER_IS_TRACED))
	{
	  ip6_reass_add_trace (vm, node, rm, reass, *bi0, RANGE_NEW, 0);
	}
      *bi0 = ~0;
      return;
    }
  fvnb->ip.reass.estimated_mtu =
    clib_min (clib_net_to_host_u16 (fip->payload_length),
	      fvnb->ip.reass.estimated_mtu);
  while (~0 != candidate_range_bi)
    {
      vlib_buffer_t *candidate_b = vlib_get_buffer (vm, candidate_range_bi);
      vnet_buffer_opaque_t *candidate_vnb = vnet_buffer (candidate_b);
      if (fragment_first > candidate_vnb->ip.reass.range_last)
	{
	  // this fragments starts after candidate range
	  prev_range_bi = candidate_range_bi;
	  candidate_range_bi = candidate_vnb->ip.reass.next_range_bi;
	  if (candidate_vnb->ip.reass.range_last < fragment_last &&
	      ~0 == candidate_range_bi)
	    {
	      // special case - this fragment falls beyond all known ranges
	      ip6_reass_insert_range_in_chain (vm, rm, reass, prev_range_bi,
					       *bi0);
	      consumed = 1;
	      break;
	    }
	  continue;
	}
      if (fragment_last < candidate_vnb->ip.reass.range_first)
	{
	  // this fragment ends before candidate range without any overlap
	  ip6_reass_insert_range_in_chain (vm, rm, reass, prev_range_bi,
					   *bi0);
	  consumed = 1;
	}
      else if (fragment_first == candidate_vnb->ip.reass.range_first &&
	       fragment_last == candidate_vnb->ip.reass.range_last)
	{
	  // duplicate fragment - ignore
	}
      else
	{
	  // overlapping fragment - not allowed by RFC 8200
	  ip6_reass_drop_all (vm, rm, reass, vec_drop_overlap);
	  ip6_reass_free (rm, reass);
	  if (PREDICT_FALSE (fb->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      ip6_reass_add_trace (vm, node, rm, reass, *bi0, RANGE_OVERLAP,
				   0);
	    }
	  *next0 = next_drop;
	  *error0 = IP6_ERROR_REASS_OVERLAPPING_FRAGMENT;
	}
      break;
    }
  if (consumed)
    {
      if (PREDICT_FALSE (fb->flags & VLIB_BUFFER_IS_TRACED))
	{
	  ip6_reass_add_trace (vm, node, rm, reass, *bi0, RANGE_NEW, 0);
	}
    }
  if (~0 != reass->last_packet_octet &&
      reass->data_len == reass->last_packet_octet + 1)
    {
      ip6_reass_finalize (vm, node, rm, reass, bi0, next0, error0, next_input,
			  vec_drop_compress);
    }
  else
    {
      if (consumed)
	{
	  *bi0 = ~0;
	}
      else
	{
	  *next0 = next_drop;
	  *error0 = IP6_ERROR_REASS_DUPLICATE_FRAGMENT;
	}
    }
}

always_inline uword
ip6_reassembly (vlib_main_t * vm, vlib_node_runtime_t * node,
		vlib_frame_t * frame)
{
  u32 *from = vlib_frame_vector_args (frame);
  u32 n_left_from, n_left_to_next, *to_next, next_index;
  ip6_reass_main_t *rm = &ip6_reass_main;

  n_left_from = frame->n_vectors;
  next_index = node->cached_next_index;
  static u32 *vec_timeout = NULL;	// indexes of buffers which timed out
  static u32 *vec_drop_overlap = NULL;	// indexes of buffers dropped due to overlap
  static u32 *vec_drop_compress = NULL;	// indexes of buffers dropped due to buffer compression
  while (n_left_from > 0 || vec_len (vec_timeout) > 0 ||
	 vec_len (vec_drop_overlap) > 0)
    {
      vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);

      while (vec_len (vec_timeout) > 0 && n_left_to_next > 0)
	{
	  u32 bi = vec_pop (vec_timeout);
	  vlib_buffer_t *b = vlib_get_buffer (vm, bi);
	  b->error = node->errors[IP6_ERROR_REASS_TIMEOUT];
	  to_next[0] = bi;
	  to_next += 1;
	  n_left_to_next -= 1;
	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
					   n_left_to_next, bi,
					   IP6_REASSEMBLY_NEXT_DROP);
	  ASSERT (rm->buffers_n > 0);
	  --rm->buffers_n;
	}

      while (vec_len (vec_drop_overlap) > 0 && n_left_to_next > 0)
	{
	  u32 bi = vec_pop (vec_drop_overlap);
	  vlib_buffer_t *b = vlib_get_buffer (vm, bi);
	  b->error = node->errors[IP6_ERROR_REASS_OVERLAPPING_FRAGMENT];
	  to_next[0] = bi;
	  to_next += 1;
	  n_left_to_next -= 1;
	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
					   n_left_to_next, bi,
					   IP6_REASSEMBLY_NEXT_DROP);
	  ASSERT (rm->buffers_n > 0);
	  --rm->buffers_n;
	}

      while (vec_len (vec_drop_compress) > 0 && n_left_to_next > 0)
	{
	  u32 bi = vec_pop (vec_drop_compress);
	  vlib_buffer_t *b = vlib_get_buffer (vm, bi);
	  b->error = node->errors[IP6_ERROR_NONE];
	  to_next[0] = bi;
	  to_next += 1;
	  n_left_to_next -= 1;
	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
					   n_left_to_next, bi,
					   IP6_REASSEMBLY_NEXT_DROP);
	  ASSERT (rm->buffers_n > 0);
	  --rm->buffers_n;
	}

      while (n_left_from > 0 && n_left_to_next > 0)
	{
	  u32 bi0;
	  vlib_buffer_t *b0;
	  u32 next0;		//, error0;

	  bi0 = from[0];
	  b0 = vlib_get_buffer (vm, bi0);

	  ip6_header_t *ip0 = vlib_buffer_get_current (b0);
	  ip6_frag_hdr_t *frag_hdr;
	  ip6_ext_header_t *prev_hdr;
	  ip6_ext_header_find_t (ip0, prev_hdr, frag_hdr,
				 IP_PROTOCOL_IPV6_FRAGMENTATION);
	  if (0 == ip6_frag_hdr_offset (frag_hdr))
	    {
	      // first fragment - verify upper-layer is present
	      ip6_ext_header_t *tmp = (ip6_ext_header_t *) frag_hdr;
	      while (ip6_ext_hdr (tmp->next_hdr))
		{
		  tmp = ip6_ext_next_header (tmp);
		}
	      if (IP_PROTOCOL_IP6_NONXT == tmp->next_hdr)
		{
		  icmp6_error_set_vnet_buffer (b0, ICMP6_parameter_problem,
					       ICMP6_parameter_problem_first_fragment_has_incomplete_header_chain,
					       0);
		  b0->error = node->errors[IP6_ERROR_REASS_MISSING_UPPER];

		  to_next[0] = bi0;
		  to_next += 1;
		  n_left_to_next -= 1;
		  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
						   to_next, n_left_to_next,
						   bi0,
						   IP6_REASSEMBLY_NEXT_ICMP_ERROR);
		  goto next;
		}
	    }
	  vnet_buffer (b0)->ip.reass.ip6_frag_hdr_offset =
	    (u8 *) frag_hdr - (u8 *) ip0;

	  ip6_reass_key_t k;
	  k.src.as_u64[0] = ip0->src_address.as_u64[0];
	  k.src.as_u64[1] = ip0->src_address.as_u64[1];
	  k.dst.as_u64[0] = ip0->dst_address.as_u64[0];
	  k.dst.as_u64[1] = ip0->dst_address.as_u64[1];
	  k.xx_id = vnet_buffer (b0)->sw_if_index[VLIB_RX];
	  k.frag_id = frag_hdr->identification;
	  k.proto = ip0->protocol;
	  k.unused = 0;
	  u32 icmp_bi = ~0;
	  ip6_reass_t *reass =
	    ip6_reass_find_or_create (vm, node, rm, &k, &icmp_bi,
				      &vec_timeout);

	  u32 error0 = IP6_ERROR_NONE;
	  if (reass)
	    {
	      ip6_reass_update (vm, node, rm, reass, &bi0, &next0, &error0,
				frag_hdr, &vec_drop_overlap,
				&vec_drop_compress, IP6_REASSEMBLY_NEXT_INPUT,
				IP6_REASSEMBLY_NEXT_DROP,
				IP6_REASSEMBLY_NEXT_ICMP_ERROR);
	    }
	  else
	    {
	      next0 = IP6_REASSEMBLY_NEXT_DROP;
	      error0 = IP6_ERROR_REASS_LIMIT_REACHED;
	    }

	  b0->error = node->errors[error0];

	  if (~0 != bi0)
	    {
	      to_next[0] = bi0;
	      to_next += 1;
	      n_left_to_next -= 1;
	      vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
					       n_left_to_next, bi0, next0);
	    }

	  if (~0 != icmp_bi)
	    {
	      next0 = IP6_REASSEMBLY_NEXT_ICMP_ERROR;
	      to_next[0] = icmp_bi;
	      to_next += 1;
	      n_left_to_next -= 1;
	      vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
					       n_left_to_next, icmp_bi,
					       next0);
	    }
	next:
	  from += 1;
	  n_left_from -= 1;
	}

      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
    }

  return frame->n_vectors;
}

static char *ip6_reassembly_error_strings[] = {
#define _(sym, string) string,
  foreach_ip6_error
#undef _
};

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ip6_reass_node, static) = {
    .function = ip6_reassembly,
    .name = "ip6-reassembly",
    .vector_size = sizeof (u32),
    .format_trace = format_ip6_reass_trace,
    .n_errors = ARRAY_LEN (ip6_reassembly_error_strings),
    .error_strings = ip6_reassembly_error_strings,
    .n_next_nodes = IP6_REASSEMBLY_N_NEXT,
    .next_nodes =
        {
                [IP6_REASSEMBLY_NEXT_INPUT] = "ip6-input",
                [IP6_REASSEMBLY_NEXT_DROP] = "ip6-drop",
                [IP6_REASSEMBLY_NEXT_ICMP_ERROR] = "ip6-icmp-error",
        },
};
/* *INDENT-ON* */

VLIB_NODE_FUNCTION_MULTIARCH (ip6_reass_node, ip6_reassembly)
     static u32 ip6_reass_get_nbuckets ()
{
  ip6_reass_main_t *rm = &ip6_reass_main;
  u32 nbuckets;
  u8 i;

  nbuckets = (u32) (rm->max_reass_n / IP6_REASS_HT_LOAD_FACTOR);

  for (i = 0; i < 31; i++)
    if ((1 << i) >= nbuckets)
      break;
  nbuckets = 1 << i;

  return nbuckets;
}

typedef enum
{
  IP6_EVENT_CONFIG_CHANGED = 1,
} ip6_reass_event_t;

typedef struct
{
  int failure;
  clib_bihash_48_8_t *new_hash;
} ip6_rehash_cb_ctx;

void
ip6_rehash_cb (clib_bihash_kv_48_8_t * kv, void *_ctx)
{
  ip6_rehash_cb_ctx *ctx = _ctx;
  if (clib_bihash_add_del_48_8 (ctx->new_hash, kv, 1))
    {
      ctx->failure = 1;
    }
}

vnet_api_error_t
ip6_reass_set (u32 timeout_ms, u32 max_reassemblies,
	       u32 expire_walk_interval_ms)
{
  u32 old_nbuckets = ip6_reass_get_nbuckets ();
  ip6_reass_main.timeout_ms = timeout_ms;
  ip6_reass_main.timeout = (f64) timeout_ms / (f64) MSEC_PER_SEC;
  ip6_reass_main.max_reass_n = max_reassemblies;
  ip6_reass_main.expire_walk_interval_ms = expire_walk_interval_ms;
  vlib_process_signal_event (ip6_reass_main.vlib_main,
			     ip6_reass_main.ip6_reass_expire_node_idx,
			     IP6_EVENT_CONFIG_CHANGED, 0);
  u32 new_nbuckets = ip6_reass_get_nbuckets ();
  if (ip6_reass_main.max_reass_n > 0 && new_nbuckets > 1 &&
      new_nbuckets != old_nbuckets)
    {
      clib_bihash_48_8_t new_hash;
      memset (&new_hash, 0, sizeof (new_hash));
      ip6_rehash_cb_ctx ctx;
      ctx.failure = 0;
      ctx.new_hash = &new_hash;
      clib_bihash_init_48_8 (&new_hash, "ip6-reass", new_nbuckets,
			     new_nbuckets * 1024);
      clib_bihash_foreach_key_value_pair_48_8 (&ip6_reass_main.hash,
					       ip6_rehash_cb, &ctx);
      if (ctx.failure)
	{
	  clib_bihash_free_48_8 (&new_hash);
	  return -1;
	}
      else
	{
	  clib_bihash_free_48_8 (&ip6_reass_main.hash);
	  clib_memcpy (&ip6_reass_main.hash, &new_hash,
		       sizeof (ip6_reass_main.hash));
	}
    }
  return 0;
}

vnet_api_error_t
ip6_reass_get (u32 * timeout_ms, u32 * max_reassemblies,
	       u32 * expire_walk_interval_ms)
{
  *timeout_ms = ip6_reass_main.timeout_ms;
  *max_reassemblies = ip6_reass_main.max_reass_n;
  *expire_walk_interval_ms = ip6_reass_main.expire_walk_interval_ms;
  return 0;
}

clib_error_t *
ip6_reass_init_function (vlib_main_t * vm)
{
  ip6_reass_main_t *rm = &ip6_reass_main;
  clib_error_t *error = 0;
  u32 nbuckets;
  vlib_node_t *node;

  rm->vlib_main = vm;
  rm->vnet_main = vnet_get_main ();

  rm->reass_n = 0;
  pool_alloc (rm->pool, rm->max_reass_n);

  node = vlib_get_node_by_name (vm, (u8 *) "ip6-reassembly-expire-walk");
  ASSERT (node);
  rm->ip6_reass_expire_node_idx = node->index;

  ip6_reass_set (IP6_REASS_TIMEOUT_DEFAULT_MS,
		 IP6_REASS_MAX_REASSEMBLIES_DEAFULT,
		 IP6_REASS_EXPIRE_WALK_INTERVAL_DEFAULT_MS);

  nbuckets = ip6_reass_get_nbuckets ();
  clib_bihash_init_48_8 (&rm->hash, "ip6-reass", nbuckets, nbuckets * 1024);

  node = vlib_get_node_by_name (vm, (u8 *) "ip6-drop");
  ASSERT (node);
  rm->ip6_drop_idx = node->index;
  node = vlib_get_node_by_name (vm, (u8 *) "ip6-icmp-error");
  ASSERT (node);
  rm->ip6_icmp_error_idx = node->index;

  if ((error = vlib_call_init_function (vm, ip_main_init)))
    return error;
  ip6_register_protocol (IP_PROTOCOL_IPV6_FRAGMENTATION,
			 ip6_reass_node.index);
  return error;
}

VLIB_INIT_FUNCTION (ip6_reass_init_function);

static uword
ip6_reass_walk_expired (vlib_main_t * vm,
			vlib_node_runtime_t * node, vlib_frame_t * f)
{
  ip6_reass_main_t *rm = &ip6_reass_main;
  uword event_type, *event_data = 0;

  while (true)
    {
      vlib_process_wait_for_event_or_clock (vm,
					    (f64) rm->expire_walk_interval_ms
					    / (f64) MSEC_PER_SEC);
      event_type = vlib_process_get_events (vm, &event_data);

      switch (event_type)
	{
	case ~0:		/* no events => timeout */
	  /* nothing to do here */
	  break;
	case IP6_EVENT_CONFIG_CHANGED:
	  break;
	default:
	  clib_warning ("BUG: event type 0x%wx", event_type);
	  break;
	}
      f64 now = vlib_time_now (vm);

      ip6_reass_t *reass;
      u32 *vec_timeout = NULL;
      int *pool_indexes_to_free = NULL;

      int index;
      /* *INDENT-OFF* */
      pool_foreach_index (index, rm->pool, ({
                            reass = pool_elt_at_index (rm->pool, index);
                            if (now > reass->last_heard + rm->timeout)
                              {
                                vec_add1 (pool_indexes_to_free, index);
                              }
                          }));
      /* *INDENT-ON* */
      int *i;
      u32 *vec_icmp_bi = NULL;
      /* *INDENT-OFF* */
      vec_foreach (i, pool_indexes_to_free)
      {
        ip6_reass_t *reass = pool_elt_at_index (rm->pool, i[0]);
        u32 icmp_bi = ~0;
        ip6_reass_on_timeout (vm, node, rm, reass, &icmp_bi, &vec_timeout);
        if (~0 != icmp_bi)
          {
            vec_add1 (vec_icmp_bi, icmp_bi);
          }
        ip6_reass_free (rm, reass);
      }
      /* *INDENT-ON* */

      while (vec_len (vec_timeout) > 0)
	{
	  vlib_frame_t *f = vlib_get_frame_to_node (vm, rm->ip6_drop_idx);
	  u32 *to_next = vlib_frame_vector_args (f);
	  u32 n_left_to_next = VLIB_FRAME_SIZE - f->n_vectors;
	  u32 n_trace = 0;
	  while (vec_len (vec_timeout) > 0 && n_left_to_next > 0)
	    {
	      u32 bi = vec_pop (vec_timeout);
	      vlib_buffer_t *b = vlib_get_buffer (vm, bi);
	      if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
		{
		  if (pool_is_free_index (vm->trace_main.trace_buffer_pool,
					  b->trace_index))
		    {
		      /* the trace is gone, don't trace this buffer anymore */
		      b->flags &= ~VLIB_BUFFER_IS_TRACED;
		    }
		  else
		    {
		      ++n_trace;
		    }
		}
	      b->error = node->errors[IP6_ERROR_REASS_TIMEOUT];
	      to_next[0] = bi;
	      ++f->n_vectors;
	      to_next += 1;
	      n_left_to_next -= 1;
	      ASSERT (rm->buffers_n > 0);
	      --rm->buffers_n;
	    }
	  if (PREDICT_FALSE (n_trace > 0))
	    {
	      f->flags |= VLIB_FRAME_TRACE;
	    }
	  vlib_put_frame_to_node (vm, rm->ip6_drop_idx, f);
	}

      while (vec_len (vec_icmp_bi) > 0)
	{
	  vlib_frame_t *f =
	    vlib_get_frame_to_node (vm, rm->ip6_icmp_error_idx);
	  u32 *to_next = vlib_frame_vector_args (f);
	  u32 n_left_to_next = VLIB_FRAME_SIZE - f->n_vectors;
	  u32 n_trace = 0;
	  while (vec_len (vec_icmp_bi) > 0 && n_left_to_next > 0)
	    {
	      u32 bi = vec_pop (vec_icmp_bi);
	      vlib_buffer_t *b = vlib_get_buffer (vm, bi);
	      if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
		{
		  if (pool_is_free_index (vm->trace_main.trace_buffer_pool,
					  b->trace_index))
		    {
		      /* the trace is gone, don't trace this buffer anymore */
		      b->flags &= ~VLIB_BUFFER_IS_TRACED;
		    }
		  else
		    {
		      ++n_trace;
		    }
		}
	      b->error = node->errors[IP6_ERROR_REASS_TIMEOUT];
	      to_next[0] = bi;
	      ++f->n_vectors;
	      to_next += 1;
	      n_left_to_next -= 1;
	      ASSERT (rm->buffers_n > 0);
	      --rm->buffers_n;
	    }
	  if (PREDICT_FALSE (n_trace > 0))
	    {
	      f->flags |= VLIB_FRAME_TRACE;
	    }
	  vlib_put_frame_to_node (vm, rm->ip6_icmp_error_idx, f);
	}

      vec_free (pool_indexes_to_free);
      vec_free (vec_timeout);
      vec_free (vec_icmp_bi);
      if (event_data)
	{
	  _vec_len (event_data) = 0;
	}
    }

  return 0;
}

static vlib_node_registration_t ip6_reass_expire_node;

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ip6_reass_expire_node, static) = {
    .function = ip6_reass_walk_expired,
    .format_trace = format_ip6_reass_trace,
    .type = VLIB_NODE_TYPE_PROCESS,
    .name = "ip6-reassembly-expire-walk",

    .n_errors = ARRAY_LEN (ip6_reassembly_error_strings),
    .error_strings = ip6_reassembly_error_strings,

};
/* *INDENT-ON* */

static u8 *
format_ip6_reass_key (u8 * s, va_list * args)
{
  ip6_reass_key_t *key = va_arg (*args, ip6_reass_key_t *);
  s = format (s, "xx_id: %u, src: %U, dst: %U, frag_id: %u, proto: %u",
	      key->xx_id, format_ip6_address, &key->src, format_ip6_address,
	      &key->dst, clib_net_to_host_u16 (key->frag_id), key->proto);
  return s;
}

static u8 *
format_ip6_reass (u8 * s, va_list * args)
{
  vlib_main_t *vm = va_arg (*args, vlib_main_t *);
  ip6_reass_t *reass = va_arg (*args, ip6_reass_t *);

  s = format (s, "ID: %u, key: %U\n  first_bi: %u, data_len: %u, "
	      "last_packet_octet: %u, trace_op_counter: %u\n",
	      reass->id, format_ip6_reass_key, &reass->key, reass->first_bi,
	      reass->data_len, reass->last_packet_octet,
	      reass->trace_op_counter);
  u32 bi = reass->first_bi;
  u32 counter = 0;
  while (~0 != bi)
    {
      vlib_buffer_t *b = vlib_get_buffer (vm, bi);
      vnet_buffer_opaque_t *vnb = vnet_buffer (b);
      s = format (s, "  #%03u: range: [%u, %u], bi: %u, off: %d, len: %u, "
		  "fragment[%u, %u]\n",
		  counter, vnb->ip.reass.range_first,
		  vnb->ip.reass.range_last, bi,
		  ip6_reass_buffer_get_data_offset_no_check (b),
		  ip6_reass_buffer_get_data_len_no_check (b),
		  vnb->ip.reass.fragment_first, vnb->ip.reass.fragment_last);
      if (b->flags & VLIB_BUFFER_NEXT_PRESENT)
	{
	  bi = b->next_buffer;
	}
      else
	{
	  bi = ~0;
	}
    }
  return s;
}

static clib_error_t *
show_ip6_reass (vlib_main_t * vm, unformat_input_t * input,
		CLIB_UNUSED (vlib_cli_command_t * lmd))
{
  ip6_reass_main_t *rm = &ip6_reass_main;

  vlib_cli_output (vm, "---------------------");
  vlib_cli_output (vm, "IP6 reassembly status");
  vlib_cli_output (vm, "---------------------");
  if (unformat (input, "details"))
    {
      ip6_reass_t *reass;
      /* *INDENT-OFF* */
      pool_foreach (reass, rm->pool, {
        vlib_cli_output (vm, "%U", format_ip6_reass, vm, reass);
      });
      /* *INDENT-ON* */
    }
  vlib_cli_output (vm, "---------------------");
  vlib_cli_output (vm, "Current IP6 reassemblies count: %lu\n", rm->reass_n);
  vlib_cli_output (vm,
		   "Maximum configured concurrent IP6 reassemblies: %lu\n",
		   (long unsigned) rm->max_reass_n);
  vlib_cli_output (vm, "Buffers in use: %lu\n",
		   (long unsigned) rm->buffers_n);
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_ip6_reassembly_cmd, static) = {
    .path = "show ip6-reassembly",
    .short_help = "show ip6-reassembly [details]",
    .function = show_ip6_reass,
};
/* *INDENT-ON* */

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