Add unit test infrastructure for LISP protocol 07/707/4
authorFilip Tehlar <ftehlar@cisco.com>
Thu, 7 Apr 2016 08:04:34 +0000 (10:04 +0200)
committerGerrit Code Review <gerrit@fd.io>
Tue, 12 Apr 2016 11:47:39 +0000 (11:47 +0000)
Change-Id: I802700ad832de1dc6f4a1981e8985aa6e926c8ad
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
13 files changed:
.gitignore
build-data/packages/vnet.mk
vnet/Makefile.am
vnet/configure.ac
vnet/test/README [new file with mode: 0644]
vnet/test/lisp-cp/test_cp_serdes.c [new file with mode: 0644]
vnet/test/lisp-cp/test_lisp_types.c [new file with mode: 0644]
vnet/test/lisp-gpe/test.c [new file with mode: 0644]
vnet/vnet/lisp-cp/control.c
vnet/vnet/lisp-cp/lisp_msg_serdes.c
vnet/vnet/lisp-cp/lisp_msg_serdes.h
vnet/vnet/lisp-cp/lisp_types.c
vnet/vnet/lisp-cp/lisp_types.h

index 5d1a597..e91f1a0 100644 (file)
@@ -39,6 +39,7 @@ missing
 stamp-h1
 ltmain.sh
 ylwrap
+test-driver
 
 .cproject
 *.iml
index 2ff9034..46d3c1d 100644 (file)
@@ -18,6 +18,10 @@ vnet_LDFLAGS = $(call installed_libs_fn,     \
     vlib                                       \
     vlib-api)
 
+ifeq ($($(PLATFORM)_enable_tests),yes)
+vnet_configure_args += --enable-tests
+endif
+
 # Platform dependent configure flags
 vnet_configure_args += $(vnet_configure_args_$(PLATFORM))
 
index 52b5a6d..3d9bae7 100644 (file)
@@ -19,6 +19,7 @@ libvnet_la_SOURCES =
 libvnetplugin_la_SOURCES =
 nobase_include_HEADERS =
 noinst_PROGRAMS =
+TESTS =
 
 ########################################
 # Generic stuff
@@ -443,6 +444,34 @@ nobase_include_HEADERS +=                  \
  vnet/lisp-cp/lisp_msg_serdes.h                        \
  vnet/lisp-cp/control.h                                
 
+
+if ENABLE_TESTS
+LDS = -lvppinfra -l:libvlib.a -l:libdpdk.a -l:libvlibmemory.a \
+       -l:libvlibapi.a -l:libsvm.a -lpthread -ldl -lrt -lm -l:libvlib_unix.a
+
+TESTS += test_cp_serdes test_lisp_types
+
+test_cp_serdes_SOURCES =                       \
+ test/lisp-cp/test_cp_serdes.c         \
+ vnet/lisp-cp/lisp_msg_serdes.c                        \
+ vnet/lisp-cp/lisp_types.c                     \
+ vnet/lisp-cp/packets.c                                \
+ vnet/ip/ip_checksum.c
+
+test_lisp_types_SOURCES =                      \
+ test/lisp-cp/test_lisp_types.c                \
+ vnet/lisp-cp/lisp_types.c
+
+test_cp_serdes_CPPFLAGS = $(AM_CPPFLAGS) -DCLIB_DEBUG
+test_lisp_types_CPPFLAGS = $(AM_CPPFLAGS) -DCLIB_DEBUG
+
+test_cp_serdes_LDADD = libvnet.la $(LDS)
+test_lisp_types_LDADD = libvnet.la $(LDS)
+
+test_cp_serdes_LDFLAGS = -static
+test_lisp_types_LDFLAGS = -static
+endif
+
 ########################################
 # Tunnel protocol: lisp-gpe
 ########################################
@@ -457,6 +486,19 @@ nobase_include_HEADERS +=                  \
  vnet/lisp-gpe/lisp_gpe_packet.h               \
  vnet/lisp-gpe/lisp_gpe_error.def              
 
