X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbonding%2Frte_eth_bond_8023ad.c;h=b77a37ddb3c42ec9d41030f3ed23e35353803bfe;hb=6cad4aa1a57f43cc41b96f15d2e8aae5dff76853;hp=51bf3f52e47af2fde335a34d4683b998d6df41e2;hpb=6d13ea8e8e49ab957deae2bba5ecf4a4bfe747d1;p=dpdk.git diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c index 51bf3f52e4..b77a37ddb3 100644 --- a/drivers/net/bonding/rte_eth_bond_8023ad.c +++ b/drivers/net/bonding/rte_eth_bond_8023ad.c @@ -12,7 +12,7 @@ #include #include -#include "rte_eth_bond_private.h" +#include "eth_bond_private.h" static void bond_mode_8023ad_ext_periodic_cb(void *arg); #ifdef RTE_LIBRTE_BOND_DEBUG_8023AD @@ -322,7 +322,7 @@ rx_machine(struct bond_dev_private *internals, uint16_t slave_id, agg = &bond_mode_8023ad_ports[port->aggregator_port_id]; bool match = port->actor.system_priority == lacp->partner.port_params.system_priority && - is_same_ether_addr(&agg->actor.system, + rte_is_same_ether_addr(&agg->actor.system, &lacp->partner.port_params.system) && port->actor.port_priority == lacp->partner.port_params.port_priority && @@ -575,9 +575,9 @@ tx_machine(struct bond_dev_private *internals, uint16_t slave_id) hdr = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *); /* Source and destination MAC */ - ether_addr_copy(&lacp_mac_addr, &hdr->eth_hdr.d_addr); + rte_ether_addr_copy(&lacp_mac_addr, &hdr->eth_hdr.d_addr); rte_eth_macaddr_get(slave_id, &hdr->eth_hdr.s_addr); - hdr->eth_hdr.ether_type = rte_cpu_to_be_16(ETHER_TYPE_SLOW); + hdr->eth_hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_SLOW); lacpdu = &hdr->lacpdu; memset(lacpdu, 0, sizeof(*lacpdu)); @@ -592,7 +592,8 @@ tx_machine(struct bond_dev_private *internals, uint16_t slave_id) memcpy(&hdr->lacpdu.actor.port_params, &port->actor, sizeof(port->actor)); agg = &bond_mode_8023ad_ports[port->aggregator_port_id]; - ether_addr_copy(&agg->actor.system, &hdr->lacpdu.actor.port_params.system); + rte_ether_addr_copy(&agg->actor.system, + &hdr->lacpdu.actor.port_params.system); lacpdu->actor.state = port->actor_state; /* PARTNER */ @@ -638,7 +639,7 @@ tx_machine(struct bond_dev_private *internals, uint16_t slave_id) SM_FLAG_CLR(port, NTT); } -static uint8_t +static uint16_t max_index(uint64_t *a, int n) { if (n <= 0) @@ -669,11 +670,12 @@ selection_logic(struct bond_dev_private *internals, uint16_t slave_id) struct port *agg, *port; uint16_t slaves_count, new_agg_id, i, j = 0; uint16_t *slaves; - uint64_t agg_bandwidth[8] = {0}; - uint64_t agg_count[8] = {0}; + uint64_t agg_bandwidth[RTE_MAX_ETHPORTS] = {0}; + uint64_t agg_count[RTE_MAX_ETHPORTS] = {0}; uint16_t default_slave = 0; - uint8_t mode_count_id, mode_band_id; struct rte_eth_link link_info; + uint16_t agg_new_idx = 0; + int ret; slaves = internals->active_slaves; slaves_count = internals->active_slave_count; @@ -686,17 +688,24 @@ selection_logic(struct bond_dev_private *internals, uint16_t slave_id) if (agg->aggregator_port_id != slaves[i]) continue; - agg_count[agg->aggregator_port_id] += 1; - rte_eth_link_get_nowait(slaves[i], &link_info); - agg_bandwidth[agg->aggregator_port_id] += link_info.link_speed; + ret = rte_eth_link_get_nowait(slaves[i], &link_info); + if (ret < 0) { + RTE_BOND_LOG(ERR, + "Slave (port %u) link get failed: %s\n", + slaves[i], rte_strerror(-ret)); + continue; + } + agg_count[i] += 1; + agg_bandwidth[i] += link_info.link_speed; /* Actors system ID is not checked since all slave device have the same * ID (MAC address). */ if ((agg->actor.key == port->actor.key && agg->partner.system_priority == port->partner.system_priority && - is_same_ether_addr(&agg->partner.system, &port->partner.system) == 1 + rte_is_same_ether_addr(&agg->partner.system, + &port->partner.system) == 1 && (agg->partner.key == port->partner.key)) && - is_zero_ether_addr(&port->partner.system) != 1 && + rte_is_zero_ether_addr(&port->partner.system) != 1 && (agg->actor.key & rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) != 0) { @@ -708,24 +717,22 @@ selection_logic(struct bond_dev_private *internals, uint16_t slave_id) switch (internals->mode4.agg_selection) { case AGG_COUNT: - mode_count_id = max_index( - (uint64_t *)agg_count, slaves_count); - new_agg_id = mode_count_id; + agg_new_idx = max_index(agg_count, slaves_count); + new_agg_id = slaves[agg_new_idx]; break; case AGG_BANDWIDTH: - mode_band_id = max_index( - (uint64_t *)agg_bandwidth, slaves_count); - new_agg_id = mode_band_id; + agg_new_idx = max_index(agg_bandwidth, slaves_count); + new_agg_id = slaves[agg_new_idx]; break; case AGG_STABLE: if (default_slave == slaves_count) - new_agg_id = slave_id; + new_agg_id = slaves[slave_id]; else new_agg_id = slaves[default_slave]; break; default: if (default_slave == slaves_count) - new_agg_id = slave_id; + new_agg_id = slaves[slave_id]; else new_agg_id = slaves[default_slave]; break; @@ -791,7 +798,7 @@ rx_machine_update(struct bond_dev_private *internals, uint16_t slave_id, RTE_ASSERT(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP); partner = &lacp->lacpdu.partner; - if (is_same_ether_addr(&partner->port_params.system, + if (rte_is_same_ether_addr(&partner->port_params.system, &internals->mode4.mac_addr)) { /* This LACP frame is sending to the bonding port * so pass it to rx_machine. @@ -819,18 +826,25 @@ bond_mode_8023ad_periodic_cb(void *arg) /* Update link status on each port */ for (i = 0; i < internals->active_slave_count; i++) { uint16_t key; + int ret; slave_id = internals->active_slaves[i]; - rte_eth_link_get_nowait(slave_id, &link_info); - rte_eth_macaddr_get(slave_id, &slave_addr); + ret = rte_eth_link_get_nowait(slave_id, &link_info); + if (ret < 0) { + RTE_BOND_LOG(ERR, + "Slave (port %u) link get failed: %s\n", + slave_id, rte_strerror(-ret)); + } - if (link_info.link_status != 0) { + if (ret >= 0 && link_info.link_status != 0) { key = link_speed_key(link_info.link_speed) << 1; if (link_info.link_duplex == ETH_LINK_FULL_DUPLEX) key |= BOND_LINK_FULL_DUPLEX_KEY; - } else + } else { key = 0; + } + rte_eth_macaddr_get(slave_id, &slave_addr); port = &bond_mode_8023ad_ports[slave_id]; key = rte_cpu_to_be_16(key); @@ -842,8 +856,8 @@ bond_mode_8023ad_periodic_cb(void *arg) SM_FLAG_SET(port, NTT); } - if (!is_same_ether_addr(&port->actor.system, &slave_addr)) { - ether_addr_copy(&slave_addr, &port->actor.system); + if (!rte_is_same_ether_addr(&port->actor.system, &slave_addr)) { + rte_ether_addr_copy(&slave_addr, &port->actor.system); if (port->aggregator_port_id == slave_id) SM_FLAG_SET(port, NTT); } @@ -908,6 +922,71 @@ bond_mode_8023ad_periodic_cb(void *arg) bond_mode_8023ad_periodic_cb, arg); } +static int +bond_mode_8023ad_register_lacp_mac(uint16_t slave_id) +{ + int ret; + + ret = rte_eth_allmulticast_enable(slave_id); + if (ret != 0) { + RTE_BOND_LOG(ERR, + "failed to enable allmulti mode for port %u: %s", + slave_id, rte_strerror(-ret)); + } + if (rte_eth_allmulticast_get(slave_id)) { + RTE_BOND_LOG(DEBUG, "forced allmulti for port %u", + slave_id); + bond_mode_8023ad_ports[slave_id].forced_rx_flags = + BOND_8023AD_FORCED_ALLMULTI; + return 0; + } + + ret = rte_eth_promiscuous_enable(slave_id); + if (ret != 0) { + RTE_BOND_LOG(ERR, + "failed to enable promiscuous mode for port %u: %s", + slave_id, rte_strerror(-ret)); + } + if (rte_eth_promiscuous_get(slave_id)) { + RTE_BOND_LOG(DEBUG, "forced promiscuous for port %u", + slave_id); + bond_mode_8023ad_ports[slave_id].forced_rx_flags = + BOND_8023AD_FORCED_PROMISC; + return 0; + } + + return -1; +} + +static void +bond_mode_8023ad_unregister_lacp_mac(uint16_t slave_id) +{ + int ret; + + switch (bond_mode_8023ad_ports[slave_id].forced_rx_flags) { + case BOND_8023AD_FORCED_ALLMULTI: + RTE_BOND_LOG(DEBUG, "unset allmulti for port %u", slave_id); + ret = rte_eth_allmulticast_disable(slave_id); + if (ret != 0) + RTE_BOND_LOG(ERR, + "failed to disable allmulti mode for port %u: %s", + slave_id, rte_strerror(-ret)); + break; + + case BOND_8023AD_FORCED_PROMISC: + RTE_BOND_LOG(DEBUG, "unset promisc for port %u", slave_id); + ret = rte_eth_promiscuous_disable(slave_id); + if (ret != 0) + RTE_BOND_LOG(ERR, + "failed to disable promiscuous mode for port %u: %s", + slave_id, rte_strerror(-ret)); + break; + + default: + break; + } +} + void bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev, uint16_t slave_id) @@ -949,7 +1028,11 @@ bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev, /* use this port as agregator */ port->aggregator_port_id = slave_id; - rte_eth_promiscuous_enable(slave_id); + + if (bond_mode_8023ad_register_lacp_mac(slave_id) < 0) { + RTE_BOND_LOG(WARNING, "slave %u is most likely broken and won't receive LACP packets", + slave_id); + } timer_cancel(&port->warning_timer); @@ -1023,6 +1106,8 @@ bond_mode_8023ad_deactivate_slave(struct rte_eth_dev *bond_dev __rte_unused, old_partner_state = port->partner_state; record_default(port); + bond_mode_8023ad_unregister_lacp_mac(slave_id); + /* If partner timeout state changes then disable timer */ if (!((old_partner_state ^ port->partner_state) & STATE_LACP_SHORT_TIMEOUT)) @@ -1055,10 +1140,10 @@ bond_mode_8023ad_mac_address_update(struct rte_eth_dev *bond_dev) slave = &bond_mode_8023ad_ports[slave_id]; rte_eth_macaddr_get(slave_id, &slave_addr); - if (is_same_ether_addr(&slave_addr, &slave->actor.system)) + if (rte_is_same_ether_addr(&slave_addr, &slave->actor.system)) continue; - ether_addr_copy(&slave_addr, &slave->actor.system); + rte_ether_addr_copy(&slave_addr, &slave->actor.system); /* Do nothing if this port is not an aggregator. In other case * Set NTT flag on every port that use this aggregator. */ if (slave->aggregator_port_id != slave_id) @@ -1301,11 +1386,12 @@ rte_eth_bond_8023ad_agg_selection_set(uint16_t port_id, struct bond_dev_private *internals; struct mode8023ad_private *mode4; + if (valid_bonded_port_id(port_id) != 0) + return -EINVAL; + bond_dev = &rte_eth_devices[port_id]; internals = bond_dev->data->dev_private; - if (valid_bonded_port_id(port_id) != 0) - return -EINVAL; if (internals->mode != 4) return -EINVAL; @@ -1322,11 +1408,12 @@ int rte_eth_bond_8023ad_agg_selection_get(uint16_t port_id) struct bond_dev_private *internals; struct mode8023ad_private *mode4; + if (valid_bonded_port_id(port_id) != 0) + return -EINVAL; + bond_dev = &rte_eth_devices[port_id]; internals = bond_dev->data->dev_private; - if (valid_bonded_port_id(port_id) != 0) - return -EINVAL; if (internals->mode != 4) return -EINVAL; mode4 = &internals->mode4; @@ -1579,9 +1666,14 @@ int rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port) { int retval = 0; - struct rte_eth_dev *dev = &rte_eth_devices[port]; - struct bond_dev_private *internals = (struct bond_dev_private *) - dev->data->dev_private; + struct rte_eth_dev *dev; + struct bond_dev_private *internals; + + if (valid_bonded_port_id(port) != 0) + return -EINVAL; + + dev = &rte_eth_devices[port]; + internals = dev->data->dev_private; if (check_for_bonded_ethdev(dev) != 0) return -1; @@ -1603,9 +1695,14 @@ int rte_eth_bond_8023ad_dedicated_queues_disable(uint16_t port) { int retval = 0; - struct rte_eth_dev *dev = &rte_eth_devices[port]; - struct bond_dev_private *internals = (struct bond_dev_private *) - dev->data->dev_private; + struct rte_eth_dev *dev; + struct bond_dev_private *internals; + + if (valid_bonded_port_id(port) != 0) + return -EINVAL; + + dev = &rte_eth_devices[port]; + internals = dev->data->dev_private; if (check_for_bonded_ethdev(dev) != 0) return -1;