IP unnumbered dump
[vpp.git] / src / vnet / ip / ip_api.c
index b4d942b..ce3ff79 100644 (file)
@@ -25,6 +25,7 @@
 #include <vnet/api_errno.h>
 #include <vnet/ethernet/ethernet.h>
 #include <vnet/ip/ip.h>
+#include <vnet/ip/ip_neighbor.h>
 #include <vnet/ip/ip6_neighbor.h>
 #include <vnet/fib/fib_table.h>
 #include <vnet/fib/fib_api.h>
@@ -73,10 +74,12 @@ _(IP_NEIGHBOR_DUMP, ip_neighbor_dump)                                   \
 _(IP_MROUTE_ADD_DEL, ip_mroute_add_del)                                 \
 _(MFIB_SIGNAL_DUMP, mfib_signal_dump)                                   \
 _(IP_ADDRESS_DUMP, ip_address_dump)                                     \
+_(IP_UNNUMBERED_DUMP, ip_unnumbered_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)                                \
+_(IP_SCAN_NEIGHBOR_ENABLE_DISABLE, ip_scan_neighbor_enable_disable)     \
 _(WANT_IP4_ARP_EVENTS, want_ip4_arp_events)                             \
 _(WANT_IP6_ND_EVENTS, want_ip6_nd_events)                               \
 _(WANT_IP6_RA_EVENTS, want_ip6_ra_events)                               \