+if ENABLE_TESTS
+TESTS += test_test
+
+test_test_SOURCES = test/lisp-gpe/test.c
+
+test_test_CPPFLAGS = $(AM_CPPFLAGS) -DCLIB_DEBUG
+
+test_test_LDADD = $(LIBOBJS)
+
+noinst_PROGRAMS += $(TESTS)
+check_PROGRAMS = $(TESTS)
+endif
+
 ########################################
 # DHCP client
 ########################################
@@ -685,3 +727,5 @@ pcap2pg_LDFLAGS = -static
 pcap2pg_LDADD = libvnet.la -l:libvppinfra.a -lpthread -lm -ldl
 
 noinst_PROGRAMS += pcap2pg
+
+
index b46a678..b4b6723 100644 (file)
@@ -32,6 +32,11 @@ AC_ARG_WITH(ipv6sr,
             [with_ipv6sr=0],
             [with_ipv6sr=1])
 
+AC_ARG_ENABLE(tests,
+              AC_HELP_STRING([--enable-tests], [Build unit tests]),
+              [enable_tests=1],
+              [enable_tests=0])
+
 AM_CONDITIONAL(WITH_DPDK, test "$with_dpdk" = "1")
 AC_SUBST(DPDK,[-DDPDK=${with_dpdk}])
 
@@ -47,4 +52,6 @@ AC_SUBST(VCGN,[-DVCGN=${with_vcgn}])
 AM_CONDITIONAL(WITH_IPV6SR, test "$with_ipv6sr" = "1")
 AC_SUBST(IPV6SR,[-DIPV6SR=${with_ipv6sr}])
 
+AM_CONDITIONAL(ENABLE_TESTS, test "$enable_tests" = "1")
+
 AC_OUTPUT([Makefile])
