From 006eb2689b901b4700f4360cc0417c6c0d93cc46 Mon Sep 17 00:00:00 2001 From: Filip Tehlar Date: Mon, 27 Jun 2016 13:09:20 +0200 Subject: [PATCH] Add support for ethernet address in LISP API Change-Id: I9f1522f55bdd11602784a421fd850b839a1070e6 Signed-off-by: Filip Tehlar --- vnet/vnet/api_errno.h | 3 +- vpp-api-test/vat/api_format.c | 138 +++++++++++++++++++++++++++--------------- vpp/vpp-api/api.c | 112 ++++++++++++++++++++++------------ vpp/vpp-api/vpe.api | 28 +++++---- 4 files changed, 183 insertions(+), 98 deletions(-) diff --git a/vnet/vnet/api_errno.h b/vnet/vnet/api_errno.h index bf49c0a27c7..f16d9781bdc 100644 --- a/vnet/vnet/api_errno.h +++ b/vnet/vnet/api_errno.h @@ -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), diff --git a/vpp-api-test/vat/api_format.c b/vpp-api-test/vat/api_format.c index b00dcccd31a..a4fbf0d08f6 100644 --- a/vpp-api-test/vat/api_format.c +++ b/vpp-api-test/vat/api_format.c @@ -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); diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c index 2ea92df019e..fbe33fe149f 100644 --- a/vpp/vpp-api/api.c +++ b/vpp/vpp-api/api.c @@ -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); diff --git a/vpp/vpp-api/vpe.api b/vpp/vpp-api/vpe.api index 0184a3e16bd..033ba24030b 100644 --- a/vpp/vpp-api/vpe.api +++ b/vpp/vpp-api/vpe.api @@ -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; }; -- 2.16.6