@@ -1393,8 +1396,11 @@ vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp)
   if (mp->is_ipv6)
     {
       /* *INDENT-OFF* */
-      foreach_ip_interface_address (lm6, ia, sw_if_index,
-                                    1 /* honor unnumbered */,
+      /* Do not send subnet details of the IP-interface for
+       * unnumbered interfaces. otherwise listening clients
+       * will be confused that the subnet is applied on more
+       * than one interface */
+      foreach_ip_interface_address (lm6, ia, sw_if_index, 0,
       ({
         r6 = ip_interface_address_get_address (lm6, ia);
         u16 prefix_length = ia->address_length;
@@ -1406,8 +1412,7 @@ vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp)
   else
     {
       /* *INDENT-OFF* */
-      foreach_ip_interface_address (lm4, ia, sw_if_index,
-                                    1 /* honor unnumbered */,
+      foreach_ip_interface_address (lm4, ia, sw_if_index, 0,
       ({
         r4 = ip_interface_address_get_address (lm4, ia);
         u16 prefix_length = ia->address_length;
@@ -1419,6 +1424,74 @@ vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp)
   BAD_SW_IF_INDEX_LABEL;
 }
 
+static void
+send_ip_unnumbered_details (vpe_api_main_t * am,
+                           vl_api_registration_t * reg,
+                           u32 sw_if_index, u32 ip_sw_if_index, u32 context)
+{
+  vl_api_ip_unnumbered_details_t *mp;
+
+  mp = vl_msg_api_alloc (sizeof (*mp));
+  memset (mp, 0, sizeof (*mp));
+  mp->_vl_msg_id = ntohs (VL_API_IP_UNNUMBERED_DETAILS);
+
+  mp->context = context;
+  mp->sw_if_index = htonl (sw_if_index);
+  mp->ip_sw_if_index = htonl (ip_sw_if_index);
+
+  vl_api_send_msg (reg, (u8 *) mp);
+}
+
+static void
+vl_api_ip_unnumbered_dump_t_handler (vl_api_ip_unnumbered_dump_t * mp)
+{
+  vnet_main_t *vnm = vnet_get_main ();
+  vnet_interface_main_t *im = &vnm->interface_main;
+  int rv __attribute__ ((unused)) = 0;
+  vpe_api_main_t *am = &vpe_api_main;
+  vl_api_registration_t *reg;
+  vnet_sw_interface_t *si;
+  u32 sw_if_index;
+
+  sw_if_index = ntohl (mp->sw_if_index);
+
+  reg = vl_api_client_index_to_registration (mp->client_index);
+  if (!reg)
+    return;
+
+  if (~0 != sw_if_index)
+    {
+      VALIDATE_SW_IF_INDEX (mp);
+
+      si = vnet_get_sw_interface (vnm, ntohl (mp->sw_if_index));
+
+      if (!(si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
+       {
+         send_ip_unnumbered_details (am, reg,
+                                     sw_if_index,
+                                     si->unnumbered_sw_if_index,
+                                     mp->context);
+       }
+    }
+  else
+    {
+      /* *INDENT-OFF* */
+      pool_foreach (si, im->sw_interfaces,
+      ({
+        if ((si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
+          {
+            send_ip_unnumbered_details(am, reg,
+                                       si->sw_if_index,
+                                       si->unnumbered_sw_if_index,
+                                       mp->context);
+          }
+      }));
+      /* *INDENT-ON* */
+    }
+
+  BAD_SW_IF_INDEX_LABEL;
+}
+
 static void
 vl_api_ip_dump_t_handler (vl_api_ip_dump_t * mp)
 {
@@ -2323,6 +2396,10 @@ wc_arp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
          ra_report_t *ra_events = event_data;
          for (i = 0; i < vec_len (ra_events); i++)
            {
+             ip6_neighbor_public_main_t *npm = &ip6_neighbor_public_main;
+             call_ip6_neighbor_callbacks (&ra_events[i],
+                                          npm->ra_report_functions);
+
              vpe_client_registration_t *reg;
               /* *INDENT-OFF* */
               pool_foreach(reg, vpe_api_main.ip6_ra_events_registrations,
@@ -2612,8 +2689,6 @@ vl_api_want_ip6_ra_events_t_handler (vl_api_want_ip6_ra_events_t * mp)
          rp = pool_elt_at_index (am->ip6_ra_events_registrations, p[0]);
          pool_put (am->ip6_ra_events_registrations, rp);
          hash_unset (am->ip6_ra_events_registration_hash, mp->client_index);
-         if (pool_elts (am->ip6_ra_events_registrations) == 0)
-           ra_set_publisher_node (~0, REPORT_MAX);
          goto reply;
        }
     }
@@ -2628,7 +2703,6 @@ vl_api_want_ip6_ra_events_t_handler (vl_api_want_ip6_ra_events_t * mp)
   rp->client_pid = ntohl (mp->pid);
   hash_set (am->ip6_ra_events_registration_hash, rp->client_index,
            rp - am->ip6_ra_events_registrations);
-  ra_set_publisher_node (wc_arp_process_node.index, RA_REPORT);
 
 reply:
   REPLY_MACRO (VL_API_WANT_IP6_RA_EVENTS_REPLY);
@@ -2722,6 +2796,25 @@ vl_api_ip_probe_neighbor_t_handler (vl_api_ip_probe_neighbor_t * mp)
   REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
 }
 
+static void
+  vl_api_ip_scan_neighbor_enable_disable_t_handler
+  (vl_api_ip_scan_neighbor_enable_disable_t * mp)
+{
+  int rv = 0;
+  vl_api_ip_scan_neighbor_enable_disable_reply_t *rmp;
+  ip_neighbor_scan_arg_t arg;
+
+  arg.mode = mp->mode;
+  arg.scan_interval = mp->scan_interval;
+  arg.max_proc_time = mp->max_proc_time;
+  arg.max_update = mp->max_update;
+  arg.scan_int_delay = mp->scan_int_delay;
+  arg.stale_threshold = mp->stale_threshold;
+  ip_neighbor_scan_enable_disable (&arg);
+
+  REPLY_MACRO (VL_API_IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY);
+}
+
 static int
 ip4_reset_fib_t_handler (vl_api_reset_fib_t * mp)
 {
@@ -2993,6 +3086,8 @@ ip_api_hookup (vlib_main_t * vm)
    */
   setup_message_id_table (am);
 
+  ra_set_publisher_node (wc_arp_process_node.index, RA_REPORT);
+
   return 0;
 }