Trivial: Clean up some typos.
[vpp.git] / src / vnet / lisp-cp / lisp_types.c
index ad3a4bd..fb3fa6c 100644 (file)
@@ -31,16 +31,28 @@ typedef int (*cmp_fct) (void *, void *);
 
 size_to_write_fct size_to_write_fcts[GID_ADDR_TYPES] =
   { ip_prefix_size_to_write, lcaf_size_to_write, mac_size_to_write,
-  sd_size_to_write, nsh_size_to_write
+  sd_size_to_write, nsh_size_to_write, 0 /* arp */ , no_addr_size_to_write
 };
+
 serdes_fct write_fcts[GID_ADDR_TYPES] =
-  { ip_prefix_write, lcaf_write, mac_write, sd_write, nsh_write };
+  { ip_prefix_write, lcaf_write, mac_write, sd_write, nsh_write, 0 /* arp */ ,
+  no_addr_write
+};
+
 cast_fct cast_fcts[GID_ADDR_TYPES] =
-  { ip_prefix_cast, lcaf_cast, mac_cast, sd_cast, nsh_cast };
+  { ip_prefix_cast, lcaf_cast, mac_cast, sd_cast, nsh_cast, 0 /* arp */ ,
+  no_addr_cast
+};
+
 addr_len_fct addr_len_fcts[GID_ADDR_TYPES] =
-  { ip_prefix_length, lcaf_length, mac_length, sd_length, nsh_length };
+  { ip_prefix_length, lcaf_length, mac_length, sd_length, nsh_length,
+  0 /* arp */ , no_addr_length
+};
+
 copy_fct copy_fcts[GID_ADDR_TYPES] =
-  { ip_prefix_copy, lcaf_copy, mac_copy, sd_copy, nsh_copy };
+  { ip_prefix_copy, lcaf_copy, mac_copy, sd_copy, nsh_copy, 0 /* arp */ ,
+  no_addr_copy
+};
 
 #define foreach_lcaf_type \
   _(1, no_addr)      \
@@ -55,7 +67,12 @@ copy_fct copy_fcts[GID_ADDR_TYPES] =
   _(0, NULL)         \
   _(0, NULL)         \
   _(0, NULL)         \
-  _(1, sd)
+  _(1, sd)           \
+  _(0, NULL)         \
+  _(0, NULL)         \
+  _(0, NULL)         \
+  _(0, NULL)         \
+  _(1, nsh)
 
 #define _(cond, name)                             \
   u16 name ## _write (u8 * p, void * a);          \
@@ -186,22 +203,6 @@ unformat_ip_prefix (unformat_input_t * input, va_list * args)
   return 1;
 }
 
-uword
-unformat_mac_address (unformat_input_t * input, va_list * args)
-{
-  u8 *a = va_arg (*args, u8 *);
-  return unformat (input, "%x:%x:%x:%x:%x:%x", &a[0], &a[1], &a[2], &a[3],
-                  &a[4], &a[5]);
-}
-
-u8 *
-format_mac_address (u8 * s, va_list * args)
-{
-  u8 *a = va_arg (*args, u8 *);
-  return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
-                a[0], a[1], a[2], a[3], a[4], a[5]);
-}
-
 uword
 unformat_nsh_address (unformat_input_t * input, va_list * args)
 {
@@ -216,6 +217,13 @@ format_nsh_address (u8 * s, va_list * args)
   return format (s, "SPI:%d SI:%d", a->spi, a->si);
 }
 