diff --git a/vnet/test/README b/vnet/test/README
new file mode 100644 (file)
index 0000000..10579e5
--- /dev/null
@@ -0,0 +1,10 @@
+Unit test infrastructure for vnet
+
+To run unit tests do the following:
+
+  1. build vpp with 'vpp_enable_tests = yes' in build-data/platforms/vpp.mk
+
+  2. go to build-root/build-$tag-$arch/vnet
+
+  3. run
+    $ make check
diff --git a/vnet/test/lisp-cp/test_cp_serdes.c b/vnet/test/lisp-cp/test_cp_serdes.c
new file mode 100644 (file)
index 0000000..9e89dd9
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vnet/vnet.h>
+#include <vppinfra/error.h>
+#include <vnet/lisp-cp/lisp_cp_messages.h>
+#include <vnet/lisp-cp/control.h>
+#include <vnet/lisp-cp/lisp_msg_serdes.h>
+#include <vlibapi/api.h>
+#include <vnet/lisp-cp/packets.h>
+
+#define _assert(e)                    \
+  error = CLIB_ERROR_ASSERT (e);      \
+  if (error)                          \
+    goto done;
+
+static void print_chunk(u8 * b, int * offset, int c, char * des)
+{
+  int i, n = offset[0] + c;;
+  for (i = offset[0]; i < n; i++)
+  {
+    printf("0x%02x, ", b[i]);
+  }
+  printf(" // %s\n", des);
+  *offset += c;
+}
+
+void print_map_request(map_request_hdr_t * h)
+{
+#define pchunk(_count, _desc) \
+  print_chunk((u8 *)h, &offset, _count, _desc)
+
+  int offset = 0;
+
+  pchunk(4, "data");
+  pchunk(8, "Nonce");
+  pchunk(2, "Source-EID-AFI");
+  pchunk(4, "Source EID Address");
+  pchunk(2, "ITR-RLOC-AFI 1");
+  pchunk(4, "ITR-RLOC Address 1");
+  pchunk(2, "ITR-RLOC-AFI 2");
+  pchunk(16, "ITR-RLOC Address 2");
+  pchunk(1, "REC: reserved");
+  pchunk(1, "REC: EID mask-len");
+  pchunk(2, "REC: EID-prefix-AFI");
+  pchunk(4, "REC: EID-prefix");
+  printf("\n");
+}
+
+static clib_error_t * test_lisp_msg_push_ecm ()
+{
+  vlib_main_t * vm = vlib_get_main ();
+  clib_error_t * error = 0;
+  gid_address_t la, ra;
+  vlib_buffer_t * b = 0;
+  u32 buff_len = 500;
+  int lp = 0x15, rp = 0x14;
+
+  b = clib_mem_alloc (buff_len);
+  memset((u8 *)b, 0, buff_len);
+  b->current_length = buff_len;
+  b->current_data = sizeof(udp_header_t) + sizeof(ip4_header_t) +
+    sizeof(ecm_hdr_t) + 1;
+
+  la.type = IP_PREFIX;
+  la.ippref.addr.ip.v4.as_u32 = 0xa1b2c3d4;
+  la.ippref.addr.version = IP4;
+
+  ra.type = IP_PREFIX;
+  ra.ippref.addr.ip.v4.as_u32 = 0x90817263;
+  ra.ippref.addr.version = IP4;
+
+  ecm_hdr_t * lh = lisp_msg_push_ecm (vm, b, lp, rp, &la, &ra);
+
+  u8 expected_ecm_hdr[] = {
+    0x80, 0x00, 0x00, 0x00
+  };
+  _assert(0 == memcmp(expected_ecm_hdr, lh, sizeof(expected_ecm_hdr)));
+
+  ip4_header_t * ih = (ip4_header_t *) (lh + 1);
+  /* clear ip checksum */
+  memset((u8 *)ih + 10, 0, 2);
+
+  u8 expected_ip4_hdr[] = {
+    0x45,                   /* version; IHL */
+    0x00,                   /* services */
+    0x02, 0x10,             /* total length */
+    0x00, 0x00,             /* identification */
+    0x40, 0x00,             /* flags; fragment offset*/
+    0xff,                   /* TTL */
+    0x11,                   /* protocol */
+    0x00, 0x00,             /* header checksum */
+    0xd4, 0xc3, 0xb2, 0xa1, /* src IP */
+    0x63, 0x72, 0x81, 0x90, /* dst IP */
+  };
+  _assert(0 == memcmp(ih, expected_ip4_hdr, sizeof(expected_ip4_hdr)));
+
+  udp_header_t * uh = (udp_header_t *) (ih + 1);
+  /* clear udp checksum */
+  memset((u8 *)uh + 6, 0, 2);
+
+  u8 expected_udp_hdr[] = {
+    0x00, 0x15, /* src port */
+    0x00, 0x14, /* dst port */
+    0x01, 0xfc, /* length */
+    0x00, 0x00, /* checksum */
+  };
+  _assert(0 == memcmp(uh, expected_udp_hdr, sizeof(expected_udp_hdr)));
+
+done:
+  clib_mem_free (b);
+  return error;
+}
+
+static clib_error_t * test_lisp_msg_parse_mapping_record ()
+{
+  clib_error_t * error = 0;
+  locator_t probed;
+  locator_t * locs = 0;
+  vlib_buffer_t * b = 0;
+  gid_address_t eid;
+  u32 buff_len = 500;
+
+  b = clib_mem_alloc (buff_len);
+  memset((u8 *)b, 0, buff_len);
+
+  u8 map_reply_records[] = {
+    /* 1. record */
+    0x01, 0x02, 0x03, 0x04, /* record TTL */
+    0x01,                   /* locator count */
+    0x00, 0x00, 0x00,       /* eid-mask-len; ... */
+    0x00, 0x00,             /* reserved; map-version num */
+    0x00, 0x01,             /* EID-Prefix-AFI */
+    0x33, 0x44, 0x55, 0x66, /* eid-prefix */
+    /* loc */
+    0x0a,                   /* prority */
+    0x0b,                   /* weight */
+    0x0c,                   /* m-prority */
+    0x0d,                   /* m-weight */
+    0x00, 0x00,             /* unused flags */
+    0x00, 0x01,             /* Loc-AFI */
+    0xaa, 0xbb, 0xcc, 0xdd, /* Loator */
+  };
+  b->current_length = buff_len;
+  memcpy(b->data, map_reply_records, sizeof(map_reply_records));
+
+  lisp_msg_parse_mapping_record (b, &eid, &locs, &probed);
+  _assert(vec_len (locs) == 1);
+  _assert(eid.ippref.addr.ip.v4.as_u32 == 0x66554433);
+  _assert(locs[0].local == 0);
+  _assert(locs[0].address.ippref.addr.ip.v4.as_u32 == 0xddccbbaa);
+  _assert(locs[0].address.type == IP_PREFIX);
+  _assert(locs[0].priority == 0xa);
+  _assert(locs[0].weight == 0xb);
+  _assert(locs[0].mpriority == 0xc);
+  _assert(locs[0].mweight == 0xd);
+
+done:
+  clib_mem_free (b);
+  if (locs)
+    vec_free (locs);
+  return error;
+}
+
+static map_request_hdr_t *
+build_map_request (lisp_cp_main_t * lcm, vlib_buffer_t * b)
+{
+  gid_address_t _seid, * seid = &_seid;
+  gid_address_t _deid, * deid = &_deid;
+  u8 is_smr_invoked = 1;
+  u64 nonce = 0;
+  map_request_hdr_t *h;
+  ip_address_t * rlocs = 0;
+  ip_address_t _addr, * addr = &_addr;
+
+  gid_address_type(seid) = IP_PREFIX;
+  gid_address_ip(seid).ip.v4.as_u32 = 0x12345678;
+  seid->ippref.addr.version = IP4;
+
+  gid_address_type(deid) = IP_PREFIX;
+  gid_address_ip(deid).ip.v4.as_u32 = 0x9abcdef0;
+  deid->ippref.addr.version = IP4;
+  gid_address_ippref_len(deid) = 24;
+
+  ip_addr_version(addr) = IP4;
+  ip_addr_v4(addr).data_u32 = 0x10203040;
+  vec_add1(rlocs, addr[0]);
+
+  ip_addr_v6(addr).as_u32[0] = 0xffeeddcc;
+  ip_addr_v6(addr).as_u32[1] = 0xbbaa9988;
+  ip_addr_v6(addr).as_u32[2] = 0x77665544;
+  ip_addr_v6(addr).as_u32[3] = 0x33221100;
+  ip_addr_version(addr) = IP6;
+  vec_add1(rlocs, addr[0]);
+
+  h = lisp_msg_put_mreq (lcm, b, seid, deid, rlocs,
+                     is_smr_invoked, &nonce);
+  vec_free(rlocs);
+  return h;
+}
+
+static clib_error_t * test_lisp_msg_parse ()
+{
+  gid_address_t eid;
+  lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
+  map_request_hdr_t *h;
+  gid_address_t gid;
+  clib_error_t * error = 0;
+  vlib_buffer_t * b;
+  gid_address_t * rlocs = 0;
+
+  u8 * data = clib_mem_alloc(500);
+  memset(data, 0, 500);
+  b = (vlib_buffer_t *) data;
+
+  h = build_map_request (lcm, b);
+
+  vlib_buffer_pull(b, sizeof(*h));
+  u32 len = lisp_msg_parse_addr(b, &gid);
+  _assert (len == 2 + 4
+      /* Source-EID-AFI field lenght + IPv4 address length */);
+  _assert (gid.ippref.addr.ip.v4.as_u32 == 0x12345678);
+  _assert (gid.ippref.addr.version == IP4);
+
+  u8 rloc_count = MREQ_ITR_RLOC_COUNT(h) + 1;
+  lisp_msg_parse_itr_rlocs (b, &rlocs, rloc_count);
+
+  _assert (vec_len (rlocs) == 2);
+  _assert (rlocs[0].ippref.addr.ip.v4.as_u32 == 0x10203040);
+  _assert (rlocs[0].ippref.addr.version == IP4);
+
+  _assert (rlocs[1].ippref.addr.ip.v6.as_u32[0] == 0xffeeddcc);
+  _assert (rlocs[1].ippref.addr.ip.v6.as_u32[1] == 0xbbaa9988);
+  _assert (rlocs[1].ippref.addr.ip.v6.as_u32[2] == 0x77665544);
+  _assert (rlocs[1].ippref.addr.ip.v6.as_u32[3] == 0x33221100);
+  _assert (rlocs[1].ippref.addr.version == IP6);
+
+  lisp_msg_parse_eid_rec (b, &eid);
+  _assert (eid.ippref.addr.ip.v4.as_u32 == 0x9abcdef0);
+  _assert (eid.ippref.addr.version == IP4);
+  _assert (eid.ippref.len == 24);
+
+done:
+  clib_mem_free (data);
+  if (rlocs)
+    vec_free (rlocs);
+  return error;
+}
+
+static clib_error_t * test_lisp_msg_put_mreq ()
+{
+  lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
+  clib_error_t * error = 0;
+  map_request_hdr_t *h;
+
+  u8 * data = clib_mem_alloc(500);
+  memset(data, 0, 500);
+
+  h = build_map_request (lcm, (vlib_buffer_t *)data);
+
+  /* clear Nonce to simplify comparison */
+  memset((u8 *)h + 4, 0, 8);
+
+  print_map_request(h);
+
+  u8 expected_data[50] = {
+    0x10, 0x40, 0x01, 0x01, /* type; flags; IRC; REC count */
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, /* nonce */
+    0x00, 0x01,             /* Source-EID-AFI */
+    0x78, 0x56, 0x34, 0x12, /* Source EID Address */
+
+    /* RLOCs */
+    0x00, 0x01,             /* ITR-RLOC-AFI 1 */
+    0x40, 0x30, 0x20, 0x10, /* ITR-RLOC Address 1 */
+    0x00, 0x02,             /* ITR-RLOC-AFI 2 */
+    0xcc, 0xdd, 0xee, 0xff,
+    0x88, 0x99, 0xaa, 0xbb,
+    0x44, 0x55, 0x66, 0x77,
+    0x00, 0x11, 0x22, 0x33, /* ITR-RLOC Address 2 */
+
+    /* record */
+    0x00,                   /* reserved */
+    0x18,                   /* EID mask-len */
+    0x00, 0x01,             /* EID-prefix-AFI */
+    0xf0, 0xde, 0xbc, 0x9a, /* EID-prefix */
+  };
+
+  int r = memcmp(expected_data, (u8 *)h, sizeof(expected_data));
+  error = CLIB_ERROR_ASSERT (r == 0);
+
+  clib_mem_free(data);
+  return error;
+}
+
+#define foreach_test_case                 \
+  _(lisp_msg_put_mreq)                    \
+  _(lisp_msg_push_ecm)                    \
+  _(lisp_msg_parse)                       \
+  _(lisp_msg_parse_mapping_record)
+
+int run_tests (void)
+{
+  clib_error_t * error;
+
+#define _(_test_name)                   \
+  error = test_ ## _test_name ();       \
+  if (error)                            \
+    {                                   \
+      clib_error_report (error);        \
+      return 0;                         \
+    }
+
+  foreach_test_case
+#undef _
+
+  return 0;
+}
+
+int main()
+{
+  return run_tests ();
+}
+#undef _assert
diff --git a/vnet/test/lisp-cp/test_lisp_types.c b/vnet/test/lisp-cp/test_lisp_types.c
new file mode 100644 (file)
index 0000000..db12f18
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vnet/vnet.h>
+#include <vppinfra/error.h>
+#include <vnet/lisp-cp/lisp_types.h>
+#include <vnet/lisp-cp/lisp_cp_messages.h>
+
+#define _assert(e)                    \
+  error = CLIB_ERROR_ASSERT (e);      \
+  if (error)                          \
+    goto done;
+
+static clib_error_t * test_locator_type (void)
+{
+  clib_error_t * error = 0;
+  gid_address_t _gid_addr, * gid_addr = &_gid_addr;
+  gid_address_type(gid_addr) = IP_PREFIX;
+  gid_address_ippref_len(gid_addr) = 24;
+  ip_prefix_version(&gid_addr->ippref) = IP4;
+  gid_addr->ippref.addr.ip.v4.as_u32 = 0x20304050;
+
+  /* local locator */
+  locator_t loc1, loc2 = {
+    .local = 1,
+    .state = 2,
+    .sw_if_index = 8,
+    .priority = 3,
+    .weight = 100,
+    .mpriority = 4,
+    .mweight = 101
+  };
+  locator_copy (&loc1, &loc2);
+  _assert (0 == locator_cmp (&loc1, &loc2));
+
+  /* remote locator */
+  loc2.local = 0;
+  loc2.address = gid_addr[0];
+  locator_copy(&loc1, &loc2);
+
+  _assert (0 == locator_cmp (&loc1, &loc2));
+
+done:
+  return error;
+}
+
+static clib_error_t * test_gid_parse ()
+{
+  clib_error_t * error = 0;
+  return error;
+}
+
+static clib_error_t * test_format_unformat_gid_address (void)
+{
+  u8 * s = 0;
+  clib_error_t * error = 0;
+  unformat_input_t _input;
+  unformat_input_t * input = &_input;
+  gid_address_t _gid_addr, * gid_addr = &_gid_addr;
+  gid_address_t unformated_gid;
+
+  /* format/unformat IPv4 global ID address */
+  gid_address_type(gid_addr) = IP_PREFIX;
+  gid_address_ippref_len(gid_addr) = 24;
+  ip_prefix_version(&gid_addr->ippref) = IP4;
+  gid_addr->ippref.addr.ip.v4.as_u32 = 0x20304050;
+
+  s = format(0, "%U", format_gid_address, gid_addr);
+  vec_add1(s, 0);
+  unformat_init_string(input, (char *)s, vec_len(s));
+
+  _assert (unformat(input, "%U",
+        unformat_gid_address, &unformated_gid));
+  _assert (0 == gid_address_cmp (&unformated_gid, gid_addr));
+
+  unformat_free(input);
+  vec_free(s);
+  s = 0;
+
+  /* format/unformat IPv6 global ID address */
+  gid_address_type(gid_addr) = IP_PREFIX;
+  gid_address_ippref_len(gid_addr) = 64;
+  ip_prefix_version(&gid_addr->ippref) = IP6;
+  u8 ipv6[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
+  memcpy(gid_addr->ippref.addr.ip.v6.as_u8, ipv6, sizeof(ipv6));
+
+  s = format(0, "%U", format_gid_address, gid_addr);
+  vec_add1(s, 0);
+  unformat_init_string(input, (char *)s, vec_len(s));
+
+  _assert (unformat (input, "%U", unformat_gid_address,
+        &unformated_gid));
+  _assert (0 == gid_address_cmp(&unformated_gid, gid_addr));
+
+  /* test address copy */
+  gid_address_t gid_addr_copy;
+  gid_address_copy(&gid_addr_copy, gid_addr);
+  _assert (0 == gid_address_cmp (&gid_addr_copy, gid_addr));
+
+done:
+  unformat_free(input);
+  vec_free(s);
+  return error;
+}
+
+#define foreach_test_case                 \
+  _(format_unformat_gid_address)          \
+  _(locator_type)                         \
+  _(gid_parse)
+
+int run_tests (void)
+{
+  clib_error_t * error;
+
+#define _(_test_name)                   \
+  error = test_ ## _test_name ();       \
+  if (error)                            \
+    {                                   \
+      clib_error_report (error);        \
+      return 0;                         \
+    }
+
+  foreach_test_case
+#undef _
+
+  return 0;
+}
+
+int main()
+{
+  return run_tests ();
+}
+
diff --git a/vnet/test/lisp-gpe/test.c b/vnet/test/lisp-gpe/test.c
new file mode 100644 (file)
index 0000000..dde633a
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+int main(int argc, char **argv) {
+    return 0;
+}
index f4cb16f..c187397 100644 (file)
@@ -692,6 +692,47 @@ get_local_iface_ip_for_dst (lisp_cp_main_t *lcm, ip_address_t * dst,
     }
 }
 
