From 6899a30bd70f219cfd182dfb0e9ac96faf5d9892 Mon Sep 17 00:00:00 2001 From: Pavel Kotucek Date: Thu, 8 Jun 2017 08:46:10 +0200 Subject: P2P Ethernet - API API for P2P Ethernet feature Change-Id: Id0280f42b9ce2428262e79c4dc309595037cd10e Signed-off-by: Pavel Kotucek --- src/vat/api_format.c | 107 ++++++++++++++++++++++++++++- src/vnet.am | 10 ++- src/vnet/ethernet/p2p_ethernet.api | 49 ++++++++++++++ src/vnet/ethernet/p2p_ethernet.c | 102 ++++++++++++++++++++++++++++ src/vnet/ethernet/p2p_ethernet.h | 23 +++++++ src/vnet/ethernet/p2p_ethernet_api.c | 128 +++++++++++++++++++++++++++++++++++ src/vnet/vnet_all_api_h.h | 1 + src/vpp/api/custom_dump.c | 28 +++++++- 8 files changed, 442 insertions(+), 6 deletions(-) create mode 100644 src/vnet/ethernet/p2p_ethernet.api create mode 100644 src/vnet/ethernet/p2p_ethernet.c create mode 100644 src/vnet/ethernet/p2p_ethernet.h create mode 100644 src/vnet/ethernet/p2p_ethernet_api.c (limited to 'src') diff --git a/src/vat/api_format.c b/src/vat/api_format.c index 79be42c8ba7..f33b4592f67 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -4445,7 +4445,9 @@ _(l2_interface_pbb_tag_rewrite_reply) \ _(punt_reply) \ _(feature_enable_disable_reply) \ _(sw_interface_tag_add_del_reply) \ -_(sw_interface_set_mtu_reply) +_(sw_interface_set_mtu_reply) \ +_(p2p_ethernet_add_reply) \ +_(p2p_ethernet_del_reply) #define _(n) \ static void vl_api_##n##_t_handler \ @@ -4720,7 +4722,9 @@ _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply) \ _(L2_XCONNECT_DETAILS, l2_xconnect_details) \ _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply) \ _(IP_NEIGHBOR_DETAILS, ip_neighbor_details) \ -_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply) +_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply) \ +_(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply) \ +_(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply) #define foreach_standalone_reply_msg \ _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \ @@ -18689,6 +18693,101 @@ api_sw_interface_set_mtu (vat_main_t * vam) return ret; } +static int +api_p2p_ethernet_add (vat_main_t * vam) +{ + unformat_input_t *i = vam->input; + vl_api_p2p_ethernet_add_t *mp; + u32 parent_if_index = ~0; + u8 remote_mac[6]; + u8 mac_set = 0; + int ret; + + memset (remote_mac, 0, sizeof (remote_mac)); + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index)) + ; + else if (unformat (i, "sw_if_index %d", &parent_if_index)) + ; + else + if (unformat + (i, "remote_mac %U", unformat_ethernet_address, remote_mac)) + mac_set++; + else + { + clib_warning ("parse error '%U'", format_unformat_error, i); + return -99; + } + } + + if (parent_if_index == ~0) + { + errmsg ("missing interface name or sw_if_index"); + return -99; + } + if (mac_set == 0) + { + errmsg ("missing remote mac address"); + return -99; + } + + M (P2P_ETHERNET_ADD, mp); + mp->parent_if_index = ntohl (parent_if_index); + clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac)); + + S (mp); + W (ret); + return ret; +} + +static int +api_p2p_ethernet_del (vat_main_t * vam) +{ + unformat_input_t *i = vam->input; + vl_api_p2p_ethernet_del_t *mp; + u32 parent_if_index = ~0; + u8 remote_mac[6]; + u8 mac_set = 0; + int ret; + + memset (remote_mac, 0, sizeof (remote_mac)); + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index)) + ; + else if (unformat (i, "sw_if_index %d", &parent_if_index)) + ; + else + if (unformat + (i, "remote_mac %U", unformat_ethernet_address, remote_mac)) + mac_set++; + else + { + clib_warning ("parse error '%U'", format_unformat_error, i); + return -99; + } + } + + if (parent_if_index == ~0) + { + errmsg ("missing interface name or sw_if_index"); + return -99; + } + if (mac_set == 0) + { + errmsg ("missing remote mac address"); + return -99; + } + + M (P2P_ETHERNET_DEL, mp); + mp->parent_if_index = ntohl (parent_if_index); + clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac)); + + S (mp); + W (ret); + return ret; +} static int q_or_quit (vat_main_t * vam) @@ -19444,7 +19543,9 @@ _(sw_interface_tag_add_del, " | sw_if_index tag " \ _(l2_xconnect_dump, "") \ _(sw_interface_set_mtu, " | sw_if_index mtu ") \ _(ip_neighbor_dump, "[ip6] | sw_if_index ") \ -_(sw_interface_get_table, " | sw_if_index [ipv6]") +_(sw_interface_get_table, " | sw_if_index [ipv6]") \ +_(p2p_ethernet_add, " | sw_if_index remote_mac ") \ +_(p2p_ethernet_del, " | sw_if_index remote_mac ") /* List of command functions, CLI names map directly to functions */ #define foreach_cli_function \ diff --git a/src/vnet.am b/src/vnet.am index 361a838b811..b5ce6d5a560 100644 --- a/src/vnet.am +++ b/src/vnet.am @@ -113,7 +113,9 @@ libvnet_la_SOURCES += \ vnet/ethernet/interface.c \ vnet/ethernet/node.c \ vnet/ethernet/pg.c \ - vnet/ethernet/sfp.c + vnet/ethernet/sfp.c \ + vnet/ethernet/p2p_ethernet.c \ + vnet/ethernet/p2p_ethernet_api.c nobase_include_HEADERS += \ vnet/ethernet/arp_packet.h \ @@ -121,7 +123,11 @@ nobase_include_HEADERS += \ vnet/ethernet/ethernet.h \ vnet/ethernet/packet.h \ vnet/ethernet/types.def \ - vnet/ethernet/sfp.h + vnet/ethernet/sfp.h \ + vnet/ethernet/p2p_ethernet.api.h \ + vnet/ethernet/p2p_ethernet.h + +API_FILES += vnet/ethernet/p2p_ethernet.api ######################################## # Layer 2 protocol: Ethernet bridging diff --git a/src/vnet/ethernet/p2p_ethernet.api b/src/vnet/ethernet/p2p_ethernet.api new file mode 100644 index 00000000000..72a734237d5 --- /dev/null +++ b/src/vnet/ethernet/p2p_ethernet.api @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2015-2016 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +define p2p_ethernet_add +{ + u32 client_index; + u32 context; + u32 parent_if_index; + u8 remote_mac[6]; +}; + +define p2p_ethernet_add_reply +{ + u32 context; + i32 retval; + u32 sw_if_index; +}; + +define p2p_ethernet_del +{ + u32 client_index; + u32 context; + u32 parent_if_index; + u8 remote_mac[6]; +}; + +define p2p_ethernet_del_reply +{ + u32 context; + i32 retval; +}; + +/* + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ \ No newline at end of file diff --git a/src/vnet/ethernet/p2p_ethernet.c b/src/vnet/ethernet/p2p_ethernet.c new file mode 100644 index 00000000000..3c077318b7b --- /dev/null +++ b/src/vnet/ethernet/p2p_ethernet.c @@ -0,0 +1,102 @@ +/* + * p2p_ethernet.c: p2p ethernet + * + * Copyright (c) 2012 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +int +p2p_ethernet_add_del (vlib_main_t * vm, u32 parent_if_index, + u8 * client_mac, int is_add) +{ + return 0; +} + +static clib_error_t * +vnet_p2p_ethernet_add_del (vlib_main_t * vm, unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + vnet_main_t *vnm = vnet_get_main (); + + int is_add = 1; + int remote_mac = 0; + u32 hw_if_index = ~0; + u8 client_mac[6]; + + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat + (input, "%U", unformat_vnet_hw_interface, vnm, &hw_if_index)) + ; + else if (unformat (input, "%U", unformat_ethernet_address, &client_mac)) + remote_mac = 1; + else if (unformat (input, "del")) + is_add = 0; + else + break; + } + + if (hw_if_index == ~0) + return clib_error_return (0, "Please specify parent interface ..."); + if (!remote_mac) + return clib_error_return (0, "Please specify client MAC address ..."); + + u32 rv; + rv = p2p_ethernet_add_del (vm, hw_if_index, client_mac, is_add); + switch (rv) + { + case VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED: + return clib_error_return (0, + "not allowed as parent interface belongs to a BondEthernet interface"); + case -1: + return clib_error_return (0, + "p2p ethernet for given parent interface and client mac already exists"); + case -2: + return clib_error_return (0, + "couldn't create p2p ethernet subinterface"); + case -3: + return clib_error_return (0, + "p2p ethernet for given parent interface and client mac doesn't exist"); + default: + break; + } + return 0; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (p2p_ethernet_add_del_command, static) = +{ + .path = "p2p_ethernet ", + .function = vnet_p2p_ethernet_add_del, + .short_help = "p2p_ethernet [del]",}; +/* *INDENT-ON* */ + +static clib_error_t * +p2p_ethernet_init (vlib_main_t * vm) +{ + return 0; +} + +VLIB_INIT_FUNCTION (p2p_ethernet_init); + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/vnet/ethernet/p2p_ethernet.h b/src/vnet/ethernet/p2p_ethernet.h new file mode 100644 index 00000000000..31b93d829fb --- /dev/null +++ b/src/vnet/ethernet/p2p_ethernet.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2015 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef included_vnet_p2p_ethernet_h +#define included_vnet_p2p_ethernet_h + +#include +#include + +int p2p_ethernet_add_del (vlib_main_t * vm, u32 parent_if_index, u8 * client_mac, int is_add); + +#endif /* included_vnet_p2p_ethernet_h */ diff --git a/src/vnet/ethernet/p2p_ethernet_api.c b/src/vnet/ethernet/p2p_ethernet_api.c new file mode 100644 index 00000000000..1d9eaeb0286 --- /dev/null +++ b/src/vnet/ethernet/p2p_ethernet_api.c @@ -0,0 +1,128 @@ +/* + *------------------------------------------------------------------ + * p2p_ethernet_api.c - p2p ethernet api + * + * Copyright (c) 2016 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------ + */ + +#include +#include + +#include +#include + +#define vl_typedefs /* define message structures */ +#include +#undef vl_typedefs + +#define vl_endianfun /* define message structures */ +#include +#undef vl_endianfun + +/* instantiate all the print functions we know about */ +#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) +#define vl_printfun +#include +#undef vl_printfun + +#include + +#define foreach_vpe_api_msg \ +_(P2P_ETHERNET_ADD, p2p_ethernet_add) \ +_(P2P_ETHERNET_DEL, p2p_ethernet_del) + +void +vl_api_p2p_ethernet_add_t_handler (vl_api_p2p_ethernet_add_t * mp) +{ + vl_api_p2p_ethernet_add_reply_t *rmp; + vlib_main_t *vm = vlib_get_main (); + int rv; + + u32 parent_if_index = htonl (mp->parent_if_index); + u8 remote_mac[6]; + + clib_memcpy (remote_mac, mp->remote_mac, 6); + rv = p2p_ethernet_add_del (vm, parent_if_index, remote_mac, 1); + + REPLY_MACRO (VL_API_P2P_ETHERNET_ADD_REPLY); +} + +void +vl_api_p2p_ethernet_del_t_handler (vl_api_p2p_ethernet_del_t * mp) +{ + vl_api_p2p_ethernet_del_reply_t *rmp; + vlib_main_t *vm = vlib_get_main (); + int rv; + + u32 parent_if_index = htonl (mp->parent_if_index); + u8 remote_mac[6]; + + clib_memcpy (remote_mac, mp->remote_mac, 6); + rv = p2p_ethernet_add_del (vm, parent_if_index, remote_mac, 0); + + REPLY_MACRO (VL_API_P2P_ETHERNET_DEL_REPLY); +} + +/* + * p2p_ethernet_api_hookup + * Add vpe's API message handlers to the table. + * vlib has alread mapped shared memory and + * added the client registration handlers. + * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process() + */ +#define vl_msg_name_crc_list +#include +#undef vl_msg_name_crc_list + +static void +setup_message_id_table (api_main_t * am) +{ +#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id); + foreach_vl_msg_name_crc_p2p_ethernet; +#undef _ +} + +static clib_error_t * +p2p_ethernet_api_hookup (vlib_main_t * vm) +{ + api_main_t *am = &api_main; + +#define _(N,n) \ + vl_msg_api_set_handlers(VL_API_##N, #n, \ + vl_api_##n##_t_handler, \ + vl_noop_handler, \ + vl_api_##n##_t_endian, \ + vl_api_##n##_t_print, \ + sizeof(vl_api_##n##_t), 1); + foreach_vpe_api_msg; +#undef _ + + /* + * Set up the (msg_name, crc, message-id) table + */ + setup_message_id_table (am); + + return 0; +} + +VLIB_API_INIT_FUNCTION (p2p_ethernet_api_hookup); + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/vnet/vnet_all_api_h.h b/src/vnet/vnet_all_api_h.h index 566e22ec8ca..5da2acb7ef9 100644 --- a/src/vnet/vnet_all_api_h.h +++ b/src/vnet/vnet_all_api_h.h @@ -56,6 +56,7 @@ #include #include #include +#include /* * fd.io coding-style-patch-verification: ON diff --git a/src/vpp/api/custom_dump.c b/src/vpp/api/custom_dump.c index 9071883b210..dc9fee9a142 100644 --- a/src/vpp/api/custom_dump.c +++ b/src/vpp/api/custom_dump.c @@ -2932,6 +2932,30 @@ static void *vl_api_sw_interface_set_mtu_t_print FINISH; } +static void *vl_api_p2p_ethernet_add_t_print + (vl_api_p2p_ethernet_add_t * mp, void *handle) +{ + u8 *s; + + s = format (0, "SCRIPT: p2p_ethernet_add "); + s = format (s, "sw_if_index %d ", ntohl (mp->parent_if_index)); + s = format (s, "remote_mac %U ", format_ethernet_address, mp->remote_mac); + + FINISH; +} + +static void *vl_api_p2p_ethernet_del_t_print + (vl_api_p2p_ethernet_del_t * mp, void *handle) +{ + u8 *s; + + s = format (0, "SCRIPT: p2p_ethernet_del "); + s = format (s, "sw_if_index %d ", ntohl (mp->parent_if_index)); + s = format (s, "remote_mac %U ", format_ethernet_address, mp->remote_mac); + + FINISH; +} + #define foreach_custom_print_no_arg_function \ _(lisp_eid_table_vni_dump) \ _(lisp_map_resolver_dump) \ @@ -3112,7 +3136,9 @@ _(IP_FIB_DUMP, ip_fib_dump) \ _(IP6_FIB_DUMP, ip6_fib_dump) \ _(FEATURE_ENABLE_DISABLE, feature_enable_disable) \ _(SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del) \ -_(SW_INTERFACE_SET_MTU, sw_interface_set_mtu) +_(SW_INTERFACE_SET_MTU, sw_interface_set_mtu) \ +_(P2P_ETHERNET_ADD, p2p_ethernet_add) \ +_(P2P_ETHERNET_DEL, p2p_ethernet_del) void vl_msg_api_custom_dump_configure (api_main_t * am) { -- cgit 1.2.3-korg