Implement LISP control plane messages
[vpp.git] / vnet / vnet / lisp-cp / lisp_types.c
index 203698a..d206e6b 100644 (file)
@@ -147,6 +147,8 @@ uword
 unformat_ip_address (unformat_input_t * input, va_list * args)
 {
   ip_address_t *a = va_arg (*args, ip_address_t *);
+
+  memset (a, 0, sizeof (*a));
   if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (a)))
     ip_addr_version (a) = IP4;
   else if (unformat_user (input, unformat_ip6_address, &ip_addr_v6 (a)))
@@ -211,7 +213,7 @@ format_fid_address (u8 * s, va_list * args)
       return format (s, "%U", format_ip_prefix, &fid_addr_ippref (a));
 
     case FID_ADDR_MAC:
-      return format (s, "%U", format_ip_prefix, &fid_addr_mac (a));
+      return format (s, "%U", format_mac_address, &fid_addr_mac (a));
 
     default:
       clib_warning ("Can't format fid address type %d!", fid_addr_type (a));
@@ -267,6 +269,31 @@ unformat_fid_address (unformat_input_t * i, va_list * args)
   return 1;
 }
 
+uword
+unformat_hmac_key_id (unformat_input_t * input, va_list * args)
+{
+  u32 *key_id = va_arg (*args, u32 *);
+  u8 *s = 0;
+
+  if (unformat (input, "%s", &s))
+    {
+      if (!strcmp ((char *) s, "sha1"))
+       key_id[0] = HMAC_SHA_1_96;
+      else if (!strcmp ((char *) s, "sha256"))
+       key_id[0] = HMAC_SHA_256_128;
+      else
+       {
+         clib_warning ("invalid key_id: '%s'", s);
+         key_id[0] = HMAC_NO_KEY;
+       }
+    }
+  else
+    return 0;
+
+  vec_free (s);
+  return 1;
+}
+
 uword
 unformat_gid_address (unformat_input_t * input, va_list * args)
 {
@@ -331,8 +358,50 @@ unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
   return 1;
 }
 
+u8 *
+format_hmac_key_id (u8 * s, va_list * args)
+{
+  lisp_key_type_t key_id = va_arg (*args, lisp_key_type_t);
+
+  switch (key_id)
+    {
+    case HMAC_SHA_1_96:
+      return format (0, "sha1");
+    case HMAC_SHA_256_128:
+      return format (0, "sha256");
+    default:
+      return 0;
+    }
+
+  return 0;
+}
+
+u8 *
+format_negative_mapping_action (u8 * s, va_list * args)
+{
+  lisp_action_e action = va_arg (*args, lisp_action_e);
+
+  switch (action)
+    {
+    case LISP_NO_ACTION:
+      s = format (s, "no-action");
+      break;
+    case LISP_FORWARD_NATIVE:
+      s = format (s, "natively-forward");
+      break;
+    case LISP_SEND_MAP_REQUEST:
+      s = format (s, "send-map-request");
+      break;
+    case LISP_DROP:
+    default:
+      s = format (s, "drop");
+      break;
+    }
+  return (s);
+}
+
 u16