+
+static ip_address_t *
+build_itr_rloc_list (lisp_cp_main_t * lcm, locator_set_t * loc_set)
+{
+  ip4_address_t * l4;
+  ip6_address_t * l6;
+  u32 i;
+  locator_t * loc;
+  u32 * loc_indexp;
+  ip_interface_address_t * ia = 0;
+  ip_address_t * rlocs = 0;
+  ip_address_t _rloc, * rloc = &_rloc;
+
+  for (i = 0; i < vec_len(loc_set->locator_indices); i++)
+    {
+      loc_indexp = vec_elt_at_index(loc_set->locator_indices, i);
+      loc = pool_elt_at_index (lcm->locator_pool, loc_indexp[0]);
+
+      ip_addr_version(rloc) = IP4;
+      /* Add ipv4 locators first TODO sort them */
+      foreach_ip_interface_address (&lcm->im4->lookup_main, ia,
+                                   loc->sw_if_index, 1 /* unnumbered */,
+      ({
+       l4 = ip_interface_address_get_address (&lcm->im4->lookup_main, ia);
+  ip_addr_v4(rloc) = l4[0];
+  vec_add1(rlocs, rloc[0]);
+      }));
+
+      ip_addr_version(rloc) = IP6;
+      /* Add ipv6 locators */
+      foreach_ip_interface_address (&lcm->im6->lookup_main, ia,
+                                   loc->sw_if_index, 1 /* unnumbered */,
+      ({
+  l6 = ip_interface_address_get_address (&lcm->im6->lookup_main, ia);
+  ip_addr_v6(rloc) = l6[0];
+  vec_add1(rlocs, rloc[0]);
+      }));
+    }
+  return rlocs;
+}
+
 static vlib_buffer_t *
 build_encapsulated_map_request (vlib_main_t * vm, lisp_cp_main_t *lcm,
                                 gid_address_t * seid, gid_address_t * deid,
@@ -701,6 +742,7 @@ build_encapsulated_map_request (vlib_main_t * vm, lisp_cp_main_t *lcm,
   vlib_buffer_t * b;
   u32 bi;
   ip_address_t * mr_ip, sloc;
+  ip_address_t * rlocs = 0;
 
   if (vlib_buffer_alloc (vm, &bi, 1) != 1)
     {
@@ -713,8 +755,11 @@ build_encapsulated_map_request (vlib_main_t * vm, lisp_cp_main_t *lcm,
   /* leave some space for the encap headers */
   vlib_buffer_make_headroom (b, MAX_LISP_MSG_ENCAP_LEN);
 
+  /* get rlocs */
+  rlocs = build_itr_rloc_list (lcm, loc_set);
+
   /* put lisp msg */
-  lisp_msg_put_mreq (lcm, b, seid, deid, loc_set, is_smr_invoked, nonce_res);
+  lisp_msg_put_mreq (lcm, b, seid, deid, rlocs, is_smr_invoked, nonce_res);
 
   /* push ecm: udp-ip-lisp */
   lisp_msg_push_ecm (vm, b, LISP_CONTROL_PORT, LISP_CONTROL_PORT, seid, deid);
@@ -730,6 +775,9 @@ build_encapsulated_map_request (vlib_main_t * vm, lisp_cp_main_t *lcm,
                        mr_ip);
 
   bi_res[0] = bi;
+
+  if (rlocs)
+    vec_free(rlocs);
   return b;
 }
 
index 0e5ba73..48e40cf 100644 (file)
@@ -27,42 +27,31 @@ lisp_msg_put_gid (vlib_buffer_t * b, gid_address_t * gid)
 
 void *
 lisp_msg_put_itr_rlocs (lisp_cp_main_t * lcm, vlib_buffer_t * b,
-                        locator_set_t * loc_set, u8 * locs_put)
+                       ip_address_t * rlocs, u8 * locs_put)
 {
-  ip_interface_address_t * ia = 0;
-  ip4_address_t * l4;
-  ip6_address_t * l6;
-  u32 * loc_indexp;
-  locator_t * loc;
-  u32 i;
   u8 * p, * bp, count = 0;
+  u32 i;
+  ip_address_t * addr;
 
   bp = vlib_buffer_get_current(b);
-  for (i = 0; i < vec_len(loc_set->locator_indices); i++)
+  for (i = 0; i < vec_len(rlocs); i++)
+  {
+    addr = &rlocs[i];
+    switch (ip_addr_version(addr))
     {
-      loc_indexp = vec_elt_at_index(loc_set->locator_indices, i);
-      loc = pool_elt_at_index (lcm->locator_pool, loc_indexp[0]);
-
-      /* Add ipv4 locators first TODO sort them */
-      foreach_ip_interface_address (&lcm->im4->lookup_main, ia,
-                                    loc->sw_if_index, 1 /* unnumbered */,
-      ({
-        l4 = ip_interface_address_get_address (&lcm->im4->lookup_main, ia);
-        p = vlib_buffer_put_uninit (b, ip4_address_size_to_put());
-        ip4_address_put (p, l4);
-        count++;
-      }));
-
-      /* Add ipv6 locators */
-      foreach_ip_interface_address (&lcm->im6->lookup_main, ia,
-                                    loc->sw_if_index, 1 /* unnumbered */,
-      ({
-        l6 = ip_interface_address_get_address (&lcm->im6->lookup_main, ia);
-        p = vlib_buffer_put_uninit (b, ip6_address_size_to_put());
-        ip6_address_put (p, l6);
-        count++;
-      }));
+    case IP4:
+      p = vlib_buffer_put_uninit (b, ip4_address_size_to_put());
+      ip4_address_put (p, &ip_addr_v4(addr));
+      count++;
+      break;
+    case IP6:
+      p = vlib_buffer_put_uninit (b, ip6_address_size_to_put());
+      ip6_address_put (p, &ip_addr_v6(addr));
+      count++;
+      break;
     }
+  }
+
   *locs_put = count-1;
   return bp;
 }
@@ -103,8 +92,8 @@ nonce_build (u32 seed)
 
 void *
 lisp_msg_put_mreq (lisp_cp_main_t * lcm, vlib_buffer_t * b,
-                   gid_address_t * seid, gid_address_t * deid,
-                   locator_set_t * loc_set, u8 is_smr_invoked, u64 * nonce)
+                  gid_address_t * seid, gid_address_t * deid,
+                  ip_address_t * rlocs, u8 is_smr_invoked, u64 * nonce)
 {
   u8 loc_count = 0;
 
@@ -123,7 +112,7 @@ lisp_msg_put_mreq (lisp_cp_main_t * lcm, vlib_buffer_t * b,
   lisp_msg_put_gid (b, seid);
 
   /* Put itr rlocs */
-  lisp_msg_put_itr_rlocs(lcm, b, loc_set, &loc_count);
+  lisp_msg_put_itr_rlocs(lcm, b, rlocs, &loc_count);
   MREQ_ITR_RLOC_COUNT(h) = loc_count;
 
   /* Put eid record */
index dddae07..d7eeb35 100644 (file)
@@ -23,7 +23,7 @@
 void *
 lisp_msg_put_mreq (lisp_cp_main_t * lcm, vlib_buffer_t * b,
                   gid_address_t * seid, gid_address_t * deid,
-                  locator_set_t * loc_set, u8 is_smr_invoked, u64 * nonce);
+                  ip_address_t * rlocs, u8 is_smr_invoked, u64 * nonce);
 
 void *
 lisp_msg_push_ecm (vlib_main_t * vm, vlib_buffer_t *b, int lp, int rp,
index a04d36f..c65745d 100644 (file)
@@ -313,7 +313,17 @@ ip_prefix_cmp(ip_prefix_t * p1, ip_prefix_t * p2)
   int cmp = 0;
   cmp = ip_address_cmp (&ip_prefix_addr(p1), &ip_prefix_addr(p2));
   if (cmp == 0)
-    cmp = ip_prefix_len(p1) < ip_prefix_len(p2) ? 1 : 2; /* XXX ? */
+  {
+    if (ip_prefix_len(p1) < ip_prefix_len(p2))
+    {
+      cmp = 1;
+    }
+    else
+    {
+      if (ip_prefix_len(p1) > ip_prefix_len(p2))
+        cmp = 2;
+    }
+  }
   return cmp;
 }
 
index 9602387..63adaa0 100644 (file)
@@ -96,6 +96,7 @@ typedef enum {
 
 u8 *format_gid_address (u8 * s, va_list * args);
 uword unformat_gid_address (unformat_input_t * input, va_list * args);
+int gid_address_cmp (gid_address_t * a1, gid_address_t * a2);
 
 u16 gid_address_size_to_put (gid_address_t * a);
 u16 gid_address_put (u8 * b, gid_address_t * gid);