/*
 * Copyright (c) 2024 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 <vnet/session/session.h>
#include <vnet/ip/ip4_forward.h>
#include <vnet/ip/ip6_forward.h>
#include <vnet/session/session_rules_table.h>
#include <vnet/session/session_sdl.h>

VLIB_REGISTER_LOG_CLASS (session_sdl_log, static) = { .class_name = "session",
						      .subclass_name = "sdl" };

#define log_debug(fmt, ...)                                                   \
  vlib_log_debug (session_sdl_log.class, "%s: " fmt, __func__, __VA_ARGS__)
#define log_warn(fmt, ...)                                                    \
  vlib_log_warn (session_sdl_log.class, fmt, __VA_ARGS__)
#define log_err(fmt, ...)                                                     \
  vlib_log_err (session_sdl_log.class, fmt, __VA_ARGS__)

static fib_source_t sdl_fib_src;
static dpo_type_t sdl_dpo_type;

const static char *const *const session_sdl_dpo_nodes[DPO_PROTO_NUM] = {
  [DPO_PROTO_IP4] = (const char *const[]){ "ip4-drop", 0 },
  [DPO_PROTO_IP6] = (const char *const[]){ "ip6-drop", 0 },
};

static fib_route_path_t *
session_sdl_fib_create_route_paths (u32 fib_index, dpo_proto_t dpo_proto)
{
  fib_route_path_t *paths = 0;
  fib_route_path_t path = {
    .frp_proto = dpo_proto,
    .frp_flags = FIB_ROUTE_PATH_EXCLUSIVE,
    .frp_fib_index = fib_index,
    .frp_sw_if_index = ~0,
    .frp_weight = 1,
  };
  vec_add1 (paths, path);
  return paths;
}

static void
session_sdl_dpo_lock (dpo_id_t *dpo)
{
}

static void
session_sdl_dpo_unlock (dpo_id_t *dpo)
{
}

static u8 *
format_session_sdl_dpo (u8 *s, va_list *va)
{
  index_t index = va_arg (*va, index_t);

  return format (s, "sdl: [index: %u, deny]", index);
}

static const dpo_vft_t session_sdl_dpo_vft = {
  .dv_lock = session_sdl_dpo_lock,
  .dv_unlock = session_sdl_dpo_unlock,
  .dv_format = format_session_sdl_dpo,
};

static u32
session_sdl_lookup6 (u32 srtg_handle, u32 proto, ip6_address_t *lcl_ip,
		     ip6_address_t *rmt_ip, u16 lcl_port, u16 rmt_port)
{
  session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
  session_sdl_block_t *sdlb = &srt->sdl_block;
  index_t lbi;
  const dpo_id_t *dpo;

  if (sdlb->ip6_fib_index == ~0)
    return SESSION_TABLE_INVALID_INDEX;
  lbi = ip6_fib_table_fwding_lookup (sdlb->ip6_fib_index, lcl_ip);
  dpo = load_balance_get_fwd_bucket (load_balance_get (lbi), 0);
  if (dpo->dpoi_type != sdl_dpo_type)
    return SESSION_TABLE_INVALID_INDEX;
  return (dpo->dpoi_index);
}

static u32
session_sdl_lookup4 (u32 srtg_handle, u32 proto, ip4_address_t *lcl_ip,
		     ip4_address_t *rmt_ip, u16 lcl_port, u16 rmt_port)
{
  session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
  session_sdl_block_t *sdlb = &srt->sdl_block;
  index_t lbi;
  const dpo_id_t *dpo;

  if (sdlb->ip_fib_index == ~0)
    return SESSION_TABLE_INVALID_INDEX;
  lbi = ip4_fib_forwarding_lookup (sdlb->ip_fib_index, lcl_ip);
  dpo = load_balance_get_fwd_bucket (load_balance_get (lbi), 0);
  if (dpo->dpoi_type != sdl_dpo_type)
    return SESSION_TABLE_INVALID_INDEX;
  return (dpo->dpoi_index);
}

typedef struct session_sdl4_fib_show_walk_ctx_t_
{
  fib_node_index_t *ifsw_indicies;
} session_sdl4_fib_show_walk_ctx_t;

static fib_table_walk_rc_t
session_sdl4_fib_show_walk_cb (fib_node_index_t fei, void *arg)
{
  session_sdl4_fib_show_walk_ctx_t *ctx = arg;

  vec_add1 (ctx->ifsw_indicies, fei);

  return (FIB_TABLE_WALK_CONTINUE);
}

typedef struct session_sdl6_fib_show_ctx_t_
{
  fib_node_index_t *entries;
} session_sdl6_fib_show_ctx_t;

static fib_table_walk_rc_t
session_sdl6_fib_table_show_walk (fib_node_index_t fei, void *arg)
{
  session_sdl6_fib_show_ctx_t *ctx = arg;

  vec_add1 (ctx->entries, fei);

  return (FIB_TABLE_WALK_CONTINUE);
}

static void
session_sdl_fib_table_show (u32 fei, ip46_address_t *lcl_ip, u16 fp_len,
			    u32 action_index, u32 fp_proto, u8 *tag,
			    void *args)
{
  vlib_main_t *vm = args;
  u32 type = (fp_proto == FIB_PROTOCOL_IP4) ? IP46_TYPE_IP4 : IP46_TYPE_IP6;

  vlib_cli_output (vm, "[%d] rule: %U/%d action: %d tag %U", fei,
		   format_ip46_address, lcl_ip, type, fp_len, action_index,
		   format_session_rule_tag, tag);
}

static void
session_sdl_cli_dump (vlib_main_t *vm, u32 srtg_handle, u32 proto,
		      u8 fib_proto)
{
  session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
  session_sdl_block_t *sdlb = &srt->sdl_block;

  if (fib_proto == FIB_PROTOCOL_IP4)
    {
      vlib_cli_output (vm, "IP4 rules, fib index %d", sdlb->ip_fib_index);
      session_sdl_table_walk4 (srtg_handle, session_sdl_fib_table_show, vm);
    }
  else if (fib_proto == FIB_PROTOCOL_IP6)
    {
      vlib_cli_output (vm, "IP6 rules, fib index %d", sdlb->ip6_fib_index);
      session_sdl_table_walk6 (srtg_handle, session_sdl_fib_table_show, vm);
    }
}

static void
session_sdl4_fib_table_show_one (session_rules_table_t *srt, u32 fib_index,
				 vlib_main_t *vm, ip4_address_t *address,
				 u32 mask_len)
{
  ip4_fib_t *fib;
  fib_node_index_t fei;

  fib = ip4_fib_get (fib_index);
  fei = ip4_fib_table_lookup (fib, address, mask_len);
  if (fei != FIB_NODE_INDEX_INVALID && fib_entry_is_sourced (fei, sdl_fib_src))
    {
      u8 *tag = session_rules_table_rule_tag (srt, fei, 1);
      fib_entry_t *fib_entry = fib_entry_get (fei);
      fib_prefix_t pfx = fib_entry->fe_prefix;
      index_t lbi = ip4_fib_forwarding_lookup (fib_index, &pfx.fp_addr.ip4);
      const dpo_id_t *dpo =
	load_balance_get_fwd_bucket (load_balance_get (lbi), 0);

      session_sdl_fib_table_show (fei, &pfx.fp_addr, pfx.fp_len,
				  dpo->dpoi_index, FIB_PROTOCOL_IP4, tag, vm);
    }
}

static void
session_sdl6_fib_table_show_one (session_rules_table_t *srt, u32 fib_index,
				 vlib_main_t *vm, ip6_address_t *address,
				 u32 mask_len)
{
  fib_node_index_t fei;

  fei = ip6_fib_table_lookup (fib_index, address, mask_len);
  if (fei != FIB_NODE_INDEX_INVALID && fib_entry_is_sourced (fei, sdl_fib_src))
    {
      u8 *tag = session_rules_table_rule_tag (srt, fei, 0);
      fib_entry_t *fib_entry = fib_entry_get (fei);
      fib_prefix_t pfx = fib_entry->fe_prefix;
      index_t lbi = ip6_fib_table_fwding_lookup (fib_index, &pfx.fp_addr.ip6);
      const dpo_id_t *dpo =
	load_balance_get_fwd_bucket (load_balance_get (lbi), 0);

      session_sdl_fib_table_show (fei, &pfx.fp_addr, pfx.fp_len,
				  dpo->dpoi_index, FIB_PROTOCOL_IP6, tag, vm);
    }
}

static void
session_sdl_show_rule (vlib_main_t *vm, u32 srtg_handle, u32 proto,
		       ip46_address_t *lcl_ip, u16 lcl_port,
		       ip46_address_t *rmt_ip, u16 rmt_port, u8 is_ip4)
{
  session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
  session_sdl_block_t *sdlb;

  sdlb = &srt->sdl_block;
  if (is_ip4)
    session_sdl4_fib_table_show_one (srt, sdlb->ip_fib_index, vm, &lcl_ip->ip4,
				     32);
  else
    session_sdl6_fib_table_show_one (srt, sdlb->ip6_fib_index, vm,
				     &lcl_ip->ip6, 128);
}

static void
session_sdl_table_init (session_table_t *st, u8 fib_proto)
{
  session_rules_table_t *srt;
  session_sdl_block_t *sdlb;
  u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0;
  char name[80];
  app_namespace_t *app_ns = app_namespace_get (st->appns_index);
  session_rules_table_group_t *srtg;

  /* Don't support local table */
  if (st->is_local == 1)
    return;

  srtg = srtg_instance_alloc (st, 0);
  srt = srtg->session_rules;
  sdlb = &srt->sdl_block;

  if (fib_proto == FIB_PROTOCOL_IP4 || all)
    {
      snprintf (name, sizeof (name), "sdl4 %s", app_ns->ns_id);
      sdlb->ip_table_id = ip_table_get_unused_id (FIB_PROTOCOL_IP4);
      sdlb->ip_fib_index = fib_table_find_or_create_and_lock_w_name (
	FIB_PROTOCOL_IP4, sdlb->ip_table_id, sdl_fib_src, (const u8 *) name);
    }

  if (fib_proto == FIB_PROTOCOL_IP6 || all)
    {
      snprintf (name, sizeof (name), "sdl6 %s", app_ns->ns_id);
      sdlb->ip6_table_id = ip_table_get_unused_id (FIB_PROTOCOL_IP6);
      sdlb->ip6_fib_index = fib_table_find_or_create_and_lock_w_name (
	FIB_PROTOCOL_IP6, sdlb->ip6_table_id, sdl_fib_src, (const u8 *) name);
    }

  srt->rules_by_tag = hash_create_vec (0, sizeof (u8), sizeof (uword));
  srt->tags_by_rules = hash_create (0, sizeof (uword));
}

