bonding: support custom interface IDs 65/16465/8
authorAlexander Chernavin <achernavin@netgate.com>
Thu, 13 Dec 2018 14:08:09 +0000 (09:08 -0500)
committerDamjan Marion <dmarion@me.com>
Sun, 13 Jan 2019 13:36:22 +0000 (13:36 +0000)
Change-Id: I78fe58144fa3ba2e1c7135897a13a2541f235c91
Signed-off-by: Alexander Chernavin <achernavin@netgate.com>
src/vat/api_format.c
src/vnet/bonding/bond.api
src/vnet/bonding/bond_api.c
src/vnet/bonding/cli.c
src/vnet/bonding/device.c
src/vnet/bonding/node.h
src/vpp/api/custom_dump.c
test/vpp_papi_provider.py

index 1b61af6..8a9a997 100644 (file)
@@ -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 <mac-addr>] {round-robin | active-backup | "                \
-  "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
+  "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
+  "[id <if-id>]")                                                       \
 _(bond_delete,                                                          \
   "<vpp-if-name> | sw_if_index <id>")                                   \
 _(bond_enslave,                                                         \
index e8919e1..e779453 100644 (file)
@@ -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;
index 691697c..50bae5d 100644 (file)
@@ -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)));
index 14c52f7..2ccf0d4 100644 (file)
@@ -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 <mac-address>]",
+    "{lacp | xor} [load-balance { l2 | l23 | l34 }]} [hw-addr <mac-address>] "
+    "[id <if-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);
   }));
index 2bbb90d..e288c57 100644 (file)
@@ -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;
 }
index b950442..1564007 100644 (file)
@@ -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;
 
index cf01600..3725dd3 100644 (file)
@@ -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;
 }
 
index 0ee51c4..584fe19 100644 (file)
@@ -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(