nat: nat44-ed add session timing out indicator in api
[vpp.git] / src / vat / api_format.c
index 52eb5ae..bb168f8 100644 (file)
@@ -579,263 +579,6 @@ ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
 }
 
 
-static void vl_api_create_loopback_reply_t_handler
-  (vl_api_create_loopback_reply_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  i32 retval = ntohl (mp->retval);
-
-  vam->retval = retval;
-  vam->regenerate_interface_table = 1;
-  vam->sw_if_index = ntohl (mp->sw_if_index);
-  vam->result_ready = 1;
-}
-
-static void vl_api_create_loopback_reply_t_handler_json
-  (vl_api_create_loopback_reply_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  vat_json_node_t node;
-
-  vat_json_init_object (&node);
-  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
-  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
-
-  vat_json_print (vam->ofp, &node);
-  vat_json_free (&node);
-  vam->retval = ntohl (mp->retval);
-  vam->result_ready = 1;
-}
-
-static void vl_api_create_loopback_instance_reply_t_handler
-  (vl_api_create_loopback_instance_reply_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  i32 retval = ntohl (mp->retval);
-
-  vam->retval = retval;
-  vam->regenerate_interface_table = 1;
-  vam->sw_if_index = ntohl (mp->sw_if_index);
-  vam->result_ready = 1;
-}
-
-static void vl_api_create_loopback_instance_reply_t_handler_json
-  (vl_api_create_loopback_instance_reply_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  vat_json_node_t node;
-
-  vat_json_init_object (&node);
-  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
-  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
-
-  vat_json_print (vam->ofp, &node);
-  vat_json_free (&node);
-  vam->retval = ntohl (mp->retval);
-  vam->result_ready = 1;
-}
-
-static void vl_api_create_vlan_subif_reply_t_handler
-  (vl_api_create_vlan_subif_reply_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  i32 retval = ntohl (mp->retval);
-
-  vam->retval = retval;
-  vam->regenerate_interface_table = 1;
-  vam->sw_if_index = ntohl (mp->sw_if_index);
-  vam->result_ready = 1;
-}
-
-static void vl_api_create_vlan_subif_reply_t_handler_json
-  (vl_api_create_vlan_subif_reply_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  vat_json_node_t node;
-
-  vat_json_init_object (&node);
-  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
-  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
-
-  vat_json_print (vam->ofp, &node);
-  vat_json_free (&node);
-
-  vam->retval = ntohl (mp->retval);
-  vam->result_ready = 1;
-}
-
-static void vl_api_create_subif_reply_t_handler
-  (vl_api_create_subif_reply_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  i32 retval = ntohl (mp->retval);
-
-  vam->retval = retval;
-  vam->regenerate_interface_table = 1;
-  vam->sw_if_index = ntohl (mp->sw_if_index);
-  vam->result_ready = 1;
-}
-
-static void vl_api_create_subif_reply_t_handler_json
-  (vl_api_create_subif_reply_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  vat_json_node_t node;
-
-  vat_json_init_object (&node);
-  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
-  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
-
-  vat_json_print (vam->ofp, &node);
-  vat_json_free (&node);
-
-  vam->retval = ntohl (mp->retval);
-  vam->result_ready = 1;
-}
-
-static void vl_api_interface_name_renumber_reply_t_handler
-  (vl_api_interface_name_renumber_reply_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  i32 retval = ntohl (mp->retval);
-
-  vam->retval = retval;
-  vam->regenerate_interface_table = 1;
-  vam->result_ready = 1;
-}
-
-static void vl_api_interface_name_renumber_reply_t_handler_json
-  (vl_api_interface_name_renumber_reply_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  vat_json_node_t node;
-
-  vat_json_init_object (&node);
-  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
-
-  vat_json_print (vam->ofp, &node);
-  vat_json_free (&node);
-
-  vam->retval = ntohl (mp->retval);
-  vam->result_ready = 1;
-}
-
-/*
- * Special-case: build the interface table, maintain
- * the next loopback sw_if_index vbl.
- */
-static void vl_api_sw_interface_details_t_handler
-  (vl_api_sw_interface_details_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  u8 *s = format (0, "%s%c", mp->interface_name, 0);
-
-  hash_set_mem (vam->sw_if_index_by_interface_name, s,
-               ntohl (mp->sw_if_index));
-
-  /* In sub interface case, fill the sub interface table entry */
-  if (mp->sw_if_index != mp->sup_sw_if_index)
-    {
-      sw_interface_subif_t *sub = NULL;
-
-      vec_add2 (vam->sw_if_subif_table, sub, 1);
-
-      vec_validate (sub->interface_name, strlen ((char *) s) + 1);
-      strncpy ((char *) sub->interface_name, (char *) s,
-              vec_len (sub->interface_name));
-      sub->sw_if_index = ntohl (mp->sw_if_index);
-      sub->sub_id = ntohl (mp->sub_id);
-
-      sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
-
-      sub->sub_number_of_tags = mp->sub_number_of_tags;
-      sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
-      sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
-
-      /* vlan tag rewrite */
-      sub->vtr_op = ntohl (mp->vtr_op);
-      sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
-      sub->vtr_tag1 = ntohl (mp->vtr_tag1);
-      sub->vtr_tag2 = ntohl (mp->vtr_tag2);
-    }
-}
-
-static void vl_api_sw_interface_details_t_handler_json
-  (vl_api_sw_interface_details_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  vat_json_node_t *node = NULL;
-
-  if (VAT_JSON_ARRAY != vam->json_tree.type)
-    {
-      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
-      vat_json_init_array (&vam->json_tree);
-    }
-  node = vat_json_array_add (&vam->json_tree);
-
-  vat_json_init_object (node);
-  vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
-  vat_json_object_add_uint (node, "sup_sw_if_index",
-                           ntohl (mp->sup_sw_if_index));
-  vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
-                            sizeof (mp->l2_address));
-  vat_json_object_add_string_copy (node, "interface_name",
-                                  mp->interface_name);
-  vat_json_object_add_string_copy (node, "interface_dev_type",
-                                  mp->interface_dev_type);
-  vat_json_object_add_uint (node, "flags", mp->flags);
-  vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
-  vat_json_object_add_uint (node, "link_speed", mp->link_speed);
-  vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
-  vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
-  vat_json_object_add_uint (node, "sub_number_of_tags",
-                           mp->sub_number_of_tags);
-  vat_json_object_add_uint (node, "sub_outer_vlan_id",
-                           ntohs (mp->sub_outer_vlan_id));
-  vat_json_object_add_uint (node, "sub_inner_vlan_id",
-                           ntohs (mp->sub_inner_vlan_id));
-  vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
-  vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
-  vat_json_object_add_uint (node, "vtr_push_dot1q",
-                           ntohl (mp->vtr_push_dot1q));
-  vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
-  vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
-  if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
-    {
-      vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
-                                      format (0, "%U",
-                                              format_ethernet_address,
-                                              &mp->b_dmac));
-      vat_json_object_add_string_copy (node, "pbb_vtr_smac",
-                                      format (0, "%U",
-                                              format_ethernet_address,
-                                              &mp->b_smac));
-      vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
-      vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
-    }
-}
-
-#if VPP_API_TEST_BUILTIN == 0
-static void vl_api_sw_interface_event_t_handler
-  (vl_api_sw_interface_event_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  if (vam->interface_event_display)
-    errmsg ("interface flags: sw_if_index %d %s %s",
-           ntohl (mp->sw_if_index),
-           ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
-           "admin-up" : "admin-down",
-           ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
-           "link-up" : "link-down");
-}
-#endif
-
-__clib_unused static void
-vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
-{
-  /* JSON output not supported */
-}
-
 static void
 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
 {
@@ -1337,20 +1080,7 @@ format_hex_bytes (u8 * s, va_list * va)
  * a single function, but that could break in subtle ways.
  */
 
-#define foreach_standard_reply_retval_handler                                 \
-  _ (sw_interface_set_flags_reply)                                            \
-  _ (sw_interface_add_del_address_reply)                                      \
-  _ (sw_interface_set_rx_placement_reply)                                     \
-  _ (sw_interface_set_unnumbered_reply)                                       \
-  _ (sw_interface_set_table_reply)                                            \
-  _ (delete_loopback_reply)                                                   \
-  _ (want_interface_events_reply)                                             \
-  _ (sw_interface_clear_stats_reply)                                          \
-  _ (delete_subif_reply)                                                      \
-  _ (sw_interface_tag_add_del_reply)                                          \
-  _ (sw_interface_add_del_mac_address_reply)                                  \
-  _ (hw_interface_set_mtu_reply)                                              \
-  _ (session_rule_add_del_reply)
+#define foreach_standard_reply_retval_handler
 
 #define _(n)                                    \
     static void vl_api_##n##_t_handler          \
@@ -1388,45 +1118,19 @@ foreach_standard_reply_retval_handler;
  * we just generated
  */
 
-#define foreach_vpe_api_reply_msg                                       \
-_(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
-_(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
-_(SW_INTERFACE_DETAILS, sw_interface_details)                           \
-_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
-_(CONTROL_PING_REPLY, control_ping_reply)                               \
-_(CLI_REPLY, cli_reply)                                                 \
-_(CLI_INBAND_REPLY, cli_inband_reply)                                   \
-_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
-  sw_interface_add_del_address_reply)                                   \
-_(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)    \
-_(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details)        \
-_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)          \
-_(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
-  sw_interface_set_unnumbered_reply)                                    \
-_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
-_(CREATE_SUBIF_REPLY, create_subif_reply)                              \
-_(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
-_(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
-_(SHOW_VERSION_REPLY, show_version_reply)                               \
-_(SHOW_THREADS_REPLY, show_threads_reply)                               \
-_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)                \
-_(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
-_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
-_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                      \
-_(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
-_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
-_(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
-_(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
-_(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)      \
-_(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
-_(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
-_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
-_(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)            \
-_(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)              \
-_(SESSION_RULES_DETAILS, session_rules_details)                                \
+#define foreach_vpe_api_reply_msg                                             \
+  _ (GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                          \
+  _ (GET_NODE_GRAPH_REPLY, get_node_graph_reply)                              \
+  _ (CONTROL_PING_REPLY, control_ping_reply)                                  \
+  _ (CLI_REPLY, cli_reply)                                                    \
+  _ (CLI_INBAND_REPLY, cli_inband_reply)                                      \
+  _ (GET_NODE_INDEX_REPLY, get_node_index_reply)                              \
+  _ (GET_NEXT_INDEX_REPLY, get_next_index_reply)                              \
+  _ (ADD_NODE_NEXT_REPLY, add_node_next_reply)                                \
+  _ (SHOW_VERSION_REPLY, show_version_reply)                                  \
+  _ (SHOW_THREADS_REPLY, show_threads_reply)                                  \
 
 #define foreach_standalone_reply_msg                                   \
-_(SW_INTERFACE_EVENT, sw_interface_event)
 
 typedef struct
 {
@@ -1438,108 +1142,6 @@ typedef struct
     case L2_VTR_ ## op:         \
         return "" # op;
 
-static const char *
-str_vtr_op (u32 vtr_op)
-{
-  switch (vtr_op)
-    {
-      STR_VTR_OP_CASE (DISABLED);
-      STR_VTR_OP_CASE (PUSH_1);
-      STR_VTR_OP_CASE (PUSH_2);
-      STR_VTR_OP_CASE (POP_1);
-      STR_VTR_OP_CASE (POP_2);
-      STR_VTR_OP_CASE (TRANSLATE_1_1);
-      STR_VTR_OP_CASE (TRANSLATE_1_2);
-      STR_VTR_OP_CASE (TRANSLATE_2_1);
-      STR_VTR_OP_CASE (TRANSLATE_2_2);
-    }
-
-  return "UNKNOWN";
-}
-
-static int
-dump_sub_interface_table (vat_main_t * vam)
-{
-  const sw_interface_subif_t *sub = NULL;
-
-  if (vam->json_output)
-    {
-      clib_warning
-       ("JSON output supported only for VPE API calls and dump_stats_table");
-      return -99;
-    }
-
-  print (vam->ofp,
-        "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
-        "Interface", "sw_if_index",
-        "sub id", "dot1ad", "tags", "outer id",
-        "inner id", "exact", "default", "outer any", "inner any");
-
-  vec_foreach (sub, vam->sw_if_subif_table)
-  {
-    print (vam->ofp,
-          "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
-          sub->interface_name,
-          sub->sw_if_index,
-          sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
-          sub->sub_number_of_tags, sub->sub_outer_vlan_id,
-          sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
-          sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
-    if (sub->vtr_op != L2_VTR_DISABLED)
-      {
-       print (vam->ofp,
-              "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
-              "tag1: %d tag2: %d ]",
-              str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
-              sub->vtr_tag1, sub->vtr_tag2);
-      }
-  }
-
-  return 0;
-}
-
-static int
-name_sort_cmp (void *a1, void *a2)
-{
-  name_sort_t *n1 = a1;
-  name_sort_t *n2 = a2;
-
-  return strcmp ((char *) n1->name, (char *) n2->name);
-}
-
-static int
-dump_interface_table (vat_main_t * vam)
-{
-  hash_pair_t *p;
-  name_sort_t *nses = 0, *ns;
-
-  if (vam->json_output)
-    {
-      clib_warning
-       ("JSON output supported only for VPE API calls and dump_stats_table");
-      return -99;
-    }
-
-  /* *INDENT-OFF* */
-  hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
-  ({
-    vec_add2 (nses, ns, 1);
-    ns->name = (u8 *)(p->key);
-    ns->value = (u32) p->value[0];
-  }));
-  /* *INDENT-ON* */
-
-  vec_sort_with_function (nses, name_sort_cmp);
-
-  print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
-  vec_foreach (ns, nses)
-  {
-    print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
-  }
-  vec_free (nses);
-  return 0;
-}
-
 /*
  * Pass CLI buffers directly in the CLI_INBAND API message,
  * instead of an additional shared memory area.
@@ -1582,599 +1184,41 @@ exec_inband (vat_main_t * vam)
 }
 
 int
-exec (vat_main_t * vam)
+exec (vat_main_t *vam)
 {
   return exec_inband (vam);
 }
 
-static int
-api_create_loopback (vat_main_t * vam)
+int
+api_sw_interface_dump (vat_main_t *vam)
 {
-  unformat_input_t *i = vam->input;
-  vl_api_create_loopback_t *mp;
-  vl_api_create_loopback_instance_t *mp_lbi;
-  u8 mac_address[6];
-  u8 mac_set = 0;
-  u8 is_specified = 0;
-  u32 user_instance = 0;
-  int ret;
-
-  clib_memset (mac_address, 0, sizeof (mac_address));
-
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
-       mac_set = 1;
-      if (unformat (i, "instance %d", &user_instance))
-       is_specified = 1;
-      else
-       break;
-    }
-
-  if (is_specified)
-    {
-      M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
-      mp_lbi->is_specified = is_specified;
-      if (is_specified)
-       mp_lbi->user_instance = htonl (user_instance);
-      if (mac_set)
-       clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
-      S (mp_lbi);
-    }
-  else
-    {
-      /* Construct the API message */
-      M (CREATE_LOOPBACK, mp);
-      if (mac_set)
-       clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
-      S (mp);
-    }
-
-  W (ret);
-  return ret;
+  return 0;
 }
 
-static int
-api_delete_loopback (vat_main_t * vam)
+uword
+unformat_vlib_pci_addr (unformat_input_t *input, va_list *args)
 {
-  unformat_input_t *i = vam->input;
-  vl_api_delete_loopback_t *mp;
-  u32 sw_if_index = ~0;
-  int ret;
-
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "sw_if_index %d", &sw_if_index))
-       ;
-      else
-       break;
-    }
+  vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
+  u32 x[4];
 
-  if (sw_if_index == ~0)
-    {
-      errmsg ("missing sw_if_index");
-      return -99;
-    }
+  if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
+    return 0;
 
-  /* Construct the API message */
-  M (DELETE_LOOPBACK, mp);
-  mp->sw_if_index = ntohl (sw_if_index);
+  addr->domain = x[0];
+  addr->bus = x[1];
+  addr->slot = x[2];
+  addr->function = x[3];
 
-  S (mp);
-  W (ret);
-  return ret;
+  return 1;
 }
 
-static int
-api_want_interface_events (vat_main_t * vam)
+uword
+unformat_fib_path (unformat_input_t *input, va_list *args)
 {
-  unformat_input_t *i = vam->input;
-  vl_api_want_interface_events_t *mp;
-  int enable = -1;
-  int ret;
-
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "enable"))
-       enable = 1;
-      else if (unformat (i, "disable"))
-       enable = 0;
-      else
-       break;
-    }
-
-  if (enable == -1)
-    {
-      errmsg ("missing enable|disable");
-      return -99;
-    }
-
-  M (WANT_INTERFACE_EVENTS, mp);
-  mp->enable_disable = enable;
-
-  vam->interface_event_display = enable;
-
-  S (mp);
-  W (ret);
-  return ret;
-}
-
-
-/* Note: non-static, called once to set up the initial intfc table */
-int
-api_sw_interface_dump (vat_main_t * vam)
-{
-  vl_api_sw_interface_dump_t *mp;
-  vl_api_control_ping_t *mp_ping;
-  hash_pair_t *p;
-  name_sort_t *nses = 0, *ns;
-  sw_interface_subif_t *sub = NULL;
-  int ret;
-
-  /* Toss the old name table */
-  /* *INDENT-OFF* */
-  hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
-  ({
-    vec_add2 (nses, ns, 1);
-    ns->name = (u8 *)(p->key);
-    ns->value = (u32) p->value[0];
-  }));
-  /* *INDENT-ON* */
-
-  hash_free (vam->sw_if_index_by_interface_name);
-
-  vec_foreach (ns, nses) vec_free (ns->name);
-
-  vec_free (nses);
-
-  vec_foreach (sub, vam->sw_if_subif_table)
-  {
-    vec_free (sub->interface_name);
-  }
-  vec_free (vam->sw_if_subif_table);
-
-  /* recreate the interface name hash table */
-  vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
-
-  /*
-   * Ask for all interface names. Otherwise, the epic catalog of
-   * name filters becomes ridiculously long, and vat ends up needing
-   * to be taught about new interface types.
-   */
-  M (SW_INTERFACE_DUMP, mp);
-  S (mp);
-
-  /* Use a control ping for synchronization */
-  MPING (CONTROL_PING, mp_ping);
-  S (mp_ping);
-
-  W (ret);
-  return ret;
-}
-
-static int
-api_sw_interface_set_flags (vat_main_t * vam)
-{
-  unformat_input_t *i = vam->input;
-  vl_api_sw_interface_set_flags_t *mp;
-  u32 sw_if_index;
-  u8 sw_if_index_set = 0;
-  u8 admin_up = 0;
-  int ret;
-
-  /* Parse args required to build the message */
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "admin-up"))
-       admin_up = 1;
-      else if (unformat (i, "admin-down"))
-       admin_up = 0;
-      else
-       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &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
-       break;
-    }
-
-  if (sw_if_index_set == 0)
-    {
-      errmsg ("missing interface name or sw_if_index");
-      return -99;
-    }
-
-  /* Construct the API message */
-  M (SW_INTERFACE_SET_FLAGS, mp);
-  mp->sw_if_index = ntohl (sw_if_index);
-  mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
-
-  /* send it... */
-  S (mp);
-
-  /* Wait for a reply, return the good/bad news... */
-  W (ret);
-  return ret;
-}
-
-static int
-api_sw_interface_set_rx_placement (vat_main_t * vam)
-{
-  unformat_input_t *i = vam->input;
-  vl_api_sw_interface_set_rx_placement_t *mp;
-  u32 sw_if_index;
-  u8 sw_if_index_set = 0;
-  int ret;
-  u8 is_main = 0;
-  u32 queue_id, thread_index;
-
-  /* Parse args required to build the message */
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "queue %d", &queue_id))
-       ;
-      else if (unformat (i, "main"))
-       is_main = 1;
-      else if (unformat (i, "worker %d", &thread_index))
-       ;
-      else
-       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &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
-       break;
-    }
-
-  if (sw_if_index_set == 0)
-    {
-      errmsg ("missing interface name or sw_if_index");
-      return -99;
-    }
-
-  if (is_main)
-    thread_index = 0;
-  /* Construct the API message */
-  M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
-  mp->sw_if_index = ntohl (sw_if_index);
-  mp->worker_id = ntohl (thread_index);
-  mp->queue_id = ntohl (queue_id);
-  mp->is_main = is_main;
-
-  /* send it... */
-  S (mp);
-  /* Wait for a reply, return the good/bad news... */
-  W (ret);
-  return ret;
-}
-
-static void vl_api_sw_interface_rx_placement_details_t_handler
-  (vl_api_sw_interface_rx_placement_details_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  u32 worker_id = ntohl (mp->worker_id);
-
-  print (vam->ofp,
-        "\n%-11d %-11s %-6d %-5d %-9s",
-        ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
-        worker_id, ntohl (mp->queue_id),
-        (mp->mode ==
-         1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
-}
-
-static void vl_api_sw_interface_rx_placement_details_t_handler_json
-  (vl_api_sw_interface_rx_placement_details_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  vat_json_node_t *node = NULL;
-
-  if (VAT_JSON_ARRAY != vam->json_tree.type)
-    {
-      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
-      vat_json_init_array (&vam->json_tree);
-    }
-  node = vat_json_array_add (&vam->json_tree);
-
-  vat_json_init_object (node);
-  vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
-  vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
-  vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
-  vat_json_object_add_uint (node, "mode", mp->mode);
-}
-
-static int
-api_sw_interface_rx_placement_dump (vat_main_t * vam)
-{
-  unformat_input_t *i = vam->input;
-  vl_api_sw_interface_rx_placement_dump_t *mp;
-  vl_api_control_ping_t *mp_ping;
-  int ret;
-  u32 sw_if_index;
-  u8 sw_if_index_set = 0;
-
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
-       sw_if_index_set++;
-      else if (unformat (i, "sw_if_index %d", &sw_if_index))
-       sw_if_index_set++;
-      else
-       break;
-    }
-
-  print (vam->ofp,
-        "\n%-11s %-11s %-6s %-5s %-4s",
-        "sw_if_index", "main/worker", "thread", "queue", "mode");
-
-  /* Dump Interface rx placement */
-  M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
-
-  if (sw_if_index_set)
-    mp->sw_if_index = htonl (sw_if_index);
-  else
-    mp->sw_if_index = ~0;
-
-  S (mp);
-
-  /* Use a control ping for synchronization */
-  MPING (CONTROL_PING, mp_ping);
-  S (mp_ping);
-
-  W (ret);
-  return ret;
-}
-
-static int
-api_sw_interface_clear_stats (vat_main_t * vam)
-{
-  unformat_input_t *i = vam->input;
-  vl_api_sw_interface_clear_stats_t *mp;
-  u32 sw_if_index;
-  u8 sw_if_index_set = 0;
-  int ret;
-
-  /* Parse args required to build the message */
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "%U", api_unformat_sw_if_index, vam, &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
-       break;
-    }
-
-  /* Construct the API message */
-  M (SW_INTERFACE_CLEAR_STATS, mp);
-
-  if (sw_if_index_set == 1)
-    mp->sw_if_index = ntohl (sw_if_index);
-  else
-    mp->sw_if_index = ~0;
-
-  /* send it... */
-  S (mp);
-
-  /* Wait for a reply, return the good/bad news... */
-  W (ret);
-  return ret;
-}
-
-static int
-api_sw_interface_add_del_address (vat_main_t * vam)
-{
-  unformat_input_t *i = vam->input;
-  vl_api_sw_interface_add_del_address_t *mp;
-  u32 sw_if_index;
-  u8 sw_if_index_set = 0;
-  u8 is_add = 1, del_all = 0;
-  u32 address_length = 0;
-  u8 v4_address_set = 0;
-  u8 v6_address_set = 0;
-  ip4_address_t v4address;
-  ip6_address_t v6address;
-  int ret;
-
-  /* Parse args required to build the message */
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "del-all"))
-       del_all = 1;
-      else if (unformat (i, "del"))
-       is_add = 0;
-      else
-       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &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 if (unformat (i, "%U/%d",
-                        unformat_ip4_address, &v4address, &address_length))
-       v4_address_set = 1;
-      else if (unformat (i, "%U/%d",
-                        unformat_ip6_address, &v6address, &address_length))
-       v6_address_set = 1;
-      else
-       break;
-    }
-
-  if (sw_if_index_set == 0)
-    {
-      errmsg ("missing interface name or sw_if_index");
-      return -99;
-    }
-  if (v4_address_set && v6_address_set)
-    {
-      errmsg ("both v4 and v6 addresses set");
-      return -99;
-    }
-  if (!v4_address_set && !v6_address_set && !del_all)
-    {
-      errmsg ("no addresses set");
-      return -99;
-    }
-
-  /* Construct the API message */
-  M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
-
-  mp->sw_if_index = ntohl (sw_if_index);
-  mp->is_add = is_add;
-  mp->del_all = del_all;
-  if (v6_address_set)
-    {
-      mp->prefix.address.af = ADDRESS_IP6;
-      clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
-    }
-  else
-    {
-      mp->prefix.address.af = ADDRESS_IP4;
-      clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
-    }
-  mp->prefix.len = address_length;
-
-  /* send it... */
-  S (mp);
-
-  /* Wait for a reply, return good/bad news  */
-  W (ret);
-  return ret;
-}
-
-static int
-api_sw_interface_set_table (vat_main_t * vam)
-{
-  unformat_input_t *i = vam->input;
-  vl_api_sw_interface_set_table_t *mp;
-  u32 sw_if_index, vrf_id = 0;
-  u8 sw_if_index_set = 0;
-  u8 is_ipv6 = 0;
-  int ret;
-
-  /* Parse args required to build the message */
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "%U", api_unformat_sw_if_index, vam, &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 if (unformat (i, "vrf %d", &vrf_id))
-       ;
-      else if (unformat (i, "ipv6"))
-       is_ipv6 = 1;
-      else
-       break;
-    }
-
-  if (sw_if_index_set == 0)
-    {
-      errmsg ("missing interface name or sw_if_index");
-      return -99;
-    }
-
-  /* Construct the API message */
-  M (SW_INTERFACE_SET_TABLE, mp);
-
-  mp->sw_if_index = ntohl (sw_if_index);
-  mp->is_ipv6 = is_ipv6;
-  mp->vrf_id = ntohl (vrf_id);
-
-  /* send it... */
-  S (mp);
-
-  /* Wait for a reply... */
-  W (ret);
-  return ret;
-}
-
-static void vl_api_sw_interface_get_table_reply_t_handler
-  (vl_api_sw_interface_get_table_reply_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-
-  print (vam->ofp, "%d", ntohl (mp->vrf_id));
-
-  vam->retval = ntohl (mp->retval);
-  vam->result_ready = 1;
-
-}
-
-static void vl_api_sw_interface_get_table_reply_t_handler_json
-  (vl_api_sw_interface_get_table_reply_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  vat_json_node_t node;
-
-  vat_json_init_object (&node);
-  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
-  vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
-
-  vat_json_print (vam->ofp, &node);
-  vat_json_free (&node);
-
-  vam->retval = ntohl (mp->retval);
-  vam->result_ready = 1;
-}
-
-static int
-api_sw_interface_get_table (vat_main_t * vam)
-{
-  unformat_input_t *i = vam->input;
-  vl_api_sw_interface_get_table_t *mp;
-  u32 sw_if_index;
-  u8 sw_if_index_set = 0;
-  u8 is_ipv6 = 0;
-  int ret;
-
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "%U", api_unformat_sw_if_index, vam, &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 if (unformat (i, "ipv6"))
-       is_ipv6 = 1;
-      else
-       break;
-    }
-
-  if (sw_if_index_set == 0)
-    {
-      errmsg ("missing interface name or sw_if_index");
-      return -99;
-    }
-
-  M (SW_INTERFACE_GET_TABLE, mp);
-  mp->sw_if_index = htonl (sw_if_index);
-  mp->is_ipv6 = is_ipv6;
-
-  S (mp);
-  W (ret);
-  return ret;
-}
-
-uword
-unformat_vlib_pci_addr (unformat_input_t *input, va_list *args)
-{
-  vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
-  u32 x[4];
-
-  if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
-    return 0;
-
-  addr->domain = x[0];
-  addr->bus = x[1];
-  addr->slot = x[2];
-  addr->function = x[3];
-
-  return 1;
-}
-
-uword
-unformat_fib_path (unformat_input_t *input, va_list *args)
-{
-  vat_main_t *vam = va_arg (*args, vat_main_t *);
-  vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
-  u32 weight, preference;
-  mpls_label_t out_label;
+  vat_main_t *vam = va_arg (*args, vat_main_t *);
+  vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
+  u32 weight, preference;
+  mpls_label_t out_label;
 
   clib_memset (path, 0, sizeof (*path));
   path->weight = 1;
@@ -2307,98 +1351,6 @@ unformat_fib_path (unformat_input_t *input, va_list *args)
   return (1);
 }
 
