api: missing support for dumping of neighbours (VPP-333)
[vpp.git] / vnet / vnet / ip / ip6_neighbor.c
index 5585c95..92417a4 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <vnet/ip/ip.h>
+#include <vnet/ip/ip6_neighbor.h>
 #include <vnet/ethernet/ethernet.h>
 #include <vppinfra/mhash.h>
 #include <vppinfra/md5.h>
 #include <vnet/fib/fib_table.h>
 #include <vnet/fib/ip6_fib.h>
 
-#if DPDK==1
-#include <vnet/devices/dpdk/dpdk.h>
-#endif
-
 /**
  * @file
  * @brief IPv6 Neighbor Adjacency and Neighbor Discovery.
  * adjacency tables and neighbor discovery logic.
  */
 
-typedef struct {
-  ip6_address_t ip6_address;
-  u32 sw_if_index;
-  u32 pad;
-} ip6_neighbor_key_t;
-
-/* can't use sizeof link_layer_address, that's 8 */ 
+/* can't use sizeof link_layer_address, that's 8 */
 #define ETHER_MAC_ADDR_LEN 6
 
-typedef struct {
-  ip6_neighbor_key_t key;
-  u8 link_layer_address[8];
-  u16 flags;
-#define IP6_NEIGHBOR_FLAG_STATIC (1 << 0)
-#define IP6_NEIGHBOR_FLAG_DYNAMIC  (2 << 0)
-  u64 cpu_time_last_updated;
-  fib_node_index_t fib_entry_index;
-} ip6_neighbor_t;
-
-/* advertised prefix option */ 
+/* advertised prefix option */
 typedef struct {
   /* basic advertised information */
   ip6_address_t prefix;
@@ -317,7 +298,6 @@ typedef struct {
   ip6_address_t addr;
 } ip6_neighbor_set_unset_rpc_args_t;
 
-#if DPDK > 0
 static void ip6_neighbor_set_unset_rpc_callback 
 ( ip6_neighbor_set_unset_rpc_args_t * a);
 
@@ -340,7 +320,6 @@ static void set_unset_ip6_neighbor_rpc
   vl_api_rpc_call_main_thread (ip6_neighbor_set_unset_rpc_callback,
                                (u8 *) &args, sizeof (args));
 }
-#endif
 
 static void
 ip6_nbr_probe (ip_adjacency_t *adj)
@@ -538,14 +517,12 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
   u32 next_index;
   pending_resolution_t * pr, * mc;
 
-#if DPDK > 0
   if (os_get_cpu_number())
     {
       set_unset_ip6_neighbor_rpc (vm, sw_if_index, a, link_layer_address,
                                   1 /* set new neighbor */, is_static);
       return 0;
     }
-#endif
 
   k.sw_if_index = sw_if_index;
   k.ip6_address = a[0];
@@ -594,7 +571,7 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
                                        n->key.sw_if_index,
                                        ~0,
                                        1,
-                                       MPLS_LABEL_INVALID,
+                                       NULL, // no label stack
                                        FIB_ROUTE_PATH_FLAG_NONE);
   }
   else
@@ -687,14 +664,12 @@ vnet_unset_ip6_ethernet_neighbor (vlib_main_t * vm,
   uword * p;
   int rv = 0;
 
-#if DPDK > 0
   if (os_get_cpu_number())
     {
       set_unset_ip6_neighbor_rpc (vm, sw_if_index, a, link_layer_address,
                                   0 /* unset */, 0);
       return 0;
     }
-#endif
 
   k.sw_if_index = sw_if_index;
   k.ip6_address = a[0];
@@ -722,7 +697,6 @@ vnet_unset_ip6_ethernet_neighbor (vlib_main_t * vm,
   return rv;
 }
 
-#if DPDK > 0
 static void ip6_neighbor_set_unset_rpc_callback 
 ( ip6_neighbor_set_unset_rpc_args_t * a)
 {
@@ -734,7 +708,6 @@ static void ip6_neighbor_set_unset_rpc_callback
     vnet_unset_ip6_ethernet_neighbor (vm, a->sw_if_index, &a->addr, 
                                       a->link_layer_address, 6);
 }
-#endif
 
 static int
 ip6_neighbor_sort (void *a1, void *a2)
@@ -749,13 +722,31 @@ ip6_neighbor_sort (void *a1, void *a2)
   return cmp;
 }
 
+ip6_neighbor_t *
+ip6_neighbors_entries (u32 sw_if_index)
+{
+  ip6_neighbor_main_t * nm = &ip6_neighbor_main;
+  ip6_neighbor_t *n, *ns = 0;
+
+  /* *INDENT-OFF* */
+  pool_foreach (n, nm->neighbor_pool, ({
+    if (sw_if_index != ~0 && n->key.sw_if_index != sw_if_index)
+      continue;
+    vec_add1 (ns, n[0]);
+  }));
+  /* *INDENT-ON* */
+
+  if (ns)
+    vec_sort_with_function (ns, ip6_neighbor_sort);
+  return ns;
+}
+
 static clib_error_t *
 show_ip6_neighbors (vlib_main_t * vm,
                    unformat_input_t * input,
                    vlib_cli_command_t * cmd)
 {
   vnet_main_t * vnm = vnet_get_main();
-  ip6_neighbor_main_t * nm = &ip6_neighbor_main;
   ip6_neighbor_t * n, * ns;
   clib_error_t * error = 0;
   u32 sw_if_index;
@@ -764,15 +755,11 @@ show_ip6_neighbors (vlib_main_t * vm,
   sw_if_index = ~0;
   (void) unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index);
 
-  ns = 0;
-  pool_foreach (n, nm->neighbor_pool, ({ vec_add1 (ns, n[0]); }));
+  ns = ip6_neighbors_entries (sw_if_index);
   if (ns)
     {
-      vec_sort_with_function (ns, ip6_neighbor_sort);
       vlib_cli_output (vm, "%U", format_ip6_neighbor_ip6_entry, vm, 0);
       vec_foreach (n, ns) {
-        if (sw_if_index != ~0 && n->key.sw_if_index != sw_if_index)
-          continue;
         vlib_cli_output (vm, "%U", format_ip6_neighbor_ip6_entry, vm, n);
       }
       vec_free (ns);
@@ -1481,9 +1468,10 @@ icmp6_router_solicitation(vlib_main_t * vm,
                                    : error0);
                               next0 = is_dropped ? 
                                   next0 : ICMP6_ROUTER_SOLICITATION_NEXT_REPLY_RW;
-                              vnet_buffer (p0)->ip.adj_index[VLIB_RX] = adj_index0;
+                              vnet_buffer (p0)->ip.adj_index[VLIB_TX] = adj_index0;
                            }
                         }
+                      p0->flags |= VNET_BUFFER_LOCALLY_ORIGINATED;
                      
                      radv_info->n_solicitations_dropped  += is_dropped;
                      radv_info->n_solicitations_rcvd  += is_solicitation;
@@ -1849,7 +1837,6 @@ ip6_neighbor_sw_interface_add_del (vnet_main_t * vnm,
          pool_put (nm->if_radv_pool,  a);
          nm->if_radv_pool_index_by_sw_if_index[sw_if_index] = ~0;
          ri = ~0;
-         ip6_sw_interface_enable_disable(sw_if_index, 0);
        }
     }
  else
@@ -1858,7 +1845,6 @@ ip6_neighbor_sw_interface_add_del (vnet_main_t * vnm,
        {
         vnet_hw_interface_t * hw_if0;
      
-        ip6_sw_interface_enable_disable(sw_if_index, 1);
         hw_if0 = vnet_get_sup_hw_interface (vnm, sw_if_index);
         
         pool_get (nm->if_radv_pool, a);
@@ -1881,11 +1867,10 @@ ip6_neighbor_sw_interface_add_del (vnet_main_t * vnm,
         a->min_delay_between_radv = MIN_DELAY_BETWEEN_RAS;
         a->max_delay_between_radv = MAX_DELAY_BETWEEN_RAS;
         a->max_rtr_default_lifetime = MAX_DEF_RTR_LIFETIME;
-        a->seed = random_default_seed();
-        
-        /* for generating random interface ids */
-        a->randomizer = 0x1119194911191949ULL;
-        a->randomizer = random_u64 ((u32 *)&a->randomizer);
+        a->seed = (u32) clib_cpu_time_now();
+         (void) random_u32 (&a->seed);
+         a->randomizer = clib_cpu_time_now();
+        (void) random_u64 (&a->randomizer);
         
         a->initial_adverts_count = MAX_INITIAL_RTR_ADVERTISEMENTS ; 
         a->initial_adverts_sent = a->initial_adverts_count-1;
@@ -2145,15 +2130,16 @@ ip6_neighbor_send_mldpv2_report(u32 sw_if_index)
 
   /* 
    * OK to override w/ no regard for actual FIB, because
-   * ip6-rewrite-local only looks at the adjacency.
+   * ip6-rewrite only looks at the adjacency.
    */
   vnet_buffer (b0)->sw_if_index[VLIB_RX] = 
     vnet_main.local_interface_sw_if_index;
   
-  vnet_buffer (b0)->ip.adj_index[VLIB_RX]  = 
+  vnet_buffer (b0)->ip.adj_index[VLIB_TX]  = 
     radv_info->all_mldv2_routers_adj_index;
+  b0->flags |= VNET_BUFFER_LOCALLY_ORIGINATED;
 
-  vlib_node_t * node = vlib_get_node_by_name (vm, (u8 *) "ip6-rewrite-local");
+  vlib_node_t * node = vlib_get_node_by_name (vm, (u8 *) "ip6-rewrite");
   
   f = vlib_get_frame_to_node (vm, node->index);
   to_next = vlib_frame_vector_args (f);
@@ -2175,7 +2161,7 @@ VLIB_REGISTER_NODE (ip6_icmp_router_solicitation_node,static) = {
   .n_next_nodes = ICMP6_ROUTER_SOLICITATION_N_NEXT,
   .next_nodes = {
     [ICMP6_ROUTER_SOLICITATION_NEXT_DROP] = "error-drop",
-    [ICMP6_ROUTER_SOLICITATION_NEXT_REPLY_RW] = "ip6-rewrite-local",
+    [ICMP6_ROUTER_SOLICITATION_NEXT_REPLY_RW] = "ip6-rewrite",
     [ICMP6_ROUTER_SOLICITATION_NEXT_REPLY_TX] = "interface-output",
   },
 };