static void
session_sdl_table_free (session_table_t *st, u8 fib_proto)
{
  session_rules_table_t *srt = srtg_handle_to_srt (st->srtg_handle, 0);
  session_sdl_block_t *sdlb;
  u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0;

  ASSERT (st->is_local == 0);
  sdlb = &srt->sdl_block;
  if ((fib_proto == FIB_PROTOCOL_IP4 || all) && (sdlb->ip_fib_index != ~0))
    {
      fib_table_flush (sdlb->ip_fib_index, FIB_PROTOCOL_IP4, sdl_fib_src);
      fib_table_unlock (sdlb->ip_fib_index, FIB_PROTOCOL_IP4, sdl_fib_src);
    }
  if ((fib_proto == FIB_PROTOCOL_IP6 || all) && (sdlb->ip6_fib_index != ~0))
    {
      fib_table_flush (sdlb->ip6_fib_index, FIB_PROTOCOL_IP6, sdl_fib_src);
      fib_table_unlock (sdlb->ip6_fib_index, FIB_PROTOCOL_IP6, sdl_fib_src);
    }

  hash_free (srt->tags_by_rules);
  hash_free (srt->rules_by_tag);

  srtg_instance_free (st);
}

static session_error_t
session_sdl_add_del (u32 srtg_handle, u32 proto,
		     session_rule_table_add_del_args_t *args)
{
  session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
  session_sdl_block_t *sdlb = &srt->sdl_block;
  u32 fib_index;
  dpo_proto_t dpo_proto;
  fib_route_path_t *paths = 0;
  fib_prefix_t pfx = args->lcl;
  session_error_t err = SESSION_E_NONE;
  fib_node_index_t fei;
  int is_ip4;

  if (!(args->lcl_port == 0 && args->rmt_port == 0 &&
	args->rmt.fp_addr.ip4.as_u32 == 0))
    return SESSION_E_NOSUPPORT;

  fei = session_rules_table_rule_for_tag (srt, args->tag);
  if (args->is_add && fei != SESSION_RULES_TABLE_INVALID_INDEX)
    return SESSION_E_INVALID;

  if (args->lcl.fp_proto == FIB_PROTOCOL_IP4)
    {
      fib_index = sdlb->ip_fib_index;
      dpo_proto = DPO_PROTO_IP4;
      is_ip4 = 1;
    }
  else
    {
      fib_index = sdlb->ip6_fib_index;
      dpo_proto = DPO_PROTO_IP6;
      is_ip4 = 0;
    }

  paths = session_sdl_fib_create_route_paths (fib_index, dpo_proto);
  if (args->is_add)
    {
      fei = fib_table_lookup_exact_match (fib_index, &pfx);
      if (fei != FIB_NODE_INDEX_INVALID)
	{
	  err = SESSION_E_IPINUSE;
	  goto done;
	}
      dpo_set (&paths->dpo, sdl_dpo_type, dpo_proto, args->action_index);
      fei = fib_table_entry_path_add2 (fib_index, &pfx, sdl_fib_src,
				       FIB_ENTRY_FLAG_EXCLUSIVE, paths);
      session_rules_table_add_tag (srt, args->tag, fei, is_ip4);
      dpo_reset (&paths->dpo);
    }
  else
    {
      if (fei == SESSION_RULES_TABLE_INVALID_INDEX)
	{
	  fei = fib_table_lookup_exact_match (fib_index, &pfx);

	  if (fei == FIB_NODE_INDEX_INVALID)
	    {
	      err = SESSION_E_NOROUTE;
	      goto done;
	    }
	}

      if (!fib_entry_is_sourced (fei, sdl_fib_src))
	{
	  err = SESSION_E_NOROUTE;
	  goto done;
	}

      fib_entry_t *fib_entry = fib_entry_get (fei);
      pfx = fib_entry->fe_prefix;
      fib_table_entry_special_remove (fib_index, &pfx, sdl_fib_src);
      session_rules_table_del_tag (srt, args->tag, is_ip4);
    }
done:
  vec_free (paths);

  return err;
}