-static int
-api_sw_interface_set_unnumbered (vat_main_t *vam)
-{
-  unformat_input_t *i = vam->input;
-  vl_api_sw_interface_set_unnumbered_t *mp;
-  u32 sw_if_index;
-  u32 unnum_sw_index = ~0;
-  u8 is_add = 1;
-  u8 sw_if_index_set = 0;
-  int ret;
-
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "%U", api_unformat_sw_if_index, vam, &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 if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
-       ;
-      else if (unformat (i, "del"))
-       is_add = 0;
-      else
-       {
-         clib_warning ("parse error '%U'", format_unformat_error, i);
-         return -99;
-       }
-    }
-
-  if (sw_if_index_set == 0)
-    {
-      errmsg ("missing interface name or sw_if_index");
-      return -99;
-    }
-
-  M (SW_INTERFACE_SET_UNNUMBERED, mp);
-
-  mp->sw_if_index = ntohl (sw_if_index);
-  mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
-  mp->is_add = is_add;
-
-  S (mp);
-  W (ret);
-  return ret;
-}
-
-static int
-api_create_vlan_subif (vat_main_t *vam)
-{
-  unformat_input_t *i = vam->input;
-  vl_api_create_vlan_subif_t *mp;
-  u32 sw_if_index;
-  u8 sw_if_index_set = 0;
-  u32 vlan_id;
-  u8 vlan_id_set = 0;
-  int ret;
-
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "sw_if_index %d", &sw_if_index))
-       sw_if_index_set = 1;
-      else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
-       sw_if_index_set = 1;
-      else if (unformat (i, "vlan %d", &vlan_id))
-       vlan_id_set = 1;
-      else
-       {
-         clib_warning ("parse error '%U'", format_unformat_error, i);
-         return -99;
-       }
-    }
-
-  if (sw_if_index_set == 0)
-    {
-      errmsg ("missing interface name or sw_if_index");
-      return -99;
-    }
-
-  if (vlan_id_set == 0)
-    {
-      errmsg ("missing vlan_id");
-      return -99;
-    }
-  M (CREATE_VLAN_SUBIF, mp);
-
-  mp->sw_if_index = ntohl (sw_if_index);
-  mp->vlan_id = ntohl (vlan_id);
-
-  S (mp);
-  W (ret);
-  return ret;
-}
-
 #define foreach_create_subif_bit                \
 _(no_tags)                                      \
 _(one_tag)                                      \