+u8 *
+format_fid_nsh_address (u8 * s, va_list * args)
+{
+  u32 *a = va_arg (*args, u32 *);
+  return format (s, "SPI:%d SI:%d", *a >> 8, *a & 0xff);
+}
+
 u8 *
 format_fid_address (u8 * s, va_list * args)
 {
@@ -228,7 +236,7 @@ format_fid_address (u8 * s, va_list * args)
     case FID_ADDR_MAC:
       return format (s, "%U", format_mac_address, &fid_addr_mac (a));
     case FID_ADDR_NSH:
-      return format (s, "%U", format_nsh_address, &fid_addr_nsh (a));
+      return format (s, "%U", format_fid_nsh_address, &fid_addr_nsh (a));
 
     default:
       clib_warning ("Can't format fid address type %d!", fid_addr_type (a));
@@ -254,8 +262,13 @@ format_gid_address (u8 * s, va_list * args)
     case GID_ADDR_MAC:
       return format (s, "[%d] %U", gid_address_vni (a), format_mac_address,
                     &gid_address_mac (a));
+    case GID_ADDR_ARP:
+    case GID_ADDR_NDP:
+      return format (s, "[%d, %U]", gid_address_arp_ndp_bd (a),
+                    format_ip_address, &gid_address_arp_ndp_ip (a));
     case GID_ADDR_NSH:
       return format (s, "%U", format_nsh_address, &gid_address_nsh (a));
+
     default:
       clib_warning ("Can't format gid type %d", type);
       return 0;
@@ -284,7 +297,7 @@ unformat_fid_address (unformat_input_t * i, va_list * args)
   else if (unformat (i, "%U", unformat_nsh_address, &nsh))
     {
       fid_addr_type (a) = FID_ADDR_NSH;
-      nsh_copy (&fid_addr_nsh (a), mac);
+      nsh_copy (&fid_addr_nsh (a), &nsh);
     }
   else
     return 0;
@@ -657,12 +670,51 @@ fid_addr_parse (u8 * p, fid_address_t * a)
       return ip_address_parse (p, afi, ip_addr);
 
     case FID_ADDR_NSH:
-      ASSERT (0);
       break;
     }
   return ~0;
 }
 
+#define INC(dst, exp)   \
+do {                    \
+  u16 _sum = (exp);     \
+  if ((u16)~0 == _sum)  \
+    return ~0;          \
+  dst += _sum;          \
+} while (0);
+
+void
+nsh_free (void *a)
+{
+  /* nothing to do */
+}
+
+u16
+nsh_parse (u8 * p, void *a)
+{
+  lcaf_spi_hdr_t *h = (lcaf_spi_hdr_t *) p;
+  gid_address_t *g = a;
+
+  gid_address_type (g) = GID_ADDR_NSH;
+  gid_address_nsh_spi (g) = clib_net_to_host_u32 (LCAF_SPI_SI (h)) >> 8;
+  gid_address_nsh_si (g) = (u8) clib_net_to_host_u32 (LCAF_SPI_SI (h));
+
+  return sizeof (lcaf_spi_hdr_t);
+}
+
+int
+nsh_cmp (void *a1, void *a2)
+{
+  nsh_t *n1 = a1;
+  nsh_t *n2 = a2;
+
+  if (n1->spi != n2->spi)
+    return 1;
+  if (n1->si != n2->si)
+    return 1;
+  return 0;
+}
+
 u16
 sd_parse (u8 * p, void *a)
 {
@@ -677,8 +729,8 @@ sd_parse (u8 * p, void *a)
   sd_hdr = (lcaf_src_dst_hdr_t *) (p + size);
   size += sizeof (sd_hdr[0]);
 
-  size += fid_addr_parse (p + size, src);
-  size += fid_addr_parse (p + size, dst);
+  INC (size, fid_addr_parse (p + size, src));
+  INC (size, fid_addr_parse (p + size, dst));
 
   if (fid_addr_type (src) == FID_ADDR_IP_PREF)
     {
@@ -704,7 +756,7 @@ try_parse_src_dst_lcaf (u8 * p, gid_address_t * a)
   if (LCAF_SOURCE_DEST != lcaf_type (&lcaf))
     return ~0;
 
-  size += sd_parse (p + size, a);
+  INC (size, sd_parse (p + size, a));
   return size;
 }
 
@@ -724,13 +776,10 @@ vni_parse (u8 * p, void *a)
   u16 afi = clib_net_to_host_u16 (*((u16 *) (p + size)));
   if (LISP_AFI_LCAF == afi)
     {
-      u16 len = try_parse_src_dst_lcaf (p + size, g);
-      if ((u16) ~ 0 == len)
-       return ~0;
-      size += len;
+      INC (size, try_parse_src_dst_lcaf (p + size, g));
     }
   else
-    size += gid_address_parse (p + size, g);
+    INC (size, gid_address_parse (p + size, g));
 
   return size;
 }
