Use IP and MAC API types for neighbors 38/14138/13
authorNeale Ranns <nranns@cisco.com>
Fri, 10 Aug 2018 12:30:06 +0000 (05:30 -0700)
committerDamjan Marion <dmarion@me.com>
Wed, 30 Jan 2019 19:47:53 +0000 (19:47 +0000)
use address_t and mac_address_t for IPv6 and ARP entries
and all other API calls in ip.api aprat from the route ones,
that will follow in a separate commit

Change-Id: I67161737c2184d3f8fc1e79ebd2b55121c5b0191
Signed-off-by: Neale Ranns <nranns@cisco.com>
46 files changed:
extras/vom/vom/api_types.cpp
extras/vom/vom/api_types.hpp
extras/vom/vom/arp_proxy_config.cpp
extras/vom/vom/arp_proxy_config_cmds.cpp
extras/vom/vom/neighbour.cpp
extras/vom/vom/neighbour_cmds.cpp
extras/vom/vom/ra_prefix.cpp
src/plugins/gbp/gbp_endpoint.c
src/plugins/mactime/mactime.c
src/plugins/mactime/mactime.h
src/vat/api_format.c
src/vnet/ethernet/arp.c
src/vnet/ethernet/arp.h
src/vnet/ethernet/arp_packet.h
src/vnet/ethernet/ethernet.h
src/vnet/ethernet/interface.c
src/vnet/ethernet/mac_address.c
src/vnet/ethernet/mac_address.h
src/vnet/ethernet/node.c
src/vnet/ip/ip.api
src/vnet/ip/ip4_forward.c
src/vnet/ip/ip6.h
src/vnet/ip/ip6_neighbor.c
src/vnet/ip/ip6_neighbor.h
src/vnet/ip/ip6_packet.h
src/vnet/ip/ip_api.c
src/vnet/ip/ip_neighbor.c
src/vnet/ip/ip_neighbor.h
src/vnet/ip/ip_types_api.c
src/vnet/ip/ip_types_api.h
src/vnet/ip/lookup.c
src/vnet/ip/rd_cp.c
src/vnet/l2/l2_bvi.h
src/vnet/lisp-cp/control.c
src/vpp/api/api.c
src/vpp/api/custom_dump.c
src/vpp/api/types.c
src/vpp/api/types.h
test/test_dhcp.py
test/test_ip6.py
test/test_l2bd_arp_term.py
test/test_nat.py
test/test_neighbor.py
test/vpp_interface.py
test/vpp_neighbor.py
test/vpp_papi_provider.py

index 4a81a41..486ebda 100644 (file)
 
 namespace VOM {
 
+void
+to_api(const boost::asio::ip::address_v4& a, vapi_type_ip4_address& v)
+{
+  std::copy_n(std::begin(a.to_bytes()), a.to_bytes().size(), v);
+}
+void
+to_api(const boost::asio::ip::address_v6& a, vapi_type_ip6_address& v)
+{
+  std::copy_n(std::begin(a.to_bytes()), a.to_bytes().size(), v);
+}
+
 void
 to_api(const ip_address_t& a, vapi_type_address& v)
 {
@@ -43,10 +54,24 @@ to_api(const ip_address_t& a,
   }
 }
 
-void
-to_api(const boost::asio::ip::address& a, vapi_type_ip4_address& v)
+boost::asio::ip::address_v6
+from_api(const vapi_type_ip6_address& v)
+{
+  std::array<uint8_t, 16> a;
+  std::copy(v, v + 16, std::begin(a));
+  boost::asio::ip::address_v6 v6(a);
+
+  return v6;
+}
+
+boost::asio::ip::address_v4
+from_api(const vapi_type_ip4_address& v)
 {
-  memcpy(v, a.to_v4().to_bytes().data(), 4);
+  std::array<uint8_t, 4> a;
+  std::copy(v, v + 4, std::begin(a));
+  boost::asio::ip::address_v4 v4(a);
+
+  return v4;
 }
 
 ip_address_t
index 5856c22..ac9a65e 100644 (file)
@@ -24,13 +24,15 @@ namespace VOM {
 typedef boost::asio::ip::address ip_address_t;
 
 void to_api(const ip_address_t& a, vapi_type_address& v);
-void to_api(const boost::asio::ip::address& a, vapi_type_ip4_address& v);
+void to_api(const boost::asio::ip::address_v4& a, vapi_type_ip4_address& v);
+void to_api(const boost::asio::ip::address_v6& a, vapi_type_ip6_address& v);
 void to_api(const boost::asio::ip::address& a,
             vapi_union_address_union& u,
             vapi_enum_address_family& af);
 
+boost::asio::ip::address_v4 from_api(const vapi_type_ip4_address& v);
+boost::asio::ip::address_v6 from_api(const vapi_type_ip6_address& v);
 ip_address_t from_api(const vapi_type_address& v);
-ip_address_t from_api(const vapi_type_ip4_address& v);
 ip_address_t from_api(const vapi_union_address_union& u,
                       vapi_enum_address_family af);
 
index 275d9f9..e21fd4a 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include "vom/arp_proxy_config.hpp"
+#include "vom/api_types.hpp"
 #include "vom/arp_proxy_config_cmds.hpp"
 #include "vom/prefix.hpp"
 #include "vom/singular_db_funcs.hpp"
@@ -125,8 +126,8 @@ arp_proxy_config::event_handler::handle_populate(const client_db::key_t& key)
   for (auto& record : *cmd) {
     auto& payload = record.get_payload();
 
-    boost::asio::ip::address lo = from_bytes(0, payload.proxy.low_address);
-    boost::asio::ip::address hi = from_bytes(0, payload.proxy.hi_address);
+    boost::asio::ip::address lo = from_api(payload.proxy.low);
+    boost::asio::ip::address hi = from_api(payload.proxy.hi);
 
     arp_proxy_config ap(lo.to_v4(), hi.to_v4());
     OM::commit(key, ap);
index deb52c4..8185c09 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include "vom/arp_proxy_config_cmds.hpp"
+#include "vom/api_types.hpp"
 
 namespace VOM {
 namespace arp_proxy_config_cmds {
@@ -41,10 +42,8 @@ config_cmd::issue(connection& con)
   auto& payload = req.get_request().get_payload();
   payload.is_add = 1;
 
-  std::copy_n(std::begin(m_low.to_bytes()), m_low.to_bytes().size(),
-              payload.proxy.low_address);
-  std::copy_n(std::begin(m_high.to_bytes()), m_high.to_bytes().size(),
-              payload.proxy.hi_address);
+  to_api(m_low, payload.proxy.low);
+  to_api(m_high, payload.proxy.hi);
 
   VAPI_CALL(req.execute());
 
@@ -86,10 +85,8 @@ unconfig_cmd::issue(connection& con)
   auto& payload = req.get_request().get_payload();
   payload.is_add = 0;
 
-  std::copy_n(std::begin(m_low.to_bytes()), m_low.to_bytes().size(),
-              payload.proxy.low_address);
-  std::copy_n(std::begin(m_high.to_bytes()), m_high.to_bytes().size(),
-              payload.proxy.hi_address);
+  to_api(m_low, payload.proxy.low);
+  to_api(m_high, payload.proxy.hi);
 
   VAPI_CALL(req.execute());
 
index 44e2760..cbcebd6 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include "vom/neighbour.hpp"
+#include "vom/api_types.hpp"
 #include "vom/neighbour_cmds.hpp"
 #include "vom/singular_db_funcs.hpp"
 
@@ -165,9 +166,8 @@ neighbour::populate_i(const client_db::key_t& key,
      */
     auto& payload = record.get_payload();
 
-    mac_address_t mac(payload.mac_address);
-    boost::asio::ip::address ip_addr =
-      from_bytes(payload.is_ipv6, payload.ip_address);
+    mac_address_t mac = from_api(payload.neighbor.mac_address);
+    boost::asio::ip::address ip_addr = from_api(payload.neighbor.ip_address);
     neighbour n(*itf, ip_addr, mac);
 
     VOM_LOG(log_level_t::DEBUG) << "neighbour-dump: " << itf->to_string()
index 9bd3292..d43e508 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include "vom/neighbour_cmds.hpp"
+#include "vom/api_types.hpp"
 
 namespace VOM {
 namespace neighbour_cmds {
@@ -41,11 +42,12 @@ create_cmd::issue(connection& con)
   msg_t req(con.ctx(), std::ref(*this));
 
   auto& payload = req.get_request().get_payload();
-  payload.sw_if_index = m_itf.value();
   payload.is_add = 1;
-  payload.is_static = 1;
-  m_mac.to_bytes(payload.mac_address, 6);
-  to_bytes(m_ip_addr, &payload.is_ipv6, payload.dst_address);
+  payload.neighbor.sw_if_index = m_itf.value();
+  payload.neighbor.flags = IP_API_NEIGHBOR_FLAG_STATIC;
+
+  to_api(m_mac, payload.neighbor.mac_address);
+  to_api(m_ip_addr, payload.neighbor.ip_address);
 
   VAPI_CALL(req.execute());
 
@@ -87,11 +89,12 @@ delete_cmd::issue(connection& con)
   msg_t req(con.ctx(), std::ref(*this));
 
   auto& payload = req.get_request().get_payload();
-  payload.sw_if_index = m_itf.value();
   payload.is_add = 0;
-  payload.is_static = 1;
-  m_mac.to_bytes(payload.mac_address, 6);
-  to_bytes(m_ip_addr, &payload.is_ipv6, payload.dst_address);
+  payload.neighbor.sw_if_index = m_itf.value();
+  payload.neighbor.flags = IP_API_NEIGHBOR_FLAG_STATIC;
+
+  to_api(m_mac, payload.neighbor.mac_address);
+  to_api(m_ip_addr, payload.neighbor.ip_address);
 
   VAPI_CALL(req.execute());
 
index 1cf0963..fe3ad32 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <sstream>
 
+#include "vom/api_types.hpp"
 #include "vom/ra_prefix.hpp"
 
 namespace VOM {
@@ -37,9 +38,7 @@ ra_prefix::ra_prefix(const route::prefix_t& pfx,
 void
 ra_prefix::to_vpp(vapi_payload_sw_interface_ip6nd_ra_prefix& ra_prefix) const
 {
-  uint8_t is_ipv6 = 0;
-
-  m_pfx.to_vpp(&is_ipv6, ra_prefix.address, &ra_prefix.address_length);
+  ra_prefix.prefix = to_api(m_pfx);
 
   ra_prefix.use_default = m_use_default;
   ra_prefix.no_advertise = m_no_advertise;
index 0746b70..f32a882 100644 (file)
@@ -111,7 +111,7 @@ static void
 gbp_endpoint_extract_key_mac_itf (const clib_bihash_kv_16_8_t * key,
                                  mac_address_t * mac, u32 * sw_if_index)
 {
-  mac_address_from_u64 (key->key[0], mac);
+  mac_address_from_u64 (mac, key->key[0]);
   *sw_if_index = key->key[1];
 }
 
index 837b317..572b913 100644 (file)
@@ -553,8 +553,7 @@ show_mactime_command_fn (vlib_main_t * vm,
       for (j = 0; j < vec_len (mm->arp_cache_copy); j++)
        {
          n = mm->arp_cache_copy + j;
-         if (!memcmp (dp->mac_address, n->ethernet_address,
-                      sizeof (n->ethernet_address)))
+         if (!memcmp (dp->mac_address, n->mac.bytes, sizeof (n->mac)))
            {
              vlib_cli_output (vm, "%17s%U", " ", format_ip4_address,
                               &n->ip4_address);
index 1a13e41..8d41652 100644 (file)
@@ -21,7 +21,7 @@
 #include <vnet/vnet.h>
 #include <vnet/ip/ip.h>
 #include <vnet/ethernet/ethernet.h>
-#include <vnet/ethernet/arp_packet.h>
+#include <vnet/ethernet/arp.h>
 #include <vlib/counter.h>
 
 #include <vppinfra/hash.h>
index 0a42900..85bf9d0 100644 (file)
@@ -24,6 +24,7 @@
 #include <vlibmemory/api.h>
 #include <vnet/ip/ip.h>
 #include <vnet/ip/ip_neighbor.h>
+#include <vnet/ip/ip_types_api.h>
 #include <vnet/l2/l2_input.h>
 #include <vnet/l2tp/l2tp.h>
 #include <vnet/vxlan/vxlan.h>
@@ -53,6 +54,8 @@
 #include <vnet/dhcp/dhcp_proxy.h>
 #include <vnet/bonding/node.h>
 #include <vnet/qos/qos_types.h>
+#include <vnet/ethernet/ethernet_types_api.h>
+#include <vnet/ip/ip_types_api.h>
 #include "vat/json_format.h"
 #include <vnet/ip/ip_types_api.h>
 #include <vnet/ethernet/ethernet_types_api.h>
@@ -1441,8 +1444,8 @@ vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
   u32 sw_if_index = ntohl (mp->sw_if_index);
   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
          mp->mac_ip ? "mac/ip binding" : "address resolution",
-         ntohl (mp->pid), format_ip4_address, &mp->address,
-         format_ethernet_address, mp->new_mac, sw_if_index);
+         ntohl (mp->pid), format_ip4_address, mp->ip,
+         format_vl_api_mac_address, &mp->mac, sw_if_index);
 }
 
 static void
@@ -1457,8 +1460,8 @@ vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
   u32 sw_if_index = ntohl (mp->sw_if_index);
   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
          mp->mac_ip ? "mac/ip binding" : "address resolution",
-         ntohl (mp->pid), format_ip6_address, mp->address,
-         format_ethernet_address, mp->new_mac, sw_if_index);
+         ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
+         format_vl_api_mac_address, mp->mac, sw_if_index);
 }
 
 static void
@@ -9117,7 +9120,7 @@ api_proxy_arp_add_del (vat_main_t * vam)
   vl_api_proxy_arp_add_del_t *mp;
   u32 vrf_id = 0;
   u8 is_add = 1;
-  ip4_address_t lo, hi;
+  vl_api_ip4_address_t lo, hi;
   u8 range_set = 0;
   int ret;
 
@@ -9125,8 +9128,8 @@ api_proxy_arp_add_del (vat_main_t * vam)
     {
       if (unformat (i, "vrf %d", &vrf_id))
        ;
-      else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
-                        unformat_ip4_address, &hi))
+      else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
+                        unformat_vl_api_ip4_address, &hi))
        range_set = 1;
       else if (unformat (i, "del"))
        is_add = 0;
@@ -9145,10 +9148,10 @@ api_proxy_arp_add_del (vat_main_t * vam)
 
   M (PROXY_ARP_ADD_DEL, mp);
 
-  mp->proxy.vrf_id = ntohl (vrf_id);
+  mp->proxy.table_id = ntohl (vrf_id);
   mp->is_add = is_add;
-  clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
-  clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
+  clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
+  clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
 
   S (mp);
   W (ret);
@@ -9356,27 +9359,25 @@ api_sw_interface_set_unnumbered (vat_main_t * vam)
 static int
 api_ip_neighbor_add_del (vat_main_t * vam)
 {
+  vl_api_mac_address_t mac_address;
   unformat_input_t *i = vam->input;
   vl_api_ip_neighbor_add_del_t *mp;
+  vl_api_address_t ip_address;
   u32 sw_if_index;
   u8 sw_if_index_set = 0;
   u8 is_add = 1;
-  u8 is_static = 0;
-  u8 is_no_fib_entry = 0;
-  u8 mac_address[6];
   u8 mac_set = 0;
-  u8 v4_address_set = 0;
-  u8 v6_address_set = 0;
-  ip4_address_t v4address;
-  ip6_address_t v6address;
+  u8 address_set = 0;
   int ret;
+  ip_neighbor_flags_t flags;
 
-  clib_memset (mac_address, 0, sizeof (mac_address));
-
+  flags = IP_NEIGHBOR_FLAG_NONE;
+  clib_memset (&ip_address, 0, sizeof (ip_address));
+  clib_memset (&mac_address, 0, sizeof (mac_address));
   /* Parse args required to build the message */
   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
+      if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
        {
          mac_set = 1;
        }
@@ -9387,14 +9388,12 @@ api_ip_neighbor_add_del (vat_main_t * vam)
        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, "is_static"))
-       is_static = 1;
+      else if (unformat (i, "static"))
+       flags |= IP_NEIGHBOR_FLAG_STATIC;
       else if (unformat (i, "no-fib-entry"))
-       is_no_fib_entry = 1;
-      else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
-       v4_address_set = 1;
-      else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
-       v6_address_set = 1;
+       flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
+      else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
+       address_set = 1;
       else
        {
          clib_warning ("parse error '%U'", format_unformat_error, i);
@@ -9407,12 +9406,7 @@ api_ip_neighbor_add_del (vat_main_t * vam)
       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)
+  if (!address_set)
     {
       errmsg ("no address set");
       return -99;
@@ -9421,22 +9415,14 @@ api_ip_neighbor_add_del (vat_main_t * vam)
   /* Construct the API message */
   M (IP_NEIGHBOR_ADD_DEL, mp);
 
-  mp->sw_if_index = ntohl (sw_if_index);
+  mp->neighbor.sw_if_index = ntohl (sw_if_index);
   mp->is_add = is_add;
-  mp->is_static = is_static;
-  mp->is_no_adj_fib = is_no_fib_entry;
+  mp->neighbor.flags = htonl (flags);
   if (mac_set)
-    clib_memcpy (mp->mac_address, mac_address, 6);
-  if (v6_address_set)
-    {
-      mp->is_ipv6 = 1;
-      clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
-    }
-  else
-    {
-      /* mp->is_ipv6 = 0; via clib_memset in M macro above */
-      clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
-    }
+    clib_memcpy (&mp->neighbor.mac_address, &mac_address,
+                sizeof (mac_address));
+  if (address_set)
+    clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
 
   /* send it... */
   S (mp);
@@ -10135,7 +10121,7 @@ api_ip6nd_proxy_add_del (vat_main_t * vam)
   vl_api_ip6nd_proxy_add_del_t *mp;
   u32 sw_if_index = ~0;
   u8 v6_address_set = 0;
-  ip6_address_t v6address;
+  vl_api_ip6_address_t v6address;
   u8 is_del = 0;
   int ret;
 
@@ -10146,7 +10132,7 @@ api_ip6nd_proxy_add_del (vat_main_t * vam)
        ;
       else if (unformat (i, "sw_if_index %d", &sw_if_index))
        ;
-      else if (unformat (i, "%U", unformat_ip6_address, &v6address))
+      else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
        v6_address_set = 1;
       if (unformat (i, "del"))
        is_del = 1;
@@ -10173,7 +10159,7 @@ api_ip6nd_proxy_add_del (vat_main_t * vam)
 
   mp->is_del = is_del;
   mp->sw_if_index = ntohl (sw_if_index);
-  clib_memcpy (mp->address, &v6address, sizeof (v6address));
+  clib_memcpy (mp->ip, v6address, sizeof (v6address));
 
   /* send it... */
   S (mp);
@@ -10208,7 +10194,7 @@ static void vl_api_ip6nd_proxy_details_t_handler
   vat_main_t *vam = &vat_main;
 
   print (vam->ofp, "host %U sw_if_index %d",
-        format_ip6_address, mp->address, ntohl (mp->sw_if_index));
+        format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
 }
 
 static void vl_api_ip6nd_proxy_details_t_handler_json
@@ -10228,7 +10214,7 @@ static void vl_api_ip6nd_proxy_details_t_handler_json
   vat_json_init_object (node);
   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
 
-  clib_memcpy (&ip6, mp->address, sizeof (ip6));
+  clib_memcpy (&ip6, mp->ip, sizeof (ip6));
   vat_json_object_add_ip6 (node, "host", ip6);
 }
 
@@ -10241,7 +10227,7 @@ api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
   u8 sw_if_index_set = 0;
   u32 address_length = 0;
   u8 v6_address_set = 0;
-  ip6_address_t v6address;
+  vl_api_prefix_t pfx;
   u8 use_default = 0;
   u8 no_advertise = 0;
   u8 off_link = 0;
@@ -10259,8 +10245,7 @@ api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
        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_ip6_address, &v6address, &address_length))
+      else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
        v6_address_set = 1;
       else if (unformat (i, "val_life %d", &val_lifetime))
        ;
@@ -10300,8 +10285,7 @@ api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
 
   mp->sw_if_index = ntohl (sw_if_index);
-  clib_memcpy (mp->address, &v6address, sizeof (v6address));
-  mp->address_length = address_length;
+  clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
   mp->use_default = use_default;
   mp->no_advertise = no_advertise;
   mp->off_link = off_link;
@@ -14310,10 +14294,9 @@ api_ip_probe_neighbor (vat_main_t * vam)
 {
   unformat_input_t *i = vam->input;
   vl_api_ip_probe_neighbor_t *mp;
+  vl_api_address_t dst_adr;
   u8 int_set = 0;
   u8 adr_set = 0;
-  u8 is_ipv6 = 0;
-  u8 dst_adr[16];
   u32 sw_if_index;
   int ret;
 
@@ -14323,13 +14306,8 @@ api_ip_probe_neighbor (vat_main_t * vam)
        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))
+      else if (unformat (i, "address %U", unformat_vl_api_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;
     }
@@ -14349,8 +14327,7 @@ api_ip_probe_neighbor (vat_main_t * vam)
   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));
+  clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
 
   S (mp);
   W (ret);
@@ -14458,7 +14435,7 @@ api_want_ip4_arp_events (vat_main_t * vam)
   M (WANT_IP4_ARP_EVENTS, mp);
   mp->enable_disable = enable_disable;
   mp->pid = htonl (getpid ());
-  mp->address = address.as_u32;
+  clib_memcpy (mp->ip, &address, sizeof (address));
 
   S (mp);
   W (ret);
@@ -14470,14 +14447,15 @@ api_want_ip6_nd_events (vat_main_t * vam)
 {
   unformat_input_t *line_input = vam->input;
   vl_api_want_ip6_nd_events_t *mp;
-  ip6_address_t address;
+  vl_api_ip6_address_t address;
   int address_set = 0;
   u32 enable_disable = 1;
   int ret;
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (line_input, "address %U", unformat_ip6_address, &address))
+      if (unformat
+         (line_input, "address %U", unformat_vl_api_ip6_address, &address))
        address_set = 1;
       else if (unformat (line_input, "del"))
        enable_disable = 0;
@@ -14494,7 +14472,7 @@ api_want_ip6_nd_events (vat_main_t * vam)
   M (WANT_IP6_ND_EVENTS, mp);
   mp->enable_disable = enable_disable;
   mp->pid = htonl (getpid ());
-  clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
+  clib_memcpy (&mp->ip, &address, sizeof (address));
 
   S (mp);
   W (ret);
@@ -20178,10 +20156,9 @@ static void vl_api_ip_neighbor_details_t_handler
   vat_main_t *vam = &vat_main;
 
   print (vam->ofp, "%c %U %U",
-        (mp->is_static) ? 'S' : 'D',
-        format_ethernet_address, &mp->mac_address,
-        (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
-        &mp->ip_address);
+        (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
+        format_vl_api_mac_address, &mp->neighbor.mac_address,
+        format_vl_api_address, &mp->neighbor.ip_address);
 }
 
 static void vl_api_ip_neighbor_details_t_handler_json
@@ -20201,22 +20178,23 @@ static void vl_api_ip_neighbor_details_t_handler_json
   node = vat_json_array_add (&vam->json_tree);
 
   vat_json_init_object (node);
-  vat_json_object_add_string_copy (node, "flag",
-                                  (mp->is_static) ? (u8 *) "static" : (u8 *)
-                                  "dynamic");
+  vat_json_object_add_string_copy
+    (node, "flag",
+     ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
+      (u8 *) "static" : (u8 *) "dynamic"));
 
   vat_json_object_add_string_copy (node, "link_layer",
-                                  format (0, "%U", format_ethernet_address,
-                                          &mp->mac_address));
+                                  format (0, "%U", format_vl_api_mac_address,
+                                          &mp->neighbor.mac_address));
 