@@ -2419,88 +1371,6 @@ _(5, "default_sub")                              \
 _(6, "outer_vlan_id_any")                      \
 _(7, "inner_vlan_id_any")
 
-static int
-api_create_subif (vat_main_t * vam)
-{
-  unformat_input_t *i = vam->input;
-  vl_api_create_subif_t *mp;
-  u32 sw_if_index;
-  u8 sw_if_index_set = 0;
-  u32 sub_id;
-  u8 sub_id_set = 0;
-  u32 __attribute__ ((unused)) no_tags = 0;
-  u32 __attribute__ ((unused)) one_tag = 0;
-  u32 __attribute__ ((unused)) two_tags = 0;
-  u32 __attribute__ ((unused)) dot1ad = 0;
-  u32 __attribute__ ((unused)) exact_match = 0;
-  u32 __attribute__ ((unused)) default_sub = 0;
-  u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
-  u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
-  u32 tmp;
-  u16 outer_vlan_id = 0;
-  u16 inner_vlan_id = 0;
-  int ret;
-
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "sw_if_index %d", &sw_if_index))
-       sw_if_index_set = 1;
-      else
-       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
-       sw_if_index_set = 1;
-      else if (unformat (i, "sub_id %d", &sub_id))
-       sub_id_set = 1;
-      else if (unformat (i, "outer_vlan_id %d", &tmp))
-       outer_vlan_id = tmp;
-      else if (unformat (i, "inner_vlan_id %d", &tmp))
-       inner_vlan_id = tmp;
-
-#define _(a) else if (unformat (i, #a)) a = 1 ;
-      foreach_create_subif_bit
-#undef _
-       else
-       {
-         clib_warning ("parse error '%U'", format_unformat_error, i);
-         return -99;
-       }
-    }
-
-  if (sw_if_index_set == 0)
-    {
-      errmsg ("missing interface name or sw_if_index");
-      return -99;
-    }
-
-  if (sub_id_set == 0)
-    {
-      errmsg ("missing sub_id");
-      return -99;
-    }
-  M (CREATE_SUBIF, mp);
-
-  mp->sw_if_index = ntohl (sw_if_index);
-  mp->sub_id = ntohl (sub_id);
-
-#define _(a,b) mp->sub_if_flags |= (1 << a);
-  foreach_create_subif_flag;
-#undef _
-
-  mp->outer_vlan_id = ntohs (outer_vlan_id);
-  mp->inner_vlan_id = ntohs (inner_vlan_id);
-
-  S (mp);
-  W (ret);
-  return ret;
-}
-
-u8 is_del;
-u8 localsid_addr[16];
-u8 end_psp;
-u8 behavior;
-u32 sw_if_index;
-u32 vlan_index;
-u32 fib_table;
-u8 nh_addr[16];
 
 #define foreach_tcp_proto_field                                               \
   _ (src_port)                                                                \
@@ -2584,1331 +1454,1023 @@ unformat_udp_mask (unformat_input_t *input, va_list *args)
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
       if (0)
-       ;
-#define _(a) else if (unformat (input, #a)) a = 1;
-      foreach_udp_proto_field
-#undef _
-       else break;
-    }
-
-#define _(a) found_something += a;
-  foreach_udp_proto_field;
-#undef _
-
-  if (found_something == 0)
-    return 0;
-
-  vec_validate (mask, sizeof (*udp) - 1);
-
-  udp = (udp_header_t *) mask;
-
-#define _(a)                                                                  \
-  if (a)                                                                      \
-    clib_memset (&udp->a, 0xff, sizeof (udp->a));
-  foreach_udp_proto_field;
-#undef _
-
-  *maskp = mask;
-  return 1;
-}
-
-uword
-unformat_l4_mask (unformat_input_t *input, va_list *args)
-{
-  u8 **maskp = va_arg (*args, u8 **);
-  u16 src_port = 0, dst_port = 0;
-  tcpudp_header_t *tcpudp;
-
-  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
-       return 1;
-      else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
-       return 1;
-      else if (unformat (input, "src_port"))
-       src_port = 0xFFFF;
-      else if (unformat (input, "dst_port"))
-       dst_port = 0xFFFF;
-      else
-       return 0;
-    }
-
-  if (!src_port && !dst_port)
-    return 0;
-
-  u8 *mask = 0;
-  vec_validate (mask, sizeof (tcpudp_header_t) - 1);
-
-  tcpudp = (tcpudp_header_t *) mask;
-  tcpudp->src_port = src_port;
-  tcpudp->dst_port = dst_port;
-
-  *maskp = mask;
-
-  return 1;
-}
-
-uword
-unformat_ip4_mask (unformat_input_t * input, va_list * args)
-{
-  u8 **maskp = va_arg (*args, u8 **);
-  u8 *mask = 0;
-  u8 found_something = 0;
-  ip4_header_t *ip;
-
-#define _(a) u8 a=0;
-  foreach_ip4_proto_field;
-#undef _
-  u8 version = 0;
-  u8 hdr_length = 0;
-
-
-  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (input, "version"))
-       version = 1;
-      else if (unformat (input, "hdr_length"))
-       hdr_length = 1;
-      else if (unformat (input, "src"))
-       src_address = 1;
-      else if (unformat (input, "dst"))
-       dst_address = 1;
-      else if (unformat (input, "proto"))
-       protocol = 1;
-
-#define _(a) else if (unformat (input, #a)) a=1;
-      foreach_ip4_proto_field
-#undef _
-       else
-       break;
-    }
-
-#define _(a) found_something += a;
-  foreach_ip4_proto_field;
-#undef _
-
-  if (found_something == 0)
-    return 0;
-
-  vec_validate (mask, sizeof (*ip) - 1);
-
-  ip = (ip4_header_t *) mask;
-
-#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
-  foreach_ip4_proto_field;
-#undef _
-
-  ip->ip_version_and_header_length = 0;
-
-  if (version)
-    ip->ip_version_and_header_length |= 0xF0;
-
-  if (hdr_length)
-    ip->ip_version_and_header_length |= 0x0F;
-
-  *maskp = mask;
-  return 1;
-}
-
-#define foreach_ip6_proto_field                 \
-_(src_address)                                  \
-_(dst_address)                                  \
-_(payload_length)                              \
-_(hop_limit)                                    \
-_(protocol)
-
-uword
-unformat_ip6_mask (unformat_input_t * input, va_list * args)
-{
-  u8 **maskp = va_arg (*args, u8 **);
-  u8 *mask = 0;
-  u8 found_something = 0;
-  ip6_header_t *ip;
-  u32 ip_version_traffic_class_and_flow_label;
-
-#define _(a) u8 a=0;
-  foreach_ip6_proto_field;
-#undef _
-  u8 version = 0;
-  u8 traffic_class = 0;
-  u8 flow_label = 0;
-
-  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (input, "version"))
-       version = 1;
-      else if (unformat (input, "traffic-class"))
-       traffic_class = 1;
-      else if (unformat (input, "flow-label"))
-       flow_label = 1;
-      else if (unformat (input, "src"))
-       src_address = 1;
-      else if (unformat (input, "dst"))
-       dst_address = 1;
-      else if (unformat (input, "proto"))
-       protocol = 1;
-
-#define _(a) else if (unformat (input, #a)) a=1;
-      foreach_ip6_proto_field
+       ;
+#define _(a) else if (unformat (input, #a)) a = 1;
+      foreach_udp_proto_field
 #undef _
-       else
-       break;
+       else break;
     }
 
 #define _(a) found_something += a;
-  foreach_ip6_proto_field;
+  foreach_udp_proto_field;
 #undef _
 
   if (found_something == 0)
     return 0;
 
-  vec_validate (mask, sizeof (*ip) - 1);
+  vec_validate (mask, sizeof (*udp) - 1);
 
-  ip = (ip6_header_t *) mask;
+  udp = (udp_header_t *) mask;
 
-#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
-  foreach_ip6_proto_field;
+#define _(a)                                                                  \
+  if (a)                                                                      \
+    clib_memset (&udp->a, 0xff, sizeof (udp->a));
+  foreach_udp_proto_field;
 #undef _
 
-  ip_version_traffic_class_and_flow_label = 0;
-
-  if (version)
-    ip_version_traffic_class_and_flow_label |= 0xF0000000;
-
-  if (traffic_class)
-    ip_version_traffic_class_and_flow_label |= 0x0FF00000;
-
-  if (flow_label)
-    ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
-
-  ip->ip_version_traffic_class_and_flow_label =
-    clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
-
   *maskp = mask;
   return 1;
 }
 
 uword
