Add support for ethernet address in LISP API 00/1800/3
authorFilip Tehlar <ftehlar@cisco.com>
Mon, 27 Jun 2016 11:09:20 +0000 (13:09 +0200)
committerFlorin Coras <florin.coras@gmail.com>
Wed, 29 Jun 2016 18:54:02 +0000 (18:54 +0000)
Change-Id: I9f1522f55bdd11602784a421fd850b839a1070e6
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
vnet/vnet/api_errno.h
vpp-api-test/vat/api_format.c
vpp/vpp-api/api.c
vpp/vpp-api/vpe.api

index bf49c0a..f16d978 100644 (file)
@@ -81,7 +81,8 @@ _(UNSUPPORTED_JNI_VERSION, -87, "Unsupported JNI version") \
 _(FAILED_TO_ATTACH_TO_JAVA_THREAD, -88, "Failed to attach to Java thread") \
 _(INVALID_WORKER, -89, "Invalid worker thread")                         \
 _(LISP_DISABLED, -90, "LISP is disabled")                               \
-_(CLASSIFY_TABLE_NOT_FOUND, -91, "Classify table not found")
+_(CLASSIFY_TABLE_NOT_FOUND, -91, "Classify table not found")            \
+_(INVALID_EID_TYPE, -92, "Unsupported LSIP EID type")
 
 typedef enum {
 #define _(a,b,c) VNET_API_ERROR_##a = (b),
index b00dccc..a4fbf0d 100644 (file)
@@ -1984,12 +1984,21 @@ vl_api_lisp_local_eid_table_details_t_handler (
 {
     vat_main_t *vam = &vat_main;
     u8 *prefix;
+    u8 * (*format_eid)(u8 *, va_list *) = 0;
 
-    prefix = format(0, "[&d] %U/%d",
+    switch (mp->eid_type)
+      {
+      case 0: format_eid = format_ip4_address; break;
+      case 1: format_eid = format_ip6_address; break;
+      case 2: format_eid = format_ethernet_address; break;
+      default:
+        errmsg ("unknown EID type %d!", mp->eid_type);
+        return;
+      }
+
+    prefix = format(0, "[%d] %U/%d",
                     clib_net_to_host_u32 (mp->vni),
-                    mp->eid_is_ipv6 ? format_ip6_address : format_ip4_address,
-                    mp->eid_ip_address,
-                    mp->eid_prefix_len);
+                    format_eid, mp->eid, mp->eid_prefix_len);
 
     fformat(vam->ofp, "%=20s%=30s\n",
             mp->locator_set_name, prefix);
@@ -2005,6 +2014,7 @@ vl_api_lisp_local_eid_table_details_t_handler_json (
     vat_json_node_t *node = NULL;
     struct in6_addr ip6;
     struct in_addr ip4;
+    u8 * s = 0;
 
     if (VAT_JSON_ARRAY != vam->json_tree.type) {
         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
@@ -2014,15 +2024,27 @@ vl_api_lisp_local_eid_table_details_t_handler_json (
 
     vat_json_init_object(node);
     vat_json_object_add_string_copy(node, "locator-set", mp->locator_set_name);
-    if (mp->eid_is_ipv6) {
-        clib_memcpy(&ip6, mp->eid_ip_address, sizeof(ip6));
-        vat_json_object_add_ip6(node, "eid address", ip6);
-    } else {
-        clib_memcpy(&ip4, mp->eid_ip_address, sizeof(ip4));
-        vat_json_object_add_ip4(node, "eid address", ip4);
-    }
+    switch (mp->eid_type)
+      {
+      case 0:
+        clib_memcpy(&ip4, mp->eid, sizeof(ip4));
+        vat_json_object_add_ip4(node, "eid-address", ip4);
+      case 1:
+        clib_memcpy(&ip6, mp->eid, sizeof(ip6));
+        vat_json_object_add_ip6(node, "eid-address", ip6);
+        break;
+      case 2:
+        s = format (0, "%U", format_ethernet_address, mp->eid);
+        vec_add1(s, 0);
+        vat_json_object_add_string_copy(node, "eid-address", s);
+        vec_free(s);
+        break;
+      default:
+        errmsg ("unknown EID type %d!", mp->eid_type);
+        return;
+      }
     vat_json_object_add_uint(node, "vni", clib_net_to_host_u32 (mp->vni));
-    vat_json_object_add_uint(node, "eid prefix len", mp->eid_prefix_len);
+    vat_json_object_add_uint(node, "eid-prefix-len", mp->eid_prefix_len);
 }
 
 static u8 *
@@ -10086,8 +10108,10 @@ api_lisp_add_del_local_eid(vat_main_t * vam)
     u8 is_add = 1;
     u8 eidv4_set = 0;
     u8 eidv6_set = 0;
+    u8 eid_type = (u8)~0;
     ip4_address_t eidv4;
     ip6_address_t eidv6;
+    u8 mac[6] = {0};
     u8 tmp_eid_lenght = ~0;
     u8 eid_lenght = ~0;
     u8 *locator_set_name = NULL;
@@ -10104,10 +10128,14 @@ api_lisp_add_del_local_eid(vat_main_t * vam)
             &eidv4, &tmp_eid_lenght)) {
             eid_lenght = tmp_eid_lenght;
             eidv4_set = 1;
+            eid_type = 0; /* ipv4 type */
         } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
             &eidv6, &tmp_eid_lenght)) {
             eid_lenght = tmp_eid_lenght;
             eidv6_set = 1;
+            eid_type = 1; /* ipv6 type */
+        } else if (unformat(input, "eid %U", unformat_ethernet_address, mac)) {
+            eid_type = 2; /* mac type */
         } else if (unformat(input, "locator-set %s", &locator_set_name)) {
             locator_set_name_set = 1;
         } else
@@ -10119,6 +10147,12 @@ api_lisp_add_del_local_eid(vat_main_t * vam)
         return -99;
     }
 
