summaryrefslogtreecommitdiffstats
path: root/src/vnet/bonding
diff options
context:
space:
mode:
authorSteven <sluong@cisco.com>2018-04-12 19:36:19 -0700
committersteven luong <sluong@cisco.com>2018-04-13 20:02:14 +0000
commit743ff8430a67f823614f5be94b361778e6223ca2 (patch)
tree25720057ad7818abc62118421a7c3591eb0fe9f9 /src/vnet/bonding
parenta45bdcacebbb2ee4b4bd45cd2d805bb6b2aa671c (diff)
bond: ping fails between l2 BD [VPP-1238]
In dpdk based bonding, when the bond interface is configured for l2, it automatically sets the bond interface to promiscuous mode and sets rx redirect to ethernet-input. This allows traffic to be bridged to non compute node facing interface when it is received from the compute node interface. For native vpp bonding, we need to do similar things. When the bond interface is configured for l2, we set the slave interfaces to promiscuous mode and set rx redirect to ethernet-input because dpdk does not know anything about the bond interface. Likewise, when a new interface is enslaved, we also need to do the same thing if the bond interface has already been configured for l2. Change-Id: I7e168008e8a4221be74929b2a20e6db0ce8f3110 Signed-off-by: Steven <sluong@cisco.com> (cherry picked from commit 4f8863b21405d1ab3e067e978a60be72a343358b)
Diffstat (limited to 'src/vnet/bonding')
-rw-r--r--src/vnet/bonding/cli.c48
-rw-r--r--src/vnet/bonding/device.c43
2 files changed, 76 insertions, 15 deletions
diff --git a/src/vnet/bonding/cli.c b/src/vnet/bonding/cli.c
index 1768912bf12..3ee99a51b62 100644
--- a/src/vnet/bonding/cli.c
+++ b/src/vnet/bonding/cli.c
@@ -135,7 +135,10 @@ bond_delete_neighbor (vlib_main_t * vm, bond_if_t * bif, slave_if_t * sif)
bond_main_t *bm = &bond_main;
vnet_main_t *vnm = vnet_get_main ();
int i;
- vnet_hw_interface_t *hw;
+ vnet_hw_interface_t *sif_hw, *bif_hw;
+
+ sif_hw = vnet_get_sup_hw_interface (vnm, sif->sw_if_index);
+ bif_hw = vnet_get_sup_hw_interface (vnm, bif->sw_if_index);
bif->port_number_bitmap =
clib_bitmap_set (bif->port_number_bitmap,
@@ -153,11 +156,17 @@ bond_delete_neighbor (vlib_main_t * vm, bond_if_t * bif, slave_if_t * sif)
}
}
+ if (bif_hw->l2_if_count)
+ {
+ ethernet_set_flags (vnm, sif_hw->hw_if_index, 0);
+ /* Allow ip packets to go directly to ip4-input etc */
+ ethernet_set_rx_redirect (vnm, sif_hw, 0);
+ }
+
bond_disable_collecting_distributing (vm, sif);
/* Put back the old mac */
- hw = vnet_get_sup_hw_interface (vnm, sif->sw_if_index);
- vnet_hw_interface_change_mac_address (vnm, hw->hw_if_index,
+ vnet_hw_interface_change_mac_address (vnm, sif_hw->hw_if_index,
sif->persistent_hw_address);
pool_put (bm->neighbors, sif);
@@ -406,7 +415,7 @@ bond_enslave (vlib_main_t * vm, bond_enslave_args_t * args)
bond_if_t *bif;
slave_if_t *sif;
vnet_interface_main_t *im = &vnm->interface_main;
- vnet_hw_interface_t *hw, *hw2;
+ vnet_hw_interface_t *bif_hw, *sif_hw;
vnet_sw_interface_t *sw;
bif = bond_get_master_by_sw_if_index (args->group);
@@ -423,8 +432,8 @@ bond_enslave (vlib_main_t * vm, bond_enslave_args_t * args)
args->error = clib_error_return (0, "interface was already enslaved");
return;
}
- hw = vnet_get_sup_hw_interface (vnm, args->slave);
- if (hw->dev_class_index == bond_dev_class.index)
+ sif_hw = vnet_get_sup_hw_interface (vnm, args->slave);
+ if (sif_hw->dev_class_index == bond_dev_class.index)
{
args->rv = VNET_API_ERROR_INVALID_INTERFACE;
args->error =
@@ -454,12 +463,14 @@ bond_enslave (vlib_main_t * vm, bond_enslave_args_t * args)
sif - bm->neighbors);
vec_add1 (bif->slaves, sif->sw_if_index);
- hw = vnet_get_sup_hw_interface (vnm, sif->sw_if_index);
+ sif_hw = vnet_get_sup_hw_interface (vnm, sif->sw_if_index);
+
/* Save the old mac */
- memcpy (sif->persistent_hw_address, hw->hw_address, 6);
+ memcpy (sif->persistent_hw_address, sif_hw->hw_address, 6);
+ bif_hw = vnet_get_sup_hw_interface (vnm, bif->sw_if_index);
if (bif->use_custom_mac)
{
- vnet_hw_interface_change_mac_address (vnm, hw->hw_if_index,
+ vnet_hw_interface_change_mac_address (vnm, sif_hw->hw_if_index,
bif->hw_address);
}
else
@@ -467,19 +478,26 @@ bond_enslave (vlib_main_t * vm, bond_enslave_args_t * args)
// bond interface gets the mac address from the first slave
if (vec_len (bif->slaves) == 1)
{
- memcpy (bif->hw_address, hw->hw_address, 6);
- hw2 = vnet_get_sup_hw_interface (vnm, bif->sw_if_index);
- vnet_hw_interface_change_mac_address (vnm, hw2->hw_if_index,
- hw->hw_address);
+ memcpy (bif->hw_address, sif_hw->hw_address, 6);
+ vnet_hw_interface_change_mac_address (vnm, bif_hw->hw_if_index,
+ sif_hw->hw_address);
}
else
{
// subsequent slaves gets the mac address of the bond interface
- vnet_hw_interface_change_mac_address (vnm, hw->hw_if_index,
+ vnet_hw_interface_change_mac_address (vnm, sif_hw->hw_if_index,
bif->hw_address);
}
}
+ if (bif_hw->l2_if_count)
+ {
+ ethernet_set_flags (vnm, sif_hw->hw_if_index,
+ ETHERNET_INTERFACE_FLAG_ACCEPT_ALL);
+ /* ensure all packets go to ethernet-input */
+ ethernet_set_rx_redirect (vnm, sif_hw, 1);
+ }
+
if ((bif->mode == BOND_MODE_LACP) && bm->lacp_enable_disable)
{
(*bm->lacp_enable_disable) (vm, bif, sif, 1);
@@ -490,7 +508,7 @@ bond_enslave (vlib_main_t * vm, bond_enslave_args_t * args)
}
args->rv = vnet_feature_enable_disable ("device-input", "bond-input",
- hw->hw_if_index, 1, 0, 0);
+ sif_hw->hw_if_index, 1, 0, 0);
if (args->rv)
{
diff --git a/src/vnet/bonding/device.c b/src/vnet/bonding/device.c
index e3c454bbc72..a27524089aa 100644
--- a/src/vnet/bonding/device.c
+++ b/src/vnet/bonding/device.c
@@ -74,6 +74,48 @@ format_bond_interface_name (u8 * s, va_list * args)
}
static __clib_unused clib_error_t *
+bond_set_l2_mode_function (vnet_main_t * vnm,
+ struct vnet_hw_interface_t *bif_hw,
+ i32 l2_if_adjust)
+{
+ bond_if_t *bif;
+ u32 *sw_if_index;
+ struct vnet_hw_interface_t *sif_hw;
+
+ bif = bond_get_master_by_sw_if_index (bif_hw->sw_if_index);
+ if (!bif)
+ return 0;
+
+ if ((bif_hw->l2_if_count == 1) && (l2_if_adjust == 1))
+ {
+ /* Just added first L2 interface on this port */
+ vec_foreach (sw_if_index, bif->slaves)
+ {
+ sif_hw = vnet_get_sup_hw_interface (vnm, *sw_if_index);
+ ethernet_set_flags (vnm, sif_hw->hw_if_index,
+ ETHERNET_INTERFACE_FLAG_ACCEPT_ALL);
+
+ /* ensure all packets go to ethernet-input */
+ ethernet_set_rx_redirect (vnm, sif_hw, 1);
+ }
+ }
+ else if ((bif_hw->l2_if_count == 0) && (l2_if_adjust == -1))
+ {
+ /* Just removed last L2 subinterface on this port */
+ vec_foreach (sw_if_index, bif->slaves)
+ {
+ sif_hw = vnet_get_sup_hw_interface (vnm, *sw_if_index);
+ ethernet_set_flags (vnm, sif_hw->hw_if_index, 0);
+
+ /* Allow ip packets to go directly to ip4-input etc */
+ ethernet_set_rx_redirect (vnm, sif_hw, 0);
+ }
+ }
+
+ return 0;
+}
+
+static __clib_unused clib_error_t *
bond_subif_add_del_function (vnet_main_t * vnm, u32 hw_if_index,
struct vnet_sw_interface_t *st, int is_add)
{
@@ -640,6 +682,7 @@ VNET_DEVICE_CLASS (bond_dev_class) = {
.tx_function_n_errors = BOND_TX_N_ERROR,
.tx_function_error_strings = bond_tx_error_strings,
.format_device_name = format_bond_interface_name,
+ .set_l2_mode_function = bond_set_l2_mode_function,
.admin_up_down_function = bond_interface_admin_up_down,
.subif_add_del_function = bond_subif_add_del_function,
.format_tx_trace = format_bond_tx_trace,