-  if (mp->is_ipv6)
+  if (ADDRESS_IP6 == mp->neighbor.ip_address.af)
     {
-      clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
+      clib_memcpy (&ip6, &mp->neighbor.ip_address.un.ip6, sizeof (ip6));
       vat_json_object_add_ip6 (node, "ip_address", ip6);
     }
   else
     {
-      clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
+      clib_memcpy (&ip4, &mp->neighbor.ip_address.un.ip4, sizeof (ip4));
       vat_json_object_add_ip4 (node, "ip_address", ip4);
     }
 }
@@ -20969,9 +20947,7 @@ api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
   u16 *high_ports = 0;
   u16 this_low;
   u16 this_hi;
-  ip4_address_t ip4_addr;
-  ip6_address_t ip6_addr;
-  u32 length;
+  vl_api_prefix_t prefix;
   u32 tmp, tmp2;
   u8 prefix_set = 0;
   u32 vrf_id = ~0;
@@ -20981,17 +20957,8 @@ api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
-       {
-         prefix_set = 1;
-       }
-      else
-       if (unformat
-           (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
-       {
-         prefix_set = 1;
-         is_ipv6 = 1;
-       }
+      if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
+       prefix_set = 1;
       else if (unformat (input, "vrf %d", &vrf_id))
        ;
       else if (unformat (input, "del"))
@@ -21062,18 +21029,8 @@ api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
 
   mp->is_add = is_add;
 
-  if (is_ipv6)
-    {
-      mp->is_ipv6 = 1;
-      clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
-    }
-  else
-    {
-      mp->is_ipv6 = 0;
-      clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
-    }
+  clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
 
-  mp->mask_length = length;
   mp->number_of_ranges = vec_len (low_ports);
 
   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
@@ -22526,10 +22483,8 @@ api_ip_container_proxy_add_del (vat_main_t * vam)
 {
   vl_api_ip_container_proxy_add_del_t *mp;
   unformat_input_t *i = vam->input;
-  u32 plen = ~0, sw_if_index = ~0;
-  ip4_address_t ip4;
-  ip6_address_t ip6;
-  u8 is_ip4 = 1;
+  u32 sw_if_index = ~0;
+  vl_api_prefix_t pfx = { };
   u8 is_add = 1;
   int ret;
 
@@ -22539,22 +22494,14 @@ api_ip_container_proxy_add_del (vat_main_t * vam)
        is_add = 0;
       else if (unformat (i, "add"))
        ;
-      if (unformat (i, "%U", unformat_ip4_address, &ip4))
-       {
-         is_ip4 = 1;
-         plen = 32;
-       }
-      else if (unformat (i, "%U", unformat_ip6_address, &ip6))
-       {
-         is_ip4 = 0;
-         plen = 128;
-       }
+      if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
+       ;
       else if (unformat (i, "sw_if_index %u", &sw_if_index))
        ;
       else
        break;
     }
-  if (sw_if_index == ~0 || plen == ~0)
+  if (sw_if_index == ~0 || pfx.address_length == 0)
     {
       errmsg ("address and sw_if_index must be set");
       return -99;
@@ -22562,14 +22509,9 @@ api_ip_container_proxy_add_del (vat_main_t * vam)
 
   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
 
-  mp->is_ip4 = is_ip4;
   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
-  mp->plen = plen;
   mp->is_add = is_add;
-  if (is_ip4)
-    clib_memcpy (mp->ip, &ip4, sizeof (ip4));
-  else
-    clib_memcpy (mp->ip, &ip6, sizeof (ip6));
+  clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
 
   S (mp);
   W (ret);
index e6e3a51..dded56a 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <vnet/ip/ip.h>
+#include <vnet/ip/ip_neighbor.h>
 #include <vnet/ip/ip6.h>
 #include <vnet/ethernet/ethernet.h>
 #include <vnet/ethernet/arp.h>
@@ -65,7 +66,7 @@ typedef struct
   uword type_opaque;
   uword data;
   /* Used for arp event notification only */
-  void *data_callback;
+  arp_change_event_cb_t data_callback;
   u32 pid;
 } pending_resolution_t;
 
@@ -103,10 +104,10 @@ static ethernet_arp_main_t ethernet_arp_main;
 typedef struct
 {
   u32 sw_if_index;
-  ethernet_arp_ip4_over_ethernet_address_t a;
-  int is_static;
-  int is_no_fib_entry;
-  int flags;
+  ip4_address_t ip4;
+  mac_address_t mac;
+  ip_neighbor_flags_t nbr_flags;
+  u32 flags;
 #define ETHERNET_ARP_ARGS_REMOVE (1<<0)
 #define ETHERNET_ARP_ARGS_FLUSH  (1<<1)
 #define ETHERNET_ARP_ARGS_POPULATE  (1<<2)
@@ -226,9 +227,9 @@ format_ethernet_arp_header (u8 * s, va_list * va)
     {
       s = format (s, "\n%U%U/%U -> %U/%U",
                  format_white_space, indent,
-                 format_ethernet_address, a->ip4_over_ethernet[0].ethernet,
+                 format_mac_address_t, &a->ip4_over_ethernet[0].mac,
                  format_ip4_address, &a->ip4_over_ethernet[0].ip4,
-                 format_ethernet_address, a->ip4_over_ethernet[1].ethernet,
+                 format_mac_address_t, &a->ip4_over_ethernet[1].mac,
                  format_ip4_address, &a->ip4_over_ethernet[1].ip4);
     }
   else
@@ -260,20 +261,20 @@ format_ethernet_arp_ip4_entry (u8 * s, va_list * va)
 
   si = vnet_get_sw_interface (vnm, e->sw_if_index);
 
-  if (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC)
+  if (e->flags & IP_NEIGHBOR_FLAG_STATIC)
     flags = format (flags, "S");
 
-  if (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_DYNAMIC)
+  if (e->flags & IP_NEIGHBOR_FLAG_DYNAMIC)
     flags = format (flags, "D");
 
-  if (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_NO_FIB_ENTRY)
+  if (e->flags & IP_NEIGHBOR_FLAG_NO_FIB_ENTRY)
     flags = format (flags, "N");
 
   s = format (s, "%=12U%=16U%=6s%=20U%U",
              format_vlib_time, vnm->vlib_main, e->time_last_updated,
              format_ip4_address, &e->ip4_address,
              flags ? (char *) flags : "",
-             format_ethernet_address, e->ethernet_address,
+             format_mac_address_t, &e->mac,
              format_vnet_sw_interface_name, vnm, si);
 
   vec_free (flags);
@@ -358,9 +359,7 @@ arp_nbr_probe (ip_adjacency_t * adj)
 
   hi = vnet_get_sup_hw_interface (vnm, adj->rewrite_header.sw_if_index);
 
-  clib_memcpy_fast (h->ip4_over_ethernet[0].ethernet,
-                   hi->hw_address,
-                   sizeof (h->ip4_over_ethernet[0].ethernet));
+  mac_address_from_bytes (&h->ip4_over_ethernet[0].mac, hi->hw_address);
 
   h->ip4_over_ethernet[0].ip4 = src[0];
   h->ip4_over_ethernet[1].ip4 = adj->sub_type.nbr.next_hop.ip4;
@@ -389,7 +388,7 @@ arp_mk_complete (adj_index_t ai, ethernet_arp_ip4_entry_t * e)
     (ai, ADJ_NBR_REWRITE_FLAG_COMPLETE,
      ethernet_build_rewrite (vnet_get_main (),
                             e->sw_if_index,
-                            adj_get_link_type (ai), e->ethernet_address));
+                            adj_get_link_type (ai), &e->mac));
 }
 
 static void
@@ -601,7 +600,7 @@ force_reuse_arp_entry (void)
       am->arp_delete_rotor = index;
       index = pool_next_index (am->ip4_entry_pool, index);
     }
-  while (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC);
+  while (e->flags & IP_NEIGHBOR_FLAG_STATIC);
 
   /* Remove ARP entry from its interface and update fib */
   hash_unset
@@ -621,15 +620,12 @@ vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm,
 {
   ethernet_arp_ip4_entry_t *e = 0;
   ethernet_arp_main_t *am = &ethernet_arp_main;
-  ethernet_arp_ip4_over_ethernet_address_t *a = &args->a;
   vlib_main_t *vm = vlib_get_main ();
   int make_new_arp_cache_entry = 1;
   uword *p;
   pending_resolution_t *pr, *mc;
   ethernet_arp_interface_t *arp_int;
-  int is_static = args->is_static;
   u32 sw_if_index = args->sw_if_index;
-  int is_no_fib_entry = args->is_no_fib_entry;
 
   vec_validate (am->ethernet_arp_by_sw_if_index, sw_if_index);
 
@@ -637,17 +633,17 @@ vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm,
 
   if (NULL != arp_int->arp_entries)
     {
-      p = hash_get (arp_int->arp_entries, a->ip4.as_u32);
+      p = hash_get (arp_int->arp_entries, args->ip4.as_u32);
       if (p)
        {
          e = pool_elt_at_index (am->ip4_entry_pool, p[0]);
 
          /* Refuse to over-write static arp. */
-         if (!is_static && (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC))
+         if (!(args->nbr_flags & IP_NEIGHBOR_FLAG_STATIC) &&
+             (e->flags & IP_NEIGHBOR_FLAG_STATIC))
            {
              /* if MAC address match, still check to send event */
-             if (0 == memcmp (e->ethernet_address,
-                              a->ethernet, sizeof (e->ethernet_address)))
+             if (mac_address_equal (&e->mac, &args->mac))
                goto check_customers;
              return -2;
            }
@@ -670,15 +666,15 @@ vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm,
       if (NULL == arp_int->arp_entries)
        arp_int->arp_entries = hash_create (0, sizeof (u32));
 
-      hash_set (arp_int->arp_entries, a->ip4.as_u32, e - am->ip4_entry_pool);
+      hash_set (arp_int->arp_entries, args->ip4.as_u32,
+               e - am->ip4_entry_pool);
 
       e->sw_if_index = sw_if_index;
-      e->ip4_address = a->ip4;
+      e->ip4_address = args->ip4;
       e->fib_entry_index = FIB_NODE_INDEX_INVALID;
-      clib_memcpy_fast (e->ethernet_address,
-                       a->ethernet, sizeof (e->ethernet_address));
+      mac_address_copy (&e->mac, &args->mac);
 
-      if (!is_no_fib_entry)
+      if (!(args->nbr_flags & IP_NEIGHBOR_FLAG_NO_FIB_ENTRY))
        {
          arp_adj_fib_add (e,
                           ip4_fib_table_get_index_for_sw_if_index
@@ -686,7 +682,7 @@ vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm,
        }
       else
        {
-         e->flags |= ETHERNET_ARP_IP4_ENTRY_FLAG_NO_FIB_ENTRY;
+         e->flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
        }
     }
   else
@@ -695,36 +691,34 @@ vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm,
        * prevent a DoS attack from the data-plane that
        * spams us with no-op updates to the MAC address
        */
-      if (0 == memcmp (e->ethernet_address,
-                      a->ethernet, sizeof (e->ethernet_address)))
+      if (mac_address_equal (&e->mac, &args->mac))
        {
          e->time_last_updated = vlib_time_now (vm);
          goto check_customers;
        }
 
       /* Update ethernet address. */
-      clib_memcpy_fast (e->ethernet_address, a->ethernet,
-                       sizeof (e->ethernet_address));
+      mac_address_copy (&e->mac, &args->mac);
     }
 
   /* Update time stamp and flags. */
   e->time_last_updated = vlib_time_now (vm);
-  if (is_static)
+  if (args->nbr_flags & IP_NEIGHBOR_FLAG_STATIC)
     {
-      e->flags &= ~ETHERNET_ARP_IP4_ENTRY_FLAG_DYNAMIC;
-      e->flags |= ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC;
+      e->flags &= ~IP_NEIGHBOR_FLAG_DYNAMIC;
+      e->flags |= IP_NEIGHBOR_FLAG_STATIC;
     }
   else
     {
-      e->flags &= ~ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC;
-      e->flags |= ETHERNET_ARP_IP4_ENTRY_FLAG_DYNAMIC;
+      e->flags &= ~IP_NEIGHBOR_FLAG_STATIC;
+      e->flags |= IP_NEIGHBOR_FLAG_DYNAMIC;
     }
 
   adj_nbr_walk_nh4 (sw_if_index, &e->ip4_address, arp_mk_complete_walk, e);
 
 check_customers:
   /* Customer(s) waiting for this address to be resolved? */
-  p = hash_get (am->pending_resolutions_by_address, a->ip4.as_u32);
+  p = hash_get (am->pending_resolutions_by_address, args->ip4.as_u32);
   if (p)
     {
       u32 next_index;
@@ -739,11 +733,11 @@ check_customers:
          pool_put (am->pending_resolutions, pr);
        }
 
-      hash_unset (am->pending_resolutions_by_address, a->ip4.as_u32);
+      hash_unset (am->pending_resolutions_by_address, args->ip4.as_u32);
     }
 
   /* Customer(s) requesting ARP event for this address? */
-  p = hash_get (am->mac_changes_by_address, a->ip4.as_u32);
+  p = hash_get (am->mac_changes_by_address, args->ip4.as_u32);
   if (p)
     {
       u32 next_index;
@@ -751,14 +745,12 @@ check_customers:
 
       while (next_index != (u32) ~ 0)
        {
-         int (*fp) (u32, u8 *, u32, u32);
          int rv = 1;
          mc = pool_elt_at_index (am->mac_changes, next_index);
-         fp = mc->data_callback;
 
          /* Call the user's data callback, return 1 to suppress dup events */
-         if (fp)
-           rv = (*fp) (mc->data, a->ethernet, sw_if_index, 0);
+         if (mc->data_callback)
+           rv = (mc->data_callback) (mc->data, &args->mac, sw_if_index, 0);
 
          /*
           * Signal the resolver process, as long as the user
@@ -807,7 +799,7 @@ vnet_register_ip4_arp_resolution_event (vnet_main_t * vnm,
 
 int
 vnet_add_del_ip4_arp_change_event (vnet_main_t * vnm,
-                                  void *data_callback,
+                                  arp_change_event_cb_t data_callback,
                                   u32 pid,
                                   void *address_arg,
                                   uword node_index,
@@ -836,11 +828,17 @@ vnet_add_del_ip4_arp_change_event (vnet_main_t * vnm,
        return VNET_API_ERROR_ENTRY_ALREADY_EXISTS;
 
       pool_get (am->mac_changes, mc);
+      /* *INDENT-OFF* */
       *mc = (pending_resolution_t)
       {
-      .next_index = ~0,.node_index = node_index,.type_opaque =
-         type_opaque,.data = data,.data_callback = data_callback,.pid =
-         pid,};
+        .next_index = ~0,
+        .node_index = node_index,
+        .type_opaque = type_opaque,
+        .data = data,
+        .data_callback = data_callback,
+        .pid = pid,
+      };
+      /* *INDENT-ON* */
 
       /* Insert new resolution at the end of the list */
       u32 new_idx = mc - am->mac_changes;
@@ -855,9 +853,9 @@ vnet_add_del_ip4_arp_change_event (vnet_main_t * vnm,
        return VNET_API_ERROR_NO_SUCH_ENTRY;
 
       /* Clients may need to clean up pool entries, too */
-      void (*fp) (u32, u8 *) = data_callback;
-      if (fp)
-       (*fp) (mc->data, 0 /* no new mac addrs */ );
+      if (data_callback)
+       /* no new mac addrs */
+       (data_callback) (mc->data, NULL, ~0, NULL);
 
       /* Remove the entry from the list and delete the entry */
       *p = mc->next_index;
@@ -934,7 +932,7 @@ arp_learn (vnet_main_t * vnm,
           ethernet_arp_main_t * am, u32 sw_if_index,
           const ethernet_arp_ip4_over_ethernet_address_t * addr)
 {
-  vnet_arp_set_ip4_over_ethernet (vnm, sw_if_index, addr, 0, 0);
+  vnet_arp_set_ip4_over_ethernet (vnm, sw_if_index, addr, 0);
   return (ETHERNET_ARP_ERROR_l3_src_address_learned);
 }
 
@@ -1178,15 +1176,15 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
              clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply))
             &&
             (!memcmp
-             (arp0->ip4_over_ethernet[0].ethernet, vrrp_prefix,
+             (arp0->ip4_over_ethernet[0].mac.bytes, vrrp_prefix,
               sizeof (vrrp_prefix))));
 
          /* Trash ARP packets whose ARP-level source addresses do not
             match their L2-frame-level source addresses, unless it's
             a reply from a VRRP virtual router */
-         if (memcmp
-             (eth_rx->src_address, arp0->ip4_over_ethernet[0].ethernet,
-              sizeof (eth_rx->src_address)) && !is_vrrp_reply0)
+         if (!ethernet_mac_address_equal
+             (eth_rx->src_address,
+              arp0->ip4_over_ethernet[0].mac.bytes) && !is_vrrp_reply0)
            {
              error0 = ETHERNET_ARP_ERROR_l2_address_mismatch;
              goto drop2;
@@ -1240,8 +1238,8 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
 
          arp0->ip4_over_ethernet[1] = arp0->ip4_over_ethernet[0];
 
-         clib_memcpy_fast (arp0->ip4_over_ethernet[0].ethernet,
-                           hw_if0->hw_address, 6);
+         mac_address_from_bytes (&arp0->ip4_over_ethernet[0].mac,
+                                 hw_if0->hw_address);
          clib_mem_unaligned (&arp0->ip4_over_ethernet[0].ip4.data_u32, u32) =
            if_addr0->data_u32;
 
@@ -1481,7 +1479,7 @@ typedef struct
   pg_edit_t opcode;
   struct
   {
-    pg_edit_t ethernet;
+    pg_edit_t mac;
     pg_edit_t ip4;
   } ip4_over_ethernet[2];
 } pg_ethernet_arp_header_t;
@@ -1496,9 +1494,9 @@ pg_ethernet_arp_header_init (pg_ethernet_arp_header_t * p)
   _(n_l2_address_bytes);
   _(n_l3_address_bytes);
   _(opcode);
-  _(ip4_over_ethernet[0].ethernet);
+  _(ip4_over_ethernet[0].mac);
   _(ip4_over_ethernet[0].ip4);
-  _(ip4_over_ethernet[1].ethernet);
+  _(ip4_over_ethernet[1].mac);
   _(ip4_over_ethernet[1].ip4);
 #undef _
 }
@@ -1524,11 +1522,11 @@ unformat_pg_arp_header (unformat_input_t * input, va_list * args)
                 unformat_pg_edit,
                 unformat_ethernet_arp_opcode_net_byte_order, &p->opcode,
                 unformat_pg_edit,
-                unformat_ethernet_address, &p->ip4_over_ethernet[0].ethernet,
+                unformat_mac_address_t, &p->ip4_over_ethernet[0].mac,
                 unformat_pg_edit,
                 unformat_ip4_address, &p->ip4_over_ethernet[0].ip4,
                 unformat_pg_edit,
