Implement ip_probe_neighbor API 73/11773/2
authorJohn Lo <loj@cisco.com>
Fri, 13 Apr 2018 20:46:22 +0000 (16:46 -0400)
committerNeale Ranns <nranns@cisco.com>
Mon, 16 Apr 2018 13:39:58 +0000 (13:39 +0000)
Add API support similar to VPP CLI "ip probe-neighbor" except API
call is asynch and will not wait, as the CLI does, for address
resolution of probed neighbor. The API client can use the APIs
want_ip4_arp_events or want_ip6_nd_events to get notified of the
desired address resolution event.

Change-Id: Ieab58abe75b5cc7f5185b3b91418b6362f8992d3
Signed-off-by: John Lo <loj@cisco.com>
src/vat/api_format.c
src/vnet/ip/ip.api
src/vnet/ip/ip_api.c
src/vpp/api/custom_dump.c

index 019d095..ceb074c 100644 (file)
@@ -5569,6 +5569,7 @@ _(l2_interface_efp_filter_reply)                        \
 _(l2_interface_vlan_tag_rewrite_reply)                  \
 _(modify_vhost_user_if_reply)                           \
 _(delete_vhost_user_if_reply)                           \
+_(ip_probe_neighbor_reply)                              \
 _(want_ip4_arp_events_reply)                            \
 _(want_ip6_nd_events_reply)                             \
 _(want_l2_macs_events_reply)                            \
@@ -5811,9 +5812,10 @@ _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
 _(SHOW_VERSION_REPLY, show_version_reply)                               \
 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                          \
-_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)          \
+_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)      \
 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)                \
+_(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                    \
 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                        \
 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                  \
@@ -14462,6 +14464,58 @@ api_interface_name_renumber (vat_main_t * vam)
   return ret;
 }
 