-unformat_l3_mask (unformat_input_t * input, va_list * args)
+unformat_l4_mask (unformat_input_t *input, va_list *args)
 {
   u8 **maskp = va_arg (*args, u8 **);
+  u16 src_port = 0, dst_port = 0;
+  tcpudp_header_t *tcpudp;
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
+      if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
        return 1;
-      else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
+      else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
        return 1;
+      else if (unformat (input, "src_port"))
+       src_port = 0xFFFF;
+      else if (unformat (input, "dst_port"))
+       dst_port = 0xFFFF;
       else
-       break;
+       return 0;
     }
-  return 0;
-}
-
-uword
-unformat_l2_mask (unformat_input_t * input, va_list * args)
-{
-  u8 **maskp = va_arg (*args, u8 **);
-  u8 *mask = 0;
-  u8 src = 0;
-  u8 dst = 0;
-  u8 proto = 0;
-  u8 tag1 = 0;
-  u8 tag2 = 0;
-  u8 ignore_tag1 = 0;
-  u8 ignore_tag2 = 0;
-  u8 cos1 = 0;
-  u8 cos2 = 0;
-  u8 dot1q = 0;
-  u8 dot1ad = 0;
-  int len = 14;
 
-  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (input, "src"))
-       src = 1;
-      else if (unformat (input, "dst"))
-       dst = 1;
-      else if (unformat (input, "proto"))
-       proto = 1;
-      else if (unformat (input, "tag1"))
-       tag1 = 1;
-      else if (unformat (input, "tag2"))
-       tag2 = 1;
-      else if (unformat (input, "ignore-tag1"))
-       ignore_tag1 = 1;
-      else if (unformat (input, "ignore-tag2"))
-       ignore_tag2 = 1;
-      else if (unformat (input, "cos1"))
-       cos1 = 1;
-      else if (unformat (input, "cos2"))
-       cos2 = 1;
-      else if (unformat (input, "dot1q"))
-       dot1q = 1;
-      else if (unformat (input, "dot1ad"))
-       dot1ad = 1;
-      else
-       break;
-    }
-  if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
-       ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
+  if (!src_port && !dst_port)
     return 0;
 
-  if (tag1 || ignore_tag1 || cos1 || dot1q)
-    len = 18;
-  if (tag2 || ignore_tag2 || cos2 || dot1ad)
-    len = 22;
-
-  vec_validate (mask, len - 1);
-
-  if (dst)
-    clib_memset (mask, 0xff, 6);
-
-  if (src)
-    clib_memset (mask + 6, 0xff, 6);
-
-  if (tag2 || dot1ad)
-    {
-      /* inner vlan tag */
-      if (tag2)
-       {
-         mask[19] = 0xff;
-         mask[18] = 0x0f;
-       }
-      if (cos2)
-       mask[18] |= 0xe0;
-      if (proto)
-       mask[21] = mask[20] = 0xff;
-      if (tag1)
-       {
-         mask[15] = 0xff;
-         mask[14] = 0x0f;
-       }
-      if (cos1)
-       mask[14] |= 0xe0;
-      *maskp = mask;
-      return 1;
-    }
-  if (tag1 | dot1q)
-    {
-      if (tag1)
-       {
-         mask[15] = 0xff;
-         mask[14] = 0x0f;
-       }
-      if (cos1)
-       mask[14] |= 0xe0;
-      if (proto)
-       mask[16] = mask[17] = 0xff;
+  u8 *mask = 0;
+  vec_validate (mask, sizeof (tcpudp_header_t) - 1);
 
-      *maskp = mask;
-      return 1;
-    }
-  if (cos2)
-    mask[18] |= 0xe0;
-  if (cos1)
-    mask[14] |= 0xe0;
-  if (proto)
-    mask[12] = mask[13] = 0xff;
+  tcpudp = (tcpudp_header_t *) mask;
+  tcpudp->src_port = src_port;
+  tcpudp->dst_port = dst_port;
 
   *maskp = mask;
+
   return 1;
 }
 
 uword
-unformat_classify_mask (unformat_input_t * input, va_list * args)
+unformat_ip4_mask (unformat_input_t * input, va_list * args)
 {
   u8 **maskp = va_arg (*args, u8 **);
-  u32 *skipp = va_arg (*args, u32 *);
-  u32 *matchp = va_arg (*args, u32 *);
-  u32 match;
   u8 *mask = 0;
-  u8 *l2 = 0;
-  u8 *l3 = 0;
-  u8 *l4 = 0;
-  int i;
+  u8 found_something = 0;
+  ip4_header_t *ip;
 
-  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (input, "hex %U", unformat_hex_string, &mask))
-       ;
-      else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
-       ;
-      else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
-       ;
-      else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
-       ;
-      else
-       break;
-    }
+#define _(a) u8 a=0;
+  foreach_ip4_proto_field;
+#undef _
+  u8 version = 0;
+  u8 hdr_length = 0;
 
-  if (l4 && !l3)
-    {
-      vec_free (mask);
-      vec_free (l2);
-      vec_free (l4);
-      return 0;
-    }
 
-  if (mask || l2 || l3 || l4)
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
-      if (l2 || l3 || l4)
-       {
-         /* "With a free Ethernet header in every package" */
-         if (l2 == 0)
-           vec_validate (l2, 13);
-         mask = l2;
-         if (vec_len (l3))
-           {
-             vec_append (mask, l3);
-             vec_free (l3);
-           }
-         if (vec_len (l4))
-           {
-             vec_append (mask, l4);
-             vec_free (l4);
-           }
-       }
-
-      /* Scan forward looking for the first significant mask octet */
-      for (i = 0; i < vec_len (mask); i++)
-       if (mask[i])
-         break;
-
-      /* compute (skip, match) params */
-      *skipp = i / sizeof (u32x4);
-      vec_delete (mask, *skipp * sizeof (u32x4), 0);
-
-      /* Pad mask to an even multiple of the vector size */
-      while (vec_len (mask) % sizeof (u32x4))
-       vec_add1 (mask, 0);
-
-      match = vec_len (mask) / sizeof (u32x4);
-
-      for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
-       {
-         u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
-         if (*tmp || *(tmp + 1))
-           break;
-         match--;
-       }
-      if (match == 0)
-       clib_warning ("BUG: match 0");
-
-      _vec_len (mask) = match * sizeof (u32x4);
-
-      *matchp = match;
-      *maskp = mask;
+      if (unformat (input, "version"))
+       version = 1;
+      else if (unformat (input, "hdr_length"))
+       hdr_length = 1;
+      else if (unformat (input, "src"))
+       src_address = 1;
+      else if (unformat (input, "dst"))
+       dst_address = 1;
+      else if (unformat (input, "proto"))
+       protocol = 1;
 
-      return 1;
+#define _(a) else if (unformat (input, #a)) a=1;
+      foreach_ip4_proto_field
+#undef _
+       else
+       break;
     }
 
-  return 0;
-}
-#endif /* VPP_API_TEST_BUILTIN */
+#define _(a) found_something += a;
+  foreach_ip4_proto_field;
+#undef _
 
-#define foreach_l2_next                         \
-_(drop, DROP)                                   \
-_(ethernet, ETHERNET_INPUT)                     \
-_(ip4, IP4_INPUT)                               \
-_(ip6, IP6_INPUT)
+  if (found_something == 0)
+    return 0;
 
-uword
-unformat_l2_next_index (unformat_input_t * input, va_list * args)
-{
-  u32 *miss_next_indexp = va_arg (*args, u32 *);
-  u32 next_index = 0;
-  u32 tmp;
+  vec_validate (mask, sizeof (*ip) - 1);
 
-#define _(n,N) \
-  if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
-  foreach_l2_next;
+  ip = (ip4_header_t *) mask;
+
+#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
+  foreach_ip4_proto_field;
 #undef _
 
-  if (unformat (input, "%d", &tmp))
-    {
-      next_index = tmp;
-      goto out;
-    }
+  ip->ip_version_and_header_length = 0;
 
-  return 0;
+  if (version)
+    ip->ip_version_and_header_length |= 0xF0;
 
-out:
-  *miss_next_indexp = next_index;
+  if (hdr_length)
+    ip->ip_version_and_header_length |= 0x0F;
+
+  *maskp = mask;
   return 1;
 }
 
-#define foreach_ip_next                         \
-_(drop, DROP)                                   \
-_(local, LOCAL)                                 \
-_(rewrite, REWRITE)
+#define foreach_ip6_proto_field                 \
+_(src_address)                                  \
+_(dst_address)                                  \
+_(payload_length)                              \
+_(hop_limit)                                    \
+_(protocol)
 
 uword
-api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
+unformat_ip6_mask (unformat_input_t * input, va_list * args)
 {
-  u32 *miss_next_indexp = va_arg (*args, u32 *);
-  u32 next_index = 0;
-  u32 tmp;
+  u8 **maskp = va_arg (*args, u8 **);
+  u8 *mask = 0;
+  u8 found_something = 0;
+  ip6_header_t *ip;
+  u32 ip_version_traffic_class_and_flow_label;
 
-#define _(n,N) \
-  if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
-  foreach_ip_next;
+#define _(a) u8 a=0;
+  foreach_ip6_proto_field;
 #undef _
+  u8 version = 0;
+  u8 traffic_class = 0;
+  u8 flow_label = 0;
 
-  if (unformat (input, "%d", &tmp))
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
-      next_index = tmp;
-      goto out;
+      if (unformat (input, "version"))
+       version = 1;
+      else if (unformat (input, "traffic-class"))
+       traffic_class = 1;
+      else if (unformat (input, "flow-label"))
+       flow_label = 1;
+      else if (unformat (input, "src"))
+       src_address = 1;
+      else if (unformat (input, "dst"))
+       dst_address = 1;
+      else if (unformat (input, "proto"))
+       protocol = 1;
+
+#define _(a) else if (unformat (input, #a)) a=1;
+      foreach_ip6_proto_field
+#undef _
+       else
+       break;
     }
 
-  return 0;
+#define _(a) found_something += a;
+  foreach_ip6_proto_field;
+#undef _
 
-out:
-  *miss_next_indexp = next_index;
-  return 1;
-}
+  if (found_something == 0)
+    return 0;
 
-#define foreach_acl_next                        \
-_(deny, DENY)
+  vec_validate (mask, sizeof (*ip) - 1);
 
-uword
-api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
-{
-  u32 *miss_next_indexp = va_arg (*args, u32 *);
-  u32 next_index = 0;
-  u32 tmp;
+  ip = (ip6_header_t *) mask;
 
-#define _(n,N) \
-  if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
-  foreach_acl_next;
+#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
+  foreach_ip6_proto_field;
 #undef _
 
-  if (unformat (input, "permit"))
-    {
-      next_index = ~0;
-      goto out;
-    }
-  else if (unformat (input, "%d", &tmp))
-    {
-      next_index = tmp;
-      goto out;
-    }
+  ip_version_traffic_class_and_flow_label = 0;
 
-  return 0;
+  if (version)
+    ip_version_traffic_class_and_flow_label |= 0xF0000000;
 
-out:
-  *miss_next_indexp = next_index;
-  return 1;
-}
+  if (traffic_class)
+    ip_version_traffic_class_and_flow_label |= 0x0FF00000;
 
-uword
-unformat_policer_precolor (unformat_input_t * input, va_list * args)
-{
-  u32 *r = va_arg (*args, u32 *);
+  if (flow_label)
+    ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
 
-  if (unformat (input, "conform-color"))
-    *r = POLICE_CONFORM;
-  else if (unformat (input, "exceed-color"))
-    *r = POLICE_EXCEED;
-  else
-    return 0;
+  ip->ip_version_traffic_class_and_flow_label =
+    clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
 
+  *maskp = mask;
   return 1;
 }
 
-#if VPP_API_TEST_BUILTIN == 0
 uword
-unformat_l4_match (unformat_input_t * input, va_list * args)
+unformat_l3_mask (unformat_input_t * input, va_list * args)
 {
-  u8 **matchp = va_arg (*args, u8 **);
-
-  u8 *proto_header = 0;
-  int src_port = 0;
-  int dst_port = 0;
-
-  tcpudp_header_t h;
+  u8 **maskp = va_arg (*args, u8 **);
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (input, "src_port %d", &src_port))
-       ;
-      else if (unformat (input, "dst_port %d", &dst_port))
-       ;
+      if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
+       return 1;
+      else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
+       return 1;
       else
-       return 0;
+       break;
     }
-
-  h.src_port = clib_host_to_net_u16 (src_port);
-  h.dst_port = clib_host_to_net_u16 (dst_port);
-  vec_validate (proto_header, sizeof (h) - 1);
-  memcpy (proto_header, &h, sizeof (h));
-
-  *matchp = proto_header;
-
-  return 1;
+  return 0;
 }
 
 uword
