ipip: Multi-point interface
[vpp.git] / src / vnet / ipip / ipip_cli.c
index 09f2eba..d341055 100644 (file)
@@ -31,6 +31,7 @@ static clib_error_t *create_ipip_tunnel_command_fn(vlib_main_t *vm,
   u32 sw_if_index;
   clib_error_t *error = NULL;
   bool ip4_set = false, ip6_set = false;
+  tunnel_mode_t mode = TUNNEL_MODE_P2P;
 
   /* Get a line of input. */
   if (!unformat_user(input, unformat_line_input, line_input))
@@ -51,6 +52,8 @@ static clib_error_t *create_ipip_tunnel_command_fn(vlib_main_t *vm,
     } else if (unformat(line_input, "dst %U", unformat_ip6_address, &dst.ip6)) {
       num_m_args++;
       ip6_set = true;
+    } else if (unformat(line_input, "%U", unformat_tunnel_mode, &mode)) {
+      num_m_args++;
     } else if (unformat(line_input, "outer-table-id %d", &table_id))
       ;
     else {
@@ -84,6 +87,7 @@ static clib_error_t *create_ipip_tunnel_command_fn(vlib_main_t *vm,
                            fib_index,
                            TUNNEL_ENCAP_DECAP_FLAG_NONE,
                            IP_DSCP_CS0,
+                           mode,
                            &sw_if_index);
     }
 
@@ -104,6 +108,9 @@ static clib_error_t *create_ipip_tunnel_command_fn(vlib_main_t *vm,
   case VNET_API_ERROR_INSTANCE_IN_USE:
     error = clib_error_return(0, "Instance is in use");
     goto done;
+  case VNET_API_ERROR_INVALID_DST_ADDRESS:
+    error = clib_error_return(0, "destination IP address when mode is multi-point");
+    goto done;
   default:
     error = clib_error_return(0, "vnet_ipip_add_del_tunnel returned %d", rv);
     goto done;
@@ -182,12 +189,16 @@ static u8 *format_ipip_tunnel(u8 *s, va_list *args) {
               format_ip6_address, &t->sixrd.ip6_prefix, t->sixrd.ip6_prefix_len);
     break;
   case IPIP_MODE_P2P:
-  default:
     s = format(s, "[%d] instance %d src %U dst %U ",
               t->dev_instance, t->user_instance,
               format_ip46_address, &t->tunnel_src, type,
               format_ip46_address, &t->tunnel_dst, type);
     break;
+  case IPIP_MODE_P2MP:
+    s = format(s, "[%d] instance %d p2mp src %U ",
+              t->dev_instance, t->user_instance,
+              format_ip46_address, &t->tunnel_src, type);
+    break;
   }
 
   s = format(s, "table-ID %d sw-if-idx %d flags [%U] dscp %U",
@@ -235,6 +246,50 @@ VLIB_CLI_COMMAND(show_ipip_tunnel_command, static) = {
 };
 /* *INDENT-ON* */
 
+static u8 *
+format_ipip_tunnel_key (u8 *s, va_list *args)
+{
+  ipip_tunnel_key_t *t = va_arg(*args, ipip_tunnel_key_t *);
+
+  s = format (s, "src:%U dst:%U fib:%d transport:%d mode:%d",
+              format_ip46_address, &t->src, IP46_TYPE_ANY,
+              format_ip46_address, &t->dst, IP46_TYPE_ANY,
+              t->fib_index, t->transport, t->mode);
+
+  return (s);
+}
+
+static clib_error_t *
+ipip_tunnel_hash_show (vlib_main_t * vm,
+                       unformat_input_t * input,
+                       vlib_cli_command_t * cmd)
+{
+  ipip_main_t *im = &ipip_main;
+  ipip_tunnel_key_t *key;
+  u32 index;
+
+  /* *INDENT-OFF* */
+  hash_foreach(key, index, im->tunnel_by_key,
+  ({
+      vlib_cli_output (vm, " %U -> %d", format_ipip_tunnel_key, key, index);
+  }));
+  /* *INDENT-ON* */
+
+  return NULL;
+}
+
+/**
+ * show IPSEC tunnel protection hash tables
+ */
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (ipip_tunnel_hash_show_node, static) =
+{
+  .path = "show ipip tunnel-hash",
+  .function = ipip_tunnel_hash_show,
+  .short_help =  "show ipip tunnel-hash",
+};
+/* *INDENT-ON* */
+
 static clib_error_t *create_sixrd_tunnel_command_fn(vlib_main_t *vm,
                                                     unformat_input_t *input,
                                                     vlib_cli_command_t *cmd) {