From 438109d576bd47a2095f2889b708306d37067d50 Mon Sep 17 00:00:00 2001 From: Andrej Kozemcak Date: Fri, 22 Jul 2016 12:54:12 +0200 Subject: [PATCH] LISP - Bug fix, can`t remove static remote mapping Fix bug, can`t remove static remote mapping, small update in LISP remote mapping API. Change-Id: Ide32485a1a0d2cf08829d544500fa2755214b8cc Signed-off-by: Andrej Kozemcak --- vnet/vnet/lisp-cp/control.c | 97 +++++++++++++++--------------------------- vnet/vnet/lisp-cp/lisp_types.c | 77 ++++++++++++++++++++++++++++++++- vnet/vnet/lisp-cp/lisp_types.h | 2 + vpp-api-test/vat/api_format.c | 72 +++++++++++++++---------------- vpp/vpp-api/api.c | 74 ++++++++++++++------------------ vpp/vpp-api/vpe.api | 9 ++-- 6 files changed, 183 insertions(+), 148 deletions(-) diff --git a/vnet/vnet/lisp-cp/control.c b/vnet/vnet/lisp-cp/control.c index fb4c8397d2d..f966b3645de 100644 --- a/vnet/vnet/lisp-cp/control.c +++ b/vnet/vnet/lisp-cp/control.c @@ -795,7 +795,8 @@ vnet_lisp_add_del_mapping (gid_address_t * eid, locator_t * rlocs, u8 action, vnet_lisp_add_del_locator_set (ls_args, 0); /* return old mapping index */ - res_map_index[0] = mi; + if (res_map_index) + res_map_index[0] = mi; } /* success */ @@ -924,11 +925,10 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm, unformat_input_t _line_input, * line_input = &_line_input; u8 is_add = 1, del_all = 0; locator_t rloc, * rlocs = 0, * curr_rloc = 0; - ip_prefix_t * deid_ippref, * seid_ippref; - gid_address_t seid, deid; - u8 * dmac = gid_address_mac (&deid); - u8 * smac = gid_address_mac (&seid); - u8 deid_set = 0, seid_set = 0; + ip_prefix_t * eid_ippref; + gid_address_t eid; + u8 * dmac = gid_address_mac (&eid); + u8 eid_set = 0; u8 * s = 0; u32 vni, action = ~0, p, w; int rv; @@ -937,12 +937,10 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm, if (! unformat_user (input, unformat_line_input, line_input)) return 0; - memset(&deid, 0, sizeof(deid)); - memset(&seid, 0, sizeof(seid)); + memset(&eid, 0, sizeof(eid)); memset(&rloc, 0, sizeof(rloc)); - seid_ippref = &gid_address_ippref(&seid); - deid_ippref = &gid_address_ippref(&deid); + eid_ippref = &gid_address_ippref(&eid); while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { @@ -952,34 +950,21 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm, is_add = 0; else if (unformat (line_input, "add")) ; - else if (unformat (line_input, "deid %U", - unformat_ip_prefix, deid_ippref)) + else if (unformat (line_input, "eid %U", + unformat_ip_prefix, eid_ippref)) { - gid_address_type (&deid) = GID_ADDR_IP_PREFIX; - deid_set = 1; + gid_address_type (&eid) = GID_ADDR_IP_PREFIX; + eid_set = 1; } - else if (unformat (line_input, "deid %U", + else if (unformat (line_input, "eid %U", unformat_mac_address, dmac)) { - gid_address_type (&deid) = GID_ADDR_MAC; - deid_set = 1; + gid_address_type (&eid) = GID_ADDR_MAC; + eid_set = 1; } else if (unformat (line_input, "vni %u", &vni)) { - gid_address_vni (&seid) = vni; - gid_address_vni (&deid) = vni; - } - else if (unformat (line_input, "seid %U", - unformat_ip_prefix, seid_ippref)) - { - gid_address_type (&seid) = GID_ADDR_IP_PREFIX; - seid_set = 1; - } - else if (unformat (line_input, "seid %U", - unformat_mac_address, smac)) - { - gid_address_type (&seid) = GID_ADDR_MAC; - seid_set = 1; + gid_address_vni (&eid) = vni; } else if (unformat (line_input, "p %d w %d", &p, &w)) { @@ -1020,31 +1005,15 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm, } } - if (!del_all) + if (!eid_set) { - if (!deid_set) - { - clib_warning ("missing deid!"); - goto done; - } + clib_warning ("missing eid!"); + goto done; + } - if (GID_ADDR_IP_PREFIX == gid_address_type (&deid)) - { - /* if seid not set, make sure the ip version is the same as that - * of the deid. This ensures the seid to be configured will be - * either 0/0 or ::/0 */ - if (!seid_set) - ip_prefix_version(seid_ippref) = ip_prefix_version(deid_ippref); + if (!del_all) + { - if (is_add && - (ip_prefix_version (deid_ippref) - != ip_prefix_version(seid_ippref))) - { - clib_warning ("source and destination EIDs are not" - " in the same IP family!"); - goto done; - } - } if (is_add && (~0 == action) && 0 == vec_len (rlocs)) @@ -1065,15 +1034,17 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm, if (!is_add) { lisp_cp_main_t * lcm = vnet_lisp_cp_get_main (); - rv = lisp_add_del_adjacency (lcm, 0, &deid, /* is_add */ 0); - } - else - { - /* add as static remote mapping, i.e., not authoritative and infinite - * ttl */ - rv = vnet_lisp_add_del_mapping (&deid, rlocs, action, 0, ~0, is_add, 0); + rv = lisp_add_del_adjacency (lcm, 0, &eid, /* is_add */ 0); + if (rv) + { + goto done; + } } + /* add as static remote mapping, i.e., not authoritative and infinite + * ttl */ + rv = vnet_lisp_add_del_mapping (&eid, rlocs, action, 0, ~0, is_add, 0); + if (rv) clib_warning("failed to %s remote mapping!", is_add ? "add" : "delete"); @@ -1087,8 +1058,8 @@ done: VLIB_CLI_COMMAND (lisp_add_del_remote_mapping_command) = { .path = "lisp remote-mapping", - .short_help = "lisp remote-mapping add|del [del-all] vni " - "deid seid [action [action ] rloc [rloc ... ]", .function = lisp_add_del_remote_mapping_command_fn, }; @@ -2441,6 +2412,7 @@ build_itr_rloc_list (lisp_cp_main_t * lcm, locator_set_t * loc_set) addr = ip_interface_address_get_address (&lcm->im4->lookup_main, ia); ip_address_set (rloc, addr, IP4); ip_prefix_len (ippref) = 32; + ip_prefix_normalize (ippref); vec_add1 (rlocs, gid[0]); })); @@ -2451,6 +2423,7 @@ build_itr_rloc_list (lisp_cp_main_t * lcm, locator_set_t * loc_set) addr = ip_interface_address_get_address (&lcm->im6->lookup_main, ia); ip_address_set (rloc, addr, IP6); ip_prefix_len (ippref) = 128; + ip_prefix_normalize (ippref); vec_add1 (rlocs, gid[0]); })); } diff --git a/vnet/vnet/lisp-cp/lisp_types.c b/vnet/vnet/lisp-cp/lisp_types.c index c1c959c55a1..b5c7c3e964a 100644 --- a/vnet/vnet/lisp-cp/lisp_types.c +++ b/vnet/vnet/lisp-cp/lisp_types.c @@ -146,8 +146,20 @@ uword unformat_ip_prefix (unformat_input_t * input, va_list * args) { ip_prefix_t * a = va_arg(*args, ip_prefix_t *); - return unformat (input, "%U/%d", unformat_ip_address, &ip_prefix_addr(a), - &ip_prefix_len(a)); + if (unformat (input, "%U/%d", unformat_ip_address, &ip_prefix_addr(a), + &ip_prefix_len(a))) + { + if ((ip_prefix_version(a) == IP4 && 32 < ip_prefix_len(a)) || + (ip_prefix_version(a) == IP6 && 128 < ip_prefix_length(a))) + { + clib_warning("Prefix length to big: %d!", ip_prefix_len(a)); + return 0; + } + ip_prefix_normalize(a); + } + else + return 0; + return 1; } uword @@ -511,6 +523,63 @@ ip_address_set(ip_address_t * dst, void * src, u8 version) ip_addr_version(dst) = version; } +void +ip_prefix_normalize(ip_prefix_t * a) +{ + ip_address_t * ip; + ip4_address_t * ip4; + ip6_address_t * ip6; + int preflen = ip_prefix_len(a); + u32 mask = ~0; + u64 mask_6[2]; + u32 * m; + u32 j, i0, i1; + + ip = &ip_prefix_addr (a); + switch (ip_addr_version (ip)) + { + case IP4: + if (32 <= preflen) + { + break; + } + + ip4 = &ip_addr_v4 (ip); + mask = pow2_mask (preflen) << (32 - preflen); + mask = clib_host_to_net_u32 (mask); + ip4->data_u32 &= mask; + break; + + case IP6: + if (128 <= preflen) + { + break; + } + ip6 = &ip_addr_v6 (ip); + memset(mask_6, 0, sizeof(mask_6)); + m = (u32 * ) mask_6; + + i0 = preflen / 32; + i1 = preflen % 32; + for (j = 0; j < i0; j++) + { + m[j] = ~0; + } + + if (i1) + { + m[i0] = clib_host_to_net_u32 (pow2_mask(i1) << (32 - i1)); + } + + ip6->as_u64[0] &= mask_6[0]; + ip6->as_u64[1] &= mask_6[1]; + break; + + default: + ASSERT(0); + } +} + void * ip_prefix_cast (gid_address_t * a) { @@ -564,6 +633,10 @@ int ip_prefix_cmp(ip_prefix_t * p1, ip_prefix_t * p2) { int cmp = 0; + + ip_prefix_normalize (p1); + ip_prefix_normalize (p2); + cmp = ip_address_cmp (&ip_prefix_addr(p1), &ip_prefix_addr(p2)); if (cmp == 0) { diff --git a/vnet/vnet/lisp-cp/lisp_types.h b/vnet/vnet/lisp-cp/lisp_types.h index ef86f71bdf3..e3a0eb799b5 100644 --- a/vnet/vnet/lisp-cp/lisp_types.h +++ b/vnet/vnet/lisp-cp/lisp_types.h @@ -57,6 +57,8 @@ typedef CLIB_PACKED(struct ip_prefix #define ip_prefix_v4(_a) ip_addr_v4(&ip_prefix_addr(_a)) #define ip_prefix_v6(_a) ip_addr_v6(&ip_prefix_addr(_a)) +void ip_prefix_normalize(ip_prefix_t * a); + typedef enum { /* NOTE: ip addresses are left out on purpose. Use max masked ip-prefixes diff --git a/vpp-api-test/vat/api_format.c b/vpp-api-test/vat/api_format.c index b9ee377e305..0b6cf7fd1b6 100644 --- a/vpp-api-test/vat/api_format.c +++ b/vpp-api-test/vat/api_format.c @@ -11280,17 +11280,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; - ip4_address_t seid4, deid4, rloc4; - ip6_address_t seid6, deid6, rloc6; - u8 deid_mac[6] = {0}; + //TODO: seid need remove + ip4_address_t seid4, eid4, rloc4; + ip6_address_t seid6, eid6, rloc6; + u8 eid_mac[6] = {0}; u8 seid_mac[6] = {0}; - u8 deid_type, seid_type; - u32 seid_len = 0, deid_len = 0, len; + u8 eid_type; + u32 eid_len = 0, len; u8 is_add = 1, del_all = 0; u32 action = ~0, p, w; rloc_t * rlocs = 0, rloc, * curr_rloc = 0; - seid_type = deid_type = (u8)~0; + eid_type = (u8)~0; /* Parse args required to build the message */ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { @@ -11301,27 +11302,33 @@ api_lisp_add_del_remote_mapping (vat_main_t * vam) } else if (unformat(input, "add")) { is_add = 1; } else if (unformat(input, "deid %U/%d", unformat_ip4_address, - &deid4, &len)) { - deid_type = 0; /* ipv4 */ - deid_len = len; + &eid4, &len)) { + eid_type = 0; /* ipv4 */ + if (32 < len) { + clib_warning ("Deid prefix length to big, %d!", len); + return -99; + } + eid_len = len; } else if (unformat(input, "deid %U/%d", unformat_ip6_address, - &deid6, &len)) { - deid_type = 1; /* ipv6 */ - deid_len = len; + &eid6, &len)) { + eid_type = 1; /* ipv6 */ + if (128 < len) { + clib_warning ("Deid prefix length to big, %d!", len); + return -99; + } + eid_len = len; } else if (unformat(input, "deid %U", unformat_ethernet_address, - deid_mac)) { - deid_type = 2; /* mac */ + eid_mac)) { + eid_type = 2; /* mac */ + //TODO: Need remove, but first must be remove from CSIT test } else if (unformat(input, "seid %U/%d", unformat_ip4_address, &seid4, &len)) { - seid_type = 0; /* ipv4 */ - seid_len = len; } else if (unformat(input, "seid %U/%d", unformat_ip6_address, &seid6, &len)) { - 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, "p %d w %d", &p, &w)) { @@ -11349,16 +11356,11 @@ api_lisp_add_del_remote_mapping (vat_main_t * vam) } } - if ((u8)~0 == deid_type) { + if ((u8)~0 == eid_type) { errmsg ("missing params!"); return -99; } - if (seid_type != deid_type) { - errmsg ("source and destination EIDs are of different types!"); - return -99; - } - if (is_add && (~0 == action) && 0 == vec_len (rlocs)) { errmsg ("no action set for negative map-reply!"); @@ -11368,24 +11370,20 @@ api_lisp_add_del_remote_mapping (vat_main_t * vam) M(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping); mp->is_add = is_add; mp->vni = htonl (vni); - mp->seid_len = seid_len; mp->action = (u8) action; - mp->deid_len = deid_len; + mp->eid_len = eid_len; mp->del_all = del_all; - mp->eid_type = deid_type; + mp->eid_type = eid_type; switch (mp->eid_type) { case 0: - clib_memcpy (mp->seid, &seid4, sizeof (seid4)); - clib_memcpy (mp->deid, &deid4, sizeof (deid4)); + clib_memcpy (mp->eid, &eid4, sizeof (eid4)); break; case 1: - clib_memcpy (mp->seid, &seid6, sizeof (seid6)); - clib_memcpy (mp->deid, &deid6, sizeof (deid6)); + clib_memcpy (mp->eid, &eid6, sizeof (eid6)); break; case 2: - clib_memcpy (mp->seid, seid_mac, 6); - clib_memcpy (mp->deid, deid_mac, 6); + clib_memcpy (mp->eid, eid_mac, 6); break; default: errmsg ("unknown EID type %d!", mp->eid_type); @@ -13591,10 +13589,10 @@ _(lisp_add_del_map_resolver, " [del]") \ _(lisp_gpe_enable_disable, "enable|disable") \ _(lisp_enable_disable, "enable|disable") \ _(lisp_gpe_add_del_iface, "up|down") \ -_(lisp_add_del_remote_mapping, "add|del vni deid seid" \ - " rloc p " \ +_(lisp_add_del_remote_mapping, "add|del vni deid " \ + "rloc p " \ "w [rloc ... ] " \ - "action ") \ + "action [del-all]") \ _(lisp_add_del_adjacency, "add|del vni deid seid " \ " rloc p w "\ "[rloc ... ] action ") \ diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c index 1f63065132f..c06045f702b 100644 --- a/vpp/vpp-api/api.c +++ b/vpp/vpp-api/api.c @@ -4902,11 +4902,13 @@ vl_api_lisp_add_del_local_eid_t_handler( gid_address_type (&eid) = GID_ADDR_IP_PREFIX; ip_address_set(ip_eid, mp->eid, IP4); ip_prefix_len(prefp) = mp->prefix_len; + ip_prefix_normalize(prefp); break; case 1: /* ipv6 */ gid_address_type (&eid) = GID_ADDR_IP_PREFIX; ip_address_set(ip_eid, mp->eid, IP6); ip_prefix_len(prefp) = mp->prefix_len; + ip_prefix_normalize(prefp); break; case 2: /* l2 mac */ gid_address_type (&eid) = GID_ADDR_MAC; @@ -4974,6 +4976,7 @@ lisp_gpe_add_del_fwd_entry_set_address( ip_addr_version(ip_eid) = IP4; } ip_prefix_len(prefp) = mp->eid_prefix_len; + ip_prefix_normalize(prefp); if (mp->address_is_ipv6) { clib_memcpy(&ip_addr_v6(slocator), mp->source_ip_address, @@ -5136,42 +5139,30 @@ vl_api_lisp_add_del_remote_mapping_t_handler ( locator_t rloc, * rlocs = 0; vl_api_lisp_add_del_remote_mapping_reply_t * rmp; int rv = 0; - gid_address_t _seid, * seid = &_seid; - gid_address_t _deid, * deid = &_deid; - ip_prefix_t * seid_pref = &gid_address_ippref(seid); - ip_prefix_t * deid_pref = &gid_address_ippref(deid); - - /* TODO remove seid from API */ - 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); + gid_address_t _eid, * eid = &_eid; + ip_prefix_t * eid_pref = &gid_address_ippref(eid); + + memset (eid, 0, sizeof (eid[0])); + ip_address_t * eid_addr = &ip_prefix_addr(eid_pref); + ip_prefix_len(eid_pref) = mp->eid_len; + u8 * eid_mac = gid_address_mac (eid); + gid_address_vni (eid) = ntohl (mp->vni); switch (mp->eid_type) { case 0: /* ipv4 */ - gid_address_type(seid) = GID_ADDR_IP_PREFIX; - gid_address_type(deid) = GID_ADDR_IP_PREFIX; - ip_address_set (seid_addr, mp->seid, IP4); - ip_address_set (deid_addr, mp->deid, IP4); + gid_address_type(eid) = GID_ADDR_IP_PREFIX; + ip_address_set (eid_addr, mp->eid, IP4); + ip_prefix_normalize (eid_pref); break; case 1: /* ipv6 */ - gid_address_type(seid) = GID_ADDR_IP_PREFIX; - gid_address_type(deid) = GID_ADDR_IP_PREFIX; - ip_address_set (seid_addr, mp->seid, IP6); - ip_address_set (deid_addr, mp->deid, IP6); + gid_address_type(eid) = GID_ADDR_IP_PREFIX; + ip_address_set (eid_addr, mp->eid, IP6); + ip_prefix_normalize (eid_pref); 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); + gid_address_type(eid) = GID_ADDR_MAC; + clib_memcpy (eid_mac, mp->eid, 6); break; default: rv = VNET_API_ERROR_INVALID_EID_TYPE; @@ -5192,26 +5183,23 @@ vl_api_lisp_add_del_remote_mapping_t_handler ( if (!mp->is_add) { vnet_lisp_add_del_adjacency_args_t _a, * a = &_a; - gid_address_copy(&a->deid, deid); + gid_address_copy(&a->deid, eid); a->is_add = 0; rv = vnet_lisp_add_del_adjacency (a); - } else { - /* NOTE: for now this works as a static remote mapping, i.e., - * not authoritative and ttl infinite. */ - rv = vnet_lisp_add_del_mapping (deid, rlocs, mp->action, 0, ~0, - mp->is_add, 0); - - /* TODO remove once CSIT switched to lisp_add_del_adjacency */ - vnet_lisp_add_del_adjacency_args_t _a, * a = &_a; - gid_address_copy(&a->seid, seid); - gid_address_copy(&a->deid, deid); - a->is_add = 1; - vnet_lisp_add_del_adjacency (a); + if (rv) { + goto out; + } } + /* NOTE: for now this works as a static remote mapping, i.e., + * not authoritative and ttl infinite. */ + rv = vnet_lisp_add_del_mapping (eid, rlocs, mp->action, 0, ~0, + mp->is_add, 0); + if (mp->del_all) vnet_lisp_clear_all_remote_adjacencies (); +out: vec_free (rlocs); send_reply: REPLY_MACRO(VL_API_LISP_ADD_DEL_REMOTE_MAPPING_REPLY); @@ -5246,12 +5234,16 @@ vl_api_lisp_add_del_adjacency_t_handler ( gid_address_type(&a->deid) = GID_ADDR_IP_PREFIX; ip_address_set (seid_addr, mp->seid, IP4); ip_address_set (deid_addr, mp->deid, IP4); + ip_prefix_normalize (seid_pref); + ip_prefix_normalize (deid_pref); break; case 1: /* ipv6 */ gid_address_type(&a->seid) = GID_ADDR_IP_PREFIX; gid_address_type(&a->deid) = GID_ADDR_IP_PREFIX; ip_address_set (seid_addr, mp->seid, IP6); ip_address_set (deid_addr, mp->deid, IP6); + ip_prefix_normalize (seid_pref); + ip_prefix_normalize (deid_pref); break; case 2: /* l2 mac */ gid_address_type(&a->seid) = GID_ADDR_MAC; diff --git a/vpp/vpp-api/vpe.api b/vpp/vpp-api/vpe.api index f8cf37016c3..1b329e97c45 100644 --- a/vpp/vpp-api/vpe.api +++ b/vpp/vpp-api/vpe.api @@ -2412,8 +2412,7 @@ define lisp_pitr_set_locator_set_reply { 0 : ipv4 1 : ipv6 2 : mac - @param deid - destination EID - @param seid - source EID + @param eid - EID @param rloc_num - number of remote locators @param rlocs - remote locator data */ @@ -2425,10 +2424,8 @@ define lisp_add_del_remote_mapping { u32 vni; u8 action; u8 eid_type; - u8 deid[16]; - u8 seid[16]; - u8 deid_len; - u8 seid_len; + u8 eid[16]; + u8 eid_len; u32 rloc_num; u8 rlocs[0]; }; -- 2.16.6