-unformat_ip4_match (unformat_input_t * input, va_list * args)
+unformat_l2_mask (unformat_input_t * input, va_list * args)
 {
-  u8 **matchp = va_arg (*args, u8 **);
-  u8 *match = 0;
-  ip4_header_t *ip;
-  int version = 0;
-  u32 version_val;
-  int hdr_length = 0;
-  u32 hdr_length_val;
-  int src = 0, dst = 0;
-  ip4_address_t src_val, dst_val;
-  int proto = 0;
-  u32 proto_val;
-  int tos = 0;
-  u32 tos_val;
-  int length = 0;
-  u32 length_val;
-  int fragment_id = 0;
-  u32 fragment_id_val;
-  int ttl = 0;
-  int ttl_val;
-  int checksum = 0;
-  u32 checksum_val;
+  u8 **maskp = va_arg (*args, u8 **);
+  u8 *mask = 0;
+  u8 src = 0;
+  u8 dst = 0;
+  u8 proto = 0;
+  u8 tag1 = 0;
+  u8 tag2 = 0;
+  u8 ignore_tag1 = 0;
+  u8 ignore_tag2 = 0;
+  u8 cos1 = 0;
+  u8 cos2 = 0;
+  u8 dot1q = 0;
+  u8 dot1ad = 0;
+  int len = 14;
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (input, "version %d", &version_val))
-       version = 1;
-      else if (unformat (input, "hdr_length %d", &hdr_length_val))
-       hdr_length = 1;
-      else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
+      if (unformat (input, "src"))
        src = 1;
-      else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
+      else if (unformat (input, "dst"))
        dst = 1;
-      else if (unformat (input, "proto %d", &proto_val))
+      else if (unformat (input, "proto"))
        proto = 1;
-      else if (unformat (input, "tos %d", &tos_val))
-       tos = 1;
-      else if (unformat (input, "length %d", &length_val))
-       length = 1;
-      else if (unformat (input, "fragment_id %d", &fragment_id_val))
-       fragment_id = 1;
-      else if (unformat (input, "ttl %d", &ttl_val))
-       ttl = 1;
-      else if (unformat (input, "checksum %d", &checksum_val))
-       checksum = 1;
+      else if (unformat (input, "tag1"))
+       tag1 = 1;
+      else if (unformat (input, "tag2"))
+       tag2 = 1;
+      else if (unformat (input, "ignore-tag1"))
+       ignore_tag1 = 1;
+      else if (unformat (input, "ignore-tag2"))
+       ignore_tag2 = 1;
+      else if (unformat (input, "cos1"))
+       cos1 = 1;
+      else if (unformat (input, "cos2"))
+       cos2 = 1;
+      else if (unformat (input, "dot1q"))
+       dot1q = 1;
+      else if (unformat (input, "dot1ad"))
+       dot1ad = 1;
       else
        break;
     }
-
-  if (version + hdr_length + src + dst + proto + tos + length + fragment_id
-      + ttl + checksum == 0)
+  if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
+       ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
     return 0;
 
-  /*
-   * Aligned because we use the real comparison functions
-   */
-  vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
-
-  ip = (ip4_header_t *) match;
+  if (tag1 || ignore_tag1 || cos1 || dot1q)
+    len = 18;
+  if (tag2 || ignore_tag2 || cos2 || dot1ad)
+    len = 22;
 
-  /* These are realistically matched in practice */
-  if (src)
-    ip->src_address.as_u32 = src_val.as_u32;
+  vec_validate (mask, len - 1);
 
   if (dst)
-    ip->dst_address.as_u32 = dst_val.as_u32;
-
-  if (proto)
-    ip->protocol = proto_val;
-
-
-  /* These are not, but they're included for completeness */
-  if (version)
-    ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
-
-  if (hdr_length)
-    ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
-
-  if (tos)
-    ip->tos = tos_val;
+    clib_memset (mask, 0xff, 6);
 
-  if (length)
-    ip->length = clib_host_to_net_u16 (length_val);
+  if (src)
+    clib_memset (mask + 6, 0xff, 6);
 
-  if (ttl)
-    ip->ttl = ttl_val;
+  if (tag2 || dot1ad)
+    {
+      /* inner vlan tag */
+      if (tag2)
+       {
+         mask[19] = 0xff;
+         mask[18] = 0x0f;
+       }
+      if (cos2)
+       mask[18] |= 0xe0;
+      if (proto)
+       mask[21] = mask[20] = 0xff;
+      if (tag1)
+       {
+         mask[15] = 0xff;
+         mask[14] = 0x0f;
+       }
+      if (cos1)
+       mask[14] |= 0xe0;
+      *maskp = mask;
+      return 1;
+    }
+  if (tag1 | dot1q)
+    {
+      if (tag1)
+       {
+         mask[15] = 0xff;
+         mask[14] = 0x0f;
+       }
+      if (cos1)
+       mask[14] |= 0xe0;
+      if (proto)
+       mask[16] = mask[17] = 0xff;
 
-  if (checksum)
-    ip->checksum = clib_host_to_net_u16 (checksum_val);
+      *maskp = mask;
+      return 1;
+    }
+  if (cos2)
+    mask[18] |= 0xe0;
+  if (cos1)
+    mask[14] |= 0xe0;
+  if (proto)
+    mask[12] = mask[13] = 0xff;
 
-  *matchp = match;
+  *maskp = mask;
   return 1;
 }
 
 uword
-unformat_ip6_match (unformat_input_t * input, va_list * args)
+unformat_classify_mask (unformat_input_t * input, va_list * args)
 {
-  u8 **matchp = va_arg (*args, u8 **);
-  u8 *match = 0;
-  ip6_header_t *ip;
-  int version = 0;
-  u32 version_val;
-  u8 traffic_class = 0;
-  u32 traffic_class_val = 0;
-  u8 flow_label = 0;
-  u8 flow_label_val;
-  int src = 0, dst = 0;
-  ip6_address_t src_val, dst_val;
-  int proto = 0;
-  u32 proto_val;
-  int payload_length = 0;
-  u32 payload_length_val;
-  int hop_limit = 0;
-  int hop_limit_val;
-  u32 ip_version_traffic_class_and_flow_label;
+  u8 **maskp = va_arg (*args, u8 **);
+  u32 *skipp = va_arg (*args, u32 *);
+  u32 *matchp = va_arg (*args, u32 *);
+  u32 match;
+  u8 *mask = 0;
+  u8 *l2 = 0;
+  u8 *l3 = 0;
+  u8 *l4 = 0;
+  int i;
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (input, "version %d", &version_val))
-       version = 1;
-      else if (unformat (input, "traffic_class %d", &traffic_class_val))
-       traffic_class = 1;
-      else if (unformat (input, "flow_label %d", &flow_label_val))
-       flow_label = 1;
-      else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
-       src = 1;
-      else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
-       dst = 1;
-      else if (unformat (input, "proto %d", &proto_val))
-       proto = 1;
-      else if (unformat (input, "payload_length %d", &payload_length_val))
-       payload_length = 1;
-      else if (unformat (input, "hop_limit %d", &hop_limit_val))
-       hop_limit = 1;
+      if (unformat (input, "hex %U", unformat_hex_string, &mask))
+       ;
+      else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
+       ;
+      else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
+       ;
+      else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
+       ;
       else
        break;
     }
 
-  if (version + traffic_class + flow_label + src + dst + proto +
-      payload_length + hop_limit == 0)
-    return 0;
-
-  /*
-   * Aligned because we use the real comparison functions
-   */
-  vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
-
-  ip = (ip6_header_t *) match;
-
-  if (src)
-    clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
-
-  if (dst)
-    clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
-
-  if (proto)
-    ip->protocol = proto_val;
-
-  ip_version_traffic_class_and_flow_label = 0;
+  if (l4 && !l3)
+    {
+      vec_free (mask);
+      vec_free (l2);
+      vec_free (l4);
+      return 0;
+    }
 
-  if (version)
-    ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
+  if (mask || l2 || l3 || l4)
+    {
+      if (l2 || l3 || l4)
+       {
+         /* "With a free Ethernet header in every package" */
+         if (l2 == 0)
+           vec_validate (l2, 13);
+         mask = l2;
+         if (vec_len (l3))
+           {
+             vec_append (mask, l3);
+             vec_free (l3);
+           }
+         if (vec_len (l4))
+           {
+             vec_append (mask, l4);
+             vec_free (l4);
+           }
+       }
 
-  if (traffic_class)
-    ip_version_traffic_class_and_flow_label |=
-      (traffic_class_val & 0xFF) << 20;
+      /* Scan forward looking for the first significant mask octet */
+      for (i = 0; i < vec_len (mask); i++)
+       if (mask[i])
+         break;
 
-  if (flow_label)
-    ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
+      /* compute (skip, match) params */
+      *skipp = i / sizeof (u32x4);
+      vec_delete (mask, *skipp * sizeof (u32x4), 0);
 
-  ip->ip_version_traffic_class_and_flow_label =
-    clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
+      /* Pad mask to an even multiple of the vector size */
+      while (vec_len (mask) % sizeof (u32x4))
+       vec_add1 (mask, 0);
 
-  if (payload_length)
-    ip->payload_length = clib_host_to_net_u16 (payload_length_val);
+      match = vec_len (mask) / sizeof (u32x4);
 
-  if (hop_limit)
-    ip->hop_limit = hop_limit_val;
+      for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
+       {
+         u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
+         if (*tmp || *(tmp + 1))
+           break;
+         match--;
+       }
+      if (match == 0)
+       clib_warning ("BUG: match 0");
 
-  *matchp = match;
-  return 1;
-}
+      _vec_len (mask) = match * sizeof (u32x4);
 
-uword
-unformat_l3_match (unformat_input_t * input, va_list * args)
-{
-  u8 **matchp = va_arg (*args, u8 **);
+      *matchp = match;
+      *maskp = mask;
 
-  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
-       return 1;
-      else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
-       return 1;
-      else
-       break;
+      return 1;
     }
+
   return 0;
 }
+#endif /* VPP_API_TEST_BUILTIN */
+
+#define foreach_l2_next                         \
+_(drop, DROP)                                   \
+_(ethernet, ETHERNET_INPUT)                     \
+_(ip4, IP4_INPUT)                               \
+_(ip6, IP6_INPUT)
 
 uword
-unformat_vlan_tag (unformat_input_t * input, va_list * args)
+unformat_l2_next_index (unformat_input_t * input, va_list * args)
 {
-  u8 *tagp = va_arg (*args, u8 *);
-  u32 tag;
+  u32 *miss_next_indexp = va_arg (*args, u32 *);
+  u32 next_index = 0;
+  u32 tmp;
 
-  if (unformat (input, "%d", &tag))
+#define _(n,N) \
+  if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
+  foreach_l2_next;
+#undef _
+
+  if (unformat (input, "%d", &tmp))
     {
-      tagp[0] = (tag >> 8) & 0x0F;
-      tagp[1] = tag & 0xFF;
-      return 1;
+      next_index = tmp;
+      goto out;
     }
 
   return 0;
+
+out:
+  *miss_next_indexp = next_index;
+  return 1;
 }
 
+#define foreach_ip_next                         \
+_(drop, DROP)                                   \
+_(local, LOCAL)                                 \
+_(rewrite, REWRITE)
+
 uword
