From: Hongjun Ni Date: Thu, 22 Jun 2017 16:18:40 +0000 (+0800) Subject: VPP crash on creating vxlan gpe interface. VPP-875 X-Git-Tag: v17.10-rc1~395 X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commitdiff_plain;h=04ffd0ad83b2d87edb669a9d76eee85f5c589564 VPP crash on creating vxlan gpe interface. VPP-875 Change-Id: I6b19634ecb03860a7624d9408e09b52e95f47aef Signed-off-by: Hongjun Ni --- diff --git a/src/vat/api_format.c b/src/vat/api_format.c index 0a38353c07a..937d7c5da08 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -1795,6 +1795,40 @@ static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json vam->result_ready = 1; } +static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler + (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp) +{ + vat_main_t *vam = &vat_main; + i32 retval = ntohl (mp->retval); + if (vam->async_mode) + { + vam->async_errors += (retval < 0); + } + else + { + vam->retval = retval; + vam->sw_if_index = ntohl (mp->sw_if_index); + vam->result_ready = 1; + } +} + +static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json + (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp) +{ + vat_main_t *vam = &vat_main; + vat_json_node_t node; + + vat_json_init_object (&node); + vat_json_object_add_int (&node, "retval", ntohl (mp->retval)); + vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index)); + + vat_json_print (vam->ofp, &node); + vat_json_free (&node); + + vam->retval = ntohl (mp->retval); + vam->result_ready = 1; +} + static void vl_api_gre_add_del_tunnel_reply_t_handler (vl_api_gre_add_del_tunnel_reply_t * mp) { @@ -4480,6 +4514,7 @@ _(sw_interface_set_table_reply) \ _(sw_interface_set_mpls_enable_reply) \ _(sw_interface_set_vpath_reply) \ _(sw_interface_set_vxlan_bypass_reply) \ +_(sw_interface_set_vxlan_gpe_bypass_reply) \ _(sw_interface_set_l2_bridge_reply) \ _(bridge_domain_add_del_reply) \ _(sw_interface_set_l2_xconnect_reply) \ @@ -4578,7 +4613,6 @@ _(gpe_enable_disable_reply) \ _(gpe_set_encap_mode_reply) \ _(gpe_add_del_iface_reply) \ _(gpe_add_del_native_fwd_rpath_reply) \ -_(vxlan_gpe_add_del_tunnel_reply) \ _(af_packet_delete_reply) \ _(policer_classify_set_interface_reply) \ _(netmap_create_reply) \ @@ -4651,6 +4685,7 @@ _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \ _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \ _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \ _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \ +_(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \ _(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \ sw_interface_set_l2_xconnect_reply) \ _(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \ @@ -6039,6 +6074,7 @@ api_sw_interface_set_vxlan_bypass (vat_main_t * vam) return ret; } + static int api_sw_interface_set_l2_xconnect (vat_main_t * vam) { @@ -12002,6 +12038,8 @@ api_vxlan_gpe_add_del_tunnel (vat_main_t * vam) u8 ipv4_set = 0, ipv6_set = 0; u8 local_set = 0; u8 remote_set = 0; + u8 grp_set = 0; + u32 mcast_sw_if_index = ~0; u32 encap_vrf_id = 0; u32 decap_vrf_id = 0; u8 protocol = ~0; @@ -12009,6 +12047,12 @@ api_vxlan_gpe_add_del_tunnel (vat_main_t * vam) u8 vni_set = 0; int ret; + /* Can't "universally zero init" (={0}) due to GCC bug 53119 */ + memset (&local4, 0, sizeof local4); + memset (&remote4, 0, sizeof remote4); + memset (&local6, 0, sizeof local6); + memset (&remote6, 0, sizeof remote6); + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { if (unformat (line_input, "del")) @@ -12037,6 +12081,35 @@ api_vxlan_gpe_add_del_tunnel (vat_main_t * vam) remote_set = 1; ipv6_set = 1; } + else if (unformat (line_input, "group %U %U", + unformat_ip4_address, &remote4, + api_unformat_sw_if_index, vam, &mcast_sw_if_index)) + { + grp_set = remote_set = 1; + ipv4_set = 1; + } + else if (unformat (line_input, "group %U", + unformat_ip4_address, &remote4)) + { + grp_set = remote_set = 1; + ipv4_set = 1; + } + else if (unformat (line_input, "group %U %U", + unformat_ip6_address, &remote6, + api_unformat_sw_if_index, vam, &mcast_sw_if_index)) + { + grp_set = remote_set = 1; + ipv6_set = 1; + } + else if (unformat (line_input, "group %U", + unformat_ip6_address, &remote6)) + { + grp_set = remote_set = 1; + ipv6_set = 1; + } + else + if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index)) + ; else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id)) ; else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id)) @@ -12068,6 +12141,11 @@ api_vxlan_gpe_add_del_tunnel (vat_main_t * vam) errmsg ("tunnel remote address not specified"); return -99; } + if (grp_set && mcast_sw_if_index == ~0) + { + errmsg ("tunnel nonexistent multicast device"); + return -99; + } if (ipv4_set && ipv6_set) { errmsg ("both IPv4 and IPv6 addresses specified"); @@ -12094,6 +12172,7 @@ api_vxlan_gpe_add_del_tunnel (vat_main_t * vam) clib_memcpy (&mp->remote, &remote4, sizeof (remote4)); } + mp->mcast_sw_if_index = ntohl (mcast_sw_if_index); mp->encap_vrf_id = ntohl (encap_vrf_id); mp->decap_vrf_id = ntohl (decap_vrf_id); mp->protocol = protocol; @@ -12110,16 +12189,19 @@ static void vl_api_vxlan_gpe_tunnel_details_t_handler (vl_api_vxlan_gpe_tunnel_details_t * mp) { vat_main_t *vam = &vat_main; + ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local); + ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote); - print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d", + print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d", ntohl (mp->sw_if_index), - format_ip46_address, &(mp->local[0]), - format_ip46_address, &(mp->remote[0]), - ntohl (mp->vni), - ntohl (mp->protocol), + format_ip46_address, &local, IP46_TYPE_ANY, + format_ip46_address, &remote, IP46_TYPE_ANY, + ntohl (mp->vni), mp->protocol, + ntohl (mp->mcast_sw_if_index), ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id)); } + static void vl_api_vxlan_gpe_tunnel_details_t_handler_json (vl_api_vxlan_gpe_tunnel_details_t * mp) { @@ -12153,6 +12235,8 @@ static void vl_api_vxlan_gpe_tunnel_details_t_handler_json } vat_json_object_add_uint (node, "vni", ntohl (mp->vni)); vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol)); + vat_json_object_add_uint (node, "mcast_sw_if_index", + ntohl (mp->mcast_sw_if_index)); vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id)); vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id)); vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0); @@ -12184,9 +12268,9 @@ api_vxlan_gpe_tunnel_dump (vat_main_t * vam) if (!vam->json_output) { - print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s", + print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s", "sw_if_index", "local", "remote", "vni", - "protocol", "encap_vrf_id", "decap_vrf_id"); + "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id"); } /* Get list of vxlan-tunnel interfaces */ @@ -12204,6 +12288,7 @@ api_vxlan_gpe_tunnel_dump (vat_main_t * vam) return ret; } + u8 * format_l2_fib_mac_address (u8 * s, va_list * args) { @@ -19673,9 +19758,10 @@ _(delete_vhost_user_if, " | sw_if_index ") \ _(sw_interface_vhost_user_dump, "") \ _(show_version, "") \ _(vxlan_gpe_add_del_tunnel, \ - "local remote vni \n" \ - "[encap-vrf-id ] [decap-vrf-id ] [next-ip4][next-ip6]" \ - "[next-ethernet] [next-nsh]\n") \ + "local remote | group \n" \ + "{ | mcast_sw_if_index } }\n" \ + "vni [encap-vrf-id ] [decap-vrf-id ]\n" \ + "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n") \ _(vxlan_gpe_tunnel_dump, "[ | sw_if_index ]") \ _(l2_fib_table_dump, "bd_id ") \ _(interface_name_renumber, \ diff --git a/src/vnet/vxlan-gpe/vxlan_gpe.api b/src/vnet/vxlan-gpe/vxlan_gpe.api index 41b10316451..04082d69c65 100644 --- a/src/vnet/vxlan-gpe/vxlan_gpe.api +++ b/src/vnet/vxlan-gpe/vxlan_gpe.api @@ -53,7 +53,6 @@ define vxlan_gpe_tunnel_details u32 mcast_sw_if_index; u32 encap_vrf_id; u32 decap_vrf_id; - u8 is_ipv6; }; diff --git a/src/vnet/vxlan-gpe/vxlan_gpe.c b/src/vnet/vxlan-gpe/vxlan_gpe.c index 3a92c88fbb6..fab887addff 100644 --- a/src/vnet/vxlan-gpe/vxlan_gpe.c +++ b/src/vnet/vxlan-gpe/vxlan_gpe.c @@ -83,6 +83,9 @@ u8 * format_vxlan_gpe_tunnel (u8 * s, va_list * args) s = format (s, "next-protocol unknown %d", t->protocol); } + if (ip46_address_is_multicast (&t->remote)) + s = format (s, "mcast_sw_if_index %d ", t->mcast_sw_if_index); + s = format (s, " fibs: (encap %d, decap %d)", t->encap_fib_index, t->decap_fib_index); diff --git a/src/vnet/vxlan-gpe/vxlan_gpe_api.c b/src/vnet/vxlan-gpe/vxlan_gpe_api.c index 3675fc55cd8..8e2684187a7 100644 --- a/src/vnet/vxlan-gpe/vxlan_gpe_api.c +++ b/src/vnet/vxlan-gpe/vxlan_gpe_api.c @@ -47,7 +47,7 @@ #define foreach_vpe_api_msg \ _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS, sw_interface_set_vxlan_gpe_bypass) \ _(VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel) \ -_(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump) \ +_(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump) static void vl_api_sw_interface_set_vxlan_gpe_bypass_t_handler @@ -156,15 +156,15 @@ static void send_vxlan_gpe_tunnel_details rmp->_vl_msg_id = ntohs (VL_API_VXLAN_GPE_TUNNEL_DETAILS); if (is_ipv6) { - memcpy (rmp->local, &(t->local.ip6), 16); - memcpy (rmp->remote, &(t->remote.ip6), 16); + memcpy (rmp->local, &(t->local.ip6.as_u8), 16); + memcpy (rmp->remote, &(t->remote.ip6.as_u8), 16); rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].ft_table_id); rmp->decap_vrf_id = htonl (im6->fibs[t->decap_fib_index].ft_table_id); } else { - memcpy (rmp->local, &(t->local.ip4), 4); - memcpy (rmp->remote, &(t->remote.ip4), 4); + memcpy (rmp->local, &(t->local.ip4.as_u8), 4); + memcpy (rmp->remote, &(t->remote.ip4.as_u8), 4); rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].ft_table_id); rmp->decap_vrf_id = htonl (im4->fibs[t->decap_fib_index].ft_table_id); } @@ -250,6 +250,9 @@ vxlan_gpe_api_hookup (vlib_main_t * vm) foreach_vpe_api_msg; #undef _ + am->api_trace_cfg[VL_API_VXLAN_GPE_ADD_DEL_TUNNEL].size += + 17 * sizeof (u32); + /* * Set up the (msg_name, crc, message-id) table */ diff --git a/src/vpp/api/custom_dump.c b/src/vpp/api/custom_dump.c index dc9fee9a142..3ac8874e852 100644 --- a/src/vpp/api/custom_dump.c +++ b/src/vpp/api/custom_dump.c @@ -1703,10 +1703,18 @@ static void *vl_api_vxlan_gpe_add_del_tunnel_t_print s = format (0, "SCRIPT: vxlan_gpe_add_del_tunnel "); - s = format (s, "local %U ", format_ip46_address, &mp->local, mp->is_ipv6); + ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local); + ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote); - s = format (s, "remote %U ", format_ip46_address, &mp->remote, mp->is_ipv6); + u8 is_grp = ip46_address_is_multicast (&remote); + char *remote_name = is_grp ? "group" : "remote"; + s = format (s, "local %U ", format_ip46_address, &local, IP46_TYPE_ANY); + s = format (s, "%s %U ", remote_name, format_ip46_address, + &remote, IP46_TYPE_ANY); + + if (is_grp) + s = format (s, "mcast_sw_if_index %d ", ntohl (mp->mcast_sw_if_index)); s = format (s, "protocol %d ", ntohl (mp->protocol)); s = format (s, "vni %d ", ntohl (mp->vni));