static const session_rt_engine_vft_t session_sdl_vft = {
  .backend_engine = RT_BACKEND_ENGINE_SDL,
  .table_lookup4 = session_sdl_lookup4,
  .table_lookup6 = session_sdl_lookup6,
  .table_cli_dump = session_sdl_cli_dump,
  .table_show_rule = session_sdl_show_rule,
  .table_add_del = session_sdl_add_del,
  .table_init = session_sdl_table_init,
  .table_free = session_sdl_table_free,
};

static void
session_sdl_fib_init (void)
{
  static u32 session_fib_inited = 0;

  if (session_fib_inited)
    return;
  session_fib_inited = 1;
  sdl_fib_src = fib_source_allocate ("session sdl", FIB_SOURCE_PRIORITY_LOW,
				     FIB_SOURCE_BH_SIMPLE);
  sdl_dpo_type =
    dpo_register_new_type (&session_sdl_dpo_vft, session_sdl_dpo_nodes);
}

static void
session_sdl_app_namespace_walk_cb (app_namespace_t *app_ns, void *ctx)
{
  u32 fib_index, table_index;
  session_table_t *st;

  log_debug ("disable app_ns %s", app_ns->ns_id);

  fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP4);
  table_index = session_lookup_get_index_for_fib (FIB_PROTOCOL_IP4, fib_index);
  st = session_table_get (table_index);
  if (st)
    session_rules_table_free (st, FIB_PROTOCOL_IP4);

  fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP6);
  table_index = session_lookup_get_index_for_fib (FIB_PROTOCOL_IP6, fib_index);
  st = session_table_get (table_index);
  if (st)
    session_rules_table_free (st, FIB_PROTOCOL_IP6);
}