@@ -757,7 +806,7 @@ lcaf_parse (void *offset, gid_address_t * addr)
       clib_warning ("Unsupported LCAF type: %u", type);
       return ~0;
     }
-  size += (*lcaf_parse_fcts[type]) (offset + size, lcaf);
+  INC (size, (*lcaf_parse_fcts[type]) (offset + size, lcaf));
   return sizeof (u16) + size;
 }
 
@@ -822,7 +871,7 @@ ip_address_copy (ip_address_t * dst, const ip_address_t * src)
 {
   if (IP4 == ip_addr_version (src))
     {
-      /* don't copy any garbe from the union */
+      /* don't copy any garbage from the union */
       memset (dst, 0, sizeof (*dst));
       dst->ip.v4 = src->ip.v4;
       dst->version = IP4;
@@ -1087,6 +1136,12 @@ mac_cast (gid_address_t * a)
   return &gid_address_mac (a);
 }
 
+void *
+no_addr_cast (gid_address_t * a)
+{
+  return (void *) a;
+}
+
 void *
 sd_cast (gid_address_t * a)
 {
@@ -1220,8 +1275,33 @@ sd_write (u8 * p, void *a)
 u16
 nsh_write (u8 * p, void *a)
 {
-  clib_warning ("not done");
-  return 0;
+  lcaf_spi_hdr_t spi;
+  lcaf_hdr_t lcaf;
+  gid_address_t *g = a;
+  u16 size = 0;
+
+  ASSERT (gid_address_type (g) == GID_ADDR_NSH);
+
+  memset (&lcaf, 0, sizeof (lcaf));
+  memset (&spi, 0, sizeof (spi));
+
+  LCAF_TYPE (&lcaf) = LCAF_NSH;
+  LCAF_LENGTH (&lcaf) = clib_host_to_net_u16 (sizeof (lcaf_spi_hdr_t));
+
+  u32 s = clib_host_to_net_u32 (gid_address_nsh_spi (g) << 8 |
+                               gid_address_nsh_si (g));
+  LCAF_SPI_SI (&spi) = s;
+
+  *(u16 *) p = clib_host_to_net_u16 (LISP_AFI_LCAF);
+  size += sizeof (u16);
+
+  clib_memcpy (p + size, &lcaf, sizeof (lcaf));
+  size += sizeof (lcaf);
+
+  clib_memcpy (p + size, &spi, sizeof (spi));
+  size += sizeof (spi);
+
+  return size;
 }
 
 u16
@@ -1347,7 +1427,7 @@ mac_size_to_write (void *a)
 u16
 nsh_size_to_write (void *a)
 {
-  return sizeof (u16) + 4;
+  return sizeof (u16) + sizeof (lcaf_hdr_t) + sizeof (lcaf_spi_hdr_t);
 }
 
 u8
@@ -1419,10 +1499,9 @@ u32
 gid_address_parse (u8 * offset, gid_address_t * a)
 {
   lisp_afi_e afi;
-  int len = 0;
+  u16 len = 0;
 
-  if (!a)
-    return 0;
+  ASSERT (a);
 
   /* NOTE: since gid_address_parse may be called by vni_parse, we can't 0
    * the gid address here */
@@ -1458,7 +1537,7 @@ gid_address_parse (u8 * offset, gid_address_t * a)
       clib_warning ("LISP AFI %d not supported!", afi);
       return ~0;
     }
-  return len;
+  return (len == (u16) ~ 0) ? ~0 : len;
 }
 
 void
@@ -1575,6 +1654,9 @@ gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
     case GID_ADDR_SRC_DST:
       cmp = sd_cmp (&gid_address_sd (a1), &gid_address_sd (a2));
       break;
+    case GID_ADDR_NSH:
+      cmp = nsh_cmp (&gid_address_nsh (a1), &gid_address_nsh (a2));
+      break;
     default:
       break;
     }