diff options
Diffstat (limited to 'src/plugins/dpdk')
-rw-r--r-- | src/plugins/dpdk/device/common.c | 62 | ||||
-rw-r--r-- | src/plugins/dpdk/device/dpdk.h | 8 | ||||
-rwxr-xr-x | src/plugins/dpdk/device/init.c | 23 |
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; |