clib_error_t *
session_sdl_enable_disable (int enable)
{
  clib_error_t *error = 0;

  if (enable)
    {
      error = session_rule_table_register_engine (&session_sdl_vft);
      if (error)
	{
	  log_err ("error in enabling sdl: %U", format_clib_error, error);
	  return error;
	}
      session_sdl_fib_init ();
    }
  else
    {
      app_namespace_walk (session_sdl_app_namespace_walk_cb, 0);

      error = session_rule_table_deregister_engine (&session_sdl_vft);
      if (error)
	log_err ("error in disabling sdl: %U", format_clib_error, error);
    }

  return error;
}

/*
 * Source Deny List
 */
static clib_error_t *
session_sdl_command_fn (vlib_main_t *vm, unformat_input_t *input,
			vlib_cli_command_t *cmd)
{
  u32 appns_index;
  app_namespace_t *app_ns;
  u32 lcl_plen = 0, action = 0;
  clib_error_t *error = 0;
  ip46_address_t lcl_ip;
  u8 conn_set = 0;
  u8 fib_proto = -1, is_add = 1, *ns_id = 0;
  u8 *tag = 0, tag_only = 0;
  int rv;
  session_rule_add_del_args_t args;

  session_cli_return_if_not_enabled ();

  if (session_sdl_is_enabled () == 0)
    return clib_error_return (0, "session sdl engine is not enabled");

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "del"))
	is_add = 0;
      else if (unformat (input, "add"))
	;
      else if (unformat (input, "appns %_%v%_", &ns_id))
	;
      else if (unformat (input, "%U/%d", unformat_ip4_address, &lcl_ip.ip4,
			 &lcl_plen))
	{
	  fib_proto = FIB_PROTOCOL_IP4;
	  conn_set = 1;
	}
      else if (unformat (input, "%U/%d", unformat_ip6_address, &lcl_ip.ip6,
			 &lcl_plen))
	{
	  fib_proto = FIB_PROTOCOL_IP6;
	  conn_set = 1;
	}
      else if (unformat (input, "action %d", &action))
	;
      else if (unformat (input, "tag %_%v%_", &tag))
	;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, input);
	  goto done;
	}
    }

  if (ns_id)
    {
      app_ns = app_namespace_get_from_id (ns_id);
      if (!app_ns)
	{
	  vlib_cli_output (vm, "namespace %v does not exist", ns_id);
	  goto done;
	}
    }
  else
    {
      app_ns = app_namespace_get_default ();
    }
  appns_index = app_namespace_index (app_ns);

  if (is_add && !conn_set && action == 0)
    {
      vlib_cli_output (vm, "connection and action must be set for add");
      goto done;
    }
  if (!is_add && !tag && !conn_set)
    {
      vlib_cli_output (vm, "connection or tag must be set for delete");
      goto done;
    }
  if (vec_len (tag) > SESSION_RULE_TAG_MAX_LEN)
    {
      vlib_cli_output (vm, "tag too long (max u64)");
      goto done;
    }

  /* Delete with only tag entered. Try v4 first and then v6 if failed */
  if ((is_add == 0) && (fib_proto == (u8) ~0))
    {
      fib_proto = FIB_PROTOCOL_IP4;
      tag_only = 1;
    }

  memset (&args, 0, sizeof (args));
  args.transport_proto = TRANSPORT_PROTO_TCP;
  args.table_args.lcl.fp_addr = lcl_ip;
  args.table_args.lcl.fp_len = lcl_plen;
  args.table_args.lcl.fp_proto = fib_proto;
  args.table_args.rmt.fp_proto = fib_proto;
  args.table_args.action_index = action;
  args.table_args.is_add = is_add;
  args.table_args.tag = tag;
  args.appns_index = appns_index;
  args.scope = SESSION_RULE_SCOPE_GLOBAL;

  if ((rv = vnet_session_rule_add_del (&args)))
    {
      /* Try tag only delete on v6 */
      if (rv && tag_only)
	{
	  args.table_args.rmt.fp_proto = FIB_PROTOCOL_IP6;
	  args.table_args.lcl.fp_proto = FIB_PROTOCOL_IP6;
	  if ((rv = vnet_session_rule_add_del (&args)))
	    {
	      error = clib_error_return (0, "sdl add del returned %u", rv);
	    }
	}
      else
	{
	  error = clib_error_return (0, "sdl add del returned %u", rv);
	}
    }