-unformat_l2_match (unformat_input_t * input, va_list * args)
+api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
 {
-  u8 **matchp = va_arg (*args, u8 **);
-  u8 *match = 0;
-  u8 src = 0;
-  u8 src_val[6];
-  u8 dst = 0;
-  u8 dst_val[6];
-  u8 proto = 0;
-  u16 proto_val;
-  u8 tag1 = 0;
-  u8 tag1_val[2];
-  u8 tag2 = 0;
-  u8 tag2_val[2];
-  int len = 14;
-  u8 ignore_tag1 = 0;
-  u8 ignore_tag2 = 0;
-  u8 cos1 = 0;
-  u8 cos2 = 0;
-  u32 cos1_val = 0;
-  u32 cos2_val = 0;
+  u32 *miss_next_indexp = va_arg (*args, u32 *);
+  u32 next_index = 0;
+  u32 tmp;
 
-  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+#define _(n,N) \
+  if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
+  foreach_ip_next;
+#undef _
+
+  if (unformat (input, "%d", &tmp))
     {
-      if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
-       src = 1;
-      else
-       if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
-       dst = 1;
-      else if (unformat (input, "proto %U",
-                        unformat_ethernet_type_host_byte_order, &proto_val))
-       proto = 1;
-      else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
-       tag1 = 1;
-      else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
-       tag2 = 1;
-      else if (unformat (input, "ignore-tag1"))
-       ignore_tag1 = 1;
-      else if (unformat (input, "ignore-tag2"))
-       ignore_tag2 = 1;
-      else if (unformat (input, "cos1 %d", &cos1_val))
-       cos1 = 1;
-      else if (unformat (input, "cos2 %d", &cos2_val))
-       cos2 = 1;
-      else
-       break;
+      next_index = tmp;
+      goto out;
     }
-  if ((src + dst + proto + tag1 + tag2 +
-       ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
-    return 0;
 
-  if (tag1 || ignore_tag1 || cos1)
-    len = 18;
-  if (tag2 || ignore_tag2 || cos2)
-    len = 22;
+  return 0;
 
-  vec_validate_aligned (match, len - 1, sizeof (u32x4));
+out:
+  *miss_next_indexp = next_index;
+  return 1;
+}
 
-  if (dst)
-    clib_memcpy (match, dst_val, 6);
+#define foreach_acl_next                        \
+_(deny, DENY)
 
-  if (src)
-    clib_memcpy (match + 6, src_val, 6);
+uword
+api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
+{
+  u32 *miss_next_indexp = va_arg (*args, u32 *);
+  u32 next_index = 0;
+  u32 tmp;
 
-  if (tag2)
-    {
-      /* inner vlan tag */
-      match[19] = tag2_val[1];
-      match[18] = tag2_val[0];
-      if (cos2)
-       match[18] |= (cos2_val & 0x7) << 5;
-      if (proto)
-       {
-         match[21] = proto_val & 0xff;
-         match[20] = proto_val >> 8;
-       }
-      if (tag1)
-       {
-         match[15] = tag1_val[1];
-         match[14] = tag1_val[0];
-       }
-      if (cos1)
-       match[14] |= (cos1_val & 0x7) << 5;
-      *matchp = match;
-      return 1;
-    }
-  if (tag1)
-    {
-      match[15] = tag1_val[1];
-      match[14] = tag1_val[0];
-      if (proto)
-       {
-         match[17] = proto_val & 0xff;
-         match[16] = proto_val >> 8;
-       }
-      if (cos1)
-       match[14] |= (cos1_val & 0x7) << 5;
+#define _(n,N) \
+  if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
+  foreach_acl_next;
+#undef _
 
-      *matchp = match;
-      return 1;
+  if (unformat (input, "permit"))
+    {
+      next_index = ~0;
+      goto out;
     }
-  if (cos2)
-    match[18] |= (cos2_val & 0x7) << 5;
-  if (cos1)
-    match[14] |= (cos1_val & 0x7) << 5;
-  if (proto)
+  else if (unformat (input, "%d", &tmp))
     {
-      match[13] = proto_val & 0xff;
-      match[12] = proto_val >> 8;
+      next_index = tmp;
+      goto out;
     }
 
-  *matchp = match;
+  return 0;
+
+out:
+  *miss_next_indexp = next_index;
   return 1;
 }
 
 uword
-unformat_qos_source (unformat_input_t * input, va_list * args)
+unformat_policer_precolor (unformat_input_t * input, va_list * args)
 {
-  int *qs = va_arg (*args, int *);
+  u32 *r = va_arg (*args, u32 *);
 
-  if (unformat (input, "ip"))
-    *qs = QOS_SOURCE_IP;
-  else if (unformat (input, "mpls"))
-    *qs = QOS_SOURCE_MPLS;
-  else if (unformat (input, "ext"))
-    *qs = QOS_SOURCE_EXT;
-  else if (unformat (input, "vlan"))
-    *qs = QOS_SOURCE_VLAN;
+  if (unformat (input, "conform-color"))
+    *r = POLICE_CONFORM;
+  else if (unformat (input, "exceed-color"))
+    *r = POLICE_EXCEED;
   else
     return 0;
 
   return 1;
 }
-#endif
 
+#if VPP_API_TEST_BUILTIN == 0
 uword
-api_unformat_classify_match (unformat_input_t * input, va_list * args)
+unformat_l4_match (unformat_input_t * input, va_list * args)
 {
   u8 **matchp = va_arg (*args, u8 **);
-  u32 skip_n_vectors = va_arg (*args, u32);
-  u32 match_n_vectors = va_arg (*args, u32);
 
-  u8 *match = 0;
-  u8 *l2 = 0;
-  u8 *l3 = 0;
-  u8 *l4 = 0;
+  u8 *proto_header = 0;
+  int src_port = 0;
+  int dst_port = 0;
+
+  tcpudp_header_t h;
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (input, "hex %U", unformat_hex_string, &match))
-       ;
-      else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
-       ;
-      else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
+      if (unformat (input, "src_port %d", &src_port))
        ;
-      else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
+      else if (unformat (input, "dst_port %d", &dst_port))
        ;
+      else
+       return 0;
+    }
+
+  h.src_port = clib_host_to_net_u16 (src_port);
+  h.dst_port = clib_host_to_net_u16 (dst_port);
+  vec_validate (proto_header, sizeof (h) - 1);
+  memcpy (proto_header, &h, sizeof (h));
+
+  *matchp = proto_header;
+
+  return 1;
+}
+
+uword
+unformat_ip4_match (unformat_input_t * input, va_list * args)
+{
+  u8 **matchp = va_arg (*args, u8 **);
+  u8 *match = 0;
+  ip4_header_t *ip;
+  int version = 0;
+  u32 version_val;
+  int hdr_length = 0;
+  u32 hdr_length_val;
+  int src = 0, dst = 0;
+  ip4_address_t src_val, dst_val;
+  int proto = 0;
+  u32 proto_val;
+  int tos = 0;
+  u32 tos_val;
+  int length = 0;
+  u32 length_val;
+  int fragment_id = 0;
+  u32 fragment_id_val;
+  int ttl = 0;
+  int ttl_val;
+  int checksum = 0;
+  u32 checksum_val;
+
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (input, "version %d", &version_val))
+       version = 1;
+      else if (unformat (input, "hdr_length %d", &hdr_length_val))
+       hdr_length = 1;
+      else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
+       src = 1;
+      else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
+       dst = 1;
+      else if (unformat (input, "proto %d", &proto_val))
+       proto = 1;
+      else if (unformat (input, "tos %d", &tos_val))
+       tos = 1;
+      else if (unformat (input, "length %d", &length_val))
+       length = 1;
+      else if (unformat (input, "fragment_id %d", &fragment_id_val))
+       fragment_id = 1;
+      else if (unformat (input, "ttl %d", &ttl_val))
+       ttl = 1;
+      else if (unformat (input, "checksum %d", &checksum_val))
+       checksum = 1;
       else
        break;
     }
 
-  if (l4 && !l3)
-    {
-      vec_free (match);
-      vec_free (l2);
-      vec_free (l4);
-      return 0;
-    }
+  if (version + hdr_length + src + dst + proto + tos + length + fragment_id
+      + ttl + checksum == 0)
+    return 0;
 
-  if (match || l2 || l3 || l4)
-    {
-      if (l2 || l3 || l4)
-       {
-         /* "Win a free Ethernet header in every packet" */
-         if (l2 == 0)
-           vec_validate_aligned (l2, 13, sizeof (u32x4));
-         match = l2;
-         if (vec_len (l3))
-           {
-             vec_append_aligned (match, l3, sizeof (u32x4));
-             vec_free (l3);
-           }
-         if (vec_len (l4))
-           {
-             vec_append_aligned (match, l4, sizeof (u32x4));
-             vec_free (l4);
-           }
-       }
+  /*
+   * Aligned because we use the real comparison functions
+   */
+  vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
 
-      /* Make sure the vector is big enough even if key is all 0's */
-      vec_validate_aligned
-       (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
-        sizeof (u32x4));
+  ip = (ip4_header_t *) match;
 
-      /* Set size, include skipped vectors */
-      _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
+  /* These are realistically matched in practice */
+  if (src)
+    ip->src_address.as_u32 = src_val.as_u32;
 
-      *matchp = match;
+  if (dst)
+    ip->dst_address.as_u32 = dst_val.as_u32;
 
-      return 1;
-    }
+  if (proto)
+    ip->protocol = proto_val;
 
-  return 0;
-}
 
-static int
-api_get_node_index (vat_main_t *vam)
-{
-  unformat_input_t *i = vam->input;
-  vl_api_get_node_index_t *mp;
-  u8 *name = 0;
-  int ret;
+  /* These are not, but they're included for completeness */
+  if (version)
+    ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
 
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "node %s", &name))
-       ;
-      else
-       break;
-    }
-  if (name == 0)
-    {
-      errmsg ("node name required");
-      return -99;
-    }
-  if (vec_len (name) >= ARRAY_LEN (mp->node_name))
-    {
-      errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
-      return -99;
-    }
+  if (hdr_length)
+    ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
 
-  M (GET_NODE_INDEX, mp);
-  clib_memcpy (mp->node_name, name, vec_len (name));
-  vec_free (name);
+  if (tos)
+    ip->tos = tos_val;
 
-  S (mp);
-  W (ret);
-  return ret;
+  if (length)
+    ip->length = clib_host_to_net_u16 (length_val);
+
+  if (ttl)
+    ip->ttl = ttl_val;
+
+  if (checksum)
+    ip->checksum = clib_host_to_net_u16 (checksum_val);
+
+  *matchp = match;
+  return 1;
 }
 
-static int
-api_get_next_index (vat_main_t *vam)
+uword
+unformat_ip6_match (unformat_input_t * input, va_list * args)
 {
-  unformat_input_t *i = vam->input;
-  vl_api_get_next_index_t *mp;
-  u8 *node_name = 0, *next_node_name = 0;
-  int ret;
+  u8 **matchp = va_arg (*args, u8 **);
+  u8 *match = 0;
+  ip6_header_t *ip;
+  int version = 0;
+  u32 version_val;
+  u8 traffic_class = 0;
+  u32 traffic_class_val = 0;
+  u8 flow_label = 0;
+  u8 flow_label_val;
+  int src = 0, dst = 0;
+  ip6_address_t src_val, dst_val;
+  int proto = 0;
+  u32 proto_val;
+  int payload_length = 0;
+  u32 payload_length_val;
+  int hop_limit = 0;
+  int hop_limit_val;
+  u32 ip_version_traffic_class_and_flow_label;
 
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (i, "node-name %s", &node_name))
-       ;
-      else if (unformat (i, "next-node-name %s", &next_node_name))
+      if (unformat (input, "version %d", &version_val))
+       version = 1;
+      else if (unformat (input, "traffic_class %d", &traffic_class_val))
+       traffic_class = 1;
+      else if (unformat (input, "flow_label %d", &flow_label_val))
+       flow_label = 1;
+      else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
+       src = 1;
+      else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
+       dst = 1;
+      else if (unformat (input, "proto %d", &proto_val))
+       proto = 1;
+      else if (unformat (input, "payload_length %d", &payload_length_val))
+       payload_length = 1;
+      else if (unformat (input, "hop_limit %d", &hop_limit_val))
+       hop_limit = 1;
+      else
        break;
     }
 
-  if (node_name == 0)
-    {
-      errmsg ("node name required");
-      return -99;
-    }
-  if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
-    {
-      errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
-      return -99;
-    }
+  if (version + traffic_class + flow_label + src + dst + proto +
+      payload_length + hop_limit == 0)
+    return 0;
 
-  if (next_node_name == 0)
-    {
-      errmsg ("next node name required");
-      return -99;
-    }
-  if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
-    {
-      errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
-      return -99;
-    }
+  /*
+   * Aligned because we use the real comparison functions
+   */
+  vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
 
-  M (GET_NEXT_INDEX, mp);
-  clib_memcpy (mp->node_name, node_name, vec_len (node_name));
-  clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
-  vec_free (node_name);
-  vec_free (next_node_name);
+  ip = (ip6_header_t *) match;
 
-  S (mp);
-  W (ret);
-  return ret;
-}
+  if (src)
+    clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
 
-static int
-api_add_node_next (vat_main_t *vam)
-{
-  unformat_input_t *i = vam->input;
-  vl_api_add_node_next_t *mp;
-  u8 *name = 0;
-  u8 *next = 0;
-  int ret;
+  if (dst)
+    clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
 
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "node %s", &name))
-       ;
-      else if (unformat (i, "next %s", &next))
-       ;
-      else
-       break;
-    }
-  if (name == 0)
-    {
-      errmsg ("node name required");
-      return -99;
-    }
-  if (vec_len (name) >= ARRAY_LEN (mp->node_name))
-    {
-      errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
-      return -99;
-    }
-  if (next == 0)
-    {
-      errmsg ("next node required");
-      return -99;
-    }
-  if (vec_len (next) >= ARRAY_LEN (mp->next_name))
-    {
-      errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
-      return -99;
-    }
+  if (proto)
+    ip->protocol = proto_val;
 
-  M (ADD_NODE_NEXT, mp);
-  clib_memcpy (mp->node_name, name, vec_len (name));
-  clib_memcpy (mp->next_name, next, vec_len (next));
-  vec_free (name);
-  vec_free (next);
+  ip_version_traffic_class_and_flow_label = 0;
 
-  S (mp);
-  W (ret);
-  return ret;
-}
+  if (version)
+    ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
 
-#define foreach_vtr_op                                                        \
-  _ ("disable", L2_VTR_DISABLED)                                              \
-  _ ("push-1", L2_VTR_PUSH_1)                                                 \
-  _ ("push-2", L2_VTR_PUSH_2)                                                 \
-  _ ("pop-1", L2_VTR_POP_1)                                                   \
-  _ ("pop-2", L2_VTR_POP_2)                                                   \
-  _ ("translate-1-1", L2_VTR_TRANSLATE_1_1)                                   \
-  _ ("translate-1-2", L2_VTR_TRANSLATE_1_2)                                   \
-  _ ("translate-2-1", L2_VTR_TRANSLATE_2_1)                                   \
-  _ ("translate-2-2", L2_VTR_TRANSLATE_2_2)
+  if (traffic_class)
+    ip_version_traffic_class_and_flow_label |=
+      (traffic_class_val & 0xFF) << 20;
 
-static int
-api_show_version (vat_main_t *vam)
-{
-  vl_api_show_version_t *mp;
-  int ret;
+  if (flow_label)
+    ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
 
-  M (SHOW_VERSION, mp);
+  ip->ip_version_traffic_class_and_flow_label =
+    clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
 
-  S (mp);
-  W (ret);
-  return ret;
+  if (payload_length)
+    ip->payload_length = clib_host_to_net_u16 (payload_length_val);
+
+  if (hop_limit)
+    ip->hop_limit = hop_limit_val;
+
+  *matchp = match;
+  return 1;
 }
 
-static int
-api_interface_name_renumber (vat_main_t *vam)
+uword
+unformat_l3_match (unformat_input_t * input, va_list * args)
 {
-  unformat_input_t *line_input = vam->input;
-  vl_api_interface_name_renumber_t *mp;
-  u32 sw_if_index = ~0;
-  u32 new_show_dev_instance = ~0;
-  int ret;
+  u8 **matchp = va_arg (*args, u8 **);
 
-  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
-                   &sw_if_index))
-       ;
-      else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
-       ;
-      else if (unformat (line_input, "new_show_dev_instance %d",
-                        &new_show_dev_instance))
-       ;
+      if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
+       return 1;
+      else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
+       return 1;
       else
        break;
     }
