aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/bonding/device.c
diff options
context:
space:
mode:
authorSteven <sluong@cisco.com>2018-06-05 11:09:32 -0700
committerSteven <sluong@cisco.com>2018-06-05 11:09:32 -0700
commit9f781d84b0943b03af2a9fd0b7c4cef721d1d4c6 (patch)
treea78172c460d265c89d3717a5cb8cb45775fe523b /src/vnet/bonding/device.c
parent439a122f3acd745dcb70e9b32bb518e43967afe4 (diff)
bond: send gratuitous arp when the active slave went down in active-backup mode
- Modify the API send_ip6_na and send_ip4_garp to take sw_if_index instead of vnet_hw_interface_t and add call to build_ethernet_rewrite to support subinterface/vlan - Add code to bonding driver to send an event to bond_process when the first interface becomes active or when the active interface is down - Create a bond_process to walk the interface and the corresponding subinterfaces to send garp/ip6_na when an event is received. - Minor cleanup in bonding/node.c Note: dpdk bonding driver does not send garp/ip6_na for subinterfaces. There is no attempt to fix it here. But the infra is now done and should be easy to add the support. Change-Id: If3ecc4cd0fb3051330f7fa11ca0dab3e18557ce1 Signed-off-by: Steven <sluong@cisco.com>
Diffstat (limited to 'src/vnet/bonding/device.c')
-rw-r--r--src/vnet/bonding/device.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/vnet/bonding/device.c b/src/vnet/bonding/device.c
index 8ddec80850a..1ade1c290a1 100644
--- a/src/vnet/bonding/device.c
+++ b/src/vnet/bonding/device.c
@@ -23,6 +23,8 @@
#include <vnet/ip/ip6_hop_by_hop_packet.h>
#include <vnet/bonding/node.h>
#include <vppinfra/lb_hash_hash.h>
+#include <vnet/ip/ip.h>
+#include <vnet/ethernet/arp_packet.h>
#define foreach_bond_tx_error \
_(NONE, "no error") \
@@ -700,6 +702,52 @@ bond_tx_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
return frame->n_vectors;
}
+static walk_rc_t
+bond_active_interface_switch_cb (vnet_main_t * vnm, u32 sw_if_index,
+ void *arg)
+{
+ bond_main_t *bm = &bond_main;
+
+ send_ip4_garp (bm->vlib_main, sw_if_index);
+ send_ip6_na (bm->vlib_main, sw_if_index);
+
+ return (WALK_CONTINUE);
+}
+
+static uword
+bond_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+ uword event_type, *event_data = 0;
+
+ while (1)
+ {
+ u32 i;
+ u32 hw_if_index;
+
+ vlib_process_wait_for_event (vm);
+ event_type = vlib_process_get_events (vm, &event_data);
+ ASSERT (event_type == BOND_SEND_GARP_NA);
+ for (i = 0; i < vec_len (event_data); i++)
+ {
+ hw_if_index = event_data[i];
+ /* walk hw interface to process all subinterfaces */
+ vnet_hw_interface_walk_sw (vnm, hw_if_index,
+ bond_active_interface_switch_cb, 0);
+ }
+ vec_reset_length (event_data);
+ }
+ return 0;
+}
+
+/* *INDENT-OFF* */
+VLIB_REGISTER_NODE (bond_process_node) = {
+ .function = bond_process,
+ .type = VLIB_NODE_TYPE_PROCESS,
+ .name = "bond-process",
+};
+/* *INDENT-ON* */
+
/* *INDENT-OFF* */
VNET_DEVICE_CLASS (bond_dev_class) = {
.name = "bond",