done:
  vec_free (ns_id);
  vec_free (tag);
  return error;
}

VLIB_CLI_COMMAND (session_sdl_command, static) = {
  .path = "session sdl",
  .short_help = "session sdl [add|del] [appns <ns_id>] <lcl-ip/plen> action "
		"<action> [tag <tag>]",
  .function = session_sdl_command_fn,
  .is_mp_safe = 1,
};

static clib_error_t *
show_session_sdl_command_fn (vlib_main_t *vm, unformat_input_t *input,
			     vlib_cli_command_t *cmd)
{
  u32 fib_index;
  ip46_address_t lcl_ip;
  u8 show_one = 0;
  app_namespace_t *app_ns;
  session_table_t *st;
  u8 *ns_id = 0, fib_proto = FIB_PROTOCOL_IP4;

  session_cli_return_if_not_enabled ();

  clib_memset (&lcl_ip, 0, sizeof (lcl_ip));
  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "appns %_%s%_", &ns_id))
	;
      else if (unformat (input, "%U", unformat_ip4_address, &lcl_ip.ip4))
	{
	  fib_proto = FIB_PROTOCOL_IP4;
	  show_one = 1;
	}
      else if (unformat (input, "%U", unformat_ip6_address, &lcl_ip.ip6))
	{
	  fib_proto = FIB_PROTOCOL_IP6;
	  show_one = 1;
	}
      else
	{
	  vec_free (ns_id);
	  return clib_error_return (0, "unknown input `%U'",
				    format_unformat_error, input);
	}
    }

  if (ns_id)
    {
      app_ns = app_namespace_get_from_id (ns_id);
      if (!app_ns)
	{
	  vlib_cli_output (vm, "appns %v doesn't exist", ns_id);
	  goto done;
	}
    }
  else
    {
      app_ns = app_namespace_get_default ();
    }

  if (session_sdl_is_enabled () == 0)
    {
      vlib_cli_output (vm, "session sdl engine is not enabled");
      goto done;
    }

  if (show_one)
    {
      fib_index = app_namespace_get_fib_index (app_ns, fib_proto);
      st = session_table_get_for_fib_index (fib_proto, fib_index);
      if (st && (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID))
	session_rules_table_show_rule (vm, st->srtg_handle, 0, &lcl_ip, 0, 0,
				       0, (fib_proto == FIB_PROTOCOL_IP4));
      goto done;
    }

  /* 2 separate session tables for global entries, 1 for ip4 and 1 for ip6 */
  fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP4);
  st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index);
  if (st && (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID))
    session_rules_table_cli_dump (vm, st->srtg_handle, 0, FIB_PROTOCOL_IP4);

  fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP6);
  st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
  if (st && (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID))
    session_rules_table_cli_dump (vm, st->srtg_handle, 0, FIB_PROTOCOL_IP6);