+  return 0;
+}
 
-  if (sw_if_index == ~0)
-    {
-      errmsg ("missing interface name or sw_if_index");
-      return -99;
-    }
+uword
+unformat_vlan_tag (unformat_input_t * input, va_list * args)
+{
+  u8 *tagp = va_arg (*args, u8 *);
+  u32 tag;
 
-  if (new_show_dev_instance == ~0)
+  if (unformat (input, "%d", &tag))
     {
-      errmsg ("missing new_show_dev_instance");
-      return -99;
+      tagp[0] = (tag >> 8) & 0x0F;
+      tagp[1] = tag & 0xFF;
+      return 1;
     }
 
-  M (INTERFACE_NAME_RENUMBER, mp);
-
-  mp->sw_if_index = ntohl (sw_if_index);
-  mp->new_show_dev_instance = ntohl (new_show_dev_instance);
-
-  S (mp);
-  W (ret);
-  return ret;
+  return 0;
 }
 
-static int
-api_get_first_msg_id (vat_main_t *vam)
+uword
+unformat_l2_match (unformat_input_t * input, va_list * args)
 {
-  vl_api_get_first_msg_id_t *mp;
-  unformat_input_t *i = vam->input;
-  u8 *name;
-  u8 name_set = 0;
-  int ret;
+  u8 **matchp = va_arg (*args, u8 **);
+  u8 *match = 0;
+  u8 src = 0;
+  u8 src_val[6];
+  u8 dst = 0;
+  u8 dst_val[6];
+  u8 proto = 0;
+  u16 proto_val;
+  u8 tag1 = 0;
+  u8 tag1_val[2];
+  u8 tag2 = 0;
+  u8 tag2_val[2];
+  int len = 14;
+  u8 ignore_tag1 = 0;
+  u8 ignore_tag2 = 0;
+  u8 cos1 = 0;
+  u8 cos2 = 0;
+  u32 cos1_val = 0;
+  u32 cos2_val = 0;
 
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (i, "client %s", &name))
-       name_set = 1;
+      if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
+       src = 1;
+      else
+       if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
+       dst = 1;
+      else if (unformat (input, "proto %U",
+                        unformat_ethernet_type_host_byte_order, &proto_val))
+       proto = 1;
+      else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
+       tag1 = 1;
+      else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
+       tag2 = 1;
+      else if (unformat (input, "ignore-tag1"))
+       ignore_tag1 = 1;
+      else if (unformat (input, "ignore-tag2"))
+       ignore_tag2 = 1;
+      else if (unformat (input, "cos1 %d", &cos1_val))
+       cos1 = 1;
+      else if (unformat (input, "cos2 %d", &cos2_val))
+       cos2 = 1;
       else
        break;
     }
+  if ((src + dst + proto + tag1 + tag2 +
+       ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
+    return 0;
 
-  if (name_set == 0)
+  if (tag1 || ignore_tag1 || cos1)
+    len = 18;
+  if (tag2 || ignore_tag2 || cos2)
+    len = 22;
+
+  vec_validate_aligned (match, len - 1, sizeof (u32x4));
+
+  if (dst)
+    clib_memcpy (match, dst_val, 6);
+
+  if (src)
+    clib_memcpy (match + 6, src_val, 6);
+
+  if (tag2)
     {
-      errmsg ("missing client name");
-      return -99;
+      /* inner vlan tag */
+      match[19] = tag2_val[1];
+      match[18] = tag2_val[0];
+      if (cos2)
+       match[18] |= (cos2_val & 0x7) << 5;
+      if (proto)
+       {
+         match[21] = proto_val & 0xff;
+         match[20] = proto_val >> 8;
+       }
+      if (tag1)
+       {
+         match[15] = tag1_val[1];
+         match[14] = tag1_val[0];
+       }
+      if (cos1)
+       match[14] |= (cos1_val & 0x7) << 5;
+      *matchp = match;
+      return 1;
     }
-  vec_add1 (name, 0);
+  if (tag1)
+    {
+      match[15] = tag1_val[1];
+      match[14] = tag1_val[0];
+      if (proto)
+       {
+         match[17] = proto_val & 0xff;
+         match[16] = proto_val >> 8;
+       }
+      if (cos1)
+       match[14] |= (cos1_val & 0x7) << 5;
 
-  if (vec_len (name) > 63)
+      *matchp = match;
+      return 1;
+    }
+  if (cos2)
+    match[18] |= (cos2_val & 0x7) << 5;
+  if (cos1)
+    match[14] |= (cos1_val & 0x7) << 5;
+  if (proto)
     {
-      errmsg ("client name too long");
-      return -99;
+      match[13] = proto_val & 0xff;
+      match[12] = proto_val >> 8;
     }
 
-  M (GET_FIRST_MSG_ID, mp);
-  clib_memcpy (mp->name, name, vec_len (name));
-  S (mp);
-  W (ret);
-  return ret;
+  *matchp = match;
+  return 1;
 }
 
-static int
-api_get_node_graph (vat_main_t *vam)
+uword
+unformat_qos_source (unformat_input_t * input, va_list * args)
 {
-  vl_api_get_node_graph_t *mp;
-  int ret;
+  int *qs = va_arg (*args, int *);
 
-  M (GET_NODE_GRAPH, mp);
+  if (unformat (input, "ip"))
+    *qs = QOS_SOURCE_IP;
+  else if (unformat (input, "mpls"))
+    *qs = QOS_SOURCE_MPLS;
+  else if (unformat (input, "ext"))
+    *qs = QOS_SOURCE_EXT;
+  else if (unformat (input, "vlan"))
+    *qs = QOS_SOURCE_VLAN;
+  else
+    return 0;
 
-  /* send it... */
-  S (mp);
-  /* Wait for the reply */
-  W (ret);
-  return ret;
+  return 1;
 }
+#endif
 
-static int
-api_delete_subif (vat_main_t * vam)
+uword
+api_unformat_classify_match (unformat_input_t * input, va_list * args)
 {
-  unformat_input_t *i = vam->input;
-  vl_api_delete_subif_t *mp;
-  u32 sw_if_index = ~0;
-  int ret;
+  u8 **matchp = va_arg (*args, u8 **);
+  u32 skip_n_vectors = va_arg (*args, u32);
+  u32 match_n_vectors = va_arg (*args, u32);
 
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+  u8 *match = 0;
+  u8 *l2 = 0;
+  u8 *l3 = 0;
+  u8 *l4 = 0;
+
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
+      if (unformat (input, "hex %U", unformat_hex_string, &match))
+       ;
+      else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
+       ;
+      else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
        ;
-      if (unformat (i, "sw_if_index %d", &sw_if_index))
+      else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
        ;
       else
        break;
     }
 
-  if (sw_if_index == ~0)
+  if (l4 && !l3)
     {
-      errmsg ("missing sw_if_index");
-      return -99;
+      vec_free (match);
+      vec_free (l2);
+      vec_free (l4);
+      return 0;
     }
 
-  /* Construct the API message */
-  M (DELETE_SUBIF, mp);
-  mp->sw_if_index = ntohl (sw_if_index);
+  if (match || l2 || l3 || l4)
+    {
+      if (l2 || l3 || l4)
+       {
+         /* "Win a free Ethernet header in every packet" */
+         if (l2 == 0)
+           vec_validate_aligned (l2, 13, sizeof (u32x4));
+         match = l2;
+         if (vec_len (l3))
+           {
+             vec_append_aligned (match, l3, sizeof (u32x4));
+             vec_free (l3);
+           }
+         if (vec_len (l4))
+           {
+             vec_append_aligned (match, l4, sizeof (u32x4));
+             vec_free (l4);
+           }
+       }
+
+      /* Make sure the vector is big enough even if key is all 0's */
+      vec_validate_aligned
+       (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
+        sizeof (u32x4));
+
+      /* Set size, include skipped vectors */
+      _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
 
-  S (mp);
-  W (ret);
-  return ret;
-}
+      *matchp = match;
 
-#define foreach_pbb_vtr_op      \
-_("disable",  L2_VTR_DISABLED)  \
-_("pop",  L2_VTR_POP_2)         \
-_("push",  L2_VTR_PUSH_2)
+      return 1;
+    }
 
+  return 0;
+}
 
 static int
-api_sw_interface_tag_add_del (vat_main_t * vam)
+api_get_node_index (vat_main_t *vam)
 {
   unformat_input_t *i = vam->input;
-  vl_api_sw_interface_tag_add_del_t *mp;
-  u32 sw_if_index = ~0;
-  u8 *tag = 0;
-  u8 enable = 1;
+  vl_api_get_node_index_t *mp;
+  u8 *name = 0;
   int ret;
 
   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (i, "tag %s", &tag))
-       ;
-      if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
-       ;
-      else if (unformat (i, "sw_if_index %d", &sw_if_index))
+      if (unformat (i, "node %s", &name))
        ;
-      else if (unformat (i, "del"))
-       enable = 0;
       else
        break;
     }
-
-  if (sw_if_index == ~0)
+  if (name == 0)
     {
-      errmsg ("missing interface name or sw_if_index");
+      errmsg ("node name required");
       return -99;
     }
-
-  if (enable && (tag == 0))
+  if (vec_len (name) >= ARRAY_LEN (mp->node_name))
     {
-      errmsg ("no tag specified");
+      errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
       return -99;
     }
 
-  /* Construct the API message */
-  M (SW_INTERFACE_TAG_ADD_DEL, mp);
-  mp->sw_if_index = ntohl (sw_if_index);
-  mp->is_add = enable;
-  if (enable)
-    strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
-  vec_free (tag);
+  M (GET_NODE_INDEX, mp);
+  clib_memcpy (mp->node_name, name, vec_len (name));
+  vec_free (name);
 
   S (mp);
   W (ret);
@@ -3916,47 +2478,48 @@ api_sw_interface_tag_add_del (vat_main_t * vam)
 }
 
 static int
-api_sw_interface_add_del_mac_address (vat_main_t * vam)
+api_get_next_index (vat_main_t *vam)
 {
   unformat_input_t *i = vam->input;
-  vl_api_mac_address_t mac = { 0 };
-  vl_api_sw_interface_add_del_mac_address_t *mp;
-  u32 sw_if_index = ~0;
-  u8 is_add = 1;
-  u8 mac_set = 0;
+  vl_api_get_next_index_t *mp;
+  u8 *node_name = 0, *next_node_name = 0;
   int ret;
 
   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
-       ;
-      else if (unformat (i, "sw_if_index %d", &sw_if_index))
+      if (unformat (i, "node-name %s", &node_name))
        ;
-      else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
-       mac_set++;
-      else if (unformat (i, "del"))
-       is_add = 0;
-      else
+      else if (unformat (i, "next-node-name %s", &next_node_name))
        break;
     }
 
-  if (sw_if_index == ~0)
+  if (node_name == 0)
+    {
+      errmsg ("node name required");
+      return -99;
+    }
+  if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
     {
-      errmsg ("missing interface name or sw_if_index");
+      errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
       return -99;
     }
 
-  if (!mac_set)
+  if (next_node_name == 0)
+    {
+      errmsg ("next node name required");
+      return -99;
+    }
+  if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
     {
-      errmsg ("missing MAC address");
+      errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
       return -99;
     }
 
-  /* Construct the API message */
-  M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
-  mp->sw_if_index = ntohl (sw_if_index);
-  mp->is_add = is_add;
-  clib_memcpy (&mp->addr, &mac, sizeof (mac));
+  M (GET_NEXT_INDEX, mp);
+  clib_memcpy (mp->node_name, node_name, vec_len (node_name));
+  clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
+  vec_free (node_name);
+  vec_free (next_node_name);
 
   S (mp);
   W (ret);
@@ -3964,131 +2527,136 @@ api_sw_interface_add_del_mac_address (vat_main_t * vam)
 }
 
 static int
-api_hw_interface_set_mtu (vat_main_t * vam)
+api_add_node_next (vat_main_t *vam)
 {
   unformat_input_t *i = vam->input;
-  vl_api_hw_interface_set_mtu_t *mp;
-  u32 sw_if_index = ~0;
-  u32 mtu = 0;
+  vl_api_add_node_next_t *mp;
+  u8 *name = 0;
+  u8 *next = 0;
   int ret;
 
   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (i, "mtu %d", &mtu))
-       ;
-      if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
+      if (unformat (i, "node %s", &name))
        ;
-      else if (unformat (i, "sw_if_index %d", &sw_if_index))
+      else if (unformat (i, "next %s", &next))
        ;
       else
        break;
     }
-
-  if (sw_if_index == ~0)
+  if (name == 0)
     {
-      errmsg ("missing interface name or sw_if_index");
+      errmsg ("node name required");
       return -99;
     }
-
-  if (mtu == 0)
+  if (vec_len (name) >= ARRAY_LEN (mp->node_name))
+    {
+      errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
+      return -99;
+    }
+  if (next == 0)
+    {
+      errmsg ("next node required");
+      return -99;
+    }
+  if (vec_len (next) >= ARRAY_LEN (mp->next_name))
     {
-      errmsg ("no mtu specified");
+      errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
       return -99;
     }
 
