summaryrefslogtreecommitdiffstats
path: root/src/plugins/dpdk/device
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/dpdk/device')
-rw-r--r--src/plugins/dpdk/device/common.c62
-rw-r--r--src/plugins/dpdk/device/dpdk.h8
-rwxr-xr-xsrc/plugins/dpdk/device/init.c23
3 files changed, 85 insertions, 8 deletions
diff --git a/src/plugins/dpdk/device/common.c b/src/plugins/dpdk/device/common.c
index 1a9688e75e5..df52c58fa18 100644
--- a/src/plugins/dpdk/device/common.c
+++ b/src/plugins/dpdk/device/common.c
@@ -12,13 +12,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#include <vnet/vnet.h>
#include <vppinfra/vec.h>
#include <vppinfra/format.h>
#include <vlib/unix/cj.h>
#include <assert.h>
+#include <vnet/ip/ip.h>
#include <vnet/ethernet/ethernet.h>
+#include <vnet/ethernet/arp_packet.h>
#include <dpdk/device/dpdk.h>
#include <dpdk/device/dpdk_priv.h>
@@ -178,6 +181,65 @@ dpdk_device_stop (dpdk_device_t * xd)
}
}
+void
+dpdk_port_state_callback (uint8_t port_id,
+ enum rte_eth_event_type type, void *param)
+{
+ struct rte_eth_link link;
+ vlib_main_t *vm = vlib_get_main ();
+ dpdk_device_t *xd = &dpdk_main.devices[port_id];
+
+ RTE_SET_USED (param);
+ if (type != RTE_ETH_EVENT_INTR_LSC)
+ {
+ clib_warning ("Unknown event %d received for port %d", type, port_id);
+ return;
+ }
+
+ rte_eth_link_get_nowait (port_id, &link);
+ u8 link_up = link.link_status;
+
+ if (xd->flags & DPDK_DEVICE_FLAG_BOND_SLAVE)
+ {
+ u8 bd_port = xd->bond_port;
+ int bd_mode = rte_eth_bond_mode_get (bd_port);
+
+ if ((link_up && !(xd->flags & DPDK_DEVICE_FLAG_BOND_SLAVE_UP)) ||
+ (!link_up && (xd->flags & DPDK_DEVICE_FLAG_BOND_SLAVE_UP)))
+ {
+ clib_warning ("Port %d state to %s, "
+ "slave of port %d BondEthernet%d in mode %d",
+ port_id, (link_up) ? "UP" : "DOWN",
+ bd_port, xd->port_id, bd_mode);
+ if (bd_mode == BONDING_MODE_ACTIVE_BACKUP)
+ {
+ rte_eth_link_get_nowait (bd_port, &link);
+ if (link.link_status) /* bonded interface up */
+ {
+ u32 hw_if_index = dpdk_main.devices[bd_port].hw_if_index;
+ vlib_process_signal_event
+ (vm, send_garp_na_process_node_index, SEND_GARP_NA,
+ hw_if_index);
+ }
+ }
+ }
+ if (link_up) /* Update slave link status */
+ xd->flags |= DPDK_DEVICE_FLAG_BOND_SLAVE_UP;
+ else
+ xd->flags &= ~DPDK_DEVICE_FLAG_BOND_SLAVE_UP;
+ }
+ else /* Should not happen as callback not setup for "normal" links */
+ {
+ if (link_up)
+ clib_warning ("Port %d Link Up - speed %u Mbps - %s",
+ port_id, (unsigned) link.link_speed,
+ (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
+ "full-duplex" : "half-duplex");
+ else
+ clib_warning ("Port %d Link Down\n\n", port_id);
+ }
+}
+
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/src/plugins/dpdk/device/dpdk.h b/src/plugins/dpdk/device/dpdk.h
index d82ba5ddaca..c6fd7388fdb 100644
--- a/src/plugins/dpdk/device/dpdk.h
+++ b/src/plugins/dpdk/device/dpdk.h
@@ -173,6 +173,8 @@ typedef struct
#define DPDK_DEVICE_FLAG_MAYBE_MULTISEG (1 << 4)
#define DPDK_DEVICE_FLAG_HAVE_SUBIF (1 << 5)
#define DPDK_DEVICE_FLAG_HQOS (1 << 6)
+#define DPDK_DEVICE_FLAG_BOND_SLAVE (1 << 7)
+#define DPDK_DEVICE_FLAG_BOND_SLAVE_UP (1 << 8)
u16 nb_tx_desc;
CLIB_CACHE_LINE_ALIGN_MARK (cacheline1);
@@ -197,6 +199,10 @@ typedef struct
/* af_packet or BondEthernet instance number */
u8 port_id;
+ /* Bonded interface port# of a slave -
+ only valid if DPDK_DEVICE_FLAG_BOND_SLAVE bit is set */
+ u8 bond_port;
+
struct rte_eth_link link;
f64 time_last_link_update;
@@ -408,6 +414,8 @@ typedef struct
void dpdk_device_setup (dpdk_device_t * xd);
void dpdk_device_start (dpdk_device_t * xd);
void dpdk_device_stop (dpdk_device_t * xd);
+void dpdk_port_state_callback (uint8_t port_id,
+ enum rte_eth_event_type type, void *param);
#define foreach_dpdk_error \
_(NONE, "no error") \
diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c
index 90968075c0b..d9ab0756f2d 100755
--- a/src/plugins/dpdk/device/init.c
+++ b/src/plugins/dpdk/device/init.c
@@ -1373,8 +1373,10 @@ dpdk_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
/*
* Extra set up for bond interfaces:
* 1. Setup MACs for bond interfaces and their slave links which was set
- * in dpdk_device_setup() but needs to be done again here to take effect.
- * 2. Set up info for bond interface related CLI support.
+ * in dpdk_device_setup() but needs to be done again here to take
+ * effect.
+ * 2. Set up info and register slave link state change callback handling.
+ * 3. Set up info for bond interface related CLI support.
*/
int nports = rte_eth_dev_count ();
if (nports > 0)
@@ -1399,7 +1401,8 @@ dpdk_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
(slink[0], (struct ether_addr *) addr);
/* Set MAC of bounded interface to that of 1st slave link */
- clib_warning ("Set MAC for bond dev# %d", i);
+ clib_warning ("Set MAC for bond port %d BondEthernet%d",
+ i, xd->port_id);
rv = rte_eth_bond_mac_address_set
(i, (struct ether_addr *) addr);
if (rv)
@@ -1428,34 +1431,38 @@ dpdk_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
/* Add MAC to all slave links except the first one */
if (nlink)
{
- clib_warning ("Add MAC for slave dev# %d", slave);
+ clib_warning ("Add MAC for slave port %d", slave);
rv = rte_eth_dev_mac_addr_add
(slave, (struct ether_addr *) addr, 0);
if (rv)
clib_warning ("Add MAC addr failure rv=%d", rv);
}
+ /* Setup slave link state change callback handling */
+ rte_eth_dev_callback_register
+ (slave, RTE_ETH_EVENT_INTR_LSC,
+ dpdk_port_state_callback, NULL);
+ dpdk_device_t *sxd = &dm->devices[slave];
+ sxd->flags |= DPDK_DEVICE_FLAG_BOND_SLAVE;
+ sxd->bond_port = i;
/* Set slaves bitmap for bonded interface */
bhi->bond_info = clib_bitmap_set
(bhi->bond_info, sdev->hw_if_index, 1);
- /* Set slave link flags on slave interface */
+ /* Set MACs and slave link flags on slave interface */
shi = vnet_get_hw_interface (vnm, sdev->hw_if_index);
ssi = vnet_get_sw_interface
(vnm, sdev->vlib_sw_if_index);
sei = pool_elt_at_index
(em->interfaces, shi->hw_instance);
-
shi->bond_info = VNET_HW_INTERFACE_BOND_INFO_SLAVE;
ssi->flags |= VNET_SW_INTERFACE_FLAG_BOND_SLAVE;
clib_memcpy (shi->hw_address, addr, 6);
clib_memcpy (sei->address, addr, 6);
-
/* Set l3 packet size allowed as the lowest of slave */
if (bhi->max_l3_packet_bytes[VLIB_RX] >
shi->max_l3_packet_bytes[VLIB_RX])
bhi->max_l3_packet_bytes[VLIB_RX] =
bhi->max_l3_packet_bytes[VLIB_TX] =
shi->max_l3_packet_bytes[VLIB_RX];
-
/* Set max packet size allowed as the lowest of slave */
if (bhi->max_packet_bytes > shi->max_packet_bytes)
bhi->max_packet_bytes = shi->max_packet_bytes;