+    if ((u8)~0 == eid_type) {
+        errmsg ("EID address not set!");
+        vec_free(locator_set_name);
+        return -99;
+    }
+
     if (vec_len(locator_set_name) > 64) {
         errmsg ("locator-set name too long\n");
         vec_free(locator_set_name);
@@ -10132,12 +10166,6 @@ api_lisp_add_del_local_eid(vat_main_t * vam)
         return -99;
     }
 
-    if (!eidv4_set && !eidv6_set) {
-        errmsg ("eid addresses not set\n");
-        vec_free(locator_set_name);
-        return -99;
-    }
-
     if (eidv4_set && eid_lenght > 32) {
         errmsg ("eid prefix to big\n");
         vec_free(locator_set_name);
@@ -10154,13 +10182,18 @@ api_lisp_add_del_local_eid(vat_main_t * vam)
     M(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
 
     mp->is_add = is_add;
-    if (eidv6_set) {
-        mp->is_ipv6 = 1;
-        clib_memcpy(mp->ip_address, &eidv6, sizeof(eidv6));
-    } else {
-        mp->is_ipv6 = 0;
-        clib_memcpy(mp->ip_address, &eidv4, sizeof(eidv4));
+    switch (eid_type) {
+    case 0: /* ipv4 */
+      clib_memcpy (mp->eid, &eidv4, sizeof(eidv4));
+      break;
+    case 1: /* ipv6 */
+      clib_memcpy (mp->eid, &eidv6, sizeof(eidv6));
+      break;
+    case 2: /* mac */
+      clib_memcpy (mp->eid, mac, 6);
+      break;
     }
+    mp->eid_type = eid_type;
     mp->prefix_len = eid_lenght;
     mp->vni = clib_host_to_net_u32(vni);
     clib_memcpy(mp->locator_set_name, locator_set_name,
@@ -10545,15 +10578,18 @@ api_lisp_add_del_remote_mapping (vat_main_t * vam)
     vl_api_lisp_add_del_remote_mapping_t *mp;
     f64 timeout = ~0;
     u32 vni = 0;
-    u8 seid_set = 0, deid_set = 0;
     ip4_address_t seid4, deid4, rloc4;
     ip6_address_t seid6, deid6, rloc6;
+    u8 deid_mac[6] = {0};
+    u8 seid_mac[6] = {0};
+    u8 deid_type, seid_type;
     u32 seid_len = 0, deid_len = 0, len;
-    u8 deid_is_ip4 = 0, seid_is_ip4 = 0;
     u8 is_add = 1, del_all = 0;
     u32 action = ~0;
     rloc_t * rlocs = 0, rloc;
 
+    seid_type = deid_type =  (u8)~0;
+
     /* Parse args required to build the message */
     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
         if (unformat(input, "del-all")) {
@@ -10564,24 +10600,26 @@ api_lisp_add_del_remote_mapping (vat_main_t * vam)
             is_add = 1;
         } else if (unformat(input, "deid %U/%d", unformat_ip4_address,
                             &deid4, &len)) {
-            deid_set = 1;
-            deid_is_ip4 = 1;
+            deid_type = 0; /* ipv4 */
             deid_len = len;
         } else if (unformat(input, "deid %U/%d", unformat_ip6_address,
                             &deid6, &len)) {
-            deid_set = 1;
-            deid_is_ip4 = 0;
+            deid_type = 1; /* ipv6 */
             deid_len = len;
+        } else if (unformat(input, "deid %U", unformat_ethernet_address,
+                            deid_mac)) {
+            deid_type = 2; /* mac */
         } else if (unformat(input, "seid %U/%d", unformat_ip4_address,
                             &seid4, &len)) {
-            seid_set = 1;
-            seid_is_ip4 = 1;
+            seid_type = 0; /* ipv4 */
             seid_len = len;
         } else if (unformat(input, "seid %U/%d", unformat_ip6_address,
                             &seid6, &len)) {
-            seid_set = 1;
-            seid_is_ip4 = 0;
+            seid_type = 1; /* ipv6 */
             seid_len = len;
+        } else if (unformat(input, "seid %U", unformat_ethernet_address,
+                            seid_mac)) {
+            seid_type = 2; /* mac */
         } else if (unformat(input, "vni %d", &vni)) {
             ;
         } else if (unformat(input, "rloc %U", unformat_ip4_address, &rloc4)) {
@@ -10600,13 +10638,13 @@ api_lisp_add_del_remote_mapping (vat_main_t * vam)
         }
     }
 
-    if (!seid_set || !deid_set) {
+    if ((u8)~0 == deid_type) {
         errmsg ("missing params!");
         return -99;
     }
 
-    if (seid_is_ip4 != deid_is_ip4) {
-        errmsg ("source and destination EIDs are not in " "same IP family!");
+    if (seid_type != deid_type) {
+        errmsg ("source and destination EIDs are of different types!");
         return -99;
     }
 
@@ -10623,20 +10661,24 @@ api_lisp_add_del_remote_mapping (vat_main_t * vam)
     mp->action = (u8) action;
     mp->deid_len = deid_len;
     mp->del_all = del_all;
-    if (seid_is_ip4) {
-        mp->eid_is_ip4 = 1;
-        clib_memcpy (mp->seid, &seid4, sizeof (seid4));
-    } else {
-        mp->eid_is_ip4 = 0;
-        clib_memcpy (mp->seid, &seid6, sizeof (seid6));
-    }
+    mp->eid_type = deid_type;
 
-    if (deid_is_ip4) {
-        mp->eid_is_ip4 = 1;
+    switch (mp->eid_type) {
+    case 0:
+        clib_memcpy (mp->seid, &seid4, sizeof (seid4));
         clib_memcpy (mp->deid, &deid4, sizeof (deid4));
-    } else {
-        mp->eid_is_ip4 = 0;
+        break;
+    case 1:
+        clib_memcpy (mp->seid, &seid6, sizeof (seid6));
         clib_memcpy (mp->deid, &deid6, sizeof (deid6));
+        break;
+    case 2:
+        clib_memcpy (mp->seid, seid_mac, 6);
+        clib_memcpy (mp->deid, deid_mac, 6);
+        break;
+    default:
+        errmsg ("unknown EID type %d!", mp->eid_type);
+        return 0;
     }
 
     mp->rloc_num = vec_len (rlocs);
index 2ea92df..fbe33fe 100644 (file)
@@ -4781,26 +4781,41 @@ vl_api_lisp_add_del_local_eid_t_handler(
     ip_prefix_t  *prefp = NULL;
     ip_address_t *ip_eid = NULL;
     gid_address_t eid;
+    u8 * mac = gid_address_mac (&eid);
     uword * p = NULL;
     u32 locator_set_index = ~0, map_index = ~0;
     vnet_lisp_add_del_mapping_args_t _a, *a = &_a;
     u8 *name = NULL;
     memset (a, 0, sizeof (a[0]));
+    memset (&eid, 0, sizeof (eid));
 
     prefp = &gid_address_ippref(&eid);
     ip_eid = &ip_prefix_addr(prefp);
-    gid_address_type (&eid) = GID_ADDR_IP_PREFIX;
 
-    if (mp->is_ipv6) {
-        clib_memcpy(&ip_addr_v6(ip_eid), mp->ip_address,
-               sizeof(ip_addr_v6(ip_eid)));
-        ip_addr_version(ip_eid) = IP6;
-    } else {
-        clib_memcpy(&ip_addr_v4(ip_eid), mp->ip_address,
+    switch (mp->eid_type)
+      {
+      case 0: /* ipv4*/
+        gid_address_type (&eid) = GID_ADDR_IP_PREFIX;
+        clib_memcpy(&ip_addr_v4(ip_eid), mp->eid,
                sizeof(ip_addr_v4(ip_eid)));
         ip_addr_version(ip_eid) = IP4;
-    }
-    ip_prefix_len(prefp) = mp->prefix_len;
+        ip_prefix_len(prefp) = mp->prefix_len;
+        break;
+      case 1: /* ipv6 */
+        gid_address_type (&eid) = GID_ADDR_IP_PREFIX;
+        clib_memcpy(&ip_addr_v6(ip_eid), mp->eid,
+               sizeof(ip_addr_v6(ip_eid)));
+        ip_addr_version(ip_eid) = IP6;
+        ip_prefix_len(prefp) = mp->prefix_len;
+        break;
+      case 2: /* l2 mac */
+        gid_address_type (&eid) = GID_ADDR_MAC;
+        clib_memcpy(mac, mp->eid, 6);
+        break;
+      default:
+        rv = VNET_API_ERROR_INVALID_EID_TYPE;
+        goto out;
+      }
 
     name = format(0, "%s", mp->locator_set_name);
     p = hash_get_mem(lcm->locator_set_index_by_name, name);
@@ -4813,7 +4828,7 @@ vl_api_lisp_add_del_local_eid_t_handler(
   /* XXX treat batch configuration */
     a->is_add = mp->is_add;
     gid_address_vni (&eid) = clib_net_to_host_u32 (mp->vni);
-    a->deid = eid;
+    gid_address_copy (&a->deid, &eid);
     a->locator_set_index = locator_set_index;
     a->local = 1;
     rv = vnet_lisp_add_del_local_mapping(a, &map_index);
@@ -5041,30 +5056,49 @@ vl_api_lisp_add_del_remote_mapping_t_handler (
     ip_prefix_t * seid_pref = &gid_address_ippref(seid);
     ip_prefix_t * deid_pref = &gid_address_ippref(deid);
 
-    gid_address_type(seid) = GID_ADDR_IP_PREFIX;
-    gid_address_type(deid) = GID_ADDR_IP_PREFIX;
+    memset (seid, 0, sizeof (seid[0]));
+    memset (deid, 0, sizeof (deid[0]));
     ip_address_t * seid_addr = &ip_prefix_addr(seid_pref);
     ip_address_t * deid_addr = &ip_prefix_addr(deid_pref);
     ip_prefix_len(seid_pref) = mp->seid_len;
     ip_prefix_len(deid_pref) = mp->deid_len;
+    u8 * seid_mac = gid_address_mac (seid);
+    u8 * deid_mac = gid_address_mac (deid);
     gid_address_vni (seid) = ntohl (mp->vni);
     gid_address_vni (deid) = ntohl (mp->vni);
 
-    if (mp->eid_is_ip4) {
+    switch (mp->eid_type)
+      {
+      case 0: /* ipv4 */
+        gid_address_type(seid) = GID_ADDR_IP_PREFIX;
+        gid_address_type(deid) = GID_ADDR_IP_PREFIX;
         ip_prefix_version(seid_pref) = IP4;
         ip_prefix_version(deid_pref) = IP4;
         clib_memcpy (&ip_addr_v4(seid_addr),
                      mp->seid, sizeof (ip_addr_v4(seid_addr)));
         clib_memcpy (&ip_addr_v4(deid_addr),
                      mp->deid, sizeof (ip_addr_v4(deid_addr)));
-    } else {
+        break;
+      case 1: /* ipv6 */
+        gid_address_type(seid) = GID_ADDR_IP_PREFIX;
+        gid_address_type(deid) = GID_ADDR_IP_PREFIX;
         ip_prefix_version(seid_pref) = IP6;
         ip_prefix_version(deid_pref) = IP6;
         clib_memcpy (&ip_addr_v6(seid_addr),
                      mp->seid, sizeof (ip_addr_v6(seid_addr)));
         clib_memcpy (&ip_addr_v6(deid_addr),
                      mp->deid, sizeof (ip_addr_v6(deid_addr)));
-    }
+        break;
+      case 2: /* l2 mac */
+        gid_address_type(seid) = GID_ADDR_MAC;
+        gid_address_type(deid) = GID_ADDR_MAC;
+        clib_memcpy (seid_mac, mp->seid, 6);
+        clib_memcpy (deid_mac, mp->deid, 6);
+        break;
+      default:
+        rv = VNET_API_ERROR_INVALID_EID_TYPE;
+        goto send_reply;
+      }
 
     for (i = 0; i < mp->rloc_num; i++) {
         rloc_t * r = &((rloc_t *) mp->rlocs)[i];
@@ -5081,6 +5115,7 @@ vl_api_lisp_add_del_remote_mapping_t_handler (
     rv = vnet_lisp_add_del_remote_mapping (deid, seid, rlocs, mp->action,
                                            mp->is_add, mp->del_all);
     vec_free (rlocs);
+send_reply:
     REPLY_MACRO(VL_API_LISP_GPE_ADD_DEL_IFACE_REPLY);
 }
 
@@ -5152,21 +5187,15 @@ send_lisp_local_eid_table_details (mapping_t *mapit,
     lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
     locator_set_t *ls = NULL;
     gid_address_t *gid = NULL;
+    u8 * mac = 0;
     ip_prefix_t *ip_prefix = NULL;
     u8 * str = NULL;
-    u8 type = ~0;
 
     ls = pool_elt_at_index (lcm->locator_set_pool,
                             mapit->locator_set_index);
-
     gid = &mapit->eid;
-    type = gid_address_type(gid);
-
-    if (type != GID_ADDR_IP_PREFIX) {
-        return;
-    }
-
     ip_prefix = &gid_address_ippref(gid);
+    mac = gid_address_mac(gid);
 
     rmp = vl_msg_api_alloc (sizeof (*rmp));
     memset (rmp, 0, sizeof (*rmp));
@@ -5182,23 +5211,30 @@ send_lisp_local_eid_table_details (mapping_t *mapit,
             vec_free(str);
     }
 
-    switch (ip_prefix_version(ip_prefix)) {
-        case IP4:
-            rmp->eid_is_ipv6 = 0;
-            clib_memcpy(rmp->eid_ip_address, &ip_prefix_v4(ip_prefix),
+    switch (gid_address_type (gid))
+      {
+      case GID_ADDR_IP_PREFIX:
+        rmp->eid_prefix_len = ip_prefix_len(ip_prefix);
+        if (ip_prefix_version(ip_prefix) == IP4)
+          {
+            rmp->eid_type = 0; /* ipv4 type */
+            clib_memcpy(rmp->eid, &ip_prefix_v4(ip_prefix),
                    sizeof(ip_prefix_v4(ip_prefix)));
-            break;
-
-        case IP6:
-            rmp->eid_is_ipv6 = 1;
-            clib_memcpy(rmp->eid_ip_address, &ip_prefix_v6(ip_prefix),
+          }
+        else
+          {
+            rmp->eid_type = 1; /* ipv6 type */
+            clib_memcpy(rmp->eid, &ip_prefix_v6(ip_prefix),
                    sizeof(ip_prefix_v6(ip_prefix)));
-            break;
-
-        default:
-            ASSERT(0);
-    }
-    rmp->eid_prefix_len = ip_prefix_len(ip_prefix);
+          }
+        break;
+      case GID_ADDR_MAC:
+        rmp->eid_type = 2; /* l2 mac type */
+        clib_memcpy(rmp->eid, mac, 6);
+        break;
+      default:
+        ASSERT(0);
+      }
     rmp->context = context;
     rmp->vni = clib_host_to_net_u32 (gid_address_vni (gid));
     vl_msg_api_send_shmem (q, (u8 *)&rmp);
index 0184a3e..033ba24 100644 (file)
@@ -2201,18 +2201,21 @@ define lisp_add_del_locator_reply {
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
     @param is_add - add address if non-zero, else delete
-    @param is_ipv6 - if non-zero the address is ipv6, else ipv4
-    @param ip_address - array of address bytes
+    @param eid_type:
+      0 : ipv4
+      1 : ipv6
+      2 : mac
+    @param eid - EID can be ip4, ip6 or mac
     @param prefix_len - prefix len
     @param locator_set_name - name of locator_set to add/del eid-table
-    @param vni - vitual network instance
+    @param vni - virtual network instance
 */
 define lisp_add_del_local_eid {
     u32 client_index;
     u32 context;
     u8  is_add;
-    u8  is_ipv6;
-    u8  ip_address[16];
+    u8  eid_type;
+    u8  eid[16];
     u8  prefix_len;
     u8  locator_set_name[64];
     u32 vni;
@@ -2374,7 +2377,10 @@ define lisp_pitr_set_locator_set_reply {
     @param del_all - if set, delete all remote mappings
     @param vni - virtual network instance
     @param action - negative map-reply action
-    @param eid_is_ip4 - ipv4/6 of source and destination EIDs
+    @param eid_type -
+      0 : ipv4
+      1 : ipv6
+      2 : mac
     @param deid - destination EID
     @param seid - source EID
     @param rloc_num - number of remote locators
@@ -2387,7 +2393,7 @@ define lisp_add_del_remote_mapping {
     u8 del_all;
     u32 vni;
     u8 action;
-    u8 eid_is_ip4;
+    u8 eid_type;
     u8 deid[16];
     u8 seid[16];
     u8 deid_len;
@@ -2482,16 +2488,16 @@ define lisp_locator_set_dump {
 
 /** \brief LISP local eid table status
     @param locator_set_name - name of the locator_set
-    @param eid_is_ipv6 - if non-zero the address is ipv6, else ipv4
-    @param eid_ip_address - array of address bytes
+    @param eid_type - ip4, ip6 or l2 mac address
+    @param eid - array of address bytes
     @param eid_prefix_len - prefix len
  */
 manual_java define lisp_local_eid_table_details {
     u32 context;
     u8  locator_set_name[64];
-    u8  eid_is_ipv6;
+    u8  eid_type;
     u32 vni;
-    u8  eid_ip_address[16];
+    u8  eid[16];
     u8  eid_prefix_len;
 };