From ad9d528314a049971b1fb9a42562b00e07cf93f4 Mon Sep 17 00:00:00 2001 From: Alexander Chernavin Date: Thu, 13 Dec 2018 09:08:09 -0500 Subject: [PATCH] bonding: support custom interface IDs Change-Id: I78fe58144fa3ba2e1c7135897a13a2541f235c91 Signed-off-by: Alexander Chernavin --- src/vat/api_format.c | 7 ++++++- src/vnet/bonding/bond.api | 4 ++++ src/vnet/bonding/bond_api.c | 3 +++ src/vnet/bonding/cli.c | 24 ++++++++++++++++++++++-- src/vnet/bonding/device.c | 2 +- src/vnet/bonding/node.h | 10 ++++++++++ src/vpp/api/custom_dump.c | 6 ++++-- test/vpp_papi_provider.py | 7 +++++-- 8 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/vat/api_format.c b/src/vat/api_format.c index 1b61af6226a..8a9a9971af2 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -7919,6 +7919,7 @@ api_bond_create (vat_main_t * vam) u8 mode; u8 lb; u8 mode_is_set = 0; + u32 id = ~0; clib_memset (mac_address, 0, sizeof (mac_address)); lb = BOND_LB_L2; @@ -7934,6 +7935,8 @@ api_bond_create (vat_main_t * vam) else if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address)) custom_mac = 1; + else if (unformat (i, "id %u", &id)) + ; else break; } @@ -7951,6 +7954,7 @@ api_bond_create (vat_main_t * vam) mp->mode = mode; mp->lb = lb; + mp->id = htonl (id); if (custom_mac) clib_memcpy (mp->mac_address, mac_address, 6); @@ -23176,7 +23180,8 @@ _(tap_delete_v2, \ _(sw_interface_tap_v2_dump, "") \ _(bond_create, \ "[hw-addr ] {round-robin | active-backup | " \ - "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}") \ + "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} " \ + "[id ]") \ _(bond_delete, \ " | sw_if_index ") \ _(bond_enslave, \ diff --git a/src/vnet/bonding/bond.api b/src/vnet/bonding/bond.api index e8919e14904..e779453b091 100644 --- a/src/vnet/bonding/bond.api +++ b/src/vnet/bonding/bond.api @@ -24,6 +24,7 @@ option version = "1.0.0"; /** \brief Initialize a new bond interface with the given paramters @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request + @param id - if non-~0, specifies a custom interface ID @param use_custom_mac - if set, mac_address is valid @param mac_address - mac addr to assign to the interface if use_custom_mac is set @param mode - mode, required (1=round-robin, 2=active-backup, 3=xor, 4=broadcastcast, 5=lacp) @@ -33,6 +34,7 @@ define bond_create { u32 client_index; u32 context; + u32 id; u8 use_custom_mac; u8 mac_address[6]; u8 mode; @@ -112,6 +114,7 @@ define sw_interface_bond_dump /** \brief Reply for bond dump request @param sw_if_index - software index of bond interface + @param id - ID of interface @param interface_name - name of interface @param mode - bonding mode @param lb - load balance algo @@ -122,6 +125,7 @@ define sw_interface_bond_details { u32 context; u32 sw_if_index; + u32 id; u8 interface_name[64]; u8 mode; u8 lb; diff --git a/src/vnet/bonding/bond_api.c b/src/vnet/bonding/bond_api.c index 691697cf4fe..50bae5d528d 100644 --- a/src/vnet/bonding/bond_api.c +++ b/src/vnet/bonding/bond_api.c @@ -106,6 +106,8 @@ vl_api_bond_create_t_handler (vl_api_bond_create_t * mp) clib_memset (ap, 0, sizeof (*ap)); + ap->id = ntohl (mp->id); + if (mp->use_custom_mac) { clib_memcpy (ap->hw_addr, mp->mac_address, 6); @@ -197,6 +199,7 @@ bond_send_sw_interface_details (vpe_api_main_t * am, clib_memset (mp, 0, sizeof (*mp)); mp->_vl_msg_id = htons (VL_API_SW_INTERFACE_BOND_DETAILS); mp->sw_if_index = htonl (bond_if->sw_if_index); + mp->id = htonl (bond_if->id); clib_memcpy (mp->interface_name, bond_if->interface_name, MIN (ARRAY_LEN (mp->interface_name) - 1, strlen ((const char *) bond_if->interface_name))); diff --git a/src/vnet/bonding/cli.c b/src/vnet/bonding/cli.c index 14c52f70b0b..2ccf0d4b4ce 100644 --- a/src/vnet/bonding/cli.c +++ b/src/vnet/bonding/cli.c @@ -92,6 +92,7 @@ bond_dump_ifs (bond_interface_details_t ** out_bondifs) pool_foreach (bif, bm->interfaces, vec_add2(r_bondifs, bondif, 1); clib_memset (bondif, 0, sizeof (*bondif)); + bondif->id = bif->id; bondif->sw_if_index = bif->sw_if_index; hi = vnet_get_hw_interface (vnm, bif->hw_if_index); clib_memcpy(bondif->interface_name, hi->name, @@ -231,6 +232,7 @@ bond_delete_if (vlib_main_t * vm, u32 sw_if_index) clib_bitmap_free (bif->port_number_bitmap); hash_unset (bm->bond_by_sw_if_index, bif->sw_if_index); + hash_unset (bm->id_used, bif->id); clib_memset (bif, 0, sizeof (*bif)); pool_put (bm->interfaces, bif); @@ -266,9 +268,21 @@ bond_create_if (vlib_main_t * vm, bond_create_if_args_t * args) pool_get (bm->interfaces, bif); clib_memset (bif, 0, sizeof (*bif)); bif->dev_instance = bif - bm->interfaces; + bif->id = args->id; bif->lb = args->lb; bif->mode = args->mode; + // Adjust requested interface id + if (bif->id == ~0) + bif->id = bif->dev_instance; + if (hash_get (bm->id_used, bif->id)) + { + args->rv = VNET_API_ERROR_INSTANCE_IN_USE; + pool_put (bm->interfaces, bif); + return; + } + hash_set (bm->id_used, bif->id, 1); + // Special load-balance mode used for rr and bc if (bif->mode == BOND_MODE_ROUND_ROBIN) bif->lb = BOND_LB_RR; @@ -291,13 +305,14 @@ bond_create_if (vlib_main_t * vm, bond_create_if_args_t * args) } memcpy (bif->hw_address, args->hw_addr, 6); args->error = ethernet_register_interface - (vnm, bond_dev_class.index, bif - bm->interfaces /* device instance */ , + (vnm, bond_dev_class.index, bif->dev_instance /* device instance */ , bif->hw_address /* ethernet address */ , &bif->hw_if_index, 0 /* flag change */ ); if (args->error) { args->rv = VNET_API_ERROR_INVALID_REGISTRATION; + hash_unset (bm->id_used, bif->id); pool_put (bm->interfaces, bif); return; } @@ -329,6 +344,7 @@ bond_create_command_fn (vlib_main_t * vm, unformat_input_t * input, if (!unformat_user (input, unformat_line_input, line_input)) return clib_error_return (0, "Missing required arguments."); + args.id = ~0; args.mode = -1; args.lb = BOND_LB_L2; while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) @@ -342,6 +358,8 @@ bond_create_command_fn (vlib_main_t * vm, unformat_input_t * input, else if (unformat (line_input, "hw-addr %U", unformat_ethernet_address, args.hw_addr)) args.hw_addr_set = 1; + else if (unformat (line_input, "id %u", &args.id)) + ; else return clib_error_return (0, "unknown input `%U'", format_unformat_error, input); @@ -360,7 +378,8 @@ bond_create_command_fn (vlib_main_t * vm, unformat_input_t * input, VLIB_CLI_COMMAND (bond_create_command, static) = { .path = "create bond", .short_help = "create bond mode {round-robin | active-backup | broadcast | " - "{lacp | xor} [load-balance { l2 | l23 | l34 }]} [hw-addr ]", + "{lacp | xor} [load-balance { l2 | l23 | l34 }]} [hw-addr ] " + "[id ]", .function = bond_create_command_fn, }; /* *INDENT-ON* */ @@ -716,6 +735,7 @@ show_bond_details (vlib_main_t * vm) vnet_get_main (), *sw_if_index); } vlib_cli_output (vm, " device instance: %d", bif->dev_instance); + vlib_cli_output (vm, " interface id: %d", bif->id); vlib_cli_output (vm, " sw_if_index: %d", bif->sw_if_index); vlib_cli_output (vm, " hw_if_index: %d", bif->hw_if_index); })); diff --git a/src/vnet/bonding/device.c b/src/vnet/bonding/device.c index 2bbb90d20f9..e288c572b19 100644 --- a/src/vnet/bonding/device.c +++ b/src/vnet/bonding/device.c @@ -72,7 +72,7 @@ format_bond_interface_name (u8 * s, va_list * args) bond_main_t *bm = &bond_main; bond_if_t *bif = pool_elt_at_index (bm->interfaces, dev_instance); - s = format (s, "BondEthernet%lu", bif->dev_instance); + s = format (s, "BondEthernet%lu", bif->id); return s; } diff --git a/src/vnet/bonding/node.h b/src/vnet/bonding/node.h index b9504424ee8..15640071aa8 100644 --- a/src/vnet/bonding/node.h +++ b/src/vnet/bonding/node.h @@ -77,6 +77,7 @@ enum typedef struct { + u32 id; u8 hw_addr_set; u8 hw_addr[6]; u8 mode; @@ -112,6 +113,7 @@ typedef struct typedef struct { u32 sw_if_index; + u32 id; u8 interface_name[64]; u8 mode; u8 lb; @@ -158,7 +160,12 @@ typedef struct /* the last slave index for the rr lb */ u32 lb_rr_last_index; + /* Real device instance in interface vector */ u32 dev_instance; + + /* Interface ID being shown to user */ + u32 id; + u32 hw_if_index; u32 sw_if_index; @@ -297,6 +304,9 @@ typedef struct /* pool of bonding interfaces */ bond_if_t *interfaces; + /* record used interface IDs */ + uword *id_used; + /* pool of slave interfaces */ slave_if_t *neighbors; diff --git a/src/vpp/api/custom_dump.c b/src/vpp/api/custom_dump.c index cf016003a47..3725dd370d4 100644 --- a/src/vpp/api/custom_dump.c +++ b/src/vpp/api/custom_dump.c @@ -675,9 +675,11 @@ static void *vl_api_bond_create_t_print s = format (s, "mac-address %U ", format_ethernet_address, mp->mac_address); if (mp->mode) - s = format (s, "mode %U", format_bond_mode, mp->mode); + s = format (s, "mode %U ", format_bond_mode, mp->mode); if (mp->lb) - s = format (s, "lb %U", format_bond_load_balance, mp->lb); + s = format (s, "lb %U ", format_bond_load_balance, mp->lb); + if (mp->id != ~0) + s = format (s, "id %u ", ntohl (mp->id)); FINISH; } diff --git a/test/vpp_papi_provider.py b/test/vpp_papi_provider.py index 0ee51c4677f..584fe191a1b 100644 --- a/test/vpp_papi_provider.py +++ b/test/vpp_papi_provider.py @@ -3884,19 +3884,22 @@ class VppPapiProvider(object): mode, lb, use_custom_mac, - mac_address=''): + mac_address='', + interface_id=0xFFFFFFFF): """ :param mode: mode :param lb: load balance :param use_custom_mac: use custom mac :param mac_address: mac address + :param interface_id: custom interface ID """ return self.api( self.papi.bond_create, {'mode': mode, 'lb': lb, 'use_custom_mac': use_custom_mac, - 'mac_address': mac_address + 'mac_address': mac_address, + 'id': interface_id }) def bond_delete( -- 2.16.6