+static int
+api_ip_probe_neighbor (vat_main_t * vam)
+{
+  unformat_input_t *i = vam->input;
+  vl_api_ip_probe_neighbor_t *mp;
+  u8 int_set = 0;
+  u8 adr_set = 0;
+  u8 is_ipv6 = 0;
+  u8 dst_adr[16];
+  u32 sw_if_index;
+  int ret;
+
+  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
+       int_set = 1;
+      else if (unformat (i, "sw_if_index %d", &sw_if_index))
+       int_set = 1;
+      else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
+       adr_set = 1;
+      else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
+       {
+         adr_set = 1;
+         is_ipv6 = 1;
+       }
+      else
+       break;
+    }
+
+  if (int_set == 0)
+    {
+      errmsg ("missing interface");
+      return -99;
+    }
+
+  if (adr_set == 0)
+    {
+      errmsg ("missing addresses");
+      return -99;
+    }
+
+  M (IP_PROBE_NEIGHBOR, mp);
+
+  mp->sw_if_index = ntohl (sw_if_index);
+  mp->is_ipv6 = is_ipv6;
+  clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
+
+  S (mp);
+  W (ret);
+  return ret;
+}
+
 static int
 api_want_ip4_arp_events (vat_main_t * vam)
 {
@@ -23403,6 +23457,7 @@ _(interface_name_renumber,                                              \
 _(input_acl_set_interface,                                              \
   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
   "  [l2-table <nn>] [del]")                                            \
+_(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
index 2ca2f56..3802492 100644 (file)
@@ -19,7 +19,7 @@
     called through a shared memory interface. 
 */
 
-option version = "1.2.0";
+option version = "1.2.2";
 import "vnet/fib/fib_types.api";
 
 /** \brief Add / del table request
@@ -650,12 +650,31 @@ autoreply define ip_source_and_port_range_check_interface_add_del
   u32 udp_out_vrf_id;
 };
 
-/** \brief Register for ip4 arp resolution events
+/** \brief IP probe neighbor address on an interface by sending an
+           ARP request (for IP4) or ICMP6 Neighbor Solicitation (for IP6)
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+    @param sw_if_index - interface index
+    @param dst_address - target IP address to send IP addr resolution request
+    @param is_ipv6 - [1|0] to indicate if address family is IPv[6|4]
+*/
+autoreply define ip_probe_neighbor
+{
+  u32 client_index;
+  u32 context;
+  u32 sw_if_index;
+  u8 dst_address[16];
+  u8 is_ipv6;
+};
+
+/** \brief Register for IP4 ARP resolution event on receing ARP reply or
+           MAC/IP info from ARP requests in L2 BDs
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
     @param enable_disable - 1 => register for events, 0 => cancel registration
     @param pid - sender's pid
-    @param address - the exact ip4 address of interest
+    @param address - exact IP4 address of interested arp resolution event, or
+                     0 to get MAC/IP info from ARP requests in BDs
 */
 autoreply define want_ip4_arp_events
 {
@@ -666,13 +685,14 @@ autoreply define want_ip4_arp_events
   u32 address;
 };
 
-/** \brief Tell client about an ip4 arp resolution event
+/** \brief Tell client about an IP4 ARP resolution event or
+           MAC/IP info from ARP requests in L2 BDs
     @param client_index - opaque cookie to identify the sender
     @param address - the exact ip4 address of interest
     @param pid - client pid registered to receive notification
     @param sw_if_index - interface which received ARP packet
     @param new_mac - the new mac address 
-    @param mac_ip - 0: resolution event, 1: mac/ip binding in bd
+    @param mac_ip - 0: ARP resolution event, 1: MAC/IP info from L2 BDs
 */
 define ip4_arp_event
 {
@@ -689,12 +709,14 @@ service {
     events ip4_arp_event;
 };
 
-/** \brief Register for ip6 nd resolution events
+/** \brief Register for IP6 ND resolution event on recieving NA reply
+           MAC/IP info from ICMP6 Neighbor Solicitation in L2 BDs
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
     @param enable_disable - 1 => register for events, 0 => cancel registration
     @param pid - sender's pid
-    @param address - the exact ip6 address of interest
+    @param address - the exact IP6 address of interested ND resolution event, or
+                     0 to get MAC/IP info from ICMP6 NS in L2 BDs.
 */
 autoreply define want_ip6_nd_events
 {
@@ -705,13 +727,14 @@ autoreply define want_ip6_nd_events
   u8 address[16];
 };
 
-/** \brief Tell client about an ip6 nd resolution or mac/ip event
+/** \brief Tell client about an IP6 ND resolution or
+           MAC/IP info from ICMP6 Neighbor Solicitation in L2 BDs.
     @param client_index - opaque cookie to identify the sender
     @param pid - client pid registered to receive notification
     @param sw_if_index - interface which received ARP packet
     @param address - the exact ip6 address of interest
     @param new_mac - the new mac address 
-    @param mac_ip - 0: resolution event, 1: mac/ip binding in bd
+    @param mac_ip - 0: ND resolution event, 1: MAC/IP info from L2 BDs
 */
 define ip6_nd_event
 {
index 0b0a7a9..69ff719 100644 (file)
@@ -76,6 +76,7 @@ _(IP_ADDRESS_DUMP, ip_address_dump)                                     \
 _(IP_DUMP, ip_dump)                                                     \
 _(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del)                             \
 _(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit)                      \
+_(IP_PROBE_NEIGHBOR, ip_probe_neighbor)                                \
 _(WANT_IP4_ARP_EVENTS, want_ip4_arp_events)                             \
 _(WANT_IP6_ND_EVENTS, want_ip6_nd_events)                               \
 _(WANT_IP6_RA_EVENTS, want_ip6_ra_events)                               \
@@ -2684,6 +2685,36 @@ static void
   REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
 }
 
+static void
+vl_api_ip_probe_neighbor_t_handler (vl_api_ip_probe_neighbor_t * mp)
+{
+  int rv = 0;
+  vlib_main_t *vm = vlib_get_main ();
+  vl_api_ip_probe_neighbor_reply_t *rmp;
+  clib_error_t *error;
+
+  VALIDATE_SW_IF_INDEX (mp);
+
+  u32 sw_if_index = ntohl (mp->sw_if_index);
+
+  if (mp->is_ipv6)
+    error = ip6_probe_neighbor (vm, (ip6_address_t *) mp->dst_address,
+                               sw_if_index);
+  else
+    error = ip4_probe_neighbor (vm, (ip4_address_t *) mp->dst_address,
+                               sw_if_index);
+
+  if (error)
+    {
+      clib_error_report (error);
+      rv = clib_error_get_code (error);
+    }
+
+  BAD_SW_IF_INDEX_LABEL;
+
+  REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
+}
+
 static int
 ip4_reset_fib_t_handler (vl_api_reset_fib_t * mp)
 {
index ded6e7d..9989bdc 100644 (file)
@@ -1996,6 +1996,21 @@ static void *vl_api_interface_name_renumber_t_print
   FINISH;
 }
 
+static void *vl_api_ip_probe_neighbor_t_print
+  (vl_api_ip_probe_neighbor_t * mp, void *handle)
+{
+  u8 *s;
+
+  s = format (0, "SCRIPT: ip_probe_neighbor ");
+  s = format (s, "sw_if_index %d ", ntohl (mp->sw_if_index));
+  if (mp->is_ipv6)
+    s = format (s, "address %U ", format_ip6_address, &mp->dst_address);
+  else
+    s = format (s, "address %U ", format_ip4_address, &mp->dst_address);
+
+  FINISH;
+}
+
 static void *vl_api_want_ip4_arp_events_t_print
   (vl_api_want_ip4_arp_events_t * mp, void *handle)
 {
@@ -3515,6 +3530,7 @@ _(L2_FIB_TABLE_DUMP, l2_fib_table_dump)                                 \
 _(VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel)                  \
 _(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump)                         \
 _(INTERFACE_NAME_RENUMBER, interface_name_renumber)                    \
+_(IP_PROBE_NEIGHBOR, ip_probe_neighbor)                                 \
 _(WANT_IP4_ARP_EVENTS, want_ip4_arp_events)                             \
 _(WANT_IP6_ND_EVENTS, want_ip6_nd_events)                               \
 _(WANT_L2_MACS_EVENTS, want_l2_macs_events)                             \