done:
  vec_free (ns_id);
  return 0;
}

void
session_sdl_table_walk4 (u32 srtg_handle, session_sdl_table_walk_fn_t fn,
			 void *args)
{
  ip4_fib_t *fib;
  session_sdl4_fib_show_walk_ctx_t ctx = {
    .ifsw_indicies = NULL,
  };
  fib_node_index_t *fei;
  session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
  session_sdl_block_t *sdlb = &srt->sdl_block;
  u32 fib_index = sdlb->ip_fib_index;

  if (fib_index == ~0)
    return;
  fib = ip4_fib_get (fib_index);
  ip4_fib_table_walk (fib, session_sdl4_fib_show_walk_cb, &ctx);
  vec_sort_with_function (ctx.ifsw_indicies, fib_entry_cmp_for_sort);

  vec_foreach (fei, ctx.ifsw_indicies)
    {
      if (*fei != FIB_NODE_INDEX_INVALID &&
	  fib_entry_is_sourced (*fei, sdl_fib_src))
	{
	  u8 *tag = session_rules_table_rule_tag (srt, *fei, 1);
	  fib_entry_t *fib_entry = fib_entry_get (*fei);
	  fib_prefix_t pfx = fib_entry->fe_prefix;
	  index_t lbi =
	    ip4_fib_forwarding_lookup (fib_index, &pfx.fp_addr.ip4);
	  const dpo_id_t *dpo =
	    load_balance_get_fwd_bucket (load_balance_get (lbi), 0);

	  fn (*fei, &pfx.fp_addr, pfx.fp_len, dpo->dpoi_index,
	      FIB_PROTOCOL_IP4, tag, args);
	}
    }

  vec_free (ctx.ifsw_indicies);
}