-  /* Construct the API message */
-  M (HW_INTERFACE_SET_MTU, mp);
-  mp->sw_if_index = ntohl (sw_if_index);
-  mp->mtu = ntohs ((u16) mtu);
+  M (ADD_NODE_NEXT, mp);
+  clib_memcpy (mp->node_name, name, vec_len (name));
+  clib_memcpy (mp->next_name, next, vec_len (next));
+  vec_free (name);
+  vec_free (next);
 
   S (mp);
   W (ret);
   return ret;
 }
 
-static void vl_api_app_namespace_add_del_reply_t_handler
-  (vl_api_app_namespace_add_del_reply_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  i32 retval = ntohl (mp->retval);
-  if (vam->async_mode)
-    {
-      vam->async_errors += (retval < 0);
-    }
-  else
-    {
-      vam->retval = retval;
-      if (retval == 0)
-       errmsg ("app ns index %d\n", ntohl (mp->appns_index));
-      vam->result_ready = 1;
-    }
-}
+#define foreach_vtr_op                                                        \
+  _ ("disable", L2_VTR_DISABLED)                                              \
+  _ ("push-1", L2_VTR_PUSH_1)                                                 \
+  _ ("push-2", L2_VTR_PUSH_2)                                                 \
+  _ ("pop-1", L2_VTR_POP_1)                                                   \
+  _ ("pop-2", L2_VTR_POP_2)                                                   \
+  _ ("translate-1-1", L2_VTR_TRANSLATE_1_1)                                   \
+  _ ("translate-1-2", L2_VTR_TRANSLATE_1_2)                                   \
+  _ ("translate-2-1", L2_VTR_TRANSLATE_2_1)                                   \
+  _ ("translate-2-2", L2_VTR_TRANSLATE_2_2)
 
-static void vl_api_app_namespace_add_del_reply_t_handler_json
-  (vl_api_app_namespace_add_del_reply_t * mp)
+static int
+api_show_version (vat_main_t *vam)
 {
-  vat_main_t *vam = &vat_main;
-  vat_json_node_t node;
-
-  vat_json_init_object (&node);
-  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
-  vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
+  vl_api_show_version_t *mp;
+  int ret;
 
-  vat_json_print (vam->ofp, &node);
-  vat_json_free (&node);
+  M (SHOW_VERSION, mp);
 
-  vam->retval = ntohl (mp->retval);
-  vam->result_ready = 1;
+  S (mp);
+  W (ret);
+  return ret;
 }
 
 static int
-api_app_namespace_add_del (vat_main_t * vam)
+api_get_first_msg_id (vat_main_t *vam)
 {
-  vl_api_app_namespace_add_del_t *mp;
+  vl_api_get_first_msg_id_t *mp;
   unformat_input_t *i = vam->input;
-  u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
-  u32 sw_if_index, ip4_fib_id, ip6_fib_id;
-  u64 secret;
+  u8 *name;
+  u8 name_set = 0;
   int ret;
 
   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (i, "id %_%v%_", &ns_id))
-       ;
-      else if (unformat (i, "secret %lu", &secret))
-       secret_set = 1;
-      else if (unformat (i, "sw_if_index %d", &sw_if_index))
-       sw_if_index_set = 1;
-      else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
-       ;
-      else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
-       ;
+      if (unformat (i, "client %s", &name))
+       name_set = 1;
       else
        break;
     }
-  if (!ns_id || !secret_set || !sw_if_index_set)
+
+  if (name_set == 0)
     {
-      errmsg ("namespace id, secret and sw_if_index must be set");
+      errmsg ("missing client name");
       return -99;
     }
-  if (vec_len (ns_id) > 64)
+  vec_add1 (name, 0);
+
+  if (vec_len (name) > 63)
     {
-      errmsg ("namespace id too long");
+      errmsg ("client name too long");
       return -99;
     }
-  M (APP_NAMESPACE_ADD_DEL, mp);
-
-  vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
-  mp->secret = clib_host_to_net_u64 (secret);
-  mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
-  mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
-  mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
-  vec_free (ns_id);
+
+  M (GET_FIRST_MSG_ID, mp);
+  clib_memcpy (mp->name, name, vec_len (name));
+  S (mp);
+  W (ret);
+  return ret;
+}
+
+static int
+api_get_node_graph (vat_main_t *vam)
+{
+  vl_api_get_node_graph_t *mp;
+  int ret;
+
+  M (GET_NODE_GRAPH, mp);
+
+  /* send it... */
   S (mp);
+  /* Wait for the reply */
   W (ret);
   return ret;
 }
 
+#define foreach_pbb_vtr_op      \
+_("disable",  L2_VTR_DISABLED)  \
+_("pop",  L2_VTR_POP_2)         \
+_("push",  L2_VTR_PUSH_2)
+
 static int
 api_sock_init_shm (vat_main_t * vam)
 {
@@ -4148,221 +2716,6 @@ api_sock_init_shm (vat_main_t * vam)
 #endif
 }
 
-static void
-vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
-{
-  vat_main_t *vam = &vat_main;
-  fib_prefix_t lcl, rmt;
-
-  ip_prefix_decode (&mp->lcl, &lcl);
-  ip_prefix_decode (&mp->rmt, &rmt);
-
-  if (lcl.fp_proto == FIB_PROTOCOL_IP4)
-    {
-      print (vam->ofp,
-            "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
-            clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
-            mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
-            clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
-            &rmt.fp_addr.ip4, rmt.fp_len,
-            clib_net_to_host_u16 (mp->rmt_port),
-            clib_net_to_host_u32 (mp->action_index), mp->tag);
-    }
-  else
-    {
-      print (vam->ofp,
-            "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
-            clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
-            mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
-            clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
-            &rmt.fp_addr.ip6, rmt.fp_len,
-            clib_net_to_host_u16 (mp->rmt_port),
-            clib_net_to_host_u32 (mp->action_index), mp->tag);
-    }
-}
-
-static void
-vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
-                                            mp)
-{
-  vat_main_t *vam = &vat_main;
-  vat_json_node_t *node = NULL;
-  struct in6_addr ip6;
-  struct in_addr ip4;
-
-  fib_prefix_t lcl, rmt;
-
-  ip_prefix_decode (&mp->lcl, &lcl);
-  ip_prefix_decode (&mp->rmt, &rmt);
-
-  if (VAT_JSON_ARRAY != vam->json_tree.type)
-    {
-      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
-      vat_json_init_array (&vam->json_tree);
-    }
-  node = vat_json_array_add (&vam->json_tree);
-  vat_json_init_object (node);
-
-  vat_json_object_add_uint (node, "appns_index",
-                           clib_net_to_host_u32 (mp->appns_index));
-  vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
-  vat_json_object_add_uint (node, "scope", mp->scope);
-  vat_json_object_add_uint (node, "action_index",
-                           clib_net_to_host_u32 (mp->action_index));
-  vat_json_object_add_uint (node, "lcl_port",
-                           clib_net_to_host_u16 (mp->lcl_port));
-  vat_json_object_add_uint (node, "rmt_port",
-                           clib_net_to_host_u16 (mp->rmt_port));
-  vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
-  vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
-  vat_json_object_add_string_copy (node, "tag", mp->tag);
-  if (lcl.fp_proto == FIB_PROTOCOL_IP4)
-    {
-      clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
-      vat_json_object_add_ip4 (node, "lcl_ip", ip4);
-      clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
-      vat_json_object_add_ip4 (node, "rmt_ip", ip4);
-    }
-  else
-    {
-      clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
-      vat_json_object_add_ip6 (node, "lcl_ip", ip6);
-      clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
-      vat_json_object_add_ip6 (node, "rmt_ip", ip6);
-    }
-}
-
-static int
-api_session_rule_add_del (vat_main_t * vam)
-{
-  vl_api_session_rule_add_del_t *mp;
-  unformat_input_t *i = vam->input;
-  u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
-  u32 appns_index = 0, scope = 0;
-  ip4_address_t lcl_ip4, rmt_ip4;
-  ip6_address_t lcl_ip6, rmt_ip6;
-  u8 is_ip4 = 1, conn_set = 0;
-  u8 is_add = 1, *tag = 0;
-  int ret;
-  fib_prefix_t lcl, rmt;
-
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "del"))
-       is_add = 0;
-      else if (unformat (i, "add"))
-       ;
-      else if (unformat (i, "proto tcp"))
-       proto = 0;
-      else if (unformat (i, "proto udp"))
-       proto = 1;
-      else if (unformat (i, "appns %d", &appns_index))
-       ;
-      else if (unformat (i, "scope %d", &scope))
-       ;
-      else if (unformat (i, "tag %_%v%_", &tag))
-       ;
-      else
-       if (unformat
-           (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
-            &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
-            &rmt_port))
-       {
-         is_ip4 = 1;
-         conn_set = 1;
-       }
-      else
-       if (unformat
-           (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
-            &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
-            &rmt_port))
-       {
-         is_ip4 = 0;
-         conn_set = 1;
-       }
-      else if (unformat (i, "action %d", &action))
-       ;
-      else
-       break;
-    }
-  if (proto == ~0 || !conn_set || action == ~0)
-    {
-      errmsg ("transport proto, connection and action must be set");
-      return -99;
-    }
-
-  if (scope > 3)
-    {
-      errmsg ("scope should be 0-3");
-      return -99;
-    }
-
-  M (SESSION_RULE_ADD_DEL, mp);
-
-  clib_memset (&lcl, 0, sizeof (lcl));
-  clib_memset (&rmt, 0, sizeof (rmt));
-  if (is_ip4)
-    {
-      ip_set (&lcl.fp_addr, &lcl_ip4, 1);
-      ip_set (&rmt.fp_addr, &rmt_ip4, 1);
-      lcl.fp_len = lcl_plen;
-      rmt.fp_len = rmt_plen;
-    }
-  else
-    {
-      ip_set (&lcl.fp_addr, &lcl_ip6, 0);
-      ip_set (&rmt.fp_addr, &rmt_ip6, 0);
-      lcl.fp_len = lcl_plen;
-      rmt.fp_len = rmt_plen;
-    }
-
-
-  ip_prefix_encode (&lcl, &mp->lcl);
-  ip_prefix_encode (&rmt, &mp->rmt);
-  mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
-  mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
-  mp->transport_proto =
-    proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
-  mp->action_index = clib_host_to_net_u32 (action);
-  mp->appns_index = clib_host_to_net_u32 (appns_index);
-  mp->scope = scope;
-  mp->is_add = is_add;
-  if (tag)
-    {
-      clib_memcpy (mp->tag, tag, vec_len (tag));
-      vec_free (tag);
-    }
-
-  S (mp);
-  W (ret);
-  return ret;
-}
-
-static int
-api_session_rules_dump (vat_main_t * vam)
-{
-  vl_api_session_rules_dump_t *mp;
-  vl_api_control_ping_t *mp_ping;
-  int ret;
-
-  if (!vam->json_output)
-    {
-      print (vam->ofp, "%=20s", "Session Rules");
-    }
-
-  M (SESSION_RULES_DUMP, mp);
-  /* send it... */
-  S (mp);
-
-  /* Use a control ping for synchronization */
-  MPING (CONTROL_PING, mp_ping);
-  S (mp_ping);
-
-  /* Wait for a reply... */
-  W (ret);
-  return ret;
-}
-
 static int
 q_or_quit (vat_main_t * vam)
 {
@@ -4867,55 +3220,17 @@ echo (vat_main_t * vam)
 
 /* List of API message constructors, CLI names map to api_xxx */
 #define foreach_vpe_api_msg                                             \
-_(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
-_(sw_interface_dump,"")                                                 \
-_(sw_interface_set_flags,                                               \
-  "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
-_(sw_interface_add_del_address,                                         \
-  "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
-_(sw_interface_set_rx_placement,                                        \
-  "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
-_(sw_interface_rx_placement_dump,                                       \
-  "[<intfc> | sw_if_index <id>]")                                         \
-_(sw_interface_set_table,                                               \
-  "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
-_(sw_interface_set_unnumbered,                                          \
-  "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
-_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
-_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
-  "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
-  "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
-  "[outer_vlan_id_any][inner_vlan_id_any]")                             \
 _(get_node_index, "node <node-name")                                    \
 _(add_node_next, "node <node-name> next <next-node-name>")              \
 _(show_version, "")                                                     \
 _(show_threads, "")                                                     \
-_(interface_name_renumber,                                              \
-  "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")             \
-_(delete_loopback,"sw_if_index <nn>")                                   \
-_(want_interface_events,  "enable|disable")                             \
 _(get_first_msg_id, "client <name>")                                   \
 _(get_node_graph, " ")                                                  \
-_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
-_(delete_subif,"<intfc> | sw_if_index <nn>")                            \
-_(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"    \
-"[disable]")                                                           \
-_(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "      \
-  "mac <mac-address> [del]")                                            \
-_(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
-_(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
 _(sock_init_shm, "size <nnn>")                                         \
-_(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
-_(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "   \
-  "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                 \
-_(session_rules_dump, "")                                              \
-
 /* List of command functions, CLI names map directly to functions */
 #define foreach_cli_function                                    \
 _(comment, "usage: comment <ignore-rest-of-line>")             \
-_(dump_interface_table, "usage: dump_interface_table")          \
-_(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
 _(dump_macro_table, "usage: dump_macro_table ")                 \
 _(dump_msg_api_table, "usage: dump_msg_api_table")             \
 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \