ip-neighbor: Use ip_address_t rather than ip46_address_t 03/28903/3
authorNeale Ranns <nranns@cisco.com>
Thu, 20 Aug 2020 08:22:56 +0000 (08:22 +0000)
committerOle Tr�an <otroan@employees.org>
Fri, 20 Nov 2020 10:27:01 +0000 (10:27 +0000)
Type: improvement

Change-Id: Ica5f395075677bda5f38d28e704f65350af88610
Signed-off-by: Neale Ranns <nranns@cisco.com>
20 files changed:
src/plugins/gbp/gbp_endpoint.c
src/plugins/mactime/builtins.c
src/plugins/mactime/mactime.c
src/vnet/arp/arp.c
src/vnet/bonding/device.c
src/vnet/ip-neighbor/ip_neighbor.c
src/vnet/ip-neighbor/ip_neighbor.h
src/vnet/ip-neighbor/ip_neighbor_api.c
src/vnet/ip-neighbor/ip_neighbor_types.c
src/vnet/ip-neighbor/ip_neighbor_types.h
src/vnet/ip-neighbor/ip_neighbor_watch.c
src/vnet/ip-neighbor/ip_neighbor_watch.h
src/vnet/ip/ip6_forward.c
src/vnet/ip/ip_types.c
src/vnet/ip/ip_types.h
src/vnet/ip6-nd/ip6_nd.c
src/vnet/ip6-nd/ip6_nd_proxy.c
src/vnet/ip6-nd/ip6_ra.c
test/test_neighbor.py
test/test_p2p_ethernet.py

index e1a810c..9cc69d0 100644 (file)
@@ -30,6 +30,8 @@
 #include <vnet/l2/l2_fib.h>
 #include <vnet/fib/fib_table.h>
 #include <vnet/ip-neighbor/ip_neighbor.h>
+#include <vnet/ip-neighbor/ip4_neighbor.h>
+#include <vnet/ip-neighbor/ip6_neighbor.h>
 #include <vnet/fib/fib_walk.h>
 #include <vnet/vxlan-gbp/vxlan_gbp.h>
 
@@ -768,11 +770,16 @@ gbb_endpoint_fwd_recalc (gbp_endpoint_t * ge)
          {
            gbp_endpoint_add_itf (gbp_itf_get_sw_if_index (gef->gef_itf),
                                  gei);
-           ip_neighbor_advertise (vlib_get_main (),
-                                  (FIB_PROTOCOL_IP4 == pfx->fp_proto ?
-                                   IP46_TYPE_IP4 :
-                                   IP46_TYPE_IP6),
-                                  &pfx->fp_addr, gg->gg_uplink_sw_if_index);
+           if (FIB_PROTOCOL_IP4 == pfx->fp_proto)
+             ip4_neighbor_advertise (vlib_get_main (),
+                                     vnet_get_main (),
+                                     gg->gg_uplink_sw_if_index,
+                                     &pfx->fp_addr.ip4);
+           else
+             ip6_neighbor_advertise (vlib_get_main (),
+                                     vnet_get_main (),
+                                     gg->gg_uplink_sw_if_index,
+                                     &pfx->fp_addr.ip6);
          }
       }
   }
index e90ac66..1525ab6 100644 (file)
@@ -35,7 +35,7 @@ handle_get_mactime (http_builtin_method_type_t reqtype,
 
   /* Walk all ip4 neighbours on all interfaces */
   vec_reset_length (mm->arp_cache_copy);
-  ip_neighbor_walk (IP46_TYPE_IP4, ~0, mactime_ip_neighbor_copy, mm);
+  ip_neighbor_walk (AF_IP4, ~0, mactime_ip_neighbor_copy, mm);
 
   now = clib_timebase_now (&mm->timebase);
 
index d418534..66df70b 100644 (file)
@@ -561,7 +561,7 @@ show_mactime_command_fn (vlib_main_t * vm,
 
   vec_reset_length (mm->arp_cache_copy);
   /* Walk all ip4 neighbours on all interfaces */
-  ip_neighbor_walk (IP46_TYPE_IP4, ~0, mactime_ip_neighbor_copy, mm);
+  ip_neighbor_walk (AF_IP4, ~0, mactime_ip_neighbor_copy, mm);
 
   now = clib_timebase_now (&mm->timebase);
 
index e02f3d8..299ed97 100644 (file)
@@ -189,12 +189,16 @@ always_inline u32
 arp_learn (u32 sw_if_index,
           const ethernet_arp_ip4_over_ethernet_address_t * addr)
 {
+  /* *INDENT-OFF* */
   ip_neighbor_learn_t l = {
-    .ip.ip4 = addr->ip4,
-    .type = IP46_TYPE_IP4,
+    .ip = {
+      .ip.ip4 = addr->ip4,
+      .version = AF_IP4,
+    },
     .mac = addr->mac,
     .sw_if_index = sw_if_index,
   };
+  /* *INDENT-ON* */
 
   ip_neighbor_learn_dp (&l);
 
@@ -906,7 +910,7 @@ ethernet_arp_init (vlib_main_t * vm)
     vec_add1 (im->enable_disable_interface_callbacks, cb);
   }
 
-  ip_neighbor_register (IP46_TYPE_IP4, &arp_vft);
+  ip_neighbor_register (AF_IP4, &arp_vft);
 
   return 0;
 }
index 7ce5ad8..e14d08a 100644 (file)
@@ -25,6 +25,8 @@
 #include <vppinfra/lb_hash_hash.h>
 #include <vnet/ip/ip.h>
 #include <vnet/ip-neighbor/ip_neighbor.h>
+#include <vnet/ip-neighbor/ip4_neighbor.h>
+#include <vnet/ip-neighbor/ip6_neighbor.h>
 
 #define foreach_bond_tx_error     \
   _(NONE, "no error")             \
@@ -801,7 +803,8 @@ bond_active_interface_switch_cb (vnet_main_t * vnm, u32 sw_if_index,
 {
   bond_main_t *bm = &bond_main;
 
-  ip_neighbor_advertise (bm->vlib_main, IP46_TYPE_BOTH, NULL, sw_if_index);
+  ip4_neighbor_advertise (bm->vlib_main, bm->vnet_main, sw_if_index, NULL);
+  ip6_neighbor_advertise (bm->vlib_main, bm->vnet_main, sw_if_index, NULL);
 
   return (WALK_CONTINUE);
 }
index 4111b02..12ce0d6 100644 (file)
@@ -30,7 +30,7 @@
 static ip_neighbor_t *ip_neighbor_pool;
 
 /** protocol specific lists of time sorted neighbors */
-index_t ip_neighbor_list_head[IP46_N_TYPES];
+index_t ip_neighbor_list_head[N_AF];
 
 typedef struct ip_neighbor_elt_t_
 {
@@ -62,14 +62,14 @@ static vlib_log_class_t ipn_logger;
 
 /* DBs of neighbours one per AF */
 /* *INDENT-OFF* */
-static ip_neighbor_db_t ip_neighbor_db[IP46_N_TYPES] = {
-  [IP46_TYPE_IP4] = {
+static ip_neighbor_db_t ip_neighbor_db[N_AF] = {
+  [AF_IP4] = {
     .ipndb_limit = 50000,
     /* Default to not aging and not recycling */
     .ipndb_age = 0,
     .ipndb_recycle = false,
   },
-  [IP46_TYPE_IP6] = {
+  [AF_IP6] = {
     .ipndb_limit = 50000,
     /* Default to not aging and not recycling */
     .ipndb_age = 0,
@@ -111,12 +111,18 @@ ip_neighbor_is_dynamic (const ip_neighbor_t * ipn)
   return (ipn->ipn_flags & IP_NEIGHBOR_FLAG_DYNAMIC);
 }
 
-const ip46_address_t *
+const ip_address_t *
 ip_neighbor_get_ip (const ip_neighbor_t * ipn)
 {
   return (&ipn->ipn_key->ipnk_ip);
 }
 
+ip_address_family_t
+ip_neighbor_get_af (const ip_neighbor_t * ipn)
+{
+  return (ip_addr_version (&ipn->ipn_key->ipnk_ip));
+}
+
 const mac_address_t *
 ip_neighbor_get_mac (const ip_neighbor_t * ipn)
 {
@@ -170,8 +176,8 @@ ip_neighbor_refresh (ip_neighbor_t * ipn)
          clib_llist_remove (ip_neighbor_elt_pool, ipne_anchor, elt);
        }
       head = pool_elt_at_index (ip_neighbor_elt_pool,
-                               ip_neighbor_list_head[ipn->
-                                                     ipn_key->ipnk_type]);
+                               ip_neighbor_list_head[ip_neighbor_get_af
+                                                     (ipn)]);
 
       elt->ipne_index = ip_neighbor_get_index (ipn);
       clib_llist_add (ip_neighbor_elt_pool, ipne_anchor, elt, head);
@@ -182,46 +188,53 @@ ip_neighbor_refresh (ip_neighbor_t * ipn)
 static void
 ip_neighbor_db_add (const ip_neighbor_t * ipn)
 {
-  vec_validate (ip_neighbor_db[ipn->ipn_key->ipnk_type].ipndb_hash,
-               ipn->ipn_key->ipnk_sw_if_index);
+  ip_address_family_t af;
+  u32 sw_if_index;
+
+  af = ip_neighbor_get_af (ipn);
+  sw_if_index = ipn->ipn_key->ipnk_sw_if_index;
 
-  if (!ip_neighbor_db[ipn->ipn_key->ipnk_type].ipndb_hash
-      [ipn->ipn_key->ipnk_sw_if_index])
-    ip_neighbor_db[ipn->ipn_key->ipnk_type].ipndb_hash[ipn->
-                                                      ipn_key->ipnk_sw_if_index]
+  vec_validate (ip_neighbor_db[af].ipndb_hash, sw_if_index);
+
+  if (!ip_neighbor_db[af].ipndb_hash[sw_if_index])
+    ip_neighbor_db[af].ipndb_hash[sw_if_index]
       = hash_create_mem (0, sizeof (ip_neighbor_key_t), sizeof (index_t));
 
-  hash_set_mem (ip_neighbor_db[ipn->ipn_key->ipnk_type].ipndb_hash
-               [ipn->ipn_key->ipnk_sw_if_index], ipn->ipn_key,
-               ip_neighbor_get_index (ipn));
+  hash_set_mem (ip_neighbor_db[af].ipndb_hash[sw_if_index],
+               ipn->ipn_key, ip_neighbor_get_index (ipn));
 
-  ip_neighbor_db[ipn->ipn_key->ipnk_type].ipndb_n_elts++;
+  ip_neighbor_db[af].ipndb_n_elts++;
 }
 
 static void
-ip_neighbor_db_remove (const ip_neighbor_key_t * key)
+ip_neighbor_db_remove (const ip_neighbor_t * ipn)
 {
-  vec_validate (ip_neighbor_db[key->ipnk_type].ipndb_hash,
-               key->ipnk_sw_if_index);
+  ip_address_family_t af;
+  u32 sw_if_index;
+
+  af = ip_neighbor_get_af (ipn);
+  sw_if_index = ipn->ipn_key->ipnk_sw_if_index;
 
-  hash_unset_mem (ip_neighbor_db[key->ipnk_type].ipndb_hash
-                 [key->ipnk_sw_if_index], key);
+  vec_validate (ip_neighbor_db[af].ipndb_hash, sw_if_index);
 
-  ip_neighbor_db[key->ipnk_type].ipndb_n_elts--;
+  hash_unset_mem (ip_neighbor_db[af].ipndb_hash[sw_if_index], ipn->ipn_key);
+
+  ip_neighbor_db[af].ipndb_n_elts--;
 }
 
 static ip_neighbor_t *
 ip_neighbor_db_find (const ip_neighbor_key_t * key)
 {
+  ip_address_family_t af;
   uword *p;
 
-  if (key->ipnk_sw_if_index >=
-      vec_len (ip_neighbor_db[key->ipnk_type].ipndb_hash))
+  af = ip_addr_version (&key->ipnk_ip);
+
+  if (key->ipnk_sw_if_index >= vec_len (ip_neighbor_db[af].ipndb_hash))
     return NULL;
 
-  p =
-    hash_get_mem (ip_neighbor_db[key->ipnk_type].ipndb_hash
-                 [key->ipnk_sw_if_index], key);
+  p = hash_get_mem (ip_neighbor_db[af].ipndb_hash
+                   [key->ipnk_sw_if_index], key);
 
   if (p)
     return ip_neighbor_get (p[0]);
@@ -230,19 +243,24 @@ ip_neighbor_db_find (const ip_neighbor_key_t * key)
 }
 
 static u8
-ip46_type_pfx_len (ip46_type_t type)
+ip_af_type_pfx_len (ip_address_family_t type)
 {
-  return (type == IP46_TYPE_IP4 ? 32 : 128);
+  return (type == AF_IP4 ? 32 : 128);
 }
 
 static void
 ip_neighbor_adj_fib_add (ip_neighbor_t * ipn, u32 fib_index)
 {
-  if (ipn->ipn_key->ipnk_type == IP46_TYPE_IP6 &&
-      ip6_address_is_link_local_unicast (&ipn->ipn_key->ipnk_ip.ip6))
+  ip_address_family_t af;
+
+  af = ip_neighbor_get_af (ipn);
+
+  if (af == AF_IP6 &&
+      ip6_address_is_link_local_unicast (&ip_addr_v6
+                                        (&ipn->ipn_key->ipnk_ip)))
     {
       ip6_ll_prefix_t pfx = {
-       .ilp_addr = ipn->ipn_key->ipnk_ip.ip6,
+       .ilp_addr = ip_addr_v6 (&ipn->ipn_key->ipnk_ip),
        .ilp_sw_if_index = ipn->ipn_key->ipnk_sw_if_index,
       };
       ipn->ipn_fib_entry_index =
@@ -252,12 +270,12 @@ ip_neighbor_adj_fib_add (ip_neighbor_t * ipn, u32 fib_index)
     {
       fib_protocol_t fproto;
 
-      fproto = fib_proto_from_ip46 (ipn->ipn_key->ipnk_type);
+      fproto = ip_address_family_to_fib_proto (af);
 
       fib_prefix_t pfx = {
-       .fp_len = ip46_type_pfx_len (ipn->ipn_key->ipnk_type),
+       .fp_len = ip_af_type_pfx_len (af),
        .fp_proto = fproto,
-       .fp_addr = ipn->ipn_key->ipnk_ip,
+       .fp_addr = ip_addr_46 (&ipn->ipn_key->ipnk_ip),
       };
 
       ipn->ipn_fib_entry_index =
@@ -268,16 +286,11 @@ ip_neighbor_adj_fib_add (ip_neighbor_t * ipn, u32 fib_index)
                                  ipn->ipn_key->ipnk_sw_if_index,
                                  ~0, 1, NULL, FIB_ROUTE_PATH_FLAG_NONE);
 
-      vec_validate (ip_neighbor_db
-                   [ipn->ipn_key->ipnk_type].ipndb_n_elts_per_fib,
-                   fib_index);
+      vec_validate (ip_neighbor_db[af].ipndb_n_elts_per_fib, fib_index);
 
-      ip_neighbor_db[ipn->ipn_key->
-                    ipnk_type].ipndb_n_elts_per_fib[fib_index]++;
+      ip_neighbor_db[af].ipndb_n_elts_per_fib[fib_index]++;
 
-      if (1 ==
-         ip_neighbor_db[ipn->ipn_key->
-                        ipnk_type].ipndb_n_elts_per_fib[fib_index])
+      if (1 == ip_neighbor_db[af].ipndb_n_elts_per_fib[fib_index])
        fib_table_lock (fib_index, fproto, FIB_SOURCE_ADJ);
     }
 }
@@ -285,13 +298,18 @@ ip_neighbor_adj_fib_add (ip_neighbor_t * ipn, u32 fib_index)
 static void
 ip_neighbor_adj_fib_remove (ip_neighbor_t * ipn, u32 fib_index)
 {
+  ip_address_family_t af;
+
+  af = ip_neighbor_get_af (ipn);
+
   if (FIB_NODE_INDEX_INVALID != ipn->ipn_fib_entry_index)
     {
-      if (ipn->ipn_key->ipnk_type == IP46_TYPE_IP6 &&
-         ip6_address_is_link_local_unicast (&ipn->ipn_key->ipnk_ip.ip6))
+      if (AF_IP6 == af &&
+         ip6_address_is_link_local_unicast (&ip_addr_v6
+                                            (&ipn->ipn_key->ipnk_ip)))
        {
          ip6_ll_prefix_t pfx = {
-           .ilp_addr = ipn->ipn_key->ipnk_ip.ip6,
+           .ilp_addr = ip_addr_v6 (&ipn->ipn_key->ipnk_ip),
            .ilp_sw_if_index = ipn->ipn_key->ipnk_sw_if_index,
          };
          ip6_ll_table_entry_delete (&pfx);
@@ -300,12 +318,12 @@ ip_neighbor_adj_fib_remove (ip_neighbor_t * ipn, u32 fib_index)
        {
          fib_protocol_t fproto;
 
-         fproto = fib_proto_from_ip46 (ipn->ipn_key->ipnk_type);
+         fproto = ip_address_family_to_fib_proto (af);
 
          fib_prefix_t pfx = {
-           .fp_len = ip46_type_pfx_len (ipn->ipn_key->ipnk_type),
+           .fp_len = ip_af_type_pfx_len (af),
            .fp_proto = fproto,
-           .fp_addr = ipn->ipn_key->ipnk_ip,
+           .fp_addr = ip_addr_46 (&ipn->ipn_key->ipnk_ip),
          };
 
          fib_table_entry_path_remove (fib_index,
@@ -316,12 +334,9 @@ ip_neighbor_adj_fib_remove (ip_neighbor_t * ipn, u32 fib_index)
                                       ipn->ipn_key->ipnk_sw_if_index,
                                       ~0, 1, FIB_ROUTE_PATH_FLAG_NONE);
 
-         ip_neighbor_db[ipn->ipn_key->
-                        ipnk_type].ipndb_n_elts_per_fib[fib_index]--;
+         ip_neighbor_db[af].ipndb_n_elts_per_fib[fib_index]--;
 
-         if (0 ==
-             ip_neighbor_db[ipn->ipn_key->
-                            ipnk_type].ipndb_n_elts_per_fib[fib_index])
+         if (0 == ip_neighbor_db[af].ipndb_n_elts_per_fib[fib_index])
            fib_table_unlock (fib_index, fproto, FIB_SOURCE_ADJ);
        }
     }
@@ -373,37 +388,39 @@ ip_neighbor_mk_incomplete_walk (adj_index_t ai, void *ctx)
 static void
 ip_neighbor_free (ip_neighbor_t * ipn)
 {
+  ip_address_family_t af;
+
+  af = ip_neighbor_get_af (ipn);
+
   IP_NEIGHBOR_DBG ("free: %U", format_ip_neighbor,
                   ip_neighbor_get_index (ipn));
 
   adj_nbr_walk_nh (ipn->ipn_key->ipnk_sw_if_index,
-                  fib_proto_from_ip46 (ipn->ipn_key->ipnk_type),
-                  &ipn->ipn_key->ipnk_ip,
+                  ip_address_family_to_fib_proto (af),
+                  &ip_addr_46 (&ipn->ipn_key->ipnk_ip),
                   ip_neighbor_mk_incomplete_walk, ipn);
   ip_neighbor_adj_fib_remove
     (ipn,
      fib_table_get_index_for_sw_if_index
-     (fib_proto_from_ip46 (ipn->ipn_key->ipnk_type),
-      ipn->ipn_key->ipnk_sw_if_index));
+     (ip_address_family_to_fib_proto (af), ipn->ipn_key->ipnk_sw_if_index));
 
   ip_neighbor_list_remove (ipn);
-  ip_neighbor_db_remove (ipn->ipn_key);
+  ip_neighbor_db_remove (ipn);
   clib_mem_free (ipn->ipn_key);
 
   pool_put (ip_neighbor_pool, ipn);
 }
 
 static bool
-ip_neighbor_force_reuse (ip46_type_t type)
+ip_neighbor_force_reuse (ip_address_family_t af)
 {
-  if (!ip_neighbor_db[type].ipndb_recycle)
+  if (!ip_neighbor_db[af].ipndb_recycle)
     return false;
 
   /* pluck the oldest entry, which is the one from the end of the list */
   ip_neighbor_elt_t *elt, *head;
 
-  head =
-    pool_elt_at_index (ip_neighbor_elt_pool, ip_neighbor_list_head[type]);
+  head = pool_elt_at_index (ip_neighbor_elt_pool, ip_neighbor_list_head[af]);
 
   if (clib_llist_is_empty (ip_neighbor_elt_pool, ipne_anchor, head))
     return (false);
@@ -418,13 +435,15 @@ static ip_neighbor_t *
 ip_neighbor_alloc (const ip_neighbor_key_t * key,
                   const mac_address_t * mac, ip_neighbor_flags_t flags)
 {
+  ip_address_family_t af;
   ip_neighbor_t *ipn;
 
-  if (ip_neighbor_db[key->ipnk_type].ipndb_limit &&
-      (ip_neighbor_db[key->ipnk_type].ipndb_n_elts >=
-       ip_neighbor_db[key->ipnk_type].ipndb_limit))
+  af = ip_addr_version (&key->ipnk_ip);
+
+  if (ip_neighbor_db[af].ipndb_limit &&
+      (ip_neighbor_db[af].ipndb_n_elts >= ip_neighbor_db[af].ipndb_limit))
     {
-      if (!ip_neighbor_force_reuse (key->ipnk_type))
+      if (!ip_neighbor_force_reuse (af))
        return (NULL);
     }
 
@@ -445,15 +464,13 @@ ip_neighbor_alloc (const ip_neighbor_key_t * key,
   if (!(ipn->ipn_flags & IP_NEIGHBOR_FLAG_NO_FIB_ENTRY))
     ip_neighbor_adj_fib_add
       (ipn, fib_table_get_index_for_sw_if_index
-       (fib_proto_from_ip46 (ipn->ipn_key->ipnk_type),
-       ipn->ipn_key->ipnk_sw_if_index));
+       (ip_address_family_to_fib_proto (af), ipn->ipn_key->ipnk_sw_if_index));
 
   return (ipn);
 }
 
 int
-ip_neighbor_add (const ip46_address_t * ip,
-                ip46_type_t type,
+ip_neighbor_add (const ip_address_t * ip,
                 const mac_address_t * mac,
                 u32 sw_if_index,
                 ip_neighbor_flags_t flags, u32 * stats_index)
@@ -464,12 +481,11 @@ ip_neighbor_add (const ip46_address_t * ip,
   /* main thread only */
   ASSERT (0 == vlib_get_thread_index ());
 
-  fproto = fib_proto_from_ip46 (type);
+  fproto = ip_address_family_to_fib_proto (ip_addr_version (ip));
 
   const ip_neighbor_key_t key = {
     .ipnk_ip = *ip,
     .ipnk_sw_if_index = sw_if_index,
-    .ipnk_type = type,
   };
 
   ipn = ip_neighbor_db_find (&key);
@@ -478,7 +494,7 @@ ip_neighbor_add (const ip46_address_t * ip,
     {
       IP_NEIGHBOR_DBG ("update: %U, %U",
                       format_vnet_sw_if_index_name, vnet_get_main (),
-                      sw_if_index, format_ip46_address, ip, type,
+                      sw_if_index, format_ip_address, ip,
                       format_ip_neighbor_flags, flags, format_mac_address_t,
                       mac);
 
@@ -521,7 +537,7 @@ ip_neighbor_add (const ip46_address_t * ip,
     {
       IP_NEIGHBOR_INFO ("add: %U, %U",
                        format_vnet_sw_if_index_name, vnet_get_main (),
-                       sw_if_index, format_ip46_address, ip, type,
+                       sw_if_index, format_ip_address, ip,
                        format_ip_neighbor_flags, flags, format_mac_address_t,
                        mac);
 
@@ -535,7 +551,7 @@ ip_neighbor_add (const ip46_address_t * ip,
   ip_neighbor_refresh (ipn);
 
   adj_nbr_walk_nh (ipn->ipn_key->ipnk_sw_if_index,
-                  fproto, &ipn->ipn_key->ipnk_ip,
+                  fproto, &ip_addr_46 (&ipn->ipn_key->ipnk_ip),
                   ip_neighbor_mk_complete_walk, ipn);
 
 check_customers:
@@ -545,13 +561,13 @@ check_customers:
   if (stats_index)
     *stats_index = adj_nbr_find (fproto,
                                 fib_proto_to_link (fproto),
-                                &ipn->ipn_key->ipnk_ip,
+                                &ip_addr_46 (&ipn->ipn_key->ipnk_ip),
                                 ipn->ipn_key->ipnk_sw_if_index);
   return 0;
 }
 
 int
-ip_neighbor_del (const ip46_address_t * ip, ip46_type_t type, u32 sw_if_index)
+ip_neighbor_del (const ip_address_t * ip, u32 sw_if_index)
 {
   ip_neighbor_t *ipn;
 
@@ -560,12 +576,11 @@ ip_neighbor_del (const ip46_address_t * ip, ip46_type_t type, u32 sw_if_index)
 
   IP_NEIGHBOR_INFO ("delete: %U, %U",
                    format_vnet_sw_if_index_name, vnet_get_main (),
-                   sw_if_index, format_ip46_address, ip, type);
+                   sw_if_index, format_ip_address, ip);
 
   const ip_neighbor_key_t key = {
     .ipnk_ip = *ip,
     .ipnk_sw_if_index = sw_if_index,
-    .ipnk_type = type,
   };
 
   ipn = ip_neighbor_db_find (&key);
@@ -594,10 +609,10 @@ ip_neighbor_del_all_walk_cb (index_t ipni, void *arg)
 }
 
 void
-ip_neighbor_del_all (ip46_type_t type, u32 sw_if_index)
+ip_neighbor_del_all (ip_address_family_t af, u32 sw_if_index)
 {
   IP_NEIGHBOR_INFO ("delete-all: %U, %U",
-                   format_ip46_type, type,
+                   format_ip_address_family, af,
                    format_vnet_sw_if_index_name, vnet_get_main (),
                    sw_if_index);
 
@@ -606,7 +621,7 @@ ip_neighbor_del_all (ip46_type_t type, u32 sw_if_index)
   };
   index_t *ipni;
 
-  ip_neighbor_walk (type, sw_if_index, ip_neighbor_del_all_walk_cb, &ctx);
+  ip_neighbor_walk (af, sw_if_index, ip_neighbor_del_all_walk_cb, &ctx);
 
   vec_foreach (ipni, ctx.ipn_del) ip_neighbor_free (ip_neighbor_get (*ipni));
   vec_free (ctx.ipn_del);
@@ -621,10 +636,12 @@ ip_neighbor_update (vnet_main_t * vnm, adj_index_t ai)
   adj = adj_get (ai);
 
   ip_neighbor_key_t key = {
-    .ipnk_ip = adj->sub_type.nbr.next_hop,
-    .ipnk_type = fib_proto_to_ip46 (adj->ia_nh_proto),
     .ipnk_sw_if_index = adj->rewrite_header.sw_if_index,
   };
+
+  ip_address_from_46 (&adj->sub_type.nbr.next_hop,
+                     adj->ia_nh_proto, &key.ipnk_ip);
+
   ipn = ip_neighbor_db_find (&key);
 
   switch (adj->lookup_next_index)
@@ -634,7 +651,7 @@ ip_neighbor_update (vnet_main_t * vnm, adj_index_t ai)
        {
          adj_nbr_walk_nh (adj->rewrite_header.sw_if_index,
                           adj->ia_nh_proto,
-                          &ipn->ipn_key->ipnk_ip,
+                          &adj->sub_type.nbr.next_hop,
                           ip_neighbor_mk_complete_walk, ipn);
        }
       else
@@ -689,7 +706,7 @@ ip_neighbor_update (vnet_main_t * vnm, adj_index_t ai)
 void
 ip_neighbor_learn (const ip_neighbor_learn_t * l)
 {
-  ip_neighbor_add (&l->ip, l->type, &l->mac, l->sw_if_index,
+  ip_neighbor_add (&l->ip, &l->mac, l->sw_if_index,
                   IP_NEIGHBOR_FLAG_DYNAMIC, NULL);
 }
 
@@ -697,7 +714,7 @@ static clib_error_t *
 ip_neighbor_cmd (vlib_main_t * vm,
                 unformat_input_t * input, vlib_cli_command_t * cmd)
 {
-  ip46_address_t ip = ip46_address_initializer;
+  ip_address_t ip = IP_ADDRESS_V6_ALL_0S;
   mac_address_t mac = ZERO_MAC_ADDRESS;
   vnet_main_t *vnm = vnet_get_main ();
   ip_neighbor_flags_t flags;
@@ -712,8 +729,7 @@ ip_neighbor_cmd (vlib_main_t * vm,
       /* set ip arp TenGigE1/1/0/1 1.2.3.4 aa:bb:... or aabb.ccdd... */
       if (unformat (input, "%U %U %U",
                    unformat_vnet_sw_interface, vnm, &sw_if_index,
-                   unformat_ip46_address, &ip, IP46_TYPE_ANY,
-                   unformat_mac_address_t, &mac))
+                   unformat_ip_address, &ip, unformat_mac_address_t, &mac))
        ;
       else if (unformat (input, "delete") || unformat (input, "del"))
        is_add = 0;
@@ -731,7 +747,7 @@ ip_neighbor_cmd (vlib_main_t * vm,
     }
 
   if (sw_if_index == ~0 ||
-      ip46_address_is_zero (&ip) || mac_address_is_zero (&mac))
+      ip_address_is_zero (&ip) || mac_address_is_zero (&mac))
     return clib_error_return (0,
                              "specify interface, IP address and MAC: `%U'",
                              format_unformat_error, input);
@@ -739,12 +755,11 @@ ip_neighbor_cmd (vlib_main_t * vm,
   while (count)
     {
       if (is_add)
-       ip_neighbor_add (&ip, ip46_address_get_type (&ip), &mac, sw_if_index,
-                        flags, NULL);
+       ip_neighbor_add (&ip, &mac, sw_if_index, flags, NULL);
       else
-       ip_neighbor_del (&ip, ip46_address_get_type (&ip), sw_if_index);
+       ip_neighbor_del (&ip, sw_if_index);
 
-      ip46_address_increment (ip46_address_get_type (&ip), &ip);
+      ip_address_increment (&ip);
       mac_address_increment (&mac);
 
       --count;
@@ -810,12 +825,12 @@ ip_neighbor_sort (void *a1, void *a2)
                                   ipn1->ipn_key->ipnk_sw_if_index,
                                   ipn2->ipn_key->ipnk_sw_if_index);
   if (!cmp)
-    cmp = ip46_address_cmp (&ipn1->ipn_key->ipnk_ip, &ipn2->ipn_key->ipnk_ip);
+    cmp = ip_address_cmp (&ipn1->ipn_key->ipnk_ip, &ipn2->ipn_key->ipnk_ip);
   return cmp;
 }
 
 static index_t *
-ip_neighbor_entries (u32 sw_if_index, ip46_type_t type)
+ip_neighbor_entries (u32 sw_if_index, ip_address_family_t af)
 {
   index_t *ipnis = NULL;
   ip_neighbor_t *ipn;
@@ -825,8 +840,8 @@ ip_neighbor_entries (u32 sw_if_index, ip46_type_t type)
   ({
     if ((sw_if_index == ~0 ||
         ipn->ipn_key->ipnk_sw_if_index == sw_if_index) &&
-        (IP46_TYPE_ANY == type ||
-         ipn->ipn_key->ipnk_type == type))
+        (N_AF == af ||
+         ip_neighbor_get_af(ipn) == af))
        vec_add1 (ipnis, ip_neighbor_get_index(ipn));
   }));
 
@@ -840,12 +855,11 @@ ip_neighbor_entries (u32 sw_if_index, ip46_type_t type)
 static clib_error_t *
 ip_neighbor_show_sorted_i (vlib_main_t * vm,
                           unformat_input_t * input,
-                          vlib_cli_command_t * cmd, ip46_type_t type)
+                          vlib_cli_command_t * cmd, ip_address_family_t af)
 {
   ip_neighbor_elt_t *elt, *head;
 
-  head = pool_elt_at_index (ip_neighbor_elt_pool,
-                           ip_neighbor_list_head[type]);
+  head = pool_elt_at_index (ip_neighbor_elt_pool, ip_neighbor_list_head[af]);
 
 
   vlib_cli_output (vm, "%=12s%=40s%=6s%=20s%=24s", "Time", "IP",
@@ -867,7 +881,7 @@ ip_neighbor_show_sorted_i (vlib_main_t * vm,
 static clib_error_t *
 ip_neighbor_show_i (vlib_main_t * vm,
                    unformat_input_t * input,
-                   vlib_cli_command_t * cmd, ip46_type_t type)
+                   vlib_cli_command_t * cmd, ip_address_family_t af)
 {
   index_t *ipni, *ipnis = NULL;
   u32 sw_if_index;
@@ -877,7 +891,7 @@ ip_neighbor_show_i (vlib_main_t * vm,
   (void) unformat_user (input, unformat_vnet_sw_interface, vnet_get_main (),
                        &sw_if_index);
 
-  ipnis = ip_neighbor_entries (sw_if_index, type);
+  ipnis = ip_neighbor_entries (sw_if_index, af);
 
   if (ipnis)
     vlib_cli_output (vm, "%=12s%=40s%=6s%=20s%=24s", "Time", "IP",
@@ -896,35 +910,35 @@ static clib_error_t *
 ip_neighbor_show (vlib_main_t * vm,
                  unformat_input_t * input, vlib_cli_command_t * cmd)
 {
-  return (ip_neighbor_show_i (vm, input, cmd, IP46_TYPE_ANY));
+  return (ip_neighbor_show_i (vm, input, cmd, N_AF));
 }
 
 static clib_error_t *
 ip6_neighbor_show (vlib_main_t * vm,
                   unformat_input_t * input, vlib_cli_command_t * cmd)
 {
-  return (ip_neighbor_show_i (vm, input, cmd, IP46_TYPE_IP6));
+  return (ip_neighbor_show_i (vm, input, cmd, AF_IP6));
 }
 
 static clib_error_t *
 ip4_neighbor_show (vlib_main_t * vm,
                   unformat_input_t * input, vlib_cli_command_t * cmd)
 {
-  return (ip_neighbor_show_i (vm, input, cmd, IP46_TYPE_IP4));
+  return (ip_neighbor_show_i (vm, input, cmd, AF_IP4));
 }
 
 static clib_error_t *
 ip6_neighbor_show_sorted (vlib_main_t * vm,
                          unformat_input_t * input, vlib_cli_command_t * cmd)
 {
-  return (ip_neighbor_show_sorted_i (vm, input, cmd, IP46_TYPE_IP6));
+  return (ip_neighbor_show_sorted_i (vm, input, cmd, AF_IP6));
 }
 
 static clib_error_t *
 ip4_neighbor_show_sorted (vlib_main_t * vm,
                          unformat_input_t * input, vlib_cli_command_t * cmd)
 {
-  return (ip_neighbor_show_sorted_i (vm, input, cmd, IP46_TYPE_IP4));
+  return (ip_neighbor_show_sorted_i (vm, input, cmd, AF_IP4));
 }
 
 /*?
@@ -984,12 +998,12 @@ VLIB_CLI_COMMAND (show_ip6_neighbor_sorted_cmd_node, static) = {
 };
 /* *INDENT-ON* */
 
-static ip_neighbor_vft_t ip_nbr_vfts[IP46_N_TYPES];
+static ip_neighbor_vft_t ip_nbr_vfts[N_AF];
 
 void
-ip_neighbor_register (ip46_type_t type, const ip_neighbor_vft_t * vft)
+ip_neighbor_register (ip_address_family_t af, const ip_neighbor_vft_t * vft)
 {
-  ip_nbr_vfts[type] = *vft;
+  ip_nbr_vfts[af] = *vft;
 }
 
 void
@@ -1020,20 +1034,7 @@ ip_neighbor_probe (const ip_adjacency_t * adj)
 }
 
 void
-ip_neighbor_advertise (vlib_main_t * vm,
-                      ip46_type_t type,
-                      const ip46_address_t * addr, u32 sw_if_index)
-{
-  vnet_main_t *vnm = vnet_get_main ();
-
-  if (type == IP46_TYPE_IP4 || type == IP46_TYPE_BOTH)
-    ip4_neighbor_advertise (vm, vnm, sw_if_index, (addr) ? &addr->ip4 : NULL);
-  if (type == IP46_TYPE_IP6 || type == IP46_TYPE_BOTH)
-    ip6_neighbor_advertise (vm, vnm, sw_if_index, (addr) ? &addr->ip6 : NULL);
-}
-
-void
-ip_neighbor_walk (ip46_type_t type,
+ip_neighbor_walk (ip_address_family_t af,
                  u32 sw_if_index, ip_neighbor_walk_cb_t cb, void *ctx)
 {
   ip_neighbor_key_t *key;
@@ -1043,7 +1044,7 @@ ip_neighbor_walk (ip46_type_t type,
     {
       uword **hash;
 
-      vec_foreach (hash, ip_neighbor_db[type].ipndb_hash)
+      vec_foreach (hash, ip_neighbor_db[af].ipndb_hash)
       {
           /* *INDENT-OFF* */
           hash_foreach (key, ipni, *hash,
@@ -1058,9 +1059,9 @@ ip_neighbor_walk (ip46_type_t type,
     {
       uword *hash;
 
-      if (vec_len (ip_neighbor_db[type].ipndb_hash) <= sw_if_index)
+      if (vec_len (ip_neighbor_db[af].ipndb_hash) <= sw_if_index)
        return;
-      hash = ip_neighbor_db[type].ipndb_hash[sw_if_index];
+      hash = ip_neighbor_db[af].ipndb_hash[sw_if_index];
 
       /* *INDENT-OFF* */
       hash_foreach (key, ipni, hash,
@@ -1077,10 +1078,9 @@ ip4_neighbor_proxy_add (u32 fib_index,
                        const ip4_address_t * start,
                        const ip4_address_t * end)
 {
-  if (ip_nbr_vfts[IP46_TYPE_IP4].inv_proxy4_add)
+  if (ip_nbr_vfts[AF_IP4].inv_proxy4_add)
     {
-      return (ip_nbr_vfts[IP46_TYPE_IP4].inv_proxy4_add
-             (fib_index, start, end));
+      return (ip_nbr_vfts[AF_IP4].inv_proxy4_add (fib_index, start, end));
     }
 
   return (-1);
@@ -1091,10 +1091,9 @@ ip4_neighbor_proxy_delete (u32 fib_index,
                           const ip4_address_t * start,
                           const ip4_address_t * end)
 {
-  if (ip_nbr_vfts[IP46_TYPE_IP4].inv_proxy4_del)
+  if (ip_nbr_vfts[AF_IP4].inv_proxy4_del)
     {
-      return (ip_nbr_vfts[IP46_TYPE_IP4].inv_proxy4_del
-             (fib_index, start, end));
+      return (ip_nbr_vfts[AF_IP4].inv_proxy4_del (fib_index, start, end));
     }
   return -1;
 }
@@ -1102,9 +1101,9 @@ ip4_neighbor_proxy_delete (u32 fib_index,
 int
 ip4_neighbor_proxy_enable (u32 sw_if_index)
 {
-  if (ip_nbr_vfts[IP46_TYPE_IP4].inv_proxy4_enable)
+  if (ip_nbr_vfts[AF_IP4].inv_proxy4_enable)
     {
-      return (ip_nbr_vfts[IP46_TYPE_IP4].inv_proxy4_enable (sw_if_index));
+      return (ip_nbr_vfts[AF_IP4].inv_proxy4_enable (sw_if_index));
     }
   return -1;
 }
@@ -1112,9 +1111,9 @@ ip4_neighbor_proxy_enable (u32 sw_if_index)
 int
 ip4_neighbor_proxy_disable (u32 sw_if_index)
 {
-  if (ip_nbr_vfts[IP46_TYPE_IP4].inv_proxy4_disable)
+  if (ip_nbr_vfts[AF_IP4].inv_proxy4_disable)
     {
-      return (ip_nbr_vfts[IP46_TYPE_IP4].inv_proxy4_disable (sw_if_index));
+      return (ip_nbr_vfts[AF_IP4].inv_proxy4_disable (sw_if_index));
     }
   return -1;
 }
@@ -1122,9 +1121,9 @@ ip4_neighbor_proxy_disable (u32 sw_if_index)
 int
 ip6_neighbor_proxy_add (u32 sw_if_index, const ip6_address_t * addr)
 {
-  if (ip_nbr_vfts[IP46_TYPE_IP6].inv_proxy6_add)
+  if (ip_nbr_vfts[AF_IP6].inv_proxy6_add)
     {
-      return (ip_nbr_vfts[IP46_TYPE_IP6].inv_proxy6_add (sw_if_index, addr));
+      return (ip_nbr_vfts[AF_IP6].inv_proxy6_add (sw_if_index, addr));
     }
   return -1;
 }
@@ -1132,9 +1131,9 @@ ip6_neighbor_proxy_add (u32 sw_if_index, const ip6_address_t * addr)
 int
 ip6_neighbor_proxy_del (u32 sw_if_index, const ip6_address_t * addr)
 {
-  if (ip_nbr_vfts[IP46_TYPE_IP6].inv_proxy6_del)
+  if (ip_nbr_vfts[AF_IP6].inv_proxy6_del)
     {
-      return (ip_nbr_vfts[IP46_TYPE_IP6].inv_proxy6_del (sw_if_index, addr));
+      return (ip_nbr_vfts[AF_IP6].inv_proxy6_del (sw_if_index, addr));
     }
   return -1;
 }
@@ -1155,8 +1154,8 @@ ip_neighbor_ethernet_change_mac (ethernet_main_t * em,
   ({
     if (ipn->ipn_key->ipnk_sw_if_index == sw_if_index)
       adj_nbr_walk_nh (ipn->ipn_key->ipnk_sw_if_index,
-                       fib_proto_from_ip46(ipn->ipn_key->ipnk_type),
-                       &ipn->ipn_key->ipnk_ip,
+                       ip_address_family_to_fib_proto(ip_neighbor_get_af(ipn)),
+                       &ip_addr_46(&ipn->ipn_key->ipnk_ip),
                        ip_neighbor_mk_complete_walk,
                        ipn);
   }));
@@ -1169,19 +1168,19 @@ ip_neighbor_ethernet_change_mac (ethernet_main_t * em,
 }
 
 void
-ip_neighbor_populate (ip46_type_t type, u32 sw_if_index)
+ip_neighbor_populate (ip_address_family_t af, u32 sw_if_index)
 {
   index_t *ipnis = NULL, *ipni;
   ip_neighbor_t *ipn;
 
   IP_NEIGHBOR_DBG ("populate: %U %U",
                   format_vnet_sw_if_index_name, vnet_get_main (),
-                  sw_if_index, format_ip46_type, type);
+                  sw_if_index, format_ip_address_family, af);
 
   /* *INDENT-OFF* */
   pool_foreach (ipn, ip_neighbor_pool,
   ({
-    if (ipn->ipn_key->ipnk_type == type &&
+    if (ip_neighbor_get_af(ipn) == af &&
         ipn->ipn_key->ipnk_sw_if_index == sw_if_index)
       vec_add1 (ipnis, ipn - ip_neighbor_pool);
   }));
@@ -1192,27 +1191,29 @@ ip_neighbor_populate (ip46_type_t type, u32 sw_if_index)
     ipn = ip_neighbor_get (*ipni);
 
     adj_nbr_walk_nh (ipn->ipn_key->ipnk_sw_if_index,
-                    fib_proto_from_ip46 (ipn->ipn_key->ipnk_type),
-                    &ipn->ipn_key->ipnk_ip,
+                    ip_address_family_to_fib_proto (ip_neighbor_get_af
+                                                    (ipn)),
+                    &ip_addr_46 (&ipn->ipn_key->ipnk_ip),
                     ip_neighbor_mk_complete_walk, ipn);
   }
   vec_free (ipnis);
 }
 
 void
-ip_neighbor_flush (ip46_type_t type, u32 sw_if_index)
+ip_neighbor_flush (ip_address_family_t af, u32 sw_if_index)
 {
   index_t *ipnis = NULL, *ipni;
   ip_neighbor_t *ipn;
 
+
   IP_NEIGHBOR_DBG ("flush: %U %U",
                   format_vnet_sw_if_index_name, vnet_get_main (),
-                  sw_if_index, format_ip46_type, type);
+                  sw_if_index, format_ip_address_family, af);
 
   /* *INDENT-OFF* */
   pool_foreach (ipn, ip_neighbor_pool,
   ({
-    if (ipn->ipn_key->ipnk_type == type &&
+    if (ip_neighbor_get_af(ipn) == af &&
         ipn->ipn_key->ipnk_sw_if_index == sw_if_index &&
         ip_neighbor_is_dynamic (ipn))
       vec_add1 (ipnis, ipn - ip_neighbor_pool);
@@ -1236,9 +1237,9 @@ ip_neighbor_mark_one (index_t ipni, void *ctx)
 }
 
 void
-ip_neighbor_mark (ip46_type_t type)
+ip_neighbor_mark (ip_address_family_t af)
 {
-  ip_neighbor_walk (type, ~0, ip_neighbor_mark_one, NULL);
+  ip_neighbor_walk (af, ~0, ip_neighbor_mark_one, NULL);
 }
 
 typedef struct ip_neighbor_sweep_ctx_t_
@@ -1263,12 +1264,12 @@ ip_neighbor_sweep_one (index_t ipni, void *arg)
 }
 
 void
-ip_neighbor_sweep (ip46_type_t type)
+ip_neighbor_sweep (ip_address_family_t af)
 {
   ip_neighbor_sweep_ctx_t ctx = { };
   index_t *ipni;
 
-  ip_neighbor_walk (type, ~0, ip_neighbor_sweep_one, &ctx);
+  ip_neighbor_walk (af, ~0, ip_neighbor_sweep_one, &ctx);
 
   vec_foreach (ipni, ctx.ipnsc_stale)
   {
@@ -1284,7 +1285,7 @@ static clib_error_t *
 ip_neighbor_interface_admin_change (vnet_main_t * vnm,
                                    u32 sw_if_index, u32 flags)
 {
-  ip46_type_t type;
+  ip_address_family_t af;
 
   IP_NEIGHBOR_DBG ("interface-admin: %U  %s",
                   format_vnet_sw_if_index_name, vnet_get_main (),
@@ -1293,12 +1294,12 @@ ip_neighbor_interface_admin_change (vnet_main_t * vnm,
 
   if (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP)
     {
-      FOREACH_IP46_TYPE (type) ip_neighbor_populate (type, sw_if_index);
+      FOR_EACH_IP_ADDRESS_FAMILY (af) ip_neighbor_populate (af, sw_if_index);
     }
   else
     {
       /* admin down, flush all neighbours */
-      FOREACH_IP46_TYPE (type) ip_neighbor_flush (type, sw_if_index);
+      FOR_EACH_IP_ADDRESS_FAMILY (af) ip_neighbor_flush (af, sw_if_index);
     }
 
   return (NULL);
@@ -1319,9 +1320,9 @@ ip_neighbor_delete_sw_interface (vnet_main_t * vnm,
 
   if (!is_add && sw_if_index != ~0)
     {
-      ip46_type_t type;
+      ip_address_family_t af;
 
-      FOREACH_IP46_TYPE (type) ip_neighbor_flush (type, sw_if_index);
+      FOR_EACH_IP_ADDRESS_FAMILY (af) ip_neighbor_flush (af, sw_if_index);
     }
 
   return (NULL);
@@ -1331,8 +1332,7 @@ VNET_SW_INTERFACE_ADD_DEL_FUNCTION (ip_neighbor_delete_sw_interface);
 
 typedef struct ip_neighbor_walk_covered_ctx_t_
 {
-  ip46_type_t type;
-  ip46_address_t addr;
+  ip_address_t addr;
   u32 length;
   index_t *ipnis;
 } ip_neighbor_walk_covered_ctx_t;
@@ -1345,13 +1345,22 @@ ip_neighbor_walk_covered (index_t ipni, void *arg)
 
   ipn = ip_neighbor_get (ipni);
 
-  ASSERT (ipn->ipn_key->ipnk_type == ctx->type);
-
-  if (IP46_TYPE_IP4 == ctx->type)
+  if (AF_IP4 == ip_addr_version (&ctx->addr))
     {
       if (ip4_destination_matches_route (&ip4_main,
-                                        &ipn->ipn_key->ipnk_ip.ip4,
-                                        &ctx->addr.ip4,
+                                        &ip_addr_v4 (&ipn->ipn_key->ipnk_ip),
+                                        &ip_addr_v4 (&ctx->addr),
+                                        ctx->length) &&
+         ip_neighbor_is_dynamic (ipn))
+       {
+         vec_add1 (ctx->ipnis, ip_neighbor_get_index (ipn));
+       }
+    }
+  else if (AF_IP6 == ip_addr_version (&ctx->addr))
+    {
+      if (ip6_destination_matches_route (&ip6_main,
+                                        &ip_addr_v6 (&ipn->ipn_key->ipnk_ip),
+                                        &ip_addr_v6 (&ctx->addr),
                                         ctx->length) &&
          ip_neighbor_is_dynamic (ipn))
        {
@@ -1384,15 +1393,18 @@ ip_neighbor_add_del_interface_address_v4 (ip4_main_t * im,
 
   if (is_del)
     {
+      /* *INDENT-OFF* */
       ip_neighbor_walk_covered_ctx_t ctx = {
-       .addr.ip4 = *address,
-       .type = IP46_TYPE_IP4,
+       .addr = {
+          .ip.ip4 = *address,
+          .version = AF_IP4,
+        },
        .length = address_length,
       };
+      /* *INDENT-ON* */
       index_t *ipni;
 
-      ip_neighbor_walk (IP46_TYPE_IP4, sw_if_index,
-                       ip_neighbor_walk_covered, &ctx);
+      ip_neighbor_walk (AF_IP4, sw_if_index, ip_neighbor_walk_covered, &ctx);
 
       vec_foreach (ipni, ctx.ipnis)
        ip_neighbor_free (ip_neighbor_get (*ipni));
@@ -1423,15 +1435,18 @@ ip_neighbor_add_del_interface_address_v6 (ip6_main_t * im,
 
   if (is_del)
     {
+      /* *INDENT-OFF* */
       ip_neighbor_walk_covered_ctx_t ctx = {
-       .addr.ip6 = *address,
-       .type = IP46_TYPE_IP6,
+       .addr = {
+          .ip.ip6 = *address,
+          .version = AF_IP6,
+        },
        .length = address_length,
       };
+      /* *INDENT-ON* */
       index_t *ipni;
 
-      ip_neighbor_walk (IP46_TYPE_IP6, sw_if_index,
-                       ip_neighbor_walk_covered, &ctx);
+      ip_neighbor_walk (AF_IP6, sw_if_index, ip_neighbor_walk_covered, &ctx);
 
       vec_foreach (ipni, ctx.ipnis)
        ip_neighbor_free (ip_neighbor_get (*ipni));
@@ -1470,8 +1485,7 @@ ip_neighbor_table_bind_v4 (ip4_main_t * im,
     .new_fib_index = new_fib_index,
   };
 
-  ip_neighbor_walk (IP46_TYPE_IP4, sw_if_index,
-                   ip_neighbor_walk_table_bind, &ctx);
+  ip_neighbor_walk (AF_IP4, sw_if_index, ip_neighbor_walk_table_bind, &ctx);
 }
 
 static void
@@ -1485,8 +1499,7 @@ ip_neighbor_table_bind_v6 (ip6_main_t * im,
     .new_fib_index = new_fib_index,
   };
 
-  ip_neighbor_walk (IP46_TYPE_IP6, sw_if_index,
-                   ip_neighbor_walk_table_bind, &ctx);
+  ip_neighbor_walk (AF_IP6, sw_if_index, ip_neighbor_walk_table_bind, &ctx);
 }
 
 typedef enum ip_neighbor_age_state_t_
@@ -1501,12 +1514,14 @@ typedef enum ip_neighbor_age_state_t_
 static ip_neighbor_age_state_t
 ip_neighbour_age_out (index_t ipni, f64 now, f64 * wait)
 {
+  ip_address_family_t af;
   ip_neighbor_t *ipn;
   u32 ipndb_age;
   u32 ttl;
 
   ipn = ip_neighbor_get (ipni);
-  ipndb_age = ip_neighbor_db[ipn->ipn_key->ipnk_type].ipndb_age;
+  af = ip_neighbor_get_af (ipn);
+  ipndb_age = ip_neighbor_db[af].ipndb_age;
   ttl = now - ipn->ipn_time_last_updated;
   *wait = ipndb_age;
 
@@ -1526,11 +1541,12 @@ ip_neighbour_age_out (index_t ipni, f64 now, f64 * wait)
        {
          adj_index_t ai;
 
-         ai = adj_glean_get (fib_proto_from_ip46 (ipn->ipn_key->ipnk_type),
+         ai = adj_glean_get (ip_address_family_to_fib_proto (af),
                              ip_neighbor_get_sw_if_index (ipn));
 
          if (ADJ_INDEX_INVALID != ai)
-           ip_neighbor_probe_dst (adj_get (ai), ip_neighbor_get_ip (ipn));
+           ip_neighbor_probe_dst (adj_get (ai),
+                                  &ip_addr_46 (&ipn->ipn_key->ipnk_ip));
 
          ipn->ipn_n_probes++;
          *wait = 1;
@@ -1554,7 +1570,7 @@ typedef enum ip_neighbor_process_event_t_
 static uword
 ip_neighbor_age_loop (vlib_main_t * vm,
                      vlib_node_runtime_t * rt,
-                     vlib_frame_t * f, ip46_type_t type)
+                     vlib_frame_t * f, ip_address_family_t af)
 {
   uword event_type, *event_data = NULL;
   f64 timeout;
@@ -1584,9 +1600,9 @@ ip_neighbor_age_loop (vlib_main_t * vm,
            ip_neighbor_elt_t *elt, *head;
            f64 wait;
 
-           timeout = ip_neighbor_db[type].ipndb_age;
+           timeout = ip_neighbor_db[af].ipndb_age;
            head = pool_elt_at_index (ip_neighbor_elt_pool,
-                                     ip_neighbor_list_head[type]);
+                                     ip_neighbor_list_head[af]);
 
           /* *INDENT-OFF*/
           /* the list is time sorted, newest first, so start from the back
@@ -1619,7 +1635,7 @@ ip_neighbor_age_loop (vlib_main_t * vm,
        case IP_NEIGHBOR_AGE_PROCESS_WAKEUP:
          {
 
-           if (!ip_neighbor_db[type].ipndb_age)
+           if (!ip_neighbor_db[af].ipndb_age)
              {
                /* aging has been disabled */
                timeout = 0;
@@ -1628,11 +1644,11 @@ ip_neighbor_age_loop (vlib_main_t * vm,
            ip_neighbor_elt_t *elt, *head;
 
            head = pool_elt_at_index (ip_neighbor_elt_pool,
-                                     ip_neighbor_list_head[type]);
+                                     ip_neighbor_list_head[af]);
            /* no neighbors yet */
            if (clib_llist_is_empty (ip_neighbor_elt_pool, ipne_anchor, head))
              {
-               timeout = ip_neighbor_db[type].ipndb_age;
+               timeout = ip_neighbor_db[af].ipndb_age;
                break;
              }
 
@@ -1650,14 +1666,14 @@ static uword
 ip4_neighbor_age_process (vlib_main_t * vm,
                          vlib_node_runtime_t * rt, vlib_frame_t * f)
 {
-  return (ip_neighbor_age_loop (vm, rt, f, IP46_TYPE_IP4));
+  return (ip_neighbor_age_loop (vm, rt, f, AF_IP4));
 }
 
 static uword
 ip6_neighbor_age_process (vlib_main_t * vm,
                          vlib_node_runtime_t * rt, vlib_frame_t * f)
 {
-  return (ip_neighbor_age_loop (vm, rt, f, IP46_TYPE_IP6));
+  return (ip_neighbor_age_loop (vm, rt, f, AF_IP6));
 }
 
 /* *INDENT-OFF* */
@@ -1674,14 +1690,14 @@ VLIB_REGISTER_NODE (ip6_neighbor_age_process_node,static) = {
 /* *INDENT-ON* */
 
 int
-ip_neighbor_config (ip46_type_t type, u32 limit, u32 age, bool recycle)
+ip_neighbor_config (ip_address_family_t af, u32 limit, u32 age, bool recycle)
 {
-  ip_neighbor_db[type].ipndb_limit = limit;
-  ip_neighbor_db[type].ipndb_recycle = recycle;
-  ip_neighbor_db[type].ipndb_age = age;
+  ip_neighbor_db[af].ipndb_limit = limit;
+  ip_neighbor_db[af].ipndb_recycle = recycle;
+  ip_neighbor_db[af].ipndb_age = age;
 
   vlib_process_signal_event (vlib_get_main (),
-                            (IP46_TYPE_IP4 == type ?
+                            (AF_IP4 == af ?
                              ip4_neighbor_age_process_node.index :
                              ip6_neighbor_age_process_node.index),
                             IP_NEIGHBOR_AGE_PROCESS_WAKEUP, 0);
@@ -1693,15 +1709,15 @@ static clib_error_t *
 ip_neighbor_config_show (vlib_main_t * vm,
                         unformat_input_t * input, vlib_cli_command_t * cmd)
 {
-  ip46_type_t type;
+  ip_address_family_t af;
 
   /* *INDENT-OFF* */
-  FOREACH_IP46_TYPE(type) {
-    vlib_cli_output (vm, "%U:", format_ip46_type, type);
+  FOR_EACH_IP_ADDRESS_FAMILY(af) {
+    vlib_cli_output (vm, "%U:", format_ip_address_family, af);
     vlib_cli_output (vm, "  limit:%d, age:%d, recycle:%d",
-                     ip_neighbor_db[type].ipndb_limit,
-                     ip_neighbor_db[type].ipndb_age,
-                     ip_neighbor_db[type].ipndb_recycle);
+                     ip_neighbor_db[af].ipndb_limit,
+                     ip_neighbor_db[af].ipndb_age,
+                     ip_neighbor_db[af].ipndb_recycle);
   }
 
   /* *INDENT-ON* */
@@ -1753,10 +1769,10 @@ ip_neighbor_init (vlib_main_t * vm)
 
   ipn_logger = vlib_log_register_class ("ip", "neighbor");
 
-  ip46_type_t type;
+  ip_address_family_t af;
 
-  FOREACH_IP46_TYPE (type)
-    ip_neighbor_list_head[type] =
+  FOR_EACH_IP_ADDRESS_FAMILY (af)
+    ip_neighbor_list_head[af] =
     clib_llist_make_head (ip_neighbor_elt_pool, ipne_anchor);
 
   return (NULL);
index cdceadb..4619479 100644 (file)
@@ -30,25 +30,24 @@ void ip_neighbor_scan_enable_disable (ip_neighbor_scan_arg_t * arg);
  */
 
 extern ip_neighbor_t *ip_neighbor_get (index_t ipni);
-extern int ip_neighbor_add (const ip46_address_t * ip,
-                           ip46_type_t type,
+extern int ip_neighbor_add (const ip_address_t * ip,
                            const mac_address_t * mac,
                            u32 sw_if_index,
                            ip_neighbor_flags_t flags, u32 * stats_index);
-extern int ip_neighbor_del (const ip46_address_t * ip,
-                           ip46_type_t type, u32 sw_if_index);
+extern int ip_neighbor_del (const ip_address_t * ip, u32 sw_if_index);
 
-extern int ip_neighbor_config (ip46_type_t type, u32 limit, u32 age,
-                              bool recycle);
+extern int ip_neighbor_config (ip_address_family_t af,
+                              u32 limit, u32 age, bool recycle);
 
-extern void ip_neighbor_del_all (ip46_type_t type, u32 sw_if_index);
+extern void ip_neighbor_del_all (ip_address_family_t af, u32 sw_if_index);
 
 typedef walk_rc_t (*ip_neighbor_walk_cb_t) (index_t ipni, void *ctx);
-extern void ip_neighbor_walk (ip46_type_t type,
+extern void ip_neighbor_walk (ip_address_family_t af,
                              u32 sw_if_index,
                              ip_neighbor_walk_cb_t fn, void *ctx);
 
-extern const ip46_address_t *ip_neighbor_get_ip (const ip_neighbor_t * ipn);
+extern const ip_address_t *ip_neighbor_get_ip (const ip_neighbor_t * ipn);
+extern ip_address_family_t ip_neighbor_get_af (const ip_neighbor_t * ipn);
 extern const mac_address_t *ip_neighbor_get_mac (const ip_neighbor_t * ipn);
 extern const u32 ip_neighbor_get_sw_if_index (const ip_neighbor_t * ipn);
 
@@ -56,16 +55,12 @@ extern void ip_neighbor_learn (const ip_neighbor_learn_t * l);
 
 extern void ip_neighbor_update (vnet_main_t * vnm, adj_index_t ai);
 
-extern void ip_neighbor_advertise (vlib_main_t * vm,
-                                  ip46_type_t tyoe,
-                                  const ip46_address_t * addr,
-                                  u32 sw_if_index);
 extern void ip_neighbor_probe (const ip_adjacency_t * adj);
 extern void ip_neighbor_probe_dst (const ip_adjacency_t * adj,
                                   const ip46_address_t * ip);
 
-extern void ip_neighbor_mark (ip46_type_t type);
-extern void ip_neighbor_sweep (ip46_type_t type);
+extern void ip_neighbor_mark (ip_address_family_t af);
+extern void ip_neighbor_sweep (ip_address_family_t af);
 
 /**
  * From the watcher to the API to publish a new neighbor
@@ -114,7 +109,7 @@ typedef struct ip_neighbor_vft_t_
   ip6_neighbor_proxy_cfg_t inv_proxy6_del;
 } ip_neighbor_vft_t;
 
-extern void ip_neighbor_register (ip46_type_t type,
+extern void ip_neighbor_register (ip_address_family_t af,
                                  const ip_neighbor_vft_t * vft);
 
 
index 02952c7..39d7785 100644 (file)
@@ -37,13 +37,6 @@ static u16 msg_id_base;
 
 #include <vnet/format_fns.h>
 
-
-static ip46_type_t
-ip46_type_from_af (ip_address_family_t af)
-{
-  return (AF_IP4 == af ? IP46_TYPE_IP4 : IP46_TYPE_IP6);
-}
-
 static vl_api_ip_neighbor_flags_t
 ip_neighbor_flags_encode (ip_neighbor_flags_t f)
 {
@@ -63,8 +56,7 @@ ip_neighbor_encode (vl_api_ip_neighbor_t * api, const ip_neighbor_t * ipn)
   api->sw_if_index = htonl (ipn->ipn_key->ipnk_sw_if_index);
   api->flags = ip_neighbor_flags_encode (ipn->ipn_flags);
 
-  ip_address_encode (&ipn->ipn_key->ipnk_ip,
-                    ipn->ipn_key->ipnk_type, &api->ip_address);
+  ip_address_encode2 (&ipn->ipn_key->ipnk_ip, &api->ip_address);
   mac_address_encode (&ipn->ipn_mac, api->mac_address);
 }
 
@@ -108,8 +100,8 @@ ip_neighbor_handle_event (const ip_neighbor_event_t * ipne)
       if (vlib_time_now (vlib_get_main ()) > last_time + 10.0)
        {
          clib_warning ("ip6 nd event for %U to pid %d: queue stuffed!",
-                       format_ip46_address, &ipn->ipn_key->ipnk_ip,
-                       IP46_TYPE_ANY, ipne->ipne_watch.ipw_pid);
+                       format_ip_address, &ipn->ipn_key->ipnk_ip,
+                       ipne->ipne_watch.ipw_pid);
          last_time = vlib_time_now (vlib_get_main ());
        }
     }
@@ -167,10 +159,7 @@ vl_api_ip_neighbor_dump_t_handler (vl_api_ip_neighbor_dump_t * mp)
   };
 
   // walk all neighbours on all interfaces
-  ip_neighbor_walk ((af == AF_IP4 ?
-                    IP46_TYPE_IP4 :
-                    IP46_TYPE_IP6),
-                   sw_if_index, send_ip_neighbor_details, &ctx);
+  ip_neighbor_walk (af, sw_if_index, send_ip_neighbor_details, &ctx);
 }
 
 static ip_neighbor_flags_t
@@ -193,15 +182,14 @@ vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
   vl_api_ip_neighbor_add_del_reply_t *rmp;
   ip_neighbor_flags_t flags;
   u32 stats_index = ~0;
-  ip46_address_t ip = ip46_address_initializer;
+  ip_address_t ip = ip_address_initializer;
   mac_address_t mac;
-  ip46_type_t type;
   int rv;
 
   VALIDATE_SW_IF_INDEX ((&mp->neighbor));
 
   flags = ip_neighbor_flags_decode (mp->neighbor.flags);
-  type = ip_address_decode (&mp->neighbor.ip_address, &ip);
+  ip_address_decode2 (&mp->neighbor.ip_address, &ip);
   mac_address_decode (mp->neighbor.mac_address, &mac);
 
   /* must be static or dynamic, default to dynamic */
@@ -215,11 +203,11 @@ vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
    * will come of adding bogus entries.
    */
   if (mp->is_add)
-    rv = ip_neighbor_add (&ip, type, &mac,
+    rv = ip_neighbor_add (&ip, &mac,
                          ntohl (mp->neighbor.sw_if_index),
                          flags, &stats_index);
   else
-    rv = ip_neighbor_del (&ip, type, ntohl (mp->neighbor.sw_if_index));
+    rv = ip_neighbor_del (&ip, ntohl (mp->neighbor.sw_if_index));
 
   BAD_SW_IF_INDEX_LABEL;
 
@@ -236,13 +224,12 @@ vl_api_want_ip_neighbor_events_t_handler (vl_api_want_ip_neighbor_events_t *
                                          mp)
 {
   vl_api_want_ip_neighbor_events_reply_t *rmp;
-  ip46_address_t ip;
-  ip46_type_t itype;
+  ip_address_t ip;
   int rv = 0;
 
   if (mp->sw_if_index != ~0)
     VALIDATE_SW_IF_INDEX (mp);
-  itype = ip_address_decode (&mp->ip, &ip);
+  ip_address_decode2 (&mp->ip, &ip);
 
   ip_neighbor_watcher_t watch = {
     .ipw_client = mp->client_index,
@@ -250,9 +237,9 @@ vl_api_want_ip_neighbor_events_t_handler (vl_api_want_ip_neighbor_events_t *
   };
 
   if (mp->enable)
-    ip_neighbor_watch (&ip, itype, ntohl (mp->sw_if_index), &watch);
+    ip_neighbor_watch (&ip, ntohl (mp->sw_if_index), &watch);
   else
-    ip_neighbor_unwatch (&ip, itype, ntohl (mp->sw_if_index), &watch);
+    ip_neighbor_unwatch (&ip, ntohl (mp->sw_if_index), &watch);
 
   BAD_SW_IF_INDEX_LABEL;
   REPLY_MACRO (VL_API_WANT_IP_NEIGHBOR_EVENTS_REPLY);
@@ -268,7 +255,7 @@ vl_api_ip_neighbor_config_t_handler (vl_api_ip_neighbor_config_t * mp)
   rv = ip_address_family_decode (mp->af, &af);
 
   if (!rv)
-    rv = ip_neighbor_config (ip46_type_from_af (af),
+    rv = ip_neighbor_config (af,
                             ntohl (mp->max_number),
                             ntohl (mp->max_age), mp->recycle);
 
@@ -282,8 +269,8 @@ vl_api_ip_neighbor_replace_begin_t_handler (vl_api_ip_neighbor_replace_begin_t
   vl_api_ip_neighbor_replace_begin_reply_t *rmp;
   int rv = 0;
 
-  ip_neighbor_mark (IP46_TYPE_IP4);
-  ip_neighbor_mark (IP46_TYPE_IP6);
+  ip_neighbor_mark (AF_IP4);
+  ip_neighbor_mark (AF_IP6);
 
   REPLY_MACRO (VL_API_IP_NEIGHBOR_REPLACE_BEGIN_REPLY);
 }
@@ -295,8 +282,8 @@ vl_api_ip_neighbor_replace_end_t_handler (vl_api_ip_neighbor_replace_end_t *
   vl_api_ip_neighbor_replace_end_reply_t *rmp;
   int rv = 0;
 
-  ip_neighbor_sweep (IP46_TYPE_IP4);
-  ip_neighbor_sweep (IP46_TYPE_IP6);
+  ip_neighbor_sweep (AF_IP4);
+  ip_neighbor_sweep (AF_IP6);
 
   REPLY_MACRO (VL_API_IP_NEIGHBOR_REPLACE_END_REPLY);
 }
@@ -314,7 +301,7 @@ vl_api_ip_neighbor_flush_t_handler (vl_api_ip_neighbor_flush_t * mp)
   rv = ip_address_family_decode (mp->af, &af);
 
   if (!rv)
-    ip_neighbor_del_all (ip46_type_from_af (af), ntohl (mp->sw_if_index));
+    ip_neighbor_del_all (af, ntohl (mp->sw_if_index));
 
   BAD_SW_IF_INDEX_LABEL;
   REPLY_MACRO (VL_API_IP_NEIGHBOR_FLUSH_REPLY);
index 32c674d..c18e494 100644 (file)
@@ -37,8 +37,7 @@ format_ip_neighbor_key (u8 * s, va_list * va)
 
   return (format (s, "[%U, %U]",
                  format_vnet_sw_if_index_name, vnet_get_main (),
-                 key->ipnk_sw_if_index,
-                 format_ip46_address, &key->ipnk_ip, key->ipnk_type));
+                 key->ipnk_sw_if_index, format_ip_address, &key->ipnk_ip));
 }
 
 u8 *
@@ -62,7 +61,7 @@ format_ip_neighbor (u8 * s, va_list * va)
   return (format (s, "%=12U%=40U%=6U%=20U%U",
                  format_vlib_time, vlib_get_main (),
                  ipn->ipn_time_last_updated,
-                 format_ip46_address, &ipn->ipn_key->ipnk_ip, IP46_TYPE_ANY,
+                 format_ip_address, &ipn->ipn_key->ipnk_ip,
                  format_ip_neighbor_flags, ipn->ipn_flags,
                  format_mac_address_t, &ipn->ipn_mac,
                  format_vnet_sw_if_index_name, vnet_get_main (),
index 82c5417..8dfc438 100644 (file)
@@ -18,7 +18,7 @@
 #ifndef __INCLUDE_IP_NEIGHBOR_TYPES_H__
 #define __INCLUDE_IP_NEIGHBOR_TYPES_H__
 
-#include <vnet/ip/ip6_packet.h>
+#include <vnet/ip/ip_types.h>
 #include <vnet/ethernet/mac_address.h>
 #include <vnet/fib/fib_types.h>
 
@@ -62,10 +62,10 @@ extern u8 *format_ip_neighbor_watcher (u8 * s, va_list * args);
 
 typedef struct ip_neighbor_key_t_
 {
-  ip46_address_t ipnk_ip;
-  ip46_type_t ipnk_type;
+  ip_address_t ipnk_ip;
+  u8 __pad[3];
   u32 ipnk_sw_if_index;
-} ip_neighbor_key_t;
+} __clib_packed ip_neighbor_key_t;
 
 /**
  * A representation of an IP neighbour/peer
@@ -110,8 +110,7 @@ extern ip_neighbor_t *ip_neighbor_get (index_t ipni);
 
 typedef struct ip_neighbor_learn_t_
 {
-  ip46_address_t ip;
-  ip46_type_t type;
+  ip_address_t ip;
   mac_address_t mac;
   u32 sw_if_index;
 } ip_neighbor_learn_t;
index 7464ee6..71d6440 100644 (file)
@@ -114,15 +114,13 @@ ip_neighbor_watch_cmp (const ip_neighbor_watcher_t * w1,
 }
 
 void
-ip_neighbor_watch (const ip46_address_t * ip,
-                  ip46_type_t type,
+ip_neighbor_watch (const ip_address_t * ip,
                   u32 sw_if_index,
                    const ip_neighbor_watcher_t * watch)
 {
   ip_neighbor_key_t key = {
     .ipnk_ip = *ip,
     .ipnk_sw_if_index = (sw_if_index == 0 ? ~0 : sw_if_index),
-    .ipnk_type = type,
   };
   ip_neighbor_watcher_t *ipws = NULL;
   uword *p;
@@ -145,15 +143,13 @@ ip_neighbor_watch (const ip46_address_t * ip,
 }
 
 void
-ip_neighbor_unwatch (const ip46_address_t * ip,
-                    ip46_type_t type,
+ip_neighbor_unwatch (const ip_address_t * ip,
                     u32 sw_if_index,
                      const ip_neighbor_watcher_t * watch)
 {
   ip_neighbor_key_t key = {
     .ipnk_ip = *ip,
     .ipnk_sw_if_index = (sw_if_index == 0 ? ~0 : sw_if_index),
-    .ipnk_type = type,
   };
   ip_neighbor_watcher_t *ipws = NULL;
   uword *p;
@@ -211,7 +207,7 @@ ip_neighbor_publish (index_t ipni)
     ip_neighbor_signal ((ip_neighbor_watcher_t*) p[0], ipni);
   }
 
-  ip46_address_reset (&key.ipnk_ip);
+  ip_address_reset (&key.ipnk_ip);
   p = mhash_get (&ipnw_db.ipnwdb_hash, &key);
 
   if (p) {
index 91d9f6f..fc190b5 100644 (file)
 
 #include <vnet/ip-neighbor/ip_neighbor_types.h>
 
-extern void ip_neighbor_watch (const ip46_address_t * ip,
-                              ip46_type_t type,
+extern void ip_neighbor_watch (const ip_address_t * ip,
                               u32 sw_if_index,
                               const ip_neighbor_watcher_t * watch);
-extern void ip_neighbor_unwatch (const ip46_address_t * ip,
-                                ip46_type_t type,
+extern void ip_neighbor_unwatch (const ip_address_t * ip,
                                 u32 sw_if_index,
                                 const ip_neighbor_watcher_t * watch);
 
index 294f632..cd753b0 100644 (file)
@@ -956,7 +956,10 @@ format_ip6_forward_next_trace (u8 * s, va_list * args)
   ip6_forward_next_trace_t *t = va_arg (*args, ip6_forward_next_trace_t *);
   u32 indent = format_get_indent (s);
 
-  s = format (s, "%U%U",
+  s = format (s, "%Ufib:%d adj:%d flow:%d",
+             format_white_space, indent,
+             t->fib_index, t->adj_index, t->flow_hash);
+  s = format (s, "\n%U%U",
              format_white_space, indent,
              format_ip6_header, t->packet_data, sizeof (t->packet_data));
   return s;
index 6e4bb3b..8f9f012 100644 (file)
@@ -288,6 +288,19 @@ ip_address_to_fib_prefix (const ip_address_t * addr, fib_prefix_t * prefix)
   prefix->___fp___pad = 0;
 }
 
+void
+ip_address_increment (ip_address_t * ip)
+{
+  ip46_address_increment ((ip_addr_version (ip) == AF_IP4 ?
+                          IP46_TYPE_IP4 : IP46_TYPE_IP6), &ip_addr_46 (ip));
+}
+
+void
+ip_address_reset (ip_address_t * ip)
+{
+  clib_memset (ip, 0, sizeof (*ip));
+}
+
 static void
 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
 {
index 2049170..f779fe7 100644 (file)
@@ -26,8 +26,6 @@ typedef enum ip_address_family_t_
 
 #define N_AF (AF_IP6+1)
 
-#define N_AF (AF_IP6+1)
-
 extern uword unformat_ip_address_family (unformat_input_t * input,
                                         va_list * args);
 extern u8 *format_ip_address_family (u8 * s, va_list * args);
@@ -76,6 +74,8 @@ extern fib_protocol_t ip_address_to_46 (const ip_address_t * addr,
                                        ip46_address_t * a);
 extern void ip_address_from_46 (const ip46_address_t * a,
                                fib_protocol_t fproto, ip_address_t * addr);
+extern void ip_address_increment (ip_address_t * ip);
+extern void ip_address_reset (ip_address_t * ip);
 
 /* *INDENT-OFF* */
 typedef struct ip_prefix
index da49666..917abdd 100644 (file)
@@ -157,12 +157,17 @@ icmp6_neighbor_solicitation_or_advertisement (vlib_main_t * vm,
          if (PREDICT_TRUE (error0 == ICMP6_ERROR_NONE && o0 != 0 &&
                            !ip6_sadd_unspecified))
            {
+              /* *INDENT-OFF* */
              ip_neighbor_learn_t learn = {
                .sw_if_index = sw_if_index0,
-               .type = IP46_TYPE_IP6,
-               .ip.ip6 = (is_solicitation ?
-                          ip0->src_address : h0->target_address),
+               .ip = {
+                  .version = AF_IP6,
+                  .ip.ip6 = (is_solicitation ?
+                             ip0->src_address :
+                             h0->target_address),
+                }
              };
+              /* *INDENT-ON* */
              memcpy (&learn.mac, o0->ethernet_address, sizeof (learn.mac));
              ip_neighbor_learn_dp (&learn);
            }
@@ -459,7 +464,7 @@ ip6_nd_init (vlib_main_t * vm)
   icmp6_register_type (vm, ICMP6_neighbor_advertisement,
                       ip6_icmp_neighbor_advertisement_node.index);
 
-  ip_neighbor_register (IP46_TYPE_IP6, &ip6_nd_impl_vft);
+  ip_neighbor_register (AF_IP6, &ip6_nd_impl_vft);
 
   ip6_nd_delegate_id = ip6_link_delegate_register (&ip6_nd_delegate_vft);
 
index 91a1339..ea7ca56 100644 (file)
@@ -52,7 +52,11 @@ ip6_nd_proxy_add_del (u32 sw_if_index, const ip6_address_t * addr, u8 is_del)
                                   sw_if_index,
                                   ~0, 1, FIB_ROUTE_PATH_FLAG_NONE);
       /* flush the ND cache of this address if it's there */
-      ip_neighbor_del (&nh, IP46_TYPE_IP6, sw_if_index);
+      ip_address_t ip = {
+       .ip = nh,
+       .version = AF_IP6,
+      };
+      ip_neighbor_del (&ip, sw_if_index);
     }
   else
     {
index 2bfa425..97c5b4a 100644 (file)
@@ -368,11 +368,15 @@ icmp6_router_solicitation (vlib_main_t * vm,
          if (PREDICT_TRUE (error0 == ICMP6_ERROR_NONE && o0 != 0 &&
                            !is_unspecified && !is_link_local))
            {
+              /* *INDENT-OFF* */
              ip_neighbor_learn_t learn = {
-               .type = IP46_TYPE_IP6,
                .sw_if_index = sw_if_index0,
-               .ip.ip6 = ip0->src_address,
+               .ip = {
+                  .ip.ip6 = ip0->src_address,
+                  .version = AF_IP6,
+                },
              };
+              /* *INDENT-ON* */
              memcpy (&learn.mac, o0->ethernet_address, sizeof (learn.mac));
              ip_neighbor_learn_dp (&learn);
            }
index dfefb15..b263007 100644 (file)
@@ -204,6 +204,8 @@ class ARPTestCase(VppTestCase):
         dyn_arp.add_vpp_config()
         self.assertTrue(dyn_arp.query_vpp_config())
 
+        self.logger.info(self.vapi.cli("show ip neighbor-watcher"))
+
         # this matches all of the listnerers
         es = [self.vapi.wait_for_event(1, "ip_neighbor_event")
               for i in range(3)]
index 7cc6cdc..fb55a36 100644 (file)
@@ -190,6 +190,7 @@ class P2PEthernetIPV6(VppTestCase):
         """standard routing without p2p subinterfaces"""
         self.logger.info("FFP_TEST_START_0001")
 
+        self.pg0.config_ip6()
         route_8000 = VppIpRoute(self, "8000::", 64,
                                 [VppRoutePath(self.pg0.remote_ip6,
                                               self.pg0.sw_if_index)])
@@ -202,6 +203,7 @@ class P2PEthernetIPV6(VppTestCase):
                          Raw(b'\xa5' * 100))]
         self.send_packets(self.pg1, self.pg0)
 
+        self.pg0.unconfig_ip6()
         self.logger.info("FFP_TEST_FINISH_0001")
 
     def test_ip6_rx_p2p_subif(self):
@@ -273,8 +275,10 @@ class P2PEthernetIPV6(VppTestCase):
         """send packet via p2p subinterface"""
         self.logger.info("FFP_TEST_START_0005")
 
+        self.pg0.config_ip6()
+
         route_8000 = VppIpRoute(self, "8000::", 64,
-                                [VppRoutePath(self.pg0.remote_ip6,
+                                [VppRoutePath(self.pg0.remote_hosts[0].ip6,
                                               self.pg0.sw_if_index)])
         route_8000.add_vpp_config()
         route_8001 = VppIpRoute(self, "8001::", 64,
@@ -301,6 +305,7 @@ class P2PEthernetIPV6(VppTestCase):
         route_8001.remove_vpp_config()
         route_8002.remove_vpp_config()
 
+        self.pg0.unconfig_ip6()
         self.logger.info("FFP_TEST_FINISH_0005")
 
     def test_ip6_tx_p2p_subif_drop(self):