void
session_sdl_table_walk6 (u32 srtg_handle, session_sdl_table_walk_fn_t fn,
			 void *args)
{
  ip6_fib_t *fib;
  fib_node_index_t *fei;
  session_sdl6_fib_show_ctx_t ctx = {
    .entries = NULL,
  };
  session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
  session_sdl_block_t *sdlb = &srt->sdl_block;
  u32 fib_index = sdlb->ip6_fib_index;

  if (fib_index == ~0)
    return;
  fib = ip6_fib_get (fib_index);
  ip6_fib_table_walk (fib->index, session_sdl6_fib_table_show_walk, &ctx);
  vec_sort_with_function (ctx.entries, fib_entry_cmp_for_sort);

  vec_foreach (fei, ctx.entries)
    {
      if (*fei != FIB_NODE_INDEX_INVALID &&
	  fib_entry_is_sourced (*fei, sdl_fib_src))
	{
	  u8 *tag = session_rules_table_rule_tag (srt, *fei, 0);
	  fib_entry_t *fib_entry = fib_entry_get (*fei);
	  fib_prefix_t pfx = fib_entry->fe_prefix;
	  index_t lbi =
	    ip6_fib_table_fwding_lookup (fib_index, &pfx.fp_addr.ip6);
	  const dpo_id_t *dpo =
	    load_balance_get_fwd_bucket (load_balance_get (lbi), 0);

	  fn (*fei, &pfx.fp_addr, pfx.fp_len, dpo->dpoi_index,
	      FIB_PROTOCOL_IP6, tag, args);
	}
    }

  vec_free (ctx.entries);
}

VLIB_CLI_COMMAND (show_session_sdl_command, static) = {
  .path = "show session sdl",
  .short_help = "show session sdl [appns <id> <lcl-ip>]",
  .function = show_session_sdl_command_fn,
  .is_mp_safe = 1,
};

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