-                unformat_ethernet_address, &p->ip4_over_ethernet[1].ethernet,
+                unformat_mac_address_t, &p->ip4_over_ethernet[1].mac,
                 unformat_pg_edit,
                 unformat_ip4_address, &p->ip4_over_ethernet[1].ip4))
     {
@@ -1558,11 +1556,12 @@ vnet_arp_unset_ip4_over_ethernet (vnet_main_t * vnm,
                                  ethernet_arp_ip4_over_ethernet_address_t *
                                  a)
 {
-  vnet_arp_set_ip4_over_ethernet_rpc_args_t args;
-
-  args.sw_if_index = sw_if_index;
-  args.flags = ETHERNET_ARP_ARGS_REMOVE;
-  clib_memcpy_fast (&args.a, a, sizeof (*a));
+  vnet_arp_set_ip4_over_ethernet_rpc_args_t args = {
+    .sw_if_index = sw_if_index,
+    .flags = ETHERNET_ARP_ARGS_REMOVE,
+    .ip4 = a->ip4,
+    .mac = a->mac,
+  };
 
   vl_api_rpc_call_main_thread (set_ip4_over_ethernet_rpc_callback,
                               (u8 *) & args, sizeof (args));
@@ -1580,7 +1579,8 @@ vnet_arp_wc_publish (u32 sw_if_index,
   vnet_arp_set_ip4_over_ethernet_rpc_args_t args = {
     .flags = ETHERNET_ARP_ARGS_WC_PUB,
     .sw_if_index = sw_if_index,
-    .a = *a
+    .ip4 = a->ip4,
+    .mac = a->mac,
   };
 
   vl_api_rpc_call_main_thread (set_ip4_over_ethernet_rpc_callback,
@@ -1602,9 +1602,9 @@ vnet_arp_wc_publish_internal (vnet_main_t * vnm,
     return;
   wc_arp_report_t *r =
     vlib_process_signal_event_data (vm, ni, et, 1, sizeof *r);
-  r->ip4 = args->a.ip4.as_u32;
+  r->ip.as_u32 = args->ip4.as_u32;
   r->sw_if_index = args->sw_if_index;
-  memcpy (r->mac, args->a.ethernet, sizeof r->mac);
+  mac_address_copy (&r->mac, &args->mac);
 }
 
 void
@@ -1632,7 +1632,7 @@ vnet_arp_flush_ip4_over_ethernet_internal (vnet_main_t * vnm,
 
   eai = &am->ethernet_arp_by_sw_if_index[args->sw_if_index];
 
-  e = arp_entry_find (eai, &args->a.ip4);
+  e = arp_entry_find (eai, &args->ip4);
 
   if (NULL != e)
     {
@@ -1646,11 +1646,11 @@ vnet_arp_flush_ip4_over_ethernet_internal (vnet_main_t * vnm,
        * does in response to interface events. unset is only done
        * by the control plane.
        */
-      if (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC)
+      if (e->flags & IP_NEIGHBOR_FLAG_STATIC)
        {
-         e->flags &= ~ETHERNET_ARP_IP4_ENTRY_FLAG_DYNAMIC;
+         e->flags &= ~IP_NEIGHBOR_FLAG_DYNAMIC;
        }
-      else if (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_DYNAMIC)
+      else if (e->flags & IP_NEIGHBOR_FLAG_DYNAMIC)
        {
          arp_entry_free (eai, e);
        }
@@ -1707,11 +1707,11 @@ arp_add_del_interface_address (ip4_main_t * im,
          e = pool_elt_at_index (am->ip4_entry_pool, to_delete[i]);
 
          vnet_arp_set_ip4_over_ethernet_rpc_args_t delme = {
-           .a.ip4.as_u32 = e->ip4_address.as_u32,
+           .ip4.as_u32 = e->ip4_address.as_u32,
            .sw_if_index = e->sw_if_index,
            .flags = ETHERNET_ARP_ARGS_FLUSH,
          };
-         clib_memcpy_fast (&delme.a.ethernet, e->ethernet_address, 6);
+         mac_address_copy (&delme.mac, &e->mac);
 
          vnet_arp_flush_ip4_over_ethernet_internal (vnet_get_main (),
                                                     &delme);
@@ -1837,7 +1837,7 @@ vnet_arp_unset_ip4_over_ethernet_internal (vnet_main_t * vnm,
 
   eai = &am->ethernet_arp_by_sw_if_index[args->sw_if_index];
 
-  e = arp_entry_find (eai, &args->a.ip4);
+  e = arp_entry_find (eai, &args->ip4);
 
   if (NULL != e)
     {
@@ -1862,7 +1862,7 @@ vnet_arp_populate_ip4_over_ethernet_internal (vnet_main_t * vnm,
   vec_validate (am->ethernet_arp_by_sw_if_index, args->sw_if_index);
   eai = &am->ethernet_arp_by_sw_if_index[args->sw_if_index];
 
-  e = arp_entry_find (eai, &args->a.ip4);
+  e = arp_entry_find (eai, &args->ip4);
 
   if (NULL != e)
     {
@@ -1916,11 +1916,10 @@ ethernet_arp_sw_interface_up_down (vnet_main_t * vnm,
       e = pool_elt_at_index (am->ip4_entry_pool, to_update[i]);
 
       vnet_arp_set_ip4_over_ethernet_rpc_args_t update_me = {
-       .a.ip4.as_u32 = e->ip4_address.as_u32,
+       .ip4.as_u32 = e->ip4_address.as_u32,
        .sw_if_index = e->sw_if_index,
       };
-
-      clib_memcpy_fast (&update_me.a.ethernet, e->ethernet_address, 6);
+      mac_address_copy (&update_me.mac, &e->mac);
 
       if (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP)
        {
@@ -1956,9 +1955,9 @@ increment_ip4_and_mac_address (ethernet_arp_ip4_over_ethernet_address_t * a)
 
   for (i = 5; i >= 0; i--)
     {
-      old = a->ethernet[i];
-      a->ethernet[i] += 1;
-      if (old < a->ethernet[i])
+      old = a->mac.bytes[i];
+      a->mac.bytes[i] += 1;
+      if (old < a->mac.bytes[i])
        break;
     }
 }
@@ -1967,15 +1966,15 @@ int
 vnet_arp_set_ip4_over_ethernet (vnet_main_t * vnm,
                                u32 sw_if_index,
                                const ethernet_arp_ip4_over_ethernet_address_t
-                               * a, int is_static, int is_no_fib_entry)
+                               * a, ip_neighbor_flags_t flags)
 {
-  vnet_arp_set_ip4_over_ethernet_rpc_args_t args;
-
-  args.sw_if_index = sw_if_index;
-  args.is_static = is_static;
-  args.is_no_fib_entry = is_no_fib_entry;
-  args.flags = 0;
-  clib_memcpy_fast (&args.a, a, sizeof (*a));
+  vnet_arp_set_ip4_over_ethernet_rpc_args_t args = {
+    .sw_if_index = sw_if_index,
+    .nbr_flags = flags,
+    .flags = 0,
+    .ip4.as_u32 = a->ip4.as_u32,
+    .mac = a->mac,
+  };
 
   vl_api_rpc_call_main_thread (set_ip4_over_ethernet_rpc_callback,
                               (u8 *) & args, sizeof (args));
@@ -2079,9 +2078,10 @@ ip_arp_add_del_command_fn (vlib_main_t * vm,
   int count = 1;
   u32 fib_index = 0;
   u32 fib_id;
-  int is_static = 0;
-  int is_no_fib_entry = 0;
   int is_proxy = 0;
+  ip_neighbor_flags_t flags;
+
+  flags = IP_NEIGHBOR_FLAG_NONE;
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
@@ -2089,17 +2089,17 @@ ip_arp_add_del_command_fn (vlib_main_t * vm,
       if (unformat (input, "%U %U %U",
                    unformat_vnet_sw_interface, vnm, &sw_if_index,
                    unformat_ip4_address, &addr.ip4,
-                   unformat_ethernet_address, &addr.ethernet))
+                   unformat_mac_address_t, &addr.mac))
        addr_valid = 1;
 
       else if (unformat (input, "delete") || unformat (input, "del"))
        is_del = 1;
 
       else if (unformat (input, "static"))
-       is_static = 1;
+       flags |= IP_NEIGHBOR_FLAG_STATIC;
 
       else if (unformat (input, "no-fib-entry"))
-       is_no_fib_entry = 1;
+       flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
 
       else if (unformat (input, "count %d", &count))
        ;
@@ -2142,8 +2142,7 @@ ip_arp_add_del_command_fn (vlib_main_t * vm,
                (vnm, &addr.ip4, vlib_current_process (vm),
                 1 /* type */ , 0 /* data */ );
 
-             vnet_arp_set_ip4_over_ethernet
-               (vnm, sw_if_index, &addr, is_static, is_no_fib_entry);
+             vnet_arp_set_ip4_over_ethernet (vnm, sw_if_index, &addr, flags);
 
              vlib_process_wait_for_event (vm);
              event_type = vlib_process_get_events (vm, &event_data);
@@ -2371,13 +2370,14 @@ arp_term_l2bd (vlib_main_t * vm,
          /* Trash ARP packets whose ARP-level source addresses do not
             match, or if requester address is mcast */
          if (PREDICT_FALSE
-             (memcmp (eth0->src_address, arp0->ip4_over_ethernet[0].ethernet,
-                      sizeof (eth0->src_address)) ||
-              ethernet_address_cast (arp0->ip4_over_ethernet[0].ethernet)))
+             (!ethernet_mac_address_equal (eth0->src_address,
+                                           arp0->ip4_over_ethernet[0].
+                                           mac.bytes))
+             || ethernet_address_cast (arp0->ip4_over_ethernet[0].mac.bytes))
            {
              /* VRRP virtual MAC may be different to SMAC in ARP reply */
-             if (memcmp (arp0->ip4_over_ethernet[0].ethernet, vrrp_prefix,
-                         sizeof (vrrp_prefix)))
+             if (!ethernet_mac_address_equal
+                 (arp0->ip4_over_ethernet[0].mac.bytes, vrrp_prefix))
                {
                  error0 = ETHERNET_ARP_ERROR_l2_address_mismatch;
                  goto drop;
@@ -2416,7 +2416,7 @@ arp_term_l2bd (vlib_main_t * vm,
          arp0->opcode = clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply);
          arp0->ip4_over_ethernet[1] = arp0->ip4_over_ethernet[0];
          arp0->ip4_over_ethernet[0].ip4.as_u32 = ip0;
-         clib_memcpy_fast (arp0->ip4_over_ethernet[0].ethernet, macp0, 6);
+         mac_address_from_bytes (&arp0->ip4_over_ethernet[0].mac, macp0);
          clib_memcpy_fast (eth0->dst_address, eth0->src_address, 6);
          clib_memcpy_fast (eth0->src_address, macp0, 6);
          n_replies_sent += 1;
@@ -2583,10 +2583,8 @@ send_ip4_garp_w_addr (vlib_main_t * vm,
       if (!h)
        return;
 
-      clib_memcpy_fast (h->ip4_over_ethernet[0].ethernet, hi->hw_address,
-                       sizeof (h->ip4_over_ethernet[0].ethernet));
-      clib_memcpy_fast (h->ip4_over_ethernet[1].ethernet, hi->hw_address,
-                       sizeof (h->ip4_over_ethernet[1].ethernet));
+      mac_address_from_bytes (&h->ip4_over_ethernet[0].mac, hi->hw_address);
+      mac_address_from_bytes (&h->ip4_over_ethernet[1].mac, hi->hw_address);
       h->ip4_over_ethernet[0].ip4 = ip4_addr[0];
       h->ip4_over_ethernet[1].ip4 = ip4_addr[0];
 
@@ -2626,8 +2624,10 @@ vnet_arp_delete_sw_interface (vnet_main_t * vnm, u32 sw_if_index, u32 is_add)
       pool_foreach (e, am->ip4_entry_pool, ({
         if (e->sw_if_index != sw_if_index)
           continue;
-        vnet_arp_set_ip4_over_ethernet_rpc_args_t args = { .sw_if_index = sw_if_index,
-                                                           .a.ip4 = e->ip4_address };
+        vnet_arp_set_ip4_over_ethernet_rpc_args_t args = {
+          .sw_if_index = sw_if_index,
+          .ip4 = e->ip4_address,
+        };
         vnet_arp_unset_ip4_over_ethernet_internal (vnm, &args);
       }));
       /* *INDENT-ON* */
index 6c89d1e..e99d7a8 100644 (file)
 #include <vnet/ethernet/ethernet.h>
 #include <vnet/ethernet/arp_packet.h>
 #include <vnet/ip/ip.h>
+#include <vnet/ip/ip_neighbor.h>
+
+typedef struct
+{
+  u32 sw_if_index;
+  ip4_address_t ip4_address;
+
+  mac_address_t mac;
+
+  ip_neighbor_flags_t flags;
+
+  f64 time_last_updated;
+
+  /**
+   * The index of the adj-fib entry created
+   */
+  fib_node_index_t fib_entry_index;
+} ethernet_arp_ip4_entry_t;
+
+extern u8 *format_ethernet_arp_ip4_entry (u8 * s, va_list * va);
+
+ethernet_arp_ip4_entry_t *ip4_neighbors_pool (void);
+ethernet_arp_ip4_entry_t *ip4_neighbor_entries (u32 sw_if_index);
 
 extern int vnet_proxy_arp_add_del (ip4_address_t * lo_addr,
                                   ip4_address_t * hi_addr,
@@ -28,8 +51,7 @@ extern int vnet_arp_set_ip4_over_ethernet (vnet_main_t * vnm,
                                           u32 sw_if_index,
                                           const
                                           ethernet_arp_ip4_over_ethernet_address_t
-                                          * a, int is_static,
-                                          int is_no_fib_entry);
+                                          * a, ip_neighbor_flags_t flags);
 
 extern int vnet_arp_unset_ip4_over_ethernet (vnet_main_t * vnm,
                                             u32 sw_if_index,
@@ -39,6 +61,38 @@ extern int vnet_arp_unset_ip4_over_ethernet (vnet_main_t * vnm,
 
 extern int vnet_proxy_arp_fib_reset (u32 fib_id);
 
+void vnet_register_ip4_arp_resolution_event (vnet_main_t * vnm,
+                                            void *address_arg,
+                                            uword node_index,
+                                            uword type_opaque, uword data);
+
+typedef int (*arp_change_event_cb_t) (u32 pool_index,
+                                     const mac_address_t * mac,
+                                     u32 sw_if_index,
+                                     const ip4_address_t * address);
+
+int vnet_add_del_ip4_arp_change_event (vnet_main_t * vnm,
+                                      arp_change_event_cb_t data_callback,
+                                      u32 pid,
+                                      void *address_arg,
+                                      uword node_index,
+                                      uword type_opaque,
+                                      uword data, int is_add);
+
+void wc_arp_set_publisher_node (uword inode_index, uword event_type);
+
+void ethernet_arp_change_mac (u32 sw_if_index);
+void ethernet_ndp_change_mac (u32 sw_if_index);
+
+void arp_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai);
+
+typedef struct
+{
+  u32 sw_if_index;
+  ip4_address_t ip;
+  mac_address_t mac;
+} wc_arp_report_t;
+
 /**
  * call back function when walking the DB of proxy ARPs
  * @return 0 to stop the walk !0 to continue
index 206be41..b4e021c 100644 (file)
@@ -18,6 +18,8 @@
 #ifndef included_ethernet_arp_packet_h
 #define included_ethernet_arp_packet_h
 
+#include <vnet/ethernet/mac_address.h>
+
 #define foreach_ethernet_arp_hardware_type     \
   _ (0, reserved)                              \
   _ (1, ethernet)                              \
@@ -119,11 +121,14 @@ typedef enum
 
 /* *INDENT-OFF* */
 typedef CLIB_PACKED (struct {
-  u8 ethernet[6];
+  mac_address_t mac;
   ip4_address_t ip4;
 }) ethernet_arp_ip4_over_ethernet_address_t;
 /* *INDENT-ON* */
 
+STATIC_ASSERT (sizeof (ethernet_arp_ip4_over_ethernet_address_t) == 10,
+              "Packet ethernet address and IP4 address too big");
+
 typedef struct
 {
   u16 l2_type;
@@ -140,34 +145,6 @@ typedef struct
   };
 } ethernet_arp_header_t;
 
-typedef enum ethernet_arp_entry_flags_t_
-{
-  ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC = (1 << 0),
-  ETHERNET_ARP_IP4_ENTRY_FLAG_DYNAMIC = (1 << 1),
-  ETHERNET_ARP_IP4_ENTRY_FLAG_NO_FIB_ENTRY = (1 << 2),
-} __attribute__ ((packed)) ethernet_arp_entry_flags_t;
-
-typedef struct
-{
-  u32 sw_if_index;
-  ip4_address_t ip4_address;
-
-  u8 ethernet_address[6];
-
-  ethernet_arp_entry_flags_t flags;
-
-  f64 time_last_updated;
-
-  /**
-   * The index of the adj-fib entry created
-   */
-  fib_node_index_t fib_entry_index;
-} ethernet_arp_ip4_entry_t;
-
-ethernet_arp_ip4_entry_t *ip4_neighbors_pool (void);
-ethernet_arp_ip4_entry_t *ip4_neighbor_entries (u32 sw_if_index);
-u8 *format_ethernet_arp_ip4_entry (u8 * s, va_list * va);
-
 void send_ip4_garp (vlib_main_t * vm, u32 sw_if_index);
 void send_ip4_garp_w_addr (vlib_main_t * vm,
                           const ip4_address_t * ip4_addr, u32 sw_if_index);
index ceaadd2..9b19143 100644 (file)
@@ -42,6 +42,7 @@
 
 #include <vnet/vnet.h>
 #include <vnet/ethernet/packet.h>
+#include <vnet/ethernet/mac_address.h>
 #include <vnet/pg/pg.h>
 #include <vnet/feature/feature.h>
 
@@ -59,40 +60,6 @@ typedef struct
   u32 hw_if_index;
 } ethernet_input_frame_t;
 
-always_inline u64
-ethernet_mac_address_u64 (const u8 * a)
-{
-  return (((u64) a[0] << (u64) (5 * 8))
-         | ((u64) a[1] << (u64) (4 * 8))
-         | ((u64) a[2] << (u64) (3 * 8))
-         | ((u64) a[3] << (u64) (2 * 8))
-         | ((u64) a[4] << (u64) (1 * 8)) | ((u64) a[5] << (u64) (0 * 8)));
-}
-
-always_inline void
-ethernet_mac_address_from_u64 (u64 u, u8 * a)
-{
-  i8 ii;
-
-  for (ii = 5; ii >= 0; ii--)
-    {
-      a[ii] = u & 0xFF;
-      u = u >> 8;
-    }
-}
-
-static inline int
-ethernet_mac_address_is_multicast_u64 (u64 a)
-{
-  return (a & (1ULL << (5 * 8))) != 0;
-}
-
-static inline int
-ethernet_mac_address_is_zero (const u8 * mac)
-{
-  return ((*((u32 *) mac) == 0) && (*((u16 *) (mac + 4)) == 0));
-}
-
 #ifdef CLIB_HAVE_VEC128
 static const u16x8 tagged_ethertypes = {
   (u16) ETHERNET_TYPE_VLAN,
@@ -565,42 +532,12 @@ matched:
   return 1;
 }
 
-// Compare two ethernet macs. Return 1 if they are the same, 0 if different
-always_inline u32
-eth_mac_equal (const u8 * mac1, const u8 * mac2)
-{
-  return (*((u32 *) (mac1 + 0)) == *((u32 *) (mac2 + 0)) &&
-         *((u32 *) (mac1 + 2)) == *((u32 *) (mac2 + 2)));
-}
-
-
 always_inline ethernet_main_t *
 vnet_get_ethernet_main (void)
 {
   return &ethernet_main;
 }
 
-void vnet_register_ip4_arp_resolution_event (vnet_main_t * vnm,
-                                            void *address_arg,
-                                            uword node_index,
-                                            uword type_opaque, uword data);
-
-
-int vnet_add_del_ip4_arp_change_event (vnet_main_t * vnm,
-                                      void *data_callback,
-                                      u32 pid,
-                                      void *address_arg,
-                                      uword node_index,
-                                      uword type_opaque,
-                                      uword data, int is_add);
-
-void wc_arp_set_publisher_node (uword inode_index, uword event_type);
-
-void ethernet_arp_change_mac (u32 sw_if_index);
-void ethernet_ndp_change_mac (u32 sw_if_index);
-
-void arp_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai);
-
 void ethernet_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai);
 u8 *ethernet_build_rewrite (vnet_main_t * vnm,
                            u32 sw_if_index,
@@ -610,13 +547,6 @@ const u8 *ethernet_ip6_mcast_dst_addr (void);
 
 extern vlib_node_registration_t ethernet_input_node;
 
-typedef struct
-{
-  u32 sw_if_index;
-  u32 ip4;
-  u8 mac[6];
-} wc_arp_report_t;
-
 #endif /* included_ethernet_h */
 
 /*
index f1e6785..408b0eb 100644 (file)
@@ -41,6 +41,7 @@
 #include <vnet/ip/ip.h>
 #include <vnet/pg/pg.h>
 #include <vnet/ethernet/ethernet.h>
+#include <vnet/ethernet/arp.h>
 #include <vnet/l2/l2_input.h>
 #include <vnet/l2/l2_bd.h>
 #include <vnet/adj/adj.h>
index 419a5b0..eab7cef 100644 (file)
@@ -37,13 +37,28 @@ uword
 unformat_mac_address_t (unformat_input_t * input, va_list * args)
 {
   mac_address_t *mac = va_arg (*args, mac_address_t *);
+  u32 i, a[3];
 
-  if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
-                &mac->bytes[0], &mac->bytes[1], &mac->bytes[2],
-                &mac->bytes[3], &mac->bytes[4], &mac->bytes[5]))
-    return 0;
+  if (unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
+               &mac->bytes[0], &mac->bytes[1], &mac->bytes[2],
+               &mac->bytes[3], &mac->bytes[4], &mac->bytes[5]))
+    return (1);
+  else if (unformat (input, "%_%x.%x.%x%_", &a[0], &a[1], &a[2]))
+    {
+      for (i = 0; i < ARRAY_LEN (a); i++)
+       if (a[i] >= (1 << 16))
+         return 0;
 
-  return 1;
+      mac->bytes[0] = (a[0] >> 8) & 0xff;
+      mac->bytes[1] = (a[0] >> 0) & 0xff;
+      mac->bytes[2] = (a[1] >> 8) & 0xff;
+      mac->bytes[3] = (a[1] >> 0) & 0xff;
+      mac->bytes[4] = (a[2] >> 8) & 0xff;
+      mac->bytes[5] = (a[2] >> 0) & 0xff;
+
+      return (1);
+    }
+  return (0);
 }
 
 /*
index e89fb65..87a66a2 100644 (file)
@@ -16,7 +16,7 @@
 #ifndef __MAC_ADDRESS_H__
 #define __MAC_ADDRESS_H__
 
-#include <vnet/ethernet/ethernet.h>
+#include <vlib/vlib.h>
 
 typedef struct mac_address_t_
 {
@@ -36,18 +36,59 @@ STATIC_ASSERT ((sizeof (mac_address_t) == 6),
 
 extern const mac_address_t ZERO_MAC_ADDRESS;
 
+always_inline u64
+ethernet_mac_address_u64 (const u8 * a)
+{
+  return (((u64) a[0] << (u64) (5 * 8))
+         | ((u64) a[1] << (u64) (4 * 8))
+         | ((u64) a[2] << (u64) (3 * 8))
+         | ((u64) a[3] << (u64) (2 * 8))
+         | ((u64) a[4] << (u64) (1 * 8)) | ((u64) a[5] << (u64) (0 * 8)));
+}
+
+always_inline void
+ethernet_mac_address_from_u64 (u64 u, u8 * a)
+{
+  i8 ii;
+
+  for (ii = 5; ii >= 0; ii--)
+    {
+      a[ii] = u & 0xFF;
+      u = u >> 8;
+    }
+}
+
+static inline int
+ethernet_mac_address_is_multicast_u64 (u64 a)
+{
+  return (a & (1ULL << (5 * 8))) != 0;
+}
+
+static inline int
+ethernet_mac_address_is_zero (const u8 * mac)
+{
+  return ((*((u32 *) mac) == 0) && (*((u16 *) (mac + 4)) == 0));
+}
+
+static inline int
+ethernet_mac_address_equal (const u8 * a, const u8 * b)
+{
+  return ((*((u32 *) a) == (*((u32 *) b))) &&
+         (*((u16 *) (a + 4)) == (*((u16 *) (b + 4)))));
+}
+
 static_always_inline void
 mac_address_from_bytes (mac_address_t * mac, const u8 * bytes)
 {
   /* zero out the last 2 bytes, then copy over only 6 */
-  clib_memcpy (mac->bytes, bytes, 6);
+  clib_memcpy_fast (mac->bytes, bytes, 6);
 }
 
 static_always_inline void
 mac_address_to_bytes (const mac_address_t * mac, u8 * bytes)
 {
   /* zero out the last 2 bytes, then copy over only 6 */
-  clib_memcpy (bytes, mac->bytes, 6);
+  clib_memcpy_fast (bytes, mac->bytes, 6);
 }
 
 static_always_inline int
@@ -67,7 +108,7 @@ mac_address_as_u64 (const mac_address_t * mac)
 }
 
 static_always_inline void
-mac_address_from_u64 (u64 u, mac_address_t * mac)
+mac_address_from_u64 (mac_address_t * mac, u64 u)
 {
   clib_memcpy (mac->bytes, &u, 6);
 }
@@ -78,6 +119,25 @@ mac_address_copy (mac_address_t * dst, const mac_address_t * src)
   mac_address_from_bytes (dst, src->bytes);
 }
 
+static_always_inline int
+mac_address_cmp (const mac_address_t * a, const mac_address_t * b)
+{
+  return (memcmp (a->bytes, b->bytes, 6));
+}
+
+static_always_inline int
+mac_address_equal (const mac_address_t * a, const mac_address_t * b)
+{
+  return (a->u.last_2 == b->u.last_2 && a->u.first_4 == b->u.first_4);
+}
+
+static_always_inline void
+mac_address_set_zero (mac_address_t * mac)
+{
+  mac->u.first_4 = 0;
+  mac->u.last_2 = 0;
+}
+
 extern uword unformat_mac_address_t (unformat_input_t * input,
                                     va_list * args);
 extern u8 *format_mac_address_t (u8 * s, va_list * args);
index 268b171..3264bdc 100755 (executable)
@@ -223,7 +223,7 @@ identify_subint (vnet_hw_interface_t * hi,
 
          if (!(ethernet_address_cast (e0->dst_address)))
            {
-             if (!eth_mac_equal ((u8 *) e0, hi->hw_address))
+             if (!ethernet_mac_address_equal ((u8 *) e0, hi->hw_address))
                {
                  *error0 = ETHERNET_ERROR_L3_MAC_MISMATCH;
                }
@@ -1123,11 +1123,11 @@ ethernet_input_inline (vlib_main_t * vm,
                {
                  if (!ethernet_address_cast (e0->dst_address) &&
                      (hi->hw_address != 0) &&
-                     !eth_mac_equal ((u8 *) e0, hi->hw_address))
+                     !ethernet_mac_address_equal ((u8 *) e0, hi->hw_address))
                    error0 = ETHERNET_ERROR_L3_MAC_MISMATCH;
                  if (!ethernet_address_cast (e1->dst_address) &&
                      (hi->hw_address != 0) &&
-                     !eth_mac_equal ((u8 *) e1, hi->hw_address))
+                     !ethernet_mac_address_equal ((u8 *) e1, hi->hw_address))
                    error1 = ETHERNET_ERROR_L3_MAC_MISMATCH;
                  vlib_buffer_advance (b0, sizeof (ethernet_header_t));
                  determine_next_node (em, variant, 0, type0, b0,
@@ -1347,7 +1347,7 @@ ethernet_input_inline (vlib_main_t * vm,
                {
                  if (!ethernet_address_cast (e0->dst_address) &&
                      (hi->hw_address != 0) &&
-                     !eth_mac_equal ((u8 *) e0, hi->hw_address))
+                     !ethernet_mac_address_equal ((u8 *) e0, hi->hw_address))
                    error0 = ETHERNET_ERROR_L3_MAC_MISMATCH;
                  vlib_buffer_advance (b0, sizeof (ethernet_header_t));
                  determine_next_node (em, variant, 0, type0, b0,
index 025fd57..b67e2e5 100644 (file)
@@ -20,7 +20,7 @@
     called through a shared memory interface. 
 */
 
-option version = "1.4.0";
+option version = "2.0.0";
 import "vnet/ip/ip_types.api";
 import "vnet/fib/fib_types.api";
 import "vnet/ethernet/ethernet_types.api";
@@ -103,66 +103,47 @@ manual_endian manual_print define ip6_fib_details
   vl_api_fib_path_t path[count];
 };
 
-/** \brief Dump IP neighboors
-    @param client_index - opaque cookie to identify the sender
-    @param context - sender context, to match reply w/ request
-    @param sw_if_index - the interface to dump neighboors, ~0 == all
-    @param is_ipv6 - [1|0] to indicate if address family is ipv[6|4]
+/** \brief IP neighbor flags
+    @param is_static - A static neighbor Entry - there are not flushed
+                       If the interface goes down.
+    @param is_no_fib_entry - Do not create a corresponding entry in the FIB
+                           table for the neighbor.
 */
-define ip_neighbor_dump
+enum ip_neighbor_flags
 {
-    u32 client_index;
-    u32 context;
-    u32 sw_if_index;
-    u8  is_ipv6;
+  IP_API_NEIGHBOR_FLAG_NONE = 0,
+  IP_API_NEIGHBOR_FLAG_STATIC = 0x1,
+  IP_API_NEIGHBOR_FLAG_NO_FIB_ENTRY = 0x2,
+  IP_API_NEIGHBOR_FLAG_FIX_ME_OLE = 0x3,
 };
 
-/** \brief IP neighboors dump response
-    @param context - sender context which was passed in the request
-    @param sw_if_index - The interface used to reach the neighbor
-    @param stats_index - An index in the stats segment that can be used to read
-                         the counters for this neighbour.
-    @param is_static - [1|0] to indicate if neighbor is statically configured
-    @param is_ipv6 - [1|0] to indicate if address family is ipv[6|4]
+/** \brief IP neighbor
+    @param sw_if_index - interface used to reach neighbor
+    @param mac_address - l2 address of the neighbor
+    @param ip_address - ip4 or ip6 address of the neighbor
+    @param flags - flags for the nieghbor
 */
-define ip_neighbor_details {
-    u32 context;
-    u32 sw_if_index;
-    u32 stats_index;
-    u8  is_static;
-    u8  is_ipv6;
-    u8  mac_address[6];
-    u8  ip_address[16];
+typedef ip_neighbor {
+  u32 sw_if_index;
+  vl_api_ip_neighbor_flags_t flags;
+  vl_api_mac_address_t mac_address;
+  vl_api_address_t ip_address;
 };
 
 /** \brief IP neighbor add / del request
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
-    @param sw_if_index - interface used to reach neighbor
     @param is_add - 1 to add neighbor, 0 to delete
-    @param is_ipv6 - 1 for IPv6 neighbor, 0 for IPv4
-    @param is_ipv6 - 1 for IPv6 neighbor, 0 for IPv4
-    @param is_static - A static neighbor Entry - there are not flushed
-                       If the interface goes down.
-    @param is_no_adj_fib - Do not create a corresponding entry in the FIB
-                           table for the neighbor.
-    @param mac_address - l2 address of the neighbor
-    @param dst_address - ip4 or ip6 address of the neighbor
+    @param neighbor - the neighor to add/remove
 */
 define ip_neighbor_add_del
 {
   u32 client_index;
   u32 context;
-  u32 sw_if_index;
   /* 1 = add, 0 = delete */
   u8 is_add;
-  u8 is_ipv6;
-  u8 is_static;
-  u8 is_no_adj_fib;
-  u8 mac_address[6];
-  u8 dst_address[16];
+  vl_api_ip_neighbor_t neighbor;
 };
-
 define ip_neighbor_add_del_reply
 {
   u32 context;
@@ -170,6 +151,29 @@ define ip_neighbor_add_del_reply
   u32 stats_index;
 };
 
+/** \brief Dump IP neighboors
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+    @param sw_if_index - the interface to dump neighboors, ~0 == all
+    @param is_ipv6 - [1|0] to indicate if address family is ipv[6|4]
+*/
+define ip_neighbor_dump
+{
+  u32 client_index;
+  u32 context;
+  u32 sw_if_index;
+  u8  is_ipv6;
+};
+
+/** \brief IP neighboors dump response
+    @param context - sender context which was passed in the request
+    @param neighbour - the neighbor
+*/
+define ip_neighbor_details {
+  u32 context;
+  vl_api_ip_neighbor_t neighbor;
+};
+
 /** \brief Set the ip flow hash config for a fib request
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
@@ -239,8 +243,7 @@ autoreply define sw_interface_ip6nd_ra_config
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
     @param sw_if_index - The interface the RA prefix information is for
-    @param address[] - The prefix to advertise
-    @param address_length - the prefix length
+    @param prefix - The prefix to advertise
     @param use_default - Revert to default settings
     @param no_advertise - Do not advertise this prefix
     @param off_link - The prefix is off link (it is not configured on the interface)
@@ -269,8 +272,7 @@ autoreply define sw_interface_ip6nd_ra_prefix
   u32 client_index;
   u32 context;
   u32 sw_if_index;
-  u8 address[16];
-  u8 address_length;
+  vl_api_prefix_t prefix;
   u8 use_default;
   u8 no_advertise;
   u8 off_link;
@@ -294,7 +296,7 @@ autoreply define ip6nd_proxy_add_del
   u32 context;
   u32 sw_if_index;
   u8 is_del;
-  u8 address[16];
+  vl_api_ip6_address_t ip;
 };
 
 /** \brief IPv6 ND proxy details returned after request
@@ -305,7 +307,7 @@ define ip6nd_proxy_details
 {
   u32 context;
   u32 sw_if_index;
-  u8 address[16];
+  vl_api_ip6_address_t ip;
 };
 
 /** \brief IPv6 ND proxy dump request
@@ -683,9 +685,7 @@ autoreply define ip_container_proxy_add_del
 {
   u32 client_index;
   u32 context;
-  u8 ip[16];
-  u8 is_ip4;
-  u8 plen;
+  vl_api_prefix_t pfx;
   u32 sw_if_index;
   u8 is_add;
 };
@@ -708,8 +708,7 @@ define ip_container_proxy_details
     @param context - sender context, to match reply w/ request
     @param is_ip6 - 1 if source address type is IPv6
     @param is_add - 1 if add, 0 if delete
-    @param mask_length - mask length for address entry
-    @param address - array of address bytes
+    @param ip - prefix to match
     @param number_of_ranges - length of low_port and high_port arrays (must match)
     @param low_ports[32] - up to 32 low end of port range entries (must have corresponding high_ports entry)
     @param high_ports[32] - up to 32 high end of port range entries (must have corresponding low_ports entry)
@@ -720,10 +719,8 @@ autoreply define ip_source_and_port_range_check_add_del
 {
   u32 client_index;
   u32 context;
-  u8 is_ipv6;
   u8 is_add;
-  u8 mask_length;
-  u8 address[16];
+  vl_api_prefix_t prefix;
   u8 number_of_ranges;
   u16 low_ports[32];
   u16 high_ports[32];
@@ -794,16 +791,14 @@ autoreply define ip_scan_neighbor_enable_disable
     @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]
+    @param dst - target IP address to send IP addr resolution request
 */
 autoreply define ip_probe_neighbor
 {
   u32 client_index;
   u32 context;
   u32 sw_if_index;
-  u8 dst_address[16];
-  u8 is_ipv6;
+  vl_api_address_t dst;
 };
 
 /** \brief Register for IP4 ARP resolution event on receing ARP reply or
@@ -812,8 +807,8 @@ autoreply define ip_probe_neighbor
     @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 - exact IP4 address of interested arp resolution event, or
-                     0 to get MAC/IP info from ARP requests in BDs
+    @param ip - 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
 {
@@ -821,25 +816,25 @@ autoreply define want_ip4_arp_events
   u32 context;
   u8 enable_disable;
   u32 pid;
-  u32 address;
+  vl_api_ip4_address_t ip;
 };
 
 /** \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 ip - 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 - the new mac address 
     @param mac_ip - 0: ARP resolution event, 1: MAC/IP info from L2 BDs
 */
 define ip4_arp_event
 {
   u32 client_index;
-  u32 address;
+  vl_api_ip4_address_t ip;
   u32 pid;
   u32 sw_if_index;
-  u8 new_mac[6];
+  vl_api_mac_address_t mac;
   u8 mac_ip;
 };
 
@@ -854,8 +849,8 @@ service {
     @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 interested ND resolution event, or
-                     0 to get MAC/IP info from ICMP6 NS in L2 BDs.
+    @param ip - 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
 {
@@ -863,7 +858,7 @@ autoreply define want_ip6_nd_events
   u32 context;
   u8 enable_disable;
   u32 pid;
-  u8 address[16];
+  vl_api_ip6_address_t ip;
 };
 
 /** \brief Tell client about an IP6 ND resolution or
@@ -871,7 +866,7 @@ autoreply define want_ip6_nd_events
     @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 ip - the exact ip6 address of interest
     @param new_mac - the new mac address 
     @param mac_ip - 0: ND resolution event, 1: MAC/IP info from L2 BDs
 */
@@ -880,8 +875,8 @@ define ip6_nd_event
   u32 client_index;
   u32 pid;
   u32 sw_if_index;
-  u8 address[16];
-  u8 new_mac[6];
+  vl_api_ip6_address_t ip;
+  vl_api_mac_address_t mac;
   u8 mac_ip;
 };
 
@@ -905,16 +900,14 @@ autoreply define want_ip6_ra_events
 };
 
 /** \brief Struct representing RA prefix info
-    @param dst_address - RA prefix info destination address
-    @param dst_address_length - RA prefix info destination address length
+    @param prefix - RA prefix info destination address
     @param flags - RA prefix info flags
     @param valid_time - RA prefix info valid time
     @param preferred_time - RA prefix info preferred time
 */
 typeonly define ip6_ra_prefix_info
 {
-  u8 dst_address[16];
-  u8 dst_address_length;
+  vl_api_prefix_t prefix;
   u8 flags;
   u32 valid_time;
   u32 preferred_time;
@@ -926,6 +919,7 @@ typeonly define ip6_ra_prefix_info
     @param current_hop_limit - RA current hop limit
     @param flags - RA flags
     @param router_lifetime_in_sec - RA lifetime in seconds
+    @param router_addr - The router's address
     @param neighbor_reachable_time_in_msec - RA neighbor reachable time in msec
     @param time_in_msec_between_retransmitted_neighbor_solicitations -
                time in msec between retransmitted neighbor solicitations
@@ -937,7 +931,7 @@ define ip6_ra_event
   u32 client_index;
   u32 pid;
   u32 sw_if_index;
-  u8 router_address[16];
+  vl_api_ip6_address_t router_addr;
   u8 current_hop_limit;
   u8 flags;
   u16 router_lifetime_in_sec;
@@ -953,15 +947,15 @@ service {
 };
 
 /** \brief Proxy ARP configuration type
-    @param vrf_id - VRF / Fib table ID
-    @param low_address[4] - Low address of the Proxy ARP range
-    @param hi_address[4] - High address of the Proxy ARP range
+    @param table_id - VRF / Fib table ID
+    @param low - Low address of the Proxy ARP range
+    @param hi - High address of the Proxy ARP range
 */
 typeonly define proxy_arp
 {
-  u32 vrf_id;
-  u8 low_address[4];
-  u8 hi_address[4];
+  u32 table_id;
+  vl_api_ip4_address_t low;
+  vl_api_ip4_address_t hi;
 };
 
 /** \brief Proxy ARP add / del request
index 1a1b7e5..5fc2552 100644 (file)
@@ -948,10 +948,6 @@ ip4_lookup_init (vlib_main_t * vm)
 
     clib_memset (&h, 0, sizeof (h));
 
-    /* Set target ethernet address to all zeros. */
-    clib_memset (h.ip4_over_ethernet[1].ethernet, 0,
-                sizeof (h.ip4_over_ethernet[1].ethernet));
-
 #define _16(f,v) h.f = clib_host_to_net_u16 (v);
 #define _8(f,v) h.f = v;
     _16 (l2_type, ETHERNET_ARP_HARDWARE_TYPE_ethernet);
@@ -1872,9 +1868,8 @@ ip4_arp_inline (vlib_main_t * vm,
          hw_if0 = vnet_get_sup_hw_interface (vnm, sw_if_index0);
 
          /* Src ethernet address in ARP header. */
-         clib_memcpy_fast (h0->ip4_over_ethernet[0].ethernet,
-                           hw_if0->hw_address,
-                           sizeof (h0->ip4_over_ethernet[0].ethernet));
+         mac_address_from_bytes (&h0->ip4_over_ethernet[0].mac,
+                                 hw_if0->hw_address);
          if (is_glean)
            {
              /* The interface's source address is stashed in the Glean Adj */
@@ -2046,8 +2041,7 @@ ip4_probe_neighbor (vlib_main_t * vm, ip4_address_t * dst, u32 sw_if_index,
                                sw_if_index);
     }
 
-  clib_memcpy_fast (h->ip4_over_ethernet[0].ethernet, hi->hw_address,
-                   sizeof (h->ip4_over_ethernet[0].ethernet));
+  mac_address_from_bytes (&h->ip4_over_ethernet[0].mac, hi->hw_address);
 
   h->ip4_over_ethernet[0].ip4 = src[0];
   h->ip4_over_ethernet[1].ip4 = dst[0];
index ab17f66..f16cda9 100644 (file)
@@ -42,6 +42,7 @@
 
 #include <vlib/buffer.h>
 #include <vnet/ethernet/packet.h>
+#include <vnet/ethernet/mac_address.h>
 #include <vnet/ip/ip6_packet.h>
 #include <vnet/ip/ip6_hop_by_hop_packet.h>
 #include <vnet/ip/lookup.h>
@@ -415,8 +416,13 @@ clib_error_t *set_ip6_link_local_address (vlib_main_t * vm,
                                          u32 sw_if_index,
                                          ip6_address_t * address);
 
+typedef int (*ip6_nd_change_event_cb_t) (u32 pool_index,
+                                        const mac_address_t * new_mac,
+                                        u32 sw_if_index,
+                                        const ip6_address_t * address);
+
 int vnet_add_del_ip6_nd_change_event (vnet_main_t * vnm,
-                                     void *data_callback,
+                                     ip6_nd_change_event_cb_t data_callback,
                                      u32 pid,
                                      void *address_arg,
                                      uword node_index,
index b4b6888..ded5b86 100755 (executable)
@@ -26,6 +26,7 @@
 #include <vnet/mfib/ip6_mfib.h>
 #include <vnet/ip/ip6_ll_table.h>
 #include <vnet/l2/l2_input.h>
+#include <vlibmemory/api.h>
 
 /**
  * @file
@@ -173,7 +174,7 @@ typedef struct
   uword type_opaque;
   uword data;
   /* Used for nd event notification only */
-  void *data_callback;
+  ip6_nd_change_event_cb_t data_callback;
   u32 pid;
 } pending_resolution_t;
 
@@ -266,15 +267,15 @@ ip6_neighbor_get_link_local_address (u32 sw_if_index)
  * @param sw_if_index The interface on which the ARP entires are acted
  */
 static int
-vnet_nd_wc_publish (u32 sw_if_index, u8 * mac, ip6_address_t * ip6)
+vnet_nd_wc_publish (u32 sw_if_index,
+                   const mac_address_t * mac, const ip6_address_t * ip6)
 {
   wc_nd_report_t r = {
     .sw_if_index = sw_if_index,
     .ip6 = *ip6,
+    .mac = *mac,
   };
-  memcpy (r.mac, mac, sizeof r.mac);
 
-  void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
   vl_api_rpc_call_main_thread (wc_nd_signal_report, (u8 *) & r, sizeof r);
   return 0;
 }
@@ -347,13 +348,13 @@ format_ip6_neighbor_ip6_entry (u8 * s, va_list * va)
     return format (s, "%=12s%=45s%=6s%=20s%=40s", "Time", "Address", "Flags",
                   "Link layer", "Interface");
 
-  if (n->flags & IP6_NEIGHBOR_FLAG_DYNAMIC)
+  if (n->flags & IP_NEIGHBOR_FLAG_DYNAMIC)
     flags = format (flags, "D");
 
-  if (n->flags & IP6_NEIGHBOR_FLAG_STATIC)
+  if (n->flags & IP_NEIGHBOR_FLAG_STATIC)
     flags = format (flags, "S");
 
-  if (n->flags & IP6_NEIGHBOR_FLAG_NO_FIB_ENTRY)
+  if (n->flags & IP_NEIGHBOR_FLAG_NO_FIB_ENTRY)
     flags = format (flags, "N");
 
   si = vnet_get_sw_interface (vnm, n->key.sw_if_index);
@@ -361,7 +362,7 @@ format_ip6_neighbor_ip6_entry (u8 * s, va_list * va)
              format_vlib_time, vm, n->time_last_updated,
              format_ip6_address, &n->key.ip6_address,
              flags ? (char *) flags : "",
-             format_ethernet_address, n->link_layer_address,
+             format_mac_address_t, &n->mac,
              format_vnet_sw_interface_name, vnm, si);
 
   vec_free (flags);
@@ -402,9 +403,8 @@ ip6_neighbor_adj_fib_remove (ip6_neighbor_t * n, u32 fib_index)
 typedef struct
 {
   u8 is_add;
-  u8 is_static;
-  u8 is_no_fib_entry;
-  u8 link_layer_address[6];
+  ip_neighbor_flags_t flags;
+  mac_address_t mac;
   u32 sw_if_index;
   ip6_address_t addr;
 } ip6_neighbor_set_unset_rpc_args_t;
@@ -416,19 +416,16 @@ static void set_unset_ip6_neighbor_rpc
   (vlib_main_t * vm,
    u32 sw_if_index,
    const ip6_address_t * a,
-   const u8 * link_layer_address,
-   int is_add, int is_static, int is_no_fib_entry)
+   const mac_address_t * mac, int is_add, ip_neighbor_flags_t flags)
 {
   ip6_neighbor_set_unset_rpc_args_t args;
   void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
 
   args.sw_if_index = sw_if_index;
   args.is_add = is_add;
-  args.is_static = is_static;
-  args.is_no_fib_entry = is_no_fib_entry;
-  clib_memcpy (&args.addr, a, sizeof (*a));
-  if (NULL != link_layer_address)
-    clib_memcpy (args.link_layer_address, link_layer_address, 6);
+  args.flags = flags;
+  ip6_address_copy (&args.addr, a);
+  mac_address_copy (&args.mac, mac);
 
   vl_api_rpc_call_main_thread (ip6_neighbor_set_unset_rpc_callback,
                               (u8 *) & args, sizeof (args));
@@ -511,7 +508,7 @@ ip6_nd_mk_complete (adj_index_t ai, ip6_neighbor_t * nbr)
                          ethernet_build_rewrite (vnet_get_main (),
                                                  nbr->key.sw_if_index,
                                                  adj_get_link_type (ai),
-                                                 nbr->link_layer_address));
+                                                 nbr->mac.bytes));
 }
 
 static void
@@ -604,7 +601,7 @@ ip6_neighbor_sw_interface_up_down (vnet_main_t * vnm,
          n = pool_elt_at_index (nm->neighbor_pool, to_delete[i]);
          adj_nbr_walk_nh6 (n->key.sw_if_index, &n->key.ip6_address,
                            ip6_nd_mk_incomplete_walk, NULL);
-         if (n->flags & IP6_NEIGHBOR_FLAG_STATIC)
+         if (n->flags & IP_NEIGHBOR_FLAG_STATIC)
            continue;
          ip6_neighbor_adj_fib_remove (n,
                                       ip6_fib_table_get_index_for_sw_if_index
@@ -759,7 +756,7 @@ force_reuse_neighbor_entry (void)
       nm->neighbor_delete_rotor = index;
       index = pool_next_index (nm->neighbor_pool, index);
     }
-  while (n->flags & IP6_NEIGHBOR_FLAG_STATIC);
+  while (n->flags & IP_NEIGHBOR_FLAG_STATIC);
 
   /* Remove ARP entry from its interface and update fib */
   adj_nbr_walk_nh6 (n->key.sw_if_index,
@@ -775,9 +772,8 @@ int
 vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
                                u32 sw_if_index,
                                const ip6_address_t * a,
-                               const u8 * link_layer_address,
-                               uword n_bytes_link_layer_address,
-                               int is_static, int is_no_fib_entry)
+                               const mac_address_t * mac,
+                               ip_neighbor_flags_t flags)
 {
   ip6_neighbor_main_t *nm = &ip6_neighbor_main;
   ip6_neighbor_key_t k;
@@ -789,9 +785,7 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
 
   if (vlib_get_thread_index ())
     {
-      set_unset_ip6_neighbor_rpc (vm, sw_if_index, a, link_layer_address,
-                                 1 /* set new neighbor */ , is_static,
-                                 is_no_fib_entry);
+      set_unset_ip6_neighbor_rpc (vm, sw_if_index, a, mac, 1, flags);
       return 0;
     }
 
@@ -804,11 +798,11 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
     {
       n = pool_elt_at_index (nm->neighbor_pool, p[0]);
       /* Refuse to over-write static neighbor entry. */
-      if (!is_static && (n->flags & IP6_NEIGHBOR_FLAG_STATIC))
+      if (!(flags & IP_NEIGHBOR_FLAG_STATIC) &&
+         (n->flags & IP_NEIGHBOR_FLAG_STATIC))
        {
          /* if MAC address match, still check to send event */
-         if (0 == memcmp (n->link_layer_address,
-                          link_layer_address, n_bytes_link_layer_address))
+         if (0 == mac_address_cmp (&n->mac, mac))
            goto check_customers;
          return -2;
        }
@@ -832,20 +826,19 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
       n->key = k;
       n->fib_entry_index = FIB_NODE_INDEX_INVALID;
 
-      clib_memcpy (n->link_layer_address,
-                  link_layer_address, n_bytes_link_layer_address);
+      mac_address_copy (&n->mac, mac);
 
       /*
        * create the adj-fib. the entry in the FIB table for and to the peer.
        */
-      if (!is_no_fib_entry)
+      if (!(flags & IP_NEIGHBOR_FLAG_NO_FIB_ENTRY))
        {
          ip6_neighbor_adj_fib_add
            (n, ip6_fib_table_get_index_for_sw_if_index (n->key.sw_if_index));
        }
       else
        {
-         n->flags |= IP6_NEIGHBOR_FLAG_NO_FIB_ENTRY;
+         n->flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
        }
     }
   else
@@ -854,28 +847,26 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
        * prevent a DoS attack from the data-plane that
        * spams us with no-op updates to the MAC address
        */
-      if (0 == memcmp (n->link_layer_address,
-                      link_layer_address, n_bytes_link_layer_address))
+      if (0 == mac_address_cmp (&n->mac, mac))
        {
          n->time_last_updated = vlib_time_now (vm);
          goto check_customers;
        }
 
-      clib_memcpy (n->link_layer_address,
-                  link_layer_address, n_bytes_link_layer_address);
+      mac_address_copy (&n->mac, mac);
     }
 
   /* Update time stamp and flags. */
   n->time_last_updated = vlib_time_now (vm);
-  if (is_static)
+  if (flags & IP_NEIGHBOR_FLAG_STATIC)
     {
-      n->flags |= IP6_NEIGHBOR_FLAG_STATIC;
-      n->flags &= ~IP6_NEIGHBOR_FLAG_DYNAMIC;
+      n->flags |= IP_NEIGHBOR_FLAG_STATIC;
+      n->flags &= ~IP_NEIGHBOR_FLAG_DYNAMIC;
     }
   else
     {
-      n->flags |= IP6_NEIGHBOR_FLAG_DYNAMIC;
-      n->flags &= ~IP6_NEIGHBOR_FLAG_STATIC;
+      n->flags |= IP_NEIGHBOR_FLAG_DYNAMIC;
+      n->flags &= ~IP_NEIGHBOR_FLAG_STATIC;
     }
 
   adj_nbr_walk_nh6 (sw_if_index,
@@ -908,16 +899,13 @@ check_customers:
 
       while (next_index != (u32) ~ 0)
        {
-         int (*fp) (u32, u8 *, u32, ip6_address_t *);
          int rv = 1;
+
          mc = pool_elt_at_index (nm->mac_changes, next_index);
-         fp = mc->data_callback;
 
          /* Call the user's data callback, return 1 to suppress dup events */
-         if (fp)
-           rv =
-             (*fp) (mc->data, (u8 *) link_layer_address, sw_if_index,
-                    &ip6a_zero);
+         if (mc->data_callback)
+           rv = (mc->data_callback) (mc->data, mac, sw_if_index, &ip6a_zero);
          /*
           * Signal the resolver process, as long as the user
           * says they want to be notified
@@ -944,8 +932,8 @@ vnet_unset_ip6_ethernet_neighbor (vlib_main_t * vm,
 
   if (vlib_get_thread_index ())
     {
-      set_unset_ip6_neighbor_rpc (vm, sw_if_index, a, NULL,
-                                 0 /* unset */ , 0, 0);
+      set_unset_ip6_neighbor_rpc (vm, sw_if_index, a, NULL, 0,
+                                 IP_NEIGHBOR_FLAG_NONE);
       return 0;
     }
 
@@ -980,8 +968,7 @@ static void ip6_neighbor_set_unset_rpc_callback
   vlib_main_t *vm = vlib_get_main ();
   if (a->is_add)
     vnet_set_ip6_ethernet_neighbor (vm, a->sw_if_index, &a->addr,
-                                   a->link_layer_address, 6, a->is_static,
-                                   a->is_no_fib_entry);
+                                   &a->mac, a->flags);
   else
     vnet_unset_ip6_ethernet_neighbor (vm, a->sw_if_index, &a->addr);
 }
@@ -1010,7 +997,7 @@ ip6_neighbor_t *
 ip6_neighbors_entries (u32 sw_if_index)
 {
   ip6_neighbor_main_t *nm = &ip6_neighbor_main;
-  ip6_neighbor_t *n, *ns = 0;
+  ip6_neighbor_t *n, *ns = NULL;
 
   /* *INDENT-OFF* */
   pool_foreach (n, nm->neighbor_pool,
@@ -1085,13 +1072,12 @@ static clib_error_t *
 set_ip6_neighbor (vlib_main_t * vm,
                  unformat_input_t * input, vlib_cli_command_t * cmd)
 {
+  ip_neighbor_flags_t flags = IP_NEIGHBOR_FLAG_NONE;
   vnet_main_t *vnm = vnet_get_main ();
   ip6_address_t addr;
-  u8 mac_address[6];
+  mac_address_t mac;
   int addr_valid = 0;
   int is_del = 0;
-  int is_static = 0;
-  int is_no_fib_entry = 0;
   u32 sw_if_index;
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
@@ -1100,15 +1086,15 @@ set_ip6_neighbor (vlib_main_t * vm,
       if (unformat (input, "%U %U %U",
                    unformat_vnet_sw_interface, vnm, &sw_if_index,
                    unformat_ip6_address, &addr,
-                   unformat_ethernet_address, mac_address))
+                   unformat_mac_address_t, &mac))
        addr_valid = 1;
 
       else if (unformat (input, "delete") || unformat (input, "del"))
        is_del = 1;
       else if (unformat (input, "static"))
-       is_static = 1;
+       flags |= IP_NEIGHBOR_FLAG_STATIC;
       else if (unformat (input, "no-fib-entry"))
-       is_no_fib_entry = 1;
+       flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
       else
        break;
     }
@@ -1117,9 +1103,7 @@ set_ip6_neighbor (vlib_main_t * vm,
     return clib_error_return (0, "Missing interface, ip6 or hw address");
 
   if (!is_del)
-    vnet_set_ip6_ethernet_neighbor (vm, sw_if_index, &addr,
-                                   mac_address, sizeof (mac_address),
-                                   is_static, is_no_fib_entry);
+    vnet_set_ip6_ethernet_neighbor (vm, sw_if_index, &addr, &mac, flags);
   else
     vnet_unset_ip6_ethernet_neighbor (vm, sw_if_index, &addr);
   return 0;
@@ -1258,9 +1242,9 @@ icmp6_neighbor_solicitation_or_advertisement (vlib_main_t * vm,
                                              is_solicitation ?
                                              &ip0->src_address :
                                              &h0->target_address,
+                                             (mac_address_t *)
                                              o0->ethernet_address,
-                                             sizeof (o0->ethernet_address),
-                                             0, 0);
+                                             IP_NEIGHBOR_FLAG_NONE);
            }
 
          if (is_solicitation && error0 == ICMP6_ERROR_NONE)
@@ -1591,11 +1575,11 @@ icmp6_router_solicitation (vlib_main_t * vm,
          if (PREDICT_TRUE (error0 == ICMP6_ERROR_NONE && o0 != 0 &&
                            !is_unspecified && !is_link_local))
            {
-             vnet_set_ip6_ethernet_neighbor (vm, sw_if_index0,
-                                             &ip0->src_address,
-                                             o0->ethernet_address,
-                                             sizeof (o0->ethernet_address),
-                                             0, 0);
+             vnet_set_ip6_ethernet_neighbor
+               (vm, sw_if_index0,
+                &ip0->src_address,
+                (mac_address_t *) o0->ethernet_address,
+                IP_NEIGHBOR_FLAG_NONE);
            }
 
          /* default is to drop */
@@ -2013,7 +1997,7 @@ icmp6_router_advertisement (vlib_main_t * vm,
                      ra_report_t r;
 
                      r.sw_if_index = sw_if_index0;
-                     memcpy (r.router_address, &ip0->src_address, 16);
+                     memcpy (&r.router_address, &ip0->src_address, 16);
                      r.current_hop_limit = h0->current_hop_limit;
                      r.flags = h0->flags;
                      r.router_lifetime_in_sec =
@@ -2208,9 +2192,9 @@ icmp6_router_advertisement (vlib_main_t * vm,
                                prefix->preferred_time = preferred;
                                prefix->valid_time = valid;
                                prefix->flags = h->flags & 0xc0;
-                               prefix->dst_address_length =
-                                 h->dst_address_length;
-                               prefix->dst_address = h->dst_address;
+                               prefix->prefix.fp_len = h->dst_address_length;
+                               prefix->prefix.fp_addr.ip6 = h->dst_address;
+                               prefix->prefix.fp_proto = FIB_PROTOCOL_IP6;
 
                                /* look for matching prefix - if we our advertising it, it better be consistant */
                                /* *INDENT-OFF* */
@@ -4686,7 +4670,7 @@ vnet_register_ip6_neighbor_resolution_event (vnet_main_t * vnm,
 
 int
 vnet_add_del_ip6_nd_change_event (vnet_main_t * vnm,
-                                 void *data_callback,
+                                 ip6_nd_change_event_cb_t data_callback,
                                  u32 pid,
                                  void *address_arg,
                                  uword node_index,
@@ -4740,9 +4724,8 @@ vnet_add_del_ip6_nd_change_event (vnet_main_t * vnm,
        return VNET_API_ERROR_NO_SUCH_ENTRY;
 
       /* Clients may need to clean up pool entries, too */
-      void (*fp) (u32, u8 *) = data_callback;
-      if (fp)
-       (*fp) (mc->data, 0 /* no new mac addrs */ );
+      if (data_callback)
+       (data_callback) (mc->data, NULL /* no new mac addrs */ , 0, NULL);
 
       /* Remove the entry from the list and delete the entry */
       *p = mc->next_index;
@@ -4764,7 +4747,9 @@ vnet_ip6_nd_term (vlib_main_t * vm,
 {
   ip6_neighbor_main_t *nm = &ip6_neighbor_main;
   icmp6_neighbor_solicitation_or_advertisement_header_t *ndh;
+  mac_address_t mac;
 
+  mac_address_from_bytes (&mac, eth->src_address);
   ndh = ip6_next_header (ip);
   if (ndh->icmp.type != ICMP6_neighbor_solicitation &&
       ndh->icmp.type != ICMP6_neighbor_advertisement)
@@ -4783,7 +4768,7 @@ vnet_ip6_nd_term (vlib_main_t * vm,
       (nm->wc_ip6_nd_publisher_node != (uword) ~ 0
        && !ip6_address_is_link_local_unicast (&ip->src_address)))
     {
-      vnet_nd_wc_publish (sw_if_index, eth->src_address, &ip->src_address);
+      vnet_nd_wc_publish (sw_if_index, &mac, &ip->src_address);
     }
 
   /* Check if MAC entry exsist for solicited target IP */
index e273a10..0707a2a 100644 (file)
@@ -20,6 +20,8 @@
 #define included_ip6_neighbor_h
 
 #include <vnet/fib/fib_types.h>
+#include <vnet/ethernet/mac_address.h>
+#include <vnet/ip/ip_neighbor.h>
 
 typedef struct
 {
@@ -28,18 +30,11 @@ typedef struct
   u32 pad;
 } ip6_neighbor_key_t;
 
-typedef enum ip6_neighbor_flags_t_
-{
-  IP6_NEIGHBOR_FLAG_STATIC = (1 << 0),
-  IP6_NEIGHBOR_FLAG_DYNAMIC = (1 << 1),
-  IP6_NEIGHBOR_FLAG_NO_FIB_ENTRY = (1 << 2),
-} __attribute__ ((packed)) ip6_neighbor_flags_t;
-
 typedef struct
 {
   ip6_neighbor_key_t key;
-  u8 link_layer_address[8];
-  ip6_neighbor_flags_t flags;
+  mac_address_t mac;
+  ip_neighbor_flags_t flags;
   f64 time_last_updated;
   fib_node_index_t fib_entry_index;
 } ip6_neighbor_t;
@@ -81,10 +76,8 @@ extern void vnet_register_ip6_neighbor_resolution_event (vnet_main_t * vnm,
 extern int vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
                                           u32 sw_if_index,
                                           const ip6_address_t * a,
-                                          const u8 * link_layer_address,
-                                          uword n_bytes_link_layer_address,
-                                          int is_static,
-                                          int is_no_fib_entry);
+                                          const mac_address_t * mac,
+                                          ip_neighbor_flags_t flags);
 
 extern int vnet_unset_ip6_ethernet_neighbor (vlib_main_t * vm,
                                             u32 sw_if_index,
@@ -99,7 +92,7 @@ typedef struct
 {
   u32 sw_if_index;
   ip6_address_t ip6;
-  u8 mac[6];
+  mac_address_t mac;
 } wc_nd_report_t;
 
 void wc_nd_set_publisher_node (uword node_index, uword event_type);
@@ -119,8 +112,7 @@ void icmp6_send_router_solicitation (vlib_main_t * vm, u32 sw_if_index,
 
 typedef struct
 {
-  ip6_address_t dst_address;
-  u8 dst_address_length;
+  fib_prefix_t prefix;
   u8 flags;
   u32 valid_time;
   u32 preferred_time;
@@ -129,7 +121,7 @@ typedef struct
 typedef struct
 {
   u32 sw_if_index;
-  u8 router_address[16];
+  ip6_address_t router_address;
   u8 current_hop_limit;
   u8 flags;
   u16 router_lifetime_in_sec;
index 015dd01..5d33cc7 100644 (file)
@@ -181,6 +181,13 @@ ip46_address_is_multicast (const ip46_address_t * a)
     ip6_address_is_multicast (&a->ip6);
 }
 
+always_inline void
+ip6_address_copy (ip6_address_t * dst, const ip6_address_t * src)
+{
+  dst->as_u64[0] = src->as_u64[0];
+  dst->as_u64[1] = src->as_u64[1];
+}
+
 always_inline void
 ip6_set_reserved_multicast_address (ip6_address_t * a,
                                    ip6_multicast_address_scope_t scope,
index b9fa001..749cb88 100644 (file)
 #include <vnet/interface.h>
 #include <vnet/api_errno.h>
 #include <vnet/ethernet/ethernet.h>
+#include <vnet/ethernet/ethernet_types_api.h>
 #include <vnet/ip/ip.h>
 #include <vnet/ip/ip_neighbor.h>
+#include <vnet/ip/ip_types_api.h>
 #include <vnet/ip/ip6_neighbor.h>
 #include <vnet/ip/ip_punt_drop.h>
 #include <vnet/fib/fib_table.h>
@@ -120,13 +122,25 @@ _(IP_PUNT_REDIRECT_DUMP, ip_punt_redirect_dump)
 extern void stats_dslock_with_hint (int hint, int tag);
 extern void stats_dsunlock (void);
 
+static vl_api_ip_neighbor_flags_t
+ip_neighbor_flags_encode (ip_neighbor_flags_t f)
+{
+  vl_api_ip_neighbor_flags_t v = IP_API_NEIGHBOR_FLAG_NONE;
+
+  if (f & IP_NEIGHBOR_FLAG_STATIC)
+    v |= IP_API_NEIGHBOR_FLAG_STATIC;
+  if (f & IP_NEIGHBOR_FLAG_NO_FIB_ENTRY)
+    v |= IP_API_NEIGHBOR_FLAG_NO_FIB_ENTRY;
+
+  return (clib_host_to_net_u32 (v));
+}
+
 static void
 send_ip_neighbor_details (u32 sw_if_index,
-                         u8 is_ipv6,
-                         u8 is_static,
-                         u8 * mac_address,
-                         u8 * ip_address, vl_api_registration_t * reg,
-                         u32 context)
+                         const ip46_address_t * ip_address,
+                         const mac_address_t * mac,
+                         ip_neighbor_flags_t flags,
+                         vl_api_registration_t * reg, u32 context)
 {
   vl_api_ip_neighbor_details_t *mp;
 
@@ -134,11 +148,11 @@ send_ip_neighbor_details (u32 sw_if_index,
   clib_memset (mp, 0, sizeof (*mp));
   mp->_vl_msg_id = ntohs (VL_API_IP_NEIGHBOR_DETAILS);
   mp->context = context;
-  mp->sw_if_index = htonl (sw_if_index);
-  mp->is_ipv6 = is_ipv6;
-  mp->is_static = is_static;
-  memcpy (mp->mac_address, mac_address, 6);
-  memcpy (mp->ip_address, ip_address, (is_ipv6) ? 16 : 4);
+  mp->neighbor.sw_if_index = htonl (sw_if_index);
+  mp->neighbor.flags = ip_neighbor_flags_encode (flags);
+
+  ip_address_encode (ip_address, IP46_TYPE_ANY, &mp->neighbor.ip_address);
+  mac_address_encode (mac, mp->neighbor.mac_address);
 
   vl_api_send_msg (reg, (u8 *) mp);
 }
@@ -162,12 +176,15 @@ vl_api_ip_neighbor_dump_t_handler (vl_api_ip_neighbor_dump_t * mp)
       /* *INDENT-OFF* */
       vec_foreach (n, ns)
       {
-        send_ip_neighbor_details
-          (n->key.sw_if_index, mp->is_ipv6,
-          ((n->flags & IP6_NEIGHBOR_FLAG_STATIC) ? 1 : 0),
-           (u8 *) n->link_layer_address,
-           (u8 *) & (n->key.ip6_address.as_u8),
-           reg, mp->context);
+        ip46_address_t nh = {
+          .ip6 = {
+            .as_u64[0] = n->key.ip6_address.as_u64[0],
+            .as_u64[1] = n->key.ip6_address.as_u64[1],
+          },
+        };
+        send_ip_neighbor_details (n->key.sw_if_index, &nh,
+                                  &n->mac, n->flags,
+                                  reg, mp->context);
       }
       /* *INDENT-ON* */
       vec_free (ns);
@@ -180,11 +197,15 @@ vl_api_ip_neighbor_dump_t_handler (vl_api_ip_neighbor_dump_t * mp)
       /* *INDENT-OFF* */
       vec_foreach (n, ns)
       {
-        send_ip_neighbor_details (n->sw_if_index, mp->is_ipv6,
-          ((n->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC) ? 1 : 0),
-          (u8*) n->ethernet_address,
-          (u8*) & (n->ip4_address.as_u8),
-          reg, mp->context);
+        ip46_address_t nh = {
+          .ip4 = {
+            .as_u32 = n->ip4_address.as_u32,
+          },
+        };
+
+        send_ip_neighbor_details (n->sw_if_index, &nh,
+                                  &n->mac, n->flags,
+                                  reg, mp->context);
       }
       /* *INDENT-ON* */
       vec_free (ns);
@@ -654,36 +675,52 @@ vl_api_ip_punt_redirect_t_handler (vl_api_ip_punt_redirect_t * mp,
   REPLY_MACRO (VL_API_IP_PUNT_REDIRECT_REPLY);
 }
 
+static ip_neighbor_flags_t
+ip_neighbor_flags_decode (vl_api_ip_neighbor_flags_t v)
+{
+  ip_neighbor_flags_t f = IP_NEIGHBOR_FLAG_NONE;
+
+  v = clib_net_to_host_u32 (v);
+
+  if (v & IP_API_NEIGHBOR_FLAG_STATIC)
+    f |= IP_NEIGHBOR_FLAG_STATIC;
+  if (v & IP_API_NEIGHBOR_FLAG_NO_FIB_ENTRY)
+    f |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
+
+  return (f);
+}
+
 static void
 vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
                                      vlib_main_t * vm)
 {
-  ip46_address_t ip = ip46_address_initializer;
   vl_api_ip_neighbor_add_del_reply_t *rmp;
   ip_neighbor_flags_t flags;
   u32 stats_index = ~0;
+  ip46_address_t ip;
+  mac_address_t mac;
+  ip46_type_t type;
   int rv = 0;
 
-  VALIDATE_SW_IF_INDEX (mp);
+  VALIDATE_SW_IF_INDEX ((&mp->neighbor));
 
   stats_dslock_with_hint (1 /* release hint */ , 7 /* tag */ );
 
-  flags = IP_NEIGHBOR_FLAG_NODE;
-  if (mp->is_static)
-    flags |= IP_NEIGHBOR_FLAG_STATIC;
-  if (mp->is_no_adj_fib)
-    flags |= IP_NEIGHBOR_FLAG_NO_ADJ_FIB;
-
-  if (mp->is_ipv6)
-    clib_memcpy (&ip.ip6, mp->dst_address, 16);
-  else
-    clib_memcpy (&ip.ip4, mp->dst_address, 4);
+  flags = ip_neighbor_flags_decode (mp->neighbor.flags);
+  type = ip_address_decode (&mp->neighbor.ip_address, &ip);
+  mac_address_decode (mp->neighbor.mac_address, &mac);
 
+  /*
+   * there's no validation here of the ND/ARP entry being added.
+   * The expectation is that the FIB will ensure that nothing bad
+   * will come of adding bogus entries.
+   */
   if (mp->is_add)
-    rv = ip_neighbor_add (&ip, mp->is_ipv6, mp->mac_address,
-                         ntohl (mp->sw_if_index), flags, &stats_index);
+    rv = ip_neighbor_add (&ip, type, &mac,
+                         ntohl (mp->neighbor.sw_if_index),
+                         flags, &stats_index);
   else
-    rv = ip_neighbor_del (&ip, mp->is_ipv6, ntohl (mp->sw_if_index));
+    rv = ip_neighbor_del (&ip, type, ntohl (mp->neighbor.sw_if_index));
 
   stats_dsunlock ();
 
@@ -1660,11 +1697,13 @@ static void
 {
   vlib_main_t *vm = vlib_get_main ();
   vl_api_sw_interface_ip6nd_ra_prefix_reply_t *rmp;
+  fib_prefix_t pfx;
   int rv = 0;
   u8 is_no, use_default, no_advertise, off_link, no_autoconfig, no_onlink;
 
   VALIDATE_SW_IF_INDEX (mp);
 
+  ip_prefix_decode (&mp->prefix, &pfx);
   is_no = mp->is_no == 1;
   use_default = mp->use_default == 1;
   no_advertise = mp->no_advertise == 1;
@@ -1673,8 +1712,8 @@ static void
   no_onlink = mp->no_onlink == 1;
 
   rv = ip6_neighbor_ra_prefix (vm, ntohl (mp->sw_if_index),
-                              (ip6_address_t *) mp->address,
-                              mp->address_length, use_default,
+                              &pfx.fp_addr.ip6,
+                              pfx.fp_len, use_default,
                               ntohl (mp->val_lifetime),
                               ntohl (mp->pref_lifetime), no_advertise,
                               off_link, no_autoconfig, no_onlink, is_no);
@@ -1695,7 +1734,8 @@ send_ip6nd_proxy_details (vl_api_registration_t * reg,
   mp->_vl_msg_id = ntohs (VL_API_IP6ND_PROXY_DETAILS);
   mp->context = context;
   mp->sw_if_index = htonl (sw_if_index);
-  memcpy (mp->address, addr, 16);
+
+  ip6_address_encode (&addr->ip6, mp->ip);
 
   vl_api_send_msg (reg, (u8 *) mp);
 }
@@ -1763,12 +1803,13 @@ static void
 vl_api_ip6nd_proxy_add_del_t_handler (vl_api_ip6nd_proxy_add_del_t * mp)
 {
   vl_api_ip6nd_proxy_add_del_reply_t *rmp;
+  ip6_address_t ip6;
   int rv = 0;
 
   VALIDATE_SW_IF_INDEX (mp);
 
-  rv = ip6_neighbor_proxy_add_del (ntohl (mp->sw_if_index),
-                                  (ip6_address_t *) mp->address, mp->is_del);
+  ip6_address_decode (mp->ip, &ip6);
+  rv = ip6_neighbor_proxy_add_del (ntohl (mp->sw_if_index), &ip6, mp->is_del);
 
   BAD_SW_IF_INDEX_LABEL;
   REPLY_MACRO (VL_API_IP6ND_PROXY_ADD_DEL_REPLY);
@@ -1910,8 +1951,9 @@ static void
   clib_error_t *error;
 
   clib_memset (&args, 0, sizeof (args));
-  ip_set (&args.prefix.fp_addr, mp->ip, mp->is_ip4);
-  args.prefix.fp_len = mp->plen ? mp->plen : (mp->is_ip4 ? 32 : 128);
+
+  ip_prefix_decode (&mp->pfx, &args.prefix);
+
   args.sw_if_index = clib_net_to_host_u32 (mp->sw_if_index);
   args.is_add = mp->is_add;
   if ((error = vnet_ip_container_proxy_add_del (&args)))
@@ -2014,11 +2056,8 @@ static void
   vl_api_ip_source_and_port_range_check_add_del_reply_t *rmp;
   int rv = 0;
 
-  u8 is_ipv6 = mp->is_ipv6;
   u8 is_add = mp->is_add;
-  u8 mask_length = mp->mask_length;
-  ip4_address_t ip4_addr;
-  ip6_address_t ip6_addr;
+  fib_prefix_t pfx;
   u16 *low_ports = 0;
   u16 *high_ports = 0;
   u32 vrf_id;
@@ -2026,6 +2065,8 @@ static void
   u8 num_ranges;
   int i;
 
+  ip_prefix_decode (&mp->prefix, &pfx);
+
   // Validate port range
   num_ranges = mp->number_of_ranges;
   if (num_ranges > 32)
@@ -2052,13 +2093,6 @@ static void
       vec_add1 (high_ports, tmp_high + 1);
     }
 
-  // Validate mask_length
-  if ((is_ipv6 && mask_length > 128) || (!is_ipv6 && mask_length > 32))
-    {
-      rv = VNET_API_ERROR_ADDRESS_LENGTH_MISMATCH;
-      goto reply;
-    }
-
   vrf_id = ntohl (mp->vrf_id);
 
   if (vrf_id < 1)
@@ -2068,20 +2102,18 @@ static void
     }
 
 
-  if (is_ipv6)
+  if (FIB_PROTOCOL_IP6 == pfx.fp_proto)
     {
-      clib_memcpy (ip6_addr.as_u8, mp->address, sizeof (ip6_addr.as_u8));
-      rv = ip6_source_and_port_range_check_add_del (&ip6_addr,
-                                                   mask_length,
+      rv = ip6_source_and_port_range_check_add_del (&pfx.fp_addr.ip6,
+                                                   pfx.fp_len,
                                                    vrf_id,
                                                    low_ports,
                                                    high_ports, is_add);
     }
   else
     {
-      clib_memcpy (ip4_addr.data, mp->address, sizeof (ip4_addr));
-      rv = ip4_source_and_port_range_check_add_del (&ip4_addr,
-                                                   mask_length,
+      rv = ip4_source_and_port_range_check_add_del (&pfx.fp_addr.ip4,
+                                                   pfx.fp_len,
                                                    vrf_id,
                                                    low_ports,
                                                    high_ports, is_add);
@@ -2181,10 +2213,22 @@ static void
 #define IP4_ARP_EVENT 3
 #define IP6_ND_EVENT 4
 
-static int arp_change_delete_callback (u32 pool_index, u8 * notused);
-static int nd_change_delete_callback (u32 pool_index, u8 * notused);
 static vlib_node_registration_t ip_resolver_process_node;
 
+static int
+arp_change_delete_callback (u32 pool_index,
+                           const mac_address_t * mac,
+                           u32 sw_if_index, const ip4_address_t * address)
+{
+  vpe_api_main_t *am = &vpe_api_main;
+
+  if (pool_is_free_index (am->arp_events, pool_index))
+    return 1;
+
+  pool_put_index (am->arp_events, pool_index);
+  return 0;
+}
+
 static void
 handle_ip4_arp_event (u32 pool_index)
 {
@@ -2206,7 +2250,7 @@ handle_ip4_arp_event (u32 pool_index)
     {
       (void) vnet_add_del_ip4_arp_change_event
        (vnm, arp_change_delete_callback,
-        event->pid, &event->address,
+        event->pid, event->ip,
         ip_resolver_process_node.index, IP4_ARP_EVENT,
         ~0 /* pool index, notused */ , 0 /* is_add */ );
       return;
@@ -2228,12 +2272,26 @@ handle_ip4_arp_event (u32 pool_index)
       if (vlib_time_now (vm) > last_time + 10.0)
        {
          clib_warning ("arp event for %U to pid %d: queue stuffed!",
-                       format_ip4_address, &event->address, event->pid);
+                       format_ip4_address, event->ip, event->pid);
          last_time = vlib_time_now (vm);
        }
     }
 }
 
+static int
+nd_change_delete_callback (u32 pool_index,
+                          const mac_address_t * mac,
+                          u32 sw_if_index, const ip6_address_t * addr)
+{
+  vpe_api_main_t *am = &vpe_api_main;
+
+  if (pool_is_free_index (am->nd_events, pool_index))
+    return 1;
+
+  pool_put_index (am->nd_events, pool_index);
+  return 0;
+}
+
 static void
 handle_ip6_nd_event (u32 pool_index)
 {
@@ -2255,7 +2313,7 @@ handle_ip6_nd_event (u32 pool_index)
     {
       (void) vnet_add_del_ip6_nd_change_event
        (vnm, nd_change_delete_callback,
-        event->pid, &event->address,
+        event->pid, event->ip,
         ip_resolver_process_node.index, IP6_ND_EVENT,
         ~0 /* pool index, notused */ , 0 /* is_add */ );
       return;
@@ -2277,7 +2335,7 @@ handle_ip6_nd_event (u32 pool_index)
       if (vlib_time_now (vm) > last_time + 10.0)
        {
          clib_warning ("ip6 nd event for %U to pid %d: queue stuffed!",
-                       format_ip6_address, &event->address, event->pid);
+                       format_ip6_address, event->ip, event->pid);
          last_time = vlib_time_now (vm);
        }
     }
@@ -2328,8 +2386,8 @@ VLIB_REGISTER_NODE (ip_resolver_process_node,static) = {
 /* *INDENT-ON* */
 
 static int
-nd_change_data_callback (u32 pool_index, u8 * new_mac,
-                        u32 sw_if_index, ip6_address_t * address)
+nd_change_data_callback (u32 pool_index, const mac_address_t * new_mac,
+                        u32 sw_if_index, const ip6_address_t * address)
 {
   vpe_api_main_t *am = &vpe_api_main;
   vl_api_ip6_nd_event_t *event;
@@ -2338,41 +2396,17 @@ nd_change_data_callback (u32 pool_index, u8 * new_mac,
     return 1;
 
   event = pool_elt_at_index (am->nd_events, pool_index);
-  if (eth_mac_equal (event->new_mac, new_mac) &&
+  if (ethernet_mac_address_equal (event->mac, new_mac->bytes) &&
       sw_if_index == ntohl (event->sw_if_index))
     {
       return 1;
     }
 
-  clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
+  mac_address_encode (new_mac, event->mac);
   event->sw_if_index = htonl (sw_if_index);
   return 0;
 }
 
-static int
-arp_change_delete_callback (u32 pool_index, u8 * notused)
-{
-  vpe_api_main_t *am = &vpe_api_main;
-
-  if (pool_is_free_index (am->arp_events, pool_index))
-    return 1;
-
-  pool_put_index (am->arp_events, pool_index);
-  return 0;
-}
-
-static int
-nd_change_delete_callback (u32 pool_index, u8 * notused)
-{
-  vpe_api_main_t *am = &vpe_api_main;
-
-  if (pool_is_free_index (am->nd_events, pool_index))
-    return 1;
-
-  pool_put_index (am->nd_events, pool_index);
-  return 0;
-}
-
 static vlib_node_registration_t wc_arp_process_node;
 
 enum
@@ -2403,9 +2437,10 @@ wc_arp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
          wc_arp_report_t *arp_events = event_data;
          for (i = 0; i < vec_len (arp_events); i++)
            {
-             /* discard dup event */
-             if (arp_prev.ip4 == arp_events[i].ip4 &&
-                 eth_mac_equal ((u8 *) arp_prev.mac, arp_events[i].mac) &&
+             /* discard dup event - cast away volatile */
+             if (arp_prev.ip.as_u32 == arp_events[i].ip.as_u32 &&
+                 mac_address_equal ((const mac_address_t *) &arp_prev.mac,
+                                    &arp_events[i].mac) &&
                  arp_prev.sw_if_index == arp_events[i].sw_if_index &&
                  (now - last_arp) < 10.0)
                {
@@ -2428,9 +2463,9 @@ wc_arp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
                  event->client_index = reg->client_index;
                  event->pid = reg->client_pid;
                  event->mac_ip = 1;
-                 event->address = arp_events[i].ip4;
+                 ip4_address_encode(&arp_events[i].ip, event->ip);
                  event->sw_if_index = htonl(arp_events[i].sw_if_index);
-                 memcpy(event->new_mac, arp_events[i].mac, sizeof event->new_mac);
+                 mac_address_encode(&arp_events[i].mac, event->mac);
                  vl_api_send_msg (vl_reg, (u8 *) event);
                }
             }));
@@ -2442,10 +2477,11 @@ wc_arp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
          wc_nd_report_t *nd_events = event_data;
          for (i = 0; i < vec_len (nd_events); i++)
            {
-             /* discard dup event */
-             if (ip6_address_is_equal
-                 ((ip6_address_t *) & nd_prev.ip6, &nd_events[i].ip6)
-                 && eth_mac_equal ((u8 *) nd_prev.mac, nd_events[i].mac)
+             /* discard dup event - cast away volatile */
+             if (ip6_address_is_equal ((const ip6_address_t *) &nd_prev.ip6,
+                                       &nd_events[i].ip6)
+                 && mac_address_equal ((const mac_address_t *) &nd_prev.mac,
+                                       &nd_events[i].mac)
                  && nd_prev.sw_if_index == nd_events[i].sw_if_index
                  && (now - last_nd) < 10.0)
                {
@@ -2467,9 +2503,9 @@ wc_arp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
                    event->client_index = reg->client_index;
                    event->pid = reg->client_pid;
                    event->mac_ip = 1;
-                   memcpy(event->address, nd_events[i].ip6.as_u8, sizeof event->address);
+                   ip6_address_encode(&nd_events[i].ip6, event->ip);
                    event->sw_if_index = htonl(nd_events[i].sw_if_index);
-                   memcpy(event->new_mac, nd_events[i].mac, sizeof event->new_mac);
+                   mac_address_encode(&nd_events[i].mac, event->mac);
                    vl_api_send_msg (vl_reg, (u8 *) event);
                  }
               }));
@@ -2507,7 +2543,8 @@ wc_arp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
 
                    event->sw_if_index = clib_host_to_net_u32 (ra_events[i].sw_if_index);
 
-                   memcpy (event->router_address, ra_events[i].router_address, 16);
+                   ip6_address_encode (&ra_events[i].router_address,
+                                        event->router_addr);
 
                    event->current_hop_limit = ra_events[i].current_hop_limit;
                    event->flags = ra_events[i].flags;
@@ -2531,9 +2568,7 @@ wc_arp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
                      {
                        ra_report_prefix_info_t *info =
                          &ra_events[i].prefixes[j];
-                       memcpy (prefix->dst_address, info->dst_address.as_u8,
-                               16);
-                       prefix->dst_address_length = info->dst_address_length;
+                       ip_prefix_encode(&info->prefix, &prefix->prefix);
                        prefix->flags = info->flags;
                        prefix->valid_time =
                          clib_host_to_net_u32 (info->valid_time);
@@ -2564,8 +2599,9 @@ VLIB_REGISTER_NODE (wc_arp_process_node,static) = {
 /* *INDENT-ON* */
 
 static int
-arp_change_data_callback (u32 pool_index, u8 * new_mac,
-                         u32 sw_if_index, u32 address)
+arp_change_data_callback (u32 pool_index,
+                         const mac_address_t * mac,
+                         u32 sw_if_index, const ip4_address_t * address)
 {
   vpe_api_main_t *am = &vpe_api_main;
   vl_api_ip4_arp_event_t *event;
@@ -2574,13 +2610,13 @@ arp_change_data_callback (u32 pool_index, u8 * new_mac,
     return 1;
 
   event = pool_elt_at_index (am->arp_events, pool_index);
-  if (eth_mac_equal (event->new_mac, new_mac) &&
+  if (ethernet_mac_address_equal (event->mac, mac->bytes) &&
       sw_if_index == ntohl (event->sw_if_index))
     {
       return 1;
     }
 
-  clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
+  mac_address_encode (mac, event->mac);
   event->sw_if_index = htonl (sw_if_index);
   return 0;
 }
@@ -2591,9 +2627,12 @@ vl_api_want_ip4_arp_events_t_handler (vl_api_want_ip4_arp_events_t * mp)
   vpe_api_main_t *am = &vpe_api_main;
   vnet_main_t *vnm = vnet_get_main ();
   vl_api_want_ip4_arp_events_reply_t *rmp;
+  ip4_address_t ip;
   int rv = 0;
 
-  if (mp->address == 0)
+  ip4_address_decode (mp->ip, &ip);
+
+  if (ip.as_u32 == 0)
     {
       uword *p =
        hash_get (am->wc_ip4_arp_events_registration_hash, mp->client_index);
@@ -2639,7 +2678,7 @@ vl_api_want_ip4_arp_events_t_handler (vl_api_want_ip4_arp_events_t * mp)
       pool_get (am->arp_events, event);
       rv = vnet_add_del_ip4_arp_change_event
        (vnm, arp_change_data_callback,
-        mp->pid, &mp->address /* addr, in net byte order */ ,
+        mp->pid, mp->ip /* addr, in net byte order */ ,
         ip_resolver_process_node.index,
         IP4_ARP_EVENT, event - am->arp_events, 1 /* is_add */ );
 
@@ -2653,16 +2692,16 @@ vl_api_want_ip4_arp_events_t_handler (vl_api_want_ip4_arp_events_t * mp)
       /* Python API expects events to have no context */
       event->_vl_msg_id = htons (VL_API_IP4_ARP_EVENT);
       event->client_index = mp->client_index;
-      event->address = mp->address;
+      memcpy (event->ip, mp->ip, 4);
       event->pid = mp->pid;
-      if (mp->address == 0)
+      if (ip.as_u32 == 0)
        event->mac_ip = 1;
     }
   else
     {
       rv = vnet_add_del_ip4_arp_change_event
        (vnm, arp_change_delete_callback,
-        mp->pid, &mp->address /* addr, in net byte order */ ,
+        mp->pid, mp->ip /* addr, in net byte order */ ,
         ip_resolver_process_node.index,
         IP4_ARP_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
     }
@@ -2700,7 +2739,7 @@ want_ip4_arp_events_reaper (u32 client_index)
     event = pool_elt_at_index (am->arp_events, *event_id);
     vnet_add_del_ip4_arp_change_event
       (vnm, arp_change_delete_callback,
-       event->pid, &event->address,
+       event->pid, event->ip,
        ip_resolver_process_node.index, IP4_ARP_EVENT,
        ~0 /* pool index, notused */ , 0 /* is_add */ );
   }
@@ -2728,9 +2767,12 @@ vl_api_want_ip6_nd_events_t_handler (vl_api_want_ip6_nd_events_t * mp)
   vpe_api_main_t *am = &vpe_api_main;
   vnet_main_t *vnm = vnet_get_main ();
   vl_api_want_ip6_nd_events_reply_t *rmp;
+  ip6_address_t ip6;
   int rv = 0;
 
-  if (ip6_address_is_zero ((ip6_address_t *) mp->address))
+  ip6_address_decode (mp->ip, &ip6);
+
+  if (ip6_address_is_zero (&ip6))
     {
       uword *p =
        hash_get (am->wc_ip6_nd_events_registration_hash, mp->client_index);
@@ -2777,7 +2819,7 @@ vl_api_want_ip6_nd_events_t_handler (vl_api_want_ip6_nd_events_t * mp)
 
       rv = vnet_add_del_ip6_nd_change_event
        (vnm, nd_change_data_callback,
-        mp->pid, mp->address /* addr, in net byte order */ ,
+        mp->pid, &ip6,
         ip_resolver_process_node.index,
         IP6_ND_EVENT, event - am->nd_events, 1 /* is_add */ );
 
@@ -2790,14 +2832,14 @@ vl_api_want_ip6_nd_events_t_handler (vl_api_want_ip6_nd_events_t * mp)
 
       event->_vl_msg_id = ntohs (VL_API_IP6_ND_EVENT);
       event->client_index = mp->client_index;
-      clib_memcpy (event->address, mp->address, sizeof event->address);
+      ip6_address_encode (&ip6, event->ip);
       event->pid = mp->pid;
     }
   else
     {
       rv = vnet_add_del_ip6_nd_change_event
        (vnm, nd_change_delete_callback,
-        mp->pid, mp->address /* addr, in net byte order */ ,
+        mp->pid, &ip6 /* addr, in net byte order */ ,
         ip_resolver_process_node.index,
         IP6_ND_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
     }
@@ -2836,7 +2878,7 @@ want_ip6_nd_events_reaper (u32 client_index)
     event = pool_elt_at_index (am->nd_events, *event_id);
     vnet_add_del_ip6_nd_change_event
       (vnm, nd_change_delete_callback,
-       event->pid, &event->address,
+       event->pid, event->ip,
        ip_resolver_process_node.index, IP6_ND_EVENT,
        ~0 /* pool index, notused */ , 0 /* is_add */ );
   }
@@ -2923,26 +2965,24 @@ static void
 vl_api_proxy_arp_add_del_t_handler (vl_api_proxy_arp_add_del_t * mp)
 {
   vl_api_proxy_arp_add_del_reply_t *rmp;
+  ip4_address_t lo, hi;
   u32 fib_index;
   int rv;
-  ip4_main_t *im = &ip4_main;
-  uword *p;
 
   stats_dslock_with_hint (1 /* release hint */ , 6 /* tag */ );
 
-  p = hash_get (im->fib_index_by_table_id, ntohl (mp->proxy.vrf_id));
+  fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->proxy.table_id));
 
-  if (!p)
+  if (~0 == fib_index)
     {
       rv = VNET_API_ERROR_NO_SUCH_FIB;
       goto out;
     }
 
-  fib_index = p[0];
+  ip4_address_decode (mp->proxy.low, &lo);
+  ip4_address_decode (mp->proxy.hi, &hi);
 
-  rv = vnet_proxy_arp_add_del ((ip4_address_t *) mp->proxy.low_address,
-                              (ip4_address_t *) mp->proxy.hi_address,
-                              fib_index, mp->is_add == 0);
+  rv = vnet_proxy_arp_add_del (&lo, &hi, fib_index, mp->is_add == 0);
 
 out:
   stats_dsunlock ();
@@ -2969,10 +3009,10 @@ send_proxy_arp_details (const ip4_address_t * lo_addr,
   clib_memset (mp, 0, sizeof (*mp));
   mp->_vl_msg_id = ntohs (VL_API_PROXY_ARP_DETAILS);
   mp->context = ctx->context;
-  mp->proxy.vrf_id = htonl (fib_index);
-  clib_memcpy (mp->proxy.low_address, lo_addr,
-              sizeof (mp->proxy.low_address));
-  clib_memcpy (mp->proxy.hi_address, hi_addr, sizeof (mp->proxy.hi_address));
+  mp->proxy.table_id = htonl (fib_index);
+
+  ip4_address_encode (lo_addr, mp->proxy.low);
+  ip4_address_encode (hi_addr, mp->proxy.hi);
 
   vl_api_send_msg (ctx->reg, (u8 *) mp);
 
@@ -3069,17 +3109,18 @@ vl_api_ip_probe_neighbor_t_handler (vl_api_ip_probe_neighbor_t * mp)
   vlib_main_t *vm = vlib_get_main ();
   vl_api_ip_probe_neighbor_reply_t *rmp;
   clib_error_t *error;
+  ip46_address_t dst;
+  ip46_type_t itype;
 
   VALIDATE_SW_IF_INDEX (mp);
 
   u32 sw_if_index = ntohl (mp->sw_if_index);
+  itype = ip_address_decode (&mp->dst, &dst);
 
-  if (mp->is_ipv6)
-    error = ip6_probe_neighbor (vm, (ip6_address_t *) mp->dst_address,
-                               sw_if_index, 0);
+  if (IP46_TYPE_IP6 == itype)
+    error = ip6_probe_neighbor (vm, &dst.ip6, sw_if_index, 0);
   else
-    error = ip4_probe_neighbor (vm, (ip4_address_t *) mp->dst_address,
-                               sw_if_index, 0);
+    error = ip4_probe_neighbor (vm, &dst.ip4, sw_if_index, 0);
 
   if (error)
     {
index 7d1998d..ad89d3f 100644 (file)
@@ -49,8 +49,8 @@ static ip_neighbor_scan_config_t ip_neighbor_scan_conf;
 
 int
 ip_neighbor_add (const ip46_address_t * ip,
-                u8 is_ip6,
-                const u8 * mac,
+                ip46_type_t type,
+                const mac_address_t * mac,
                 u32 sw_if_index,
                 ip_neighbor_flags_t flags, u32 * stats_index)
 {
@@ -63,13 +63,10 @@ ip_neighbor_add (const ip46_address_t * ip,
    * The expectation is that the FIB will ensure that nothing bad
    * will come of adding bogus entries.
    */
-  if (is_ip6)
+  if (IP46_TYPE_IP6 == type)
     {
       rv = vnet_set_ip6_ethernet_neighbor (vlib_get_main (),
-                                          sw_if_index, &ip->ip6, mac, 6,
-                                          (flags & IP_NEIGHBOR_FLAG_STATIC),
-                                          (flags &
-                                           IP_NEIGHBOR_FLAG_NO_ADJ_FIB));
+                                          sw_if_index, &ip->ip6, mac, flags);
       fproto = FIB_PROTOCOL_IP6;
       linkt = VNET_LINK_IP6;
     }
@@ -77,16 +74,12 @@ ip_neighbor_add (const ip46_address_t * ip,
     {
       ethernet_arp_ip4_over_ethernet_address_t a = {
        .ip4 = ip->ip4,
+       .mac = *mac,
       };
 
-      clib_memcpy (&a.ethernet, mac, 6);
-
-      rv = vnet_arp_set_ip4_over_ethernet (vnet_get_main (),
-                                          sw_if_index,
-                                          &a,
-                                          (flags & IP_NEIGHBOR_FLAG_STATIC),
-                                          (flags &
-                                           IP_NEIGHBOR_FLAG_NO_ADJ_FIB));
+      rv =
+       vnet_arp_set_ip4_over_ethernet (vnet_get_main (), sw_if_index, &a,
+                                       flags);
       fproto = FIB_PROTOCOL_IP4;
       linkt = VNET_LINK_IP4;
     }
@@ -98,11 +91,11 @@ ip_neighbor_add (const ip46_address_t * ip,
 }
 
 int
-ip_neighbor_del (const ip46_address_t * ip, u8 is_ip6, u32 sw_if_index)
+ip_neighbor_del (const ip46_address_t * ip, ip46_type_t type, u32 sw_if_index)
 {
   int rv;
 
-  if (is_ip6)
+  if (IP46_TYPE_IP6 == type)
     {
       rv = vnet_unset_ip6_ethernet_neighbor (vlib_get_main (),
                                             sw_if_index, &ip->ip6);
@@ -180,14 +173,14 @@ ip_neighbor_scan (vlib_main_t * vm, f64 start_time, u32 start_idx,
       if (!is_ip6)
        {
          n4 = pool_elt_at_index (np4, curr_idx);
-         if (n4->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC)
+         if (n4->flags & IP_NEIGHBOR_FLAG_STATIC)
            goto next_neighbor;
          update_time = n4->time_last_updated;
        }
       else
        {
          n6 = pool_elt_at_index (np6, curr_idx);
-         if (n6->flags & IP6_NEIGHBOR_FLAG_STATIC)
+         if (n6->flags & IP_NEIGHBOR_FLAG_STATIC)
            goto next_neighbor;
          update_time = n6->time_last_updated;
        }
@@ -199,9 +192,11 @@ ip_neighbor_scan (vlib_main_t * vm, f64 start_time, u32 start_idx,
          /* delete stale neighbor */
          if (!is_ip6)
            {
-             ethernet_arp_ip4_over_ethernet_address_t delme;
-             clib_memcpy (&delme.ethernet, n4->ethernet_address, 6);
-             delme.ip4.as_u32 = n4->ip4_address.as_u32;
+             ethernet_arp_ip4_over_ethernet_address_t delme = {
+               .ip4.as_u32 = n4->ip4_address.as_u32,
+               .mac = n4->mac,
+             };
+
              vnet_arp_unset_ip4_over_ethernet (vnm, n4->sw_if_index, &delme);
            }
          else
index 9eeebdb..84247f2 100644 (file)
@@ -37,19 +37,22 @@ void ip_neighbor_scan_enable_disable (ip_neighbor_scan_arg_t * arg);
 
 typedef enum ip_neighbor_flags_t_
 {
-  IP_NEIGHBOR_FLAG_NODE = 0,
+  IP_NEIGHBOR_FLAG_NONE = 0,
   IP_NEIGHBOR_FLAG_STATIC = (1 << 0),
-  IP_NEIGHBOR_FLAG_NO_ADJ_FIB = (1 << 1),
-} ip_neighbor_flags_t;
+  IP_NEIGHBOR_FLAG_DYNAMIC = (1 << 1),
+  IP_NEIGHBOR_FLAG_NO_FIB_ENTRY = (1 << 2),
+} __attribute__ ((packed)) ip_neighbor_flags_t;
+
+extern u8 *format_ip_neighbor_flags (u8 * s, va_list * args);
 
 extern int ip_neighbor_add (const ip46_address_t * ip,
-                           u8 is_ip6,
-                           const u8 * mac,
+                           ip46_type_t type,
+                           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,
-                           u8 is_ip6, u32 sw_if_index);
+                           ip46_type_t type, u32 sw_if_index);
 
 #endif /* included_ip_neighbor_h */
 
index 6bc035e..b56101c 100644 (file)
 #include <vnet/vnet_all_api_h.h>
 #undef vl_printfun
 
+void
+ip6_address_encode (const ip6_address_t * in, vl_api_ip6_address_t out)
+{
+  clib_memcpy (out, in, sizeof (*in));
+}
+
+void
+ip6_address_decode (const vl_api_ip6_address_t in, ip6_address_t * out)
+{
+  clib_memcpy (out, in, sizeof (*out));
+}
+
+void
+ip4_address_encode (const ip4_address_t * in, vl_api_ip4_address_t out)
+{
+  clib_memcpy (out, in, sizeof (*in));
+}
+
+void
+ip4_address_decode (const vl_api_ip4_address_t in, ip4_address_t * out)
+{
+  clib_memcpy (out, in, sizeof (*out));
+}
+
 static ip46_type_t
 ip_address_union_decode (const vl_api_address_union_t * in,
                         vl_api_address_family_t af, ip46_address_t * out)
@@ -67,9 +91,9 @@ ip_address_union_encode (const ip46_address_t * in,
                         vl_api_address_union_t * out)
 {
   if (ADDRESS_IP6 == clib_net_to_host_u32 (af))
-    memcpy (&out->ip6, &in->ip6, sizeof (out->ip6));
+    ip6_address_encode (&in->ip6, out->ip6);
   else
-    memcpy (&out->ip4, &in->ip4, sizeof (out->ip4));
+    ip4_address_encode (&in->ip4, out->ip4);
 }
 
 void
index be41bf5..a67134c 100644 (file)
@@ -27,6 +27,8 @@
 /**
  * Forward declarations so we need not #include the API definitions here
  */
+typedef u8 vl_api_ip6_address_t[16];
+typedef u8 vl_api_ip4_address_t[4];
 struct _vl_api_address;
 struct _vl_api_prefix;
 struct _vl_api_mprefix;
@@ -35,6 +37,14 @@ extern ip46_type_t ip_address_decode (const struct _vl_api_address *in,
                                      ip46_address_t * out);
 extern void ip_address_encode (const ip46_address_t * in,
                               ip46_type_t type, struct _vl_api_address *out);
+extern void ip6_address_encode (const ip6_address_t * in,
+                               vl_api_ip6_address_t out);
+extern void ip6_address_decode (const vl_api_ip6_address_t in,
+                               ip6_address_t * out);
+extern void ip4_address_encode (const ip4_address_t * in,
+                               vl_api_ip4_address_t out);
+extern void ip4_address_decode (const vl_api_ip4_address_t in,
+                               ip4_address_t * out);
 
 extern void ip_prefix_decode (const struct _vl_api_prefix *in,
                              fib_prefix_t * out);
index 2a9b3fe..5c6fec1 100644 (file)
@@ -51,6 +51,7 @@
 #include <vnet/dpo/ip_null_dpo.h>
 #include <vnet/dpo/l3_proxy_dpo.h>
 #include <vnet/ip/ip6_neighbor.h>
+#include <vnet/ethernet/arp.h>
 
 /**
  * @file
index 1a6122f..a0894fa 100644 (file)
@@ -297,7 +297,7 @@ ip6_ra_report_handler (void *data)
         if (default_route->sw_if_index != sw_if_index)
           ;
         else if (0 != memcmp (&default_route->router_address,
-                              r->router_address, 16))
+                              &r->router_address, 16))
           ;
         else
           {
@@ -311,7 +311,7 @@ ip6_ra_report_handler (void *data)
       if (!route_already_present)
        {
          if (router_lifetime_in_sec != 0)
-           add_default_route (vm, sw_if_index, (void *) r->router_address,
+           add_default_route (vm, sw_if_index, &r->router_address,
                               current_time + router_lifetime_in_sec);
        }
       else
@@ -346,8 +346,8 @@ ip6_ra_report_handler (void *data)
       if (!(prefix->flags & PREFIX_FLAG_A))
        continue;
 
-      dst_address = &prefix->dst_address;
-      prefix_length = prefix->dst_address_length;
+      dst_address = &prefix->prefix.fp_addr.ip6;
+      prefix_length = prefix->prefix.fp_len;
 
       if (ip6_address_is_link_local_unicast (dst_address))
        continue;
index 7abe462..51c8dac 100644 (file)
@@ -46,7 +46,7 @@ l2_to_bvi (vlib_main_t * vlib_main,
     {
       vnet_hw_interface_t *hi =
        vnet_get_sup_hw_interface (vnet_main, bvi_sw_if_index);
-      if (!eth_mac_equal (e0->dst_address, hi->hw_address))
+      if (!ethernet_mac_address_equal (e0->dst_address, hi->hw_address))
        return TO_BVI_ERR_BAD_MAC;
     }
 
index 1caad6a..6369e4e 100644 (file)
@@ -3458,8 +3458,7 @@ lisp_cp_lookup_inline (vlib_main_t * vm,
                                                + sizeof (*eth0));
              arp0->opcode = clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply);
              arp0->ip4_over_ethernet[1] = arp0->ip4_over_ethernet[0];
-             clib_memcpy (arp0->ip4_over_ethernet[0].ethernet,
-                          (u8 *) & mac0, 6);
+             mac_address_from_u64 (&arp0->ip4_over_ethernet[0].mac, mac0);
              clib_memcpy (&arp0->ip4_over_ethernet[0].ip4,
                           &gid_address_arp_ip4 (&dst), 4);
 
index ed769d2..b5ff3cc 100644 (file)
@@ -59,6 +59,7 @@
 #include <vnet/ip/format.h>
 
 #include <vpp/api/vpe_msg_enum.h>
+#include <vpp/api/types.h>
 
 #define vl_typedefs            /* define message structures */
 #include <vpp/api/vpe_all_api_h.h>
@@ -698,7 +699,7 @@ format_arp_event (u8 * s, va_list * args)
   vl_api_ip4_arp_event_t *event = va_arg (*args, vl_api_ip4_arp_event_t *);
 
   s = format (s, "pid %d: ", ntohl (event->pid));
-  s = format (s, "resolution for %U", format_ip4_address, &event->address);
+  s = format (s, "resolution for %U", format_vl_api_ip4_address, event->ip);
   return s;
 }
 
@@ -708,7 +709,7 @@ format_nd_event (u8 * s, va_list * args)
   vl_api_ip6_nd_event_t *event = va_arg (*args, vl_api_ip6_nd_event_t *);
 
   s = format (s, "pid %d: ", ntohl (event->pid));
-  s = format (s, "resolution for %U", format_ip6_address, event->address);
+  s = format (s, "resolution for %U", format_vl_api_ip6_address, event->ip);
   return s;
 }
 
index b1894a5..ab98954 100644 (file)
@@ -20,6 +20,7 @@
 #include <vnet/vnet.h>
 #include <vnet/ip/ip.h>
 #include <vnet/ip/ip_neighbor.h>
+#include <vnet/ip/ip_types_api.h>
 #include <vnet/unix/tuntap.h>
 #include <vnet/mpls/mpls.h>
 #include <vnet/dhcp/dhcp_proxy.h>
@@ -44,6 +45,7 @@
 #include <vpp/oam/oam.h>
 
 #include <vnet/ethernet/ethernet.h>
+#include <vnet/ethernet/ethernet_types_api.h>
 #include <vnet/l2/l2_vtr.h>
 
 #include <vpp/api/vpe_msg_enum.h>
@@ -897,11 +899,10 @@ static void *vl_api_proxy_arp_add_del_t_print
   s = format (0, "SCRIPT: proxy_arp_add_del ");
 
   s = format (s, "%U - %U ",
-             format_ip4_address, mp->proxy.low_address,
-             format_ip4_address, mp->proxy.hi_address);
+             format_vl_api_ip4_address, mp->proxy.low,
+             format_vl_api_ip4_address, mp->proxy.hi);
 
-  if (mp->proxy.vrf_id)
-    s = format (s, "vrf %d ", ntohl (mp->proxy.vrf_id));
+  s = format (s, "table %d ", ntohl (mp->proxy.table_id));
 
   if (mp->is_add == 0)
     s = format (s, "del ");
@@ -1020,31 +1021,21 @@ static void *vl_api_ip_neighbor_add_del_t_print
   (vl_api_ip_neighbor_add_del_t * mp, void *handle)
 {
   u8 *s;
-  u8 null_mac[6];
-
-  clib_memset (null_mac, 0, sizeof (null_mac));
 
   s = format (0, "SCRIPT: ip_neighbor_add_del ");
 
-  s = format (s, "sw_if_index %d ", ntohl (mp->sw_if_index));
+  s = format (s, "sw_if_index %d ", ntohl (mp->neighbor.sw_if_index));
 
-  if (mp->is_static)
+  if (IP_API_NEIGHBOR_FLAG_STATIC & ntohl (mp->neighbor.flags))
     s = format (s, "is_static ");
 
-  if (mp->is_no_adj_fib)
+  if (IP_API_NEIGHBOR_FLAG_NO_FIB_ENTRY & ntohl (mp->neighbor.flags))
     s = format (s, "is_no_fib_entry ");
 
-  if (memcmp (mp->mac_address, null_mac, 6))
-    s = format (s, "mac %U ", format_ethernet_address, mp->mac_address);
+  s = format (s, "mac %U ", format_vl_api_mac_address,
+             &mp->neighbor.mac_address);
 
-  if (mp->is_ipv6)
-    s =
-      format (s, "dst %U ", format_ip6_address,
-             (ip6_address_t *) mp->dst_address);
-  else
-    s =
-      format (s, "dst %U ", format_ip4_address,
-             (ip4_address_t *) mp->dst_address);
+  s = format (s, "dst %U ", format_vl_api_address, &mp->neighbor.ip_address);
 
   if (mp->is_add == 0)
     s = format (s, "del ");
@@ -1052,6 +1043,7 @@ static void *vl_api_ip_neighbor_add_del_t_print
   FINISH;
 }
 
+
 static void *vl_api_create_vlan_subif_t_print
   (vl_api_create_vlan_subif_t * mp, void *handle)
 {
@@ -1269,8 +1261,7 @@ static void *vl_api_sw_interface_ip6nd_ra_prefix_t_print
 
   s = format (s, "sw_if_index %d ", ntohl (mp->sw_if_index));
 
-  s = format (s, "%U/%d ", format_ip6_address, mp->address,
-             mp->address_length);
+  s = format (s, "%U ", format_vl_api_prefix, &mp->prefix);
 
   s = format (s, "val_life %d ", ntohl (mp->val_lifetime));
 
@@ -2217,10 +2208,7 @@ static void *vl_api_ip_probe_neighbor_t_print
 
   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);
+  s = format (s, "address %U ", format_vl_api_address, &mp->dst);
 
   FINISH;
 }
@@ -2263,7 +2251,7 @@ static void *vl_api_want_ip4_arp_events_t_print
 
   s = format (0, "SCRIPT: want_ip4_arp_events ");
   s = format (s, "pid %d address %U ", ntohl (mp->pid),
-             format_ip4_address, &mp->address);
+             format_ip4_address, mp->ip);
   if (mp->enable_disable == 0)
     s = format (s, "del ");
 
@@ -2277,7 +2265,7 @@ static void *vl_api_want_ip6_nd_events_t_print
 
   s = format (0, "SCRIPT: want_ip6_nd_events ");
   s = format (s, "pid %d address %U ", ntohl (mp->pid),
-             format_ip6_address, mp->address);
+             format_vl_api_ip6_address, mp->ip);
   if (mp->enable_disable == 0)
     s = format (s, "del ");
 
@@ -2867,12 +2855,7 @@ static void *vl_api_ip_source_and_port_range_check_add_del_t_print
   int i;
 
   s = format (0, "SCRIPT: ip_source_and_port_range_check_add_del ");
-  if (mp->is_ipv6)
-    s = format (s, "%U/%d ", format_ip6_address, mp->address,
-               mp->mask_length);
-  else
-    s = format (s, "%U/%d ", format_ip4_address, mp->address,
-               mp->mask_length);
+  s = format (s, "%U ", format_vl_api_prefix, &mp->prefix);
 
   for (i = 0; i < mp->number_of_ranges; i++)
     {
@@ -3662,14 +3645,9 @@ static void *vl_api_ip_container_proxy_add_del_t_print
 {
   u8 *s;
   s = format (0, "SCRIPT: ip_container_proxy_add_del ");
-  if (mp->is_ip4)
-    s = format (s, "is_add %d address %U/%d sw_if_index %d",
-               mp->is_add, format_ip4_address,
-               (ip4_address_t *) mp->ip, mp->plen, mp->sw_if_index);
-  else
-    s = format (s, "is_add %d address %U/%d sw_if_index %d",
-               mp->is_add, format_ip6_address,
-               (ip6_address_t *) mp->ip, mp->plen, mp->sw_if_index);
+  s = format (s, "is_add %d prefix %U sw_if_index %d",
+             mp->is_add, format_vl_api_prefix, mp->sw_if_index);
+
   FINISH;
 }
 
@@ -3680,9 +3658,8 @@ static void *vl_api_qos_record_enable_disable_t_print
 
   s = format (0, "SCRIPT: qos_record_enable_disable ");
   s = format (s, "sw_if_index %d ", ntohl (mp->sw_if_index));
-  s =
-    format (s, "input_source %U ", format_qos_source,
-           ntohl (mp->input_source));
+  s = format (s, "input_source %U ", format_qos_source,
+             ntohl (mp->input_source));
 
   if (!mp->enable)
     s = format (s, "disable ");
index 0a48711..e36b8dd 100644 (file)
@@ -47,6 +47,26 @@ format_vl_api_address_union (u8 * s, va_list * args)
   return s;
 }
 
+u8 *
+format_vl_api_ip4_address (u8 * s, va_list * args)
+{
+  const vl_api_ip4_address_t *addr = va_arg (*args, vl_api_ip4_address_t *);
+
+  s = format (s, "%U", format_ip4_address, addr);
+
+  return s;
+}
+
+u8 *
+format_vl_api_ip6_address (u8 * s, va_list * args)
+{
+  const vl_api_ip6_address_t *addr = va_arg (*args, vl_api_ip6_address_t *);
+
+  s = format (s, "%U", format_ip6_address, addr);
+
+  return s;
+}
+
 u8 *
 format_vl_api_prefix (u8 * s, va_list * args)
 {
@@ -58,6 +78,14 @@ format_vl_api_prefix (u8 * s, va_list * args)
   return s;
 }
 
+u8 *
+format_vl_api_mac_address (u8 * s, va_list * args)
+{
+  vl_api_mac_address_t *mac = va_arg (*args, vl_api_mac_address_t *);
+
+  return (format (s, "%U", format_ethernet_address, mac));
+}
+
 uword
 unformat_vl_api_mac_address (unformat_input_t * input, va_list * args)
 {
@@ -81,11 +109,34 @@ unformat_vl_api_address (unformat_input_t * input, va_list * args)
   return (1);
 }
 
-u8 *
-format_vl_api_mac_address (u8 * s, va_list * args)
+uword
+unformat_vl_api_ip4_address (unformat_input_t * input, va_list * args)
 {
-  vl_api_mac_address_t *mac = va_arg (*args, vl_api_mac_address_t *);
+  vl_api_ip4_address_t *ip = va_arg (*args, vl_api_ip4_address_t *);
 
-  return (format (s, "%U", format_ethernet_address, mac));
+  if (unformat (input, "%U", unformat_ip4_address, ip))
+      return (1);
+  return (0);
+}
+
+uword
+unformat_vl_api_ip6_address (unformat_input_t * input, va_list * args)
+{
+  vl_api_ip6_address_t *ip = va_arg (*args, vl_api_ip6_address_t *);
+
+  if (unformat (input, "%U", unformat_ip6_address, ip))
+      return (1);
+  return (0);
+}
+
+uword
+unformat_vl_api_prefix (unformat_input_t * input, va_list * args)
+{
+   vl_api_prefix_t *pfx = va_arg (*args, vl_api_prefix_t *);
+
+  if (unformat (input, "%U/%d", unformat_vl_api_address, &pfx->address,
+                &pfx->address_length))
+      return (1);
+  return (0);
 }
 
index 9a45639..cf1b26d 100644 (file)
@@ -28,8 +28,13 @@ const vl_api_address_t VL_API_ZERO_ADDRESS;
 
 extern uword unformat_vl_api_mac_address (unformat_input_t * input, va_list * args);
 extern uword unformat_vl_api_address (unformat_input_t * input, va_list * args);
+extern uword unformat_vl_api_ip4_address (unformat_input_t * input, va_list * args);
+extern uword unformat_vl_api_ip6_address (unformat_input_t * input, va_list * args);
+extern uword unformat_vl_api_prefix (unformat_input_t * input, va_list * args);
 
 extern u8 *format_vl_api_address (u8 * s, va_list * args);
+extern u8 *format_vl_api_ip4_address (u8 * s, va_list * args);
+extern u8 *format_vl_api_ip6_address (u8 * s, va_list * args);
 extern u8 *format_vl_api_address_union (u8 * s, va_list * args);
 extern u8 *format_vl_api_prefix (u8 * s, va_list * args);
 extern u8 *format_vl_api_mprefix (u8 * s, va_list * args);
index 3d00f1b..833ee00 100644 (file)
@@ -1052,8 +1052,7 @@ class TestDHCP(VppTestCase):
         nd_entry = VppNeighbor(self,
                                self.pg1.sw_if_index,
                                self.pg1.remote_hosts[1].mac,
-                               self.pg1.remote_hosts[1].ip6,
-                               af=AF_INET6)
+                               self.pg1.remote_hosts[1].ip6)
         nd_entry.add_vpp_config()
 
         #
@@ -1267,9 +1266,10 @@ class TestDHCP(VppTestCase):
 
         # remove the left over ARP entry
         self.vapi.ip_neighbor_add_del(self.pg3.sw_if_index,
-                                      mac_pton(self.pg3.remote_mac),
+                                      self.pg3.remote_mac,
                                       self.pg3.remote_ip4,
                                       is_add=0)
+
         #
         # remove the DHCP config
         #
@@ -1423,7 +1423,7 @@ class TestDHCP(VppTestCase):
 
         # remove the left over ARP entry
         self.vapi.ip_neighbor_add_del(self.pg3.sw_if_index,
-                                      mac_pton(self.pg3.remote_mac),
+                                      self.pg3.remote_mac,
                                       self.pg3.remote_ip4,
                                       is_add=0)
 
@@ -1530,7 +1530,7 @@ class TestDHCP(VppTestCase):
 
         # remove the left over ARP entry
         self.vapi.ip_neighbor_add_del(self.pg3.sw_if_index,
-                                      mac_pton(self.pg3.remote_mac),
+                                      self.pg3.remote_mac,
                                       self.pg3.remote_ip4,
                                       is_add=0)
 
index 930d556..bfb5506 100644 (file)
@@ -26,6 +26,7 @@ from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, VppIpMRoute, \
 from vpp_neighbor import find_nbr, VppNeighbor
 from vpp_pg_interface import is_ipv6_misc
 from vpp_sub_interface import VppSubInterface, VppDot1QSubint
+from ipaddress import IPv6Network, IPv4Network
 
 AF_INET6 = socket.AF_INET6
 
@@ -445,7 +446,6 @@ class TestIPv6(TestIPv6ND):
                                self.pg0.sw_if_index,
                                self.pg0.remote_hosts[2].mac,
                                self.pg0.remote_hosts[2].ip6,
-                               af=AF_INET6,
                                is_no_fib_entry=1)
         nd_entry.add_vpp_config()
 
@@ -454,8 +454,7 @@ class TestIPv6(TestIPv6ND):
         #
         self.assertTrue(find_nbr(self,
                                  self.pg0.sw_if_index,
-                                 self.pg0._remote_hosts[2].ip6,
-                                 inet=AF_INET6))
+                                 self.pg0._remote_hosts[2].ip6))
         self.assertFalse(find_route(self,
                                     self.pg0._remote_hosts[2].ip6,
                                     128,
@@ -483,8 +482,7 @@ class TestIPv6(TestIPv6ND):
         #
         self.assertTrue(find_nbr(self,
                                  self.pg0.sw_if_index,
-                                 self.pg0._remote_hosts[2].ip6_ll,
-                                 inet=AF_INET6))
+                                 self.pg0._remote_hosts[2].ip6_ll))
         self.assertFalse(find_route(self,
                                     self.pg0._remote_hosts[2].ip6_ll,
                                     128,
@@ -511,8 +509,7 @@ class TestIPv6(TestIPv6ND):
         #
         self.assertTrue(find_nbr(self,
                                  self.pg0.sw_if_index,
-                                 self.pg0._remote_hosts[3].ip6_ll,
-                                 inet=AF_INET6))
+                                 self.pg0._remote_hosts[3].ip6_ll))
         self.assertFalse(find_route(self,
                                     self.pg0._remote_hosts[3].ip6_ll,
                                     128,
@@ -532,14 +529,12 @@ class TestIPv6(TestIPv6ND):
         ns_pg1 = VppNeighbor(self,
                              self.pg1.sw_if_index,
                              self.pg1.remote_hosts[1].mac,
-                             self.pg1.remote_hosts[1].ip6,
-                             af=AF_INET6)
+                             self.pg1.remote_hosts[1].ip6)
         ns_pg1.add_vpp_config()
         ns_pg2 = VppNeighbor(self,
                              self.pg2.sw_if_index,
                              self.pg2.remote_mac,
-                             self.pg1.remote_hosts[1].ip6,
-                             af=AF_INET6)
+                             self.pg1.remote_hosts[1].ip6)
         ns_pg2.add_vpp_config()
 
         #
@@ -755,7 +750,7 @@ class TestIPv6(TestIPv6ND):
         #
         # Configure The RA to announce the links prefix
         #
-        self.pg0.ip6_ra_prefix(self.pg0.local_ip6n,
+        self.pg0.ip6_ra_prefix(self.pg0.local_ip6,
                                self.pg0.local_ip6_prefix_len)
 
         #
@@ -781,7 +776,7 @@ class TestIPv6(TestIPv6ND):
         # Change the prefix info to not off-link
         #  L-flag is clear
         #
-        self.pg0.ip6_ra_prefix(self.pg0.local_ip6n,
+        self.pg0.ip6_ra_prefix(self.pg0.local_ip6,
                                self.pg0.local_ip6_prefix_len,
                                off_link=1)
 
@@ -801,7 +796,7 @@ class TestIPv6(TestIPv6ND):
         # Change the prefix info to not off-link, no-autoconfig
         #  L and A flag are clear in the advert
         #
-        self.pg0.ip6_ra_prefix(self.pg0.local_ip6n,
+        self.pg0.ip6_ra_prefix(self.pg0.local_ip6,
                                self.pg0.local_ip6_prefix_len,
                                off_link=1,
                                no_autoconfig=1)
@@ -822,7 +817,7 @@ class TestIPv6(TestIPv6ND):
         # Change the flag settings back to the defaults
         #  L and A flag are set in the advert
         #
-        self.pg0.ip6_ra_prefix(self.pg0.local_ip6n,
+        self.pg0.ip6_ra_prefix(self.pg0.local_ip6,
                                self.pg0.local_ip6_prefix_len)
 
         opt = ICMPv6NDOptPrefixInfo(
@@ -841,7 +836,7 @@ class TestIPv6(TestIPv6ND):
         # Change the prefix info to not off-link, no-autoconfig
         #  L and A flag are clear in the advert
         #
-        self.pg0.ip6_ra_prefix(self.pg0.local_ip6n,
+        self.pg0.ip6_ra_prefix(self.pg0.local_ip6,
                                self.pg0.local_ip6_prefix_len,
                                off_link=1,
                                no_autoconfig=1)
@@ -862,7 +857,7 @@ class TestIPv6(TestIPv6ND):
         # Use the reset to defults option to revert to defaults
         #  L and A flag are clear in the advert
         #
-        self.pg0.ip6_ra_prefix(self.pg0.local_ip6n,
+        self.pg0.ip6_ra_prefix(self.pg0.local_ip6,
                                self.pg0.local_ip6_prefix_len,
                                use_default=1)
 
@@ -881,7 +876,7 @@ class TestIPv6(TestIPv6ND):
         #
         # Advertise Another prefix. With no L-flag/A-flag
         #
-        self.pg0.ip6_ra_prefix(self.pg1.local_ip6n,
+        self.pg0.ip6_ra_prefix(self.pg1.local_ip6,
                                self.pg1.local_ip6_prefix_len,
                                off_link=1,
                                no_autoconfig=1)
@@ -911,7 +906,7 @@ class TestIPv6(TestIPv6ND):
         # Remove the first refix-info - expect the second is still in the
         # advert
         #
-        self.pg0.ip6_ra_prefix(self.pg0.local_ip6n,
+        self.pg0.ip6_ra_prefix(self.pg0.local_ip6,
                                self.pg0.local_ip6_prefix_len,
                                is_no=1)
 
@@ -930,7 +925,7 @@ class TestIPv6(TestIPv6ND):
         #
         # Remove the second prefix-info - expect no prefix-info i nthe adverts
         #
-        self.pg0.ip6_ra_prefix(self.pg1.local_ip6n,
+        self.pg0.ip6_ra_prefix(self.pg1.local_ip6,
                                self.pg1.local_ip6_prefix_len,
                                is_no=1)
 
@@ -1064,11 +1059,13 @@ class TestIPv6RD(TestIPv6ND):
                 self.pg1.local_mac)
 
     def verify_prefix_info(self, reported_prefix, prefix_option):
-        prefix = socket.inet_pton(socket.AF_INET6,
-                                  prefix_option.getfieldval("prefix"))
-        self.assert_equal(reported_prefix.dst_address, prefix)
-        self.assert_equal(reported_prefix.dst_address_length,
-                          prefix_option.getfieldval("prefixlen"))
+        prefix = IPv6Network(
+            unicode(prefix_option.getfieldval("prefix") +
+                    "/" +
+                    str(prefix_option.getfieldval("prefixlen"))),
+            strict=False)
+        self.assert_equal(reported_prefix.prefix.network_address,
+                          prefix.network_address)
         L = prefix_option.getfieldval("L")
         A = prefix_option.getfieldval("A")
         option_flags = (L << 7) | (A << 6)
@@ -1366,8 +1363,7 @@ class IPv6NDProxyTest(TestIPv6ND):
         #
         self.assertTrue(find_nbr(self,
                                  self.pg1.sw_if_index,
-                                 self.pg0._remote_hosts[2].ip6,
-                                 inet=AF_INET6))
+                                 self.pg0._remote_hosts[2].ip6))
 
         #
         # ... and we can route traffic to it
@@ -1428,8 +1424,7 @@ class IPv6NDProxyTest(TestIPv6ND):
 
         self.assertTrue(find_nbr(self,
                                  self.pg2.sw_if_index,
-                                 self.pg0._remote_hosts[3].ip6,
-                                 inet=AF_INET6))
+                                 self.pg0._remote_hosts[3].ip6))
 
         #
         # hosts can communicate. pg2->pg1
@@ -1469,12 +1464,10 @@ class IPv6NDProxyTest(TestIPv6ND):
 
         self.assertFalse(find_nbr(self,
                                   self.pg2.sw_if_index,
-                                  self.pg0._remote_hosts[3].ip6,
-                                  inet=AF_INET6))
+                                  self.pg0._remote_hosts[3].ip6))
         self.assertFalse(find_nbr(self,
                                   self.pg1.sw_if_index,
-                                  self.pg0._remote_hosts[2].ip6,
-                                  inet=AF_INET6))
+                                  self.pg0._remote_hosts[2].ip6))
 
         #
         # no longer proxy-ing...
index 2321aa7..6d01daa 100644 (file)
@@ -163,15 +163,13 @@ class TestL2bdArpTerm(VppTestCase):
         return '%s.%s.%s.%s' % (o1, o2, o3, o4)
 
     def arp_event_host(self, e):
-        return Host(mac=':'.join(['%02x' % ord(char) for char in e.new_mac]),
-                    ip4=self.inttoip4(e.address))
+        return Host(str(e.mac), ip4=str(e.ip))
 
     def arp_event_hosts(self, evs):
         return {self.arp_event_host(e) for e in evs}
 
     def nd_event_host(self, e):
-        return Host(mac=':'.join(['%02x' % ord(char) for char in e.new_mac]),
-                    ip6=inet_ntop(AF_INET6, e.address))
+        return Host(str(e.mac), ip6=str(e.ip))
 
     def nd_event_hosts(self, evs):
         return {self.nd_event_host(e) for e in evs}
@@ -439,7 +437,7 @@ class TestL2bdArpTerm(VppTestCase):
     def test_l2bd_arp_term_12(self):
         """ L2BD ND term - send NS packets verify reports
         """
-        self.vapi.want_ip6_nd_events(address=inet_pton(AF_INET6, "::0"))
+        self.vapi.want_ip6_nd_events(ip="::")
         dst_host = self.ip6_host(50, 50, "00:00:11:22:33:44")
         self.bd_add_del(1, is_add=1)
         self.set_bd_flags(1, arp_term=True, flood=False,
@@ -475,8 +473,7 @@ class TestL2bdArpTerm(VppTestCase):
     def test_l2bd_arp_term_14(self):
         """ L2BD ND term - disable ip4 arp events,send ns, verify no events
         """
-        self.vapi.want_ip6_nd_events(enable_disable=0,
-                                     address=inet_pton(AF_INET6, "::0"))
+        self.vapi.want_ip6_nd_events(enable_disable=0, ip="::")
         dst_host = self.ip6_host(50, 50, "00:00:11:22:33:44")
         macs = self.mac_list(range(10, 15))
         hosts = self.ip6_hosts(5, 1, macs)
index f51a950..0d74cb6 100644 (file)
@@ -23,6 +23,7 @@ from syslog_rfc5424_parser import SyslogMessage, ParseError
 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
 from vpp_papi_provider import SYSLOG_SEVERITY
 from io import BytesIO
+from vpp_papi import VppEnum
 
 
 class MethodHolder(VppTestCase):
@@ -48,12 +49,13 @@ class MethodHolder(VppTestCase):
                 is_add=0)
 
             for intf in [self.pg7, self.pg8]:
-                neighbors = self.vapi.ip_neighbor_dump(intf.sw_if_index)
-                for n in neighbors:
-                    self.vapi.ip_neighbor_add_del(intf.sw_if_index,
-                                                  n.mac_address,
-                                                  n.ip_address,
-                                                  is_add=0)
+                self.vapi.ip_neighbor_add_del(
+                    intf.sw_if_index,
+                    intf.remote_mac,
+                    intf.remote_ip4,
+                    flags=(VppEnum.vl_api_ip_neighbor_flags_t.
+                           IP_API_NEIGHBOR_FLAG_STATIC),
+                    is_add=0)
 
             if self.pg7.has_ip4_config:
                 self.pg7.unconfig_ip4()
@@ -2964,14 +2966,18 @@ class TestNAT44(MethodHolder):
     def test_dynamic_ipless_interfaces(self):
         """ NAT44 interfaces without configured IP address """
 
-        self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
-                                      mac_pton(self.pg7.remote_mac),
-                                      self.pg7.remote_ip4n,
-                                      is_static=1)
-        self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
-                                      mac_pton(self.pg8.remote_mac),
-                                      self.pg8.remote_ip4n,
-                                      is_static=1)
+        self.vapi.ip_neighbor_add_del(
+            self.pg7.sw_if_index,
+            self.pg7.remote_mac,
+            self.pg7.remote_ip4,
+            flags=(VppEnum.vl_api_ip_neighbor_flags_t.
+                   IP_API_NEIGHBOR_FLAG_STATIC))
+        self.vapi.ip_neighbor_add_del(
+            self.pg8.sw_if_index,
+            self.pg8.remote_mac,
+            self.pg8.remote_ip4,
+            flags=(VppEnum.vl_api_ip_neighbor_flags_t.
+                   IP_API_NEIGHBOR_FLAG_STATIC))
 
         self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
                                    dst_address_length=32,
@@ -3006,14 +3012,18 @@ class TestNAT44(MethodHolder):
     def test_static_ipless_interfaces(self):
         """ NAT44 interfaces without configured IP address - 1:1 NAT """
 
-        self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
-                                      mac_pton(self.pg7.remote_mac),
-                                      self.pg7.remote_ip4n,
-                                      is_static=1)
-        self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
-                                      mac_pton(self.pg8.remote_mac),
-                                      self.pg8.remote_ip4n,
-                                      is_static=1)
+        self.vapi.ip_neighbor_add_del(
+            self.pg7.sw_if_index,
+            self.pg7.remote_mac,
+            self.pg7.remote_ip4,
+            flags=(VppEnum.vl_api_ip_neighbor_flags_t.
+                   IP_API_NEIGHBOR_FLAG_STATIC))
+        self.vapi.ip_neighbor_add_del(
+            self.pg8.sw_if_index,
+            self.pg8.remote_mac,
+            self.pg8.remote_ip4,
+            flags=(VppEnum.vl_api_ip_neighbor_flags_t.
+                   IP_API_NEIGHBOR_FLAG_STATIC))
 
         self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
                                    dst_address_length=32,
@@ -3052,14 +3062,18 @@ class TestNAT44(MethodHolder):
         self.udp_port_out = 30607
         self.icmp_id_out = 30608
 
-        self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
-                                      mac_pton(self.pg7.remote_mac),
-                                      self.pg7.remote_ip4n,
-                                      is_static=1)
-        self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
-                                      mac_pton(self.pg8.remote_mac),
-                                      self.pg8.remote_ip4n,
-                                      is_static=1)
+        self.vapi.ip_neighbor_add_del(
+            self.pg7.sw_if_index,
+            self.pg7.remote_mac,
+            self.pg7.remote_ip4,
+            flags=(VppEnum.vl_api_ip_neighbor_flags_t.
+                   IP_API_NEIGHBOR_FLAG_STATIC))
+        self.vapi.ip_neighbor_add_del(
+            self.pg8.sw_if_index,
+            self.pg8.remote_mac,
+            self.pg8.remote_ip4,
+            flags=(VppEnum.vl_api_ip_neighbor_flags_t.
+                   IP_API_NEIGHBOR_FLAG_STATIC))
 
         self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
                                    dst_address_length=32,
index 47f002c..c378cff 100644 (file)
@@ -7,6 +7,7 @@ from framework import VppTestCase, VppTestRunner
 from vpp_neighbor import VppNeighbor, find_nbr
 from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, \
     VppIpTable, DpoProto
+from vpp_papi import VppEnum
 
 from scapy.packet import Raw
 from scapy.layers.l2 import Ether, ARP, Dot1Q
@@ -693,8 +694,8 @@ class ARPTestCase(VppTestCase):
         #
         # Configure Proxy ARP for the subnet on PG0addresses on pg0
         #
-        self.vapi.proxy_arp_add_del(self.pg0._local_ip4n_subnet,
-                                    self.pg0._local_ip4n_bcast)
+        self.vapi.proxy_arp_add_del(self.pg0._local_ip4_subnet,
+                                    self.pg0._local_ip4_bcast)
 
         # Make pg2 un-numbered to pg0
         #
@@ -731,8 +732,8 @@ class ARPTestCase(VppTestCase):
         # cleanup
         #
         self.pg2.set_proxy_arp(0)
-        self.vapi.proxy_arp_add_del(self.pg0._local_ip4n_subnet,
-                                    self.pg0._local_ip4n_bcast,
+        self.vapi.proxy_arp_add_del(self.pg0._local_ip4_subnet,
+                                    self.pg0._local_ip4_bcast,
                                     is_add=0)
 
     def test_proxy_arp(self):
@@ -971,11 +972,7 @@ class ARPTestCase(VppTestCase):
               UDP(sport=1234, dport=1234) /
               Raw())
 
-        self.pg0.add_stream(p0)
-        self.pg_enable_capture(self.pg_interfaces)
-        self.pg_start()
-
-        rx1 = self.pg1.get_capture(1)
+        rx1 = self.send_and_expect(self.pg0, [p0], self.pg1)
 
         self.verify_arp_req(rx1[0],
                             self.pg1.local_mac,
@@ -992,20 +989,14 @@ class ARPTestCase(VppTestCase):
                   hwsrc="00:00:5e:00:01:09", pdst=self.pg1.local_ip4,
                   psrc=self.pg1.remote_ip4))
 
-        self.pg1.add_stream(p1)
-        self.pg_enable_capture(self.pg_interfaces)
-        self.pg_start()
+        self.send_and_assert_no_replies(self.pg1, p1, "ARP reply")
 
         #
         # IP packet destined for pg1 remote host arrives on pg0 again.
         # VPP should have an ARP entry for that address now and the packet
         # should be sent out pg1.
         #
-        self.pg0.add_stream(p0)
-        self.pg_enable_capture(self.pg_interfaces)
-        self.pg_start()
-
-        rx1 = self.pg1.get_capture(1)
+        rx1 = self.send_and_expect(self.pg0, [p0], self.pg1)
 
         self.verify_ip(rx1[0],
                        self.pg1.local_mac,
@@ -1416,7 +1407,7 @@ class ARPTestCase(VppTestCase):
 
 
 class NeighborStatsTestCase(VppTestCase):
-    """ ARP Test Case """
+    """ ARP/ND Counters """
 
     def setUp(self):
         super(NeighborStatsTestCase, self).setUp()
@@ -1489,14 +1480,12 @@ class NeighborStatsTestCase(VppTestCase):
         nd1 = VppNeighbor(self,
                           self.pg0.sw_if_index,
                           self.pg0.remote_hosts[1].mac,
-                          self.pg0.remote_hosts[1].ip6,
-                          af=AF_INET6)
+                          self.pg0.remote_hosts[1].ip6)
         nd1.add_vpp_config()
         nd2 = VppNeighbor(self,
                           self.pg0.sw_if_index,
                           self.pg0.remote_hosts[2].mac,
-                          self.pg0.remote_hosts[2].ip6,
-                          af=AF_INET6)
+                          self.pg0.remote_hosts[2].ip6)
         nd2.add_vpp_config()
 
         p1 = (Ether(dst=self.pg1.local_mac,
index 719f77b..58384d2 100644 (file)
@@ -5,7 +5,7 @@ from abc import abstractmethod, ABCMeta
 from six import moves
 
 from util import Host, mk_ll_addr
-from vpp_papi import mac_pton, mac_ntop
+from vpp_papi import mac_ntop
 
 
 class VppInterface(object):
@@ -273,10 +273,9 @@ class VppInterface(object):
         :param vrf_id: The FIB table / VRF ID. (Default value = 0)
         """
         for host in self._remote_hosts:
-            macn = mac_pton(host.mac)
-            ipn = host.ip4n
-            self.test.vapi.ip_neighbor_add_del(
-                self.sw_if_index, macn, ipn)
+            self.test.vapi.ip_neighbor_add_del(self.sw_if_index,
+                                               host.mac,
+                                               host.ip4)
 
     def config_ip6(self):
         """Configure IPv6 address on the VPP interface."""
@@ -304,10 +303,9 @@ class VppInterface(object):
         :param vrf_id: The FIB table / VRF ID. (Default value = 0)
         """
         for host in self._remote_hosts:
-            macn = mac_pton(host.mac)
-            ipn = host.ip6n
-            self.test.vapi.ip_neighbor_add_del(
-                self.sw_if_index, macn, ipn, is_ipv6=1)
+            self.test.vapi.ip_neighbor_add_del(self.sw_if_index,
+                                               host.mac,
+                                               host.ip6)
 
     def unconfig(self):
         """Unconfigure IPv6 and IPv4 address on the VPP interface."""
index 7815a28..7391447 100644 (file)
@@ -4,25 +4,22 @@
   object abstractions for ARP and ND
 """
 
-from socket import inet_pton, inet_ntop, AF_INET, AF_INET6
+from ipaddress import ip_address
 from vpp_object import *
-from vpp_papi import mac_pton
+from vpp_papi import mac_pton, VppEnum
 
 
-def find_nbr(test, sw_if_index, ip_addr, is_static=0, inet=AF_INET, mac=None):
+def find_nbr(test, sw_if_index, nbr_addr, is_static=0, mac=None):
+    ip_addr = ip_address(unicode(nbr_addr))
+    e = VppEnum.vl_api_ip_neighbor_flags_t
     nbrs = test.vapi.ip_neighbor_dump(sw_if_index,
-                                      is_ipv6=1 if AF_INET6 == inet else 0)
-    if inet == AF_INET:
-        s = 4
-    else:
-        s = 16
-    nbr_addr = inet_pton(inet, ip_addr)
+                                      is_ipv6=(6 is ip_addr.version))
 
     for n in nbrs:
-        if nbr_addr == n.ip_address[:s] \
-           and is_static == n.is_static:
+        if ip_addr == n.neighbor.ip_address and \
+           is_static == (n.neighbor.flags & e.IP_API_NEIGHBOR_FLAG_STATIC):
             if mac:
-                if n.mac_address == mac_pton(mac):
+                if mac == str(n.neighbor.mac_address):
                     return True
             else:
                 return True
@@ -35,25 +32,26 @@ class VppNeighbor(VppObject):
     """
 
     def __init__(self, test, sw_if_index, mac_addr, nbr_addr,
-                 af=AF_INET, is_static=False, is_no_fib_entry=0):
+                 is_static=False, is_no_fib_entry=False):
         self._test = test
         self.sw_if_index = sw_if_index
-        self.mac_addr = mac_pton(mac_addr)
-        self.af = af
-        self.is_static = is_static
-        self.is_no_fib_entry = is_no_fib_entry
+        self.mac_addr = mac_addr
         self.nbr_addr = nbr_addr
-        self.nbr_addr_n = inet_pton(af, nbr_addr)
+
+        e = VppEnum.vl_api_ip_neighbor_flags_t
+        self.flags = e.IP_API_NEIGHBOR_FLAG_NONE
+        if is_static:
+            self.flags |= e.IP_API_NEIGHBOR_FLAG_STATIC
+        if is_no_fib_entry:
+            self.flags |= e.IP_API_NEIGHBOR_FLAG_NO_FIB_ENTRY
 
     def add_vpp_config(self):
         r = self._test.vapi.ip_neighbor_add_del(
             self.sw_if_index,
             self.mac_addr,
-            self.nbr_addr_n,
+            self.nbr_addr,
             is_add=1,
-            is_ipv6=1 if AF_INET6 == self.af else 0,
-            is_static=self.is_static,
-            is_no_adj_fib=self.is_no_fib_entry)
+            flags=self.flags)
         self.stats_index = r.stats_index
         self._test.registry.register(self, self._test.logger)
 
@@ -61,17 +59,19 @@ class VppNeighbor(VppObject):
         self._test.vapi.ip_neighbor_add_del(
             self.sw_if_index,
             self.mac_addr,
-            self.nbr_addr_n,
-            is_ipv6=1 if AF_INET6 == self.af else 0,
+            self.nbr_addr,
             is_add=0,
-            is_static=self.is_static)
+            flags=self.flags)
+
+    def is_static(self):
+        e = VppEnum.vl_api_ip_neighbor_flags_t
+        return (self.flags & e.IP_API_NEIGHBOR_FLAG_STATIC)
 
     def query_vpp_config(self):
         return find_nbr(self._test,
                         self.sw_if_index,
                         self.nbr_addr,
-                        self.is_static,
-                        self.af)
+                        self.is_static())
 
     def __str__(self):
         return self.object_id()
index d35fae9..efe1454 100644 (file)
@@ -338,9 +338,9 @@ class VppPapiProvider(object):
                          'reverse': reverse,
                          'is_ipv6': is_ip6})
 
-    def ip6_nd_proxy(self, address, sw_if_index, is_del=0):
+    def ip6_nd_proxy(self, ip, sw_if_index, is_del=0):
         return self.api(self.papi.ip6nd_proxy_add_del,
-                        {'address': address,
+                        {'ip': ip,
                          'sw_if_index': sw_if_index,
                          'is_del': is_del})
 
@@ -368,8 +368,10 @@ class VppPapiProvider(object):
                                    pref_lifetime=0xffffffff):
         return self.api(self.papi.sw_interface_ip6nd_ra_prefix,
                         {'sw_if_index': sw_if_index,
-                         'address': address,
-                         'address_length': address_length,
+                         'prefix': {
+                             'address': address,
+                             'address_length': address_length,
+                         },
                          'use_default': use_default,
                          'no_advertise': no_advertise,
                          'off_link': off_link,
@@ -491,16 +493,16 @@ class VppPapiProvider(object):
         return self.api(self.papi.bd_ip_mac_dump,
                         {'bd_id': bd_id})
 
-    def want_ip4_arp_events(self, enable_disable=1, address=0):
+    def want_ip4_arp_events(self, enable_disable=1, ip="0.0.0.0"):
         return self.api(self.papi.want_ip4_arp_events,
                         {'enable_disable': enable_disable,
-                         'address': address,
+                         'ip': ip,
                          'pid': os.getpid(), })
 
-    def want_ip6_nd_events(self, enable_disable=1, address=0):
+    def want_ip6_nd_events(self, enable_disable=1, ip="::"):
         return self.api(self.papi.want_ip6_nd_events,
                         {'enable_disable': enable_disable,
-                         'address': address,
+                         'ip': ip,
                          'pid': os.getpid(), })
 
     def want_ip6_ra_events(self, enable_disable=1):
@@ -1006,32 +1008,28 @@ class VppPapiProvider(object):
     def ip_neighbor_add_del(self,
                             sw_if_index,
                             mac_address,
-                            dst_address,
+                            ip_address,
                             is_add=1,
-                            is_ipv6=0,
-                            is_static=0,
-                            is_no_adj_fib=0,
-                            ):
+                            flags=0):
         """ Add neighbor MAC to IPv4 or IPv6 address.
 
         :param sw_if_index:
         :param mac_address:
         :param dst_address:
         :param is_add:  (Default value = 1)
-        :param is_ipv6:  (Default value = 0)
-        :param is_static:  (Default value = 0)
-        :param is_no_adj_fib:  (Default value = 0)
+        :param flags:  (Default value = 0/NONE)
         """
         return self.api(
             self.papi.ip_neighbor_add_del,
-            {'sw_if_index': sw_if_index,
-             'is_add': is_add,
-             'is_ipv6': is_ipv6,
-             'is_static': is_static,
-             'is_no_adj_fib': is_no_adj_fib,
-             'mac_address': mac_address,
-             'dst_address': dst_address
-             }
+            {
+                'is_add': is_add,
+                'neighbor': {
+                    'sw_if_index': sw_if_index,
+                    'flags': flags,
+                    'mac_address': mac_address,
+                    'ip_address': ip_address
+                }
+            }
         )
 
     def ip_neighbor_dump(self,
@@ -1051,9 +1049,9 @@ class VppPapiProvider(object):
         )
 
     def proxy_arp_add_del(self,
-                          low_address,
-                          hi_address,
-                          vrf_id=0,
+                          low,
+                          hi,
+                          table_id=0,
                           is_add=1):
         """ Config Proxy Arp Range.
 
@@ -1066,9 +1064,9 @@ class VppPapiProvider(object):
             self.papi.proxy_arp_add_del,
             {'proxy':
              {
-                 'vrf_id': vrf_id,
-                 'low_address': low_address,
-                 'hi_address': hi_address,
+                 'table_id': table_id,
+                 'low': low,
+                 'hi': hi,
              },
              'is_add': is_add})