-ip_address_size (ip_address_t * a)
+ip_address_size (const ip_address_t * a)
 {
   switch (ip_addr_version (a))
     {
@@ -652,8 +721,16 @@ gid_address_free (gid_address_t * a)
   (*lcaf_free_fcts[lcaf_type]) (lcaf);
 }
 
+void
+gid_address_from_ip (gid_address_t * g, ip_address_t * ip)
+{
+  memset (g, 0, sizeof (g[0]));
+  ip_address_set (&gid_address_ip (g), ip, ip_addr_version (ip));
+  gid_address_ippref_len (g) = 32;
+}
+
 int
-ip_address_cmp (ip_address_t * ip1, ip_address_t * ip2)
+ip_address_cmp (const ip_address_t * ip1, const ip_address_t * ip2)
 {
   int res = 0;
   if (ip_addr_version (ip1) != ip_addr_version (ip2))
@@ -670,24 +747,54 @@ ip_address_cmp (ip_address_t * ip1, ip_address_t * ip2)
 }
 
 void
-ip_address_copy (ip_address_t * dst, ip_address_t * src)
+ip_address_copy (ip_address_t * dst, const ip_address_t * src)
 {
-  clib_memcpy (dst, src, sizeof (ip_address_t));
+  if (IP4 == ip_addr_version (src))
+    {
+      /* don't copy any garbe from the union */
+      memset (dst, 0, sizeof (*dst));
+      dst->ip.v4 = src->ip.v4;
+      dst->version = IP4;
+    }
+  else
+    {
+      clib_memcpy (dst, src, sizeof (ip_address_t));
+    }
 }
 
 void
-ip_address_copy_addr (void *dst, ip_address_t * src)
+ip_address_copy_addr (void *dst, const ip_address_t * src)
 {
   clib_memcpy (dst, src, ip_address_size (src));
 }
 
 void
-ip_address_set (ip_address_t * dst, void *src, u8 version)
+ip_address_set (ip_address_t * dst, const void *src, u8 version)
 {
   clib_memcpy (dst, src, ip_version_to_size (version));
   ip_addr_version (dst) = version;
 }
 
+void
+ip_address_to_46 (const ip_address_t * addr,
+                 ip46_address_t * a, fib_protocol_t * proto)
+{
+  *proto = (IP4 == ip_addr_version (addr) ?
+           FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
+  switch (*proto)
+    {
+    case FIB_PROTOCOL_IP4:
+      ip46_address_set_ip4 (a, &addr->ip.v4);
+      break;
+    case FIB_PROTOCOL_IP6:
+      a->ip6 = addr->ip.v6;
+      break;
+    default:
+      ASSERT (0);
+      break;
+    }
+}
+
 static void
 ip_prefix_normalize_ip4 (ip4_address_t * ip4, u8 preflen)
 {
@@ -1253,6 +1360,7 @@ gid_address_parse (u8 * offset, gid_address_t * a)
 void
 gid_address_ip_set (gid_address_t * dst, void *src, u8 version)
 {
+  gid_address_ippref_len (dst) = ip_address_max_len (version);
   ip_address_set (&gid_address_ip (dst), src, version);
 }
 
@@ -1275,6 +1383,12 @@ vni_cmp (void *a1, void *a2)
   return gid_address_cmp (vni_gid (v1), vni_gid (v2));
 }
 
+static int
+mac_cmp (void *a1, void *a2)
+{
+  return memcmp (a1, a2, 6);
+}
+
 static int
 fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
 {
@@ -1287,7 +1401,7 @@ fid_addr_cmp (fid_address_t * a1, fid_address_t * a2)
       return ip_prefix_cmp (&fid_addr_ippref (a1), &fid_addr_ippref (a2));
 
     case FID_ADDR_MAC:
-      return memcmp (&fid_addr_mac (a1), &fid_addr_mac (a2), 6);
+      return mac_cmp (fid_addr_mac (a1), fid_addr_mac (a2));
 
     default:
       return -1;
@@ -1348,8 +1462,7 @@ gid_address_cmp (gid_address_t * a1, gid_address_t * a2)
        cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)]) (lcaf1, lcaf2);
       break;
     case GID_ADDR_MAC:
-      cmp = memcmp (gid_address_mac (a1), gid_address_mac (a2),
-                   sizeof (gid_address_mac (a1)));
+      cmp = mac_cmp (gid_address_mac (a1), gid_address_mac (a2));
       break;
 
     case GID_ADDR_SRC_DST:
@@ -1421,6 +1534,37 @@ locator_free (locator_t * l)
     gid_address_free (&l->address);
 }
 
+void
+build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst)
+{
+  memset (sd, 0, sizeof (*sd));
+  gid_address_type (sd) = GID_ADDR_SRC_DST;
+  gid_address_vni (sd) = gid_address_vni (dst);
+  gid_address_vni_mask (sd) = gid_address_vni_mask (dst);
+
+  switch (gid_address_type (dst))
+    {
+    case GID_ADDR_IP_PREFIX:
+      gid_address_sd_src_type (sd) = FID_ADDR_IP_PREF;
+      gid_address_sd_dst_type (sd) = FID_ADDR_IP_PREF;
+      ip_prefix_copy (&gid_address_sd_src_ippref (sd),
+                     &gid_address_ippref (src));
+      ip_prefix_copy (&gid_address_sd_dst_ippref (sd),
+                     &gid_address_ippref (dst));
+      break;
+    case GID_ADDR_MAC:
+      gid_address_sd_src_type (sd) = FID_ADDR_MAC;
+      gid_address_sd_dst_type (sd) = FID_ADDR_MAC;
+      mac_copy (gid_address_sd_src_mac (sd), gid_address_mac (src));
+      mac_copy (gid_address_sd_dst_mac (sd), gid_address_mac (dst));
+      break;
+    default:
+      clib_warning ("Unsupported gid type %d while conversion!",
+                   gid_address_type (dst));
+      break;
+    }
+}
+
 /*
  * fd.io coding-style-patch-verification: ON
  *