#include "test.h"
-#define TEST_MAX_NUMBER_OF_PORTS (16)
+#define TEST_MAX_NUMBER_OF_PORTS (6)
#define RX_RING_SIZE 128
#define RX_FREE_THRESH 32
ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \
ETH_TXQ_FLAGS_NOXSUMTCP)
-#define MBUF_PAYLOAD_SIZE (2048)
-#define MBUF_SIZE (MBUF_PAYLOAD_SIZE + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
+#define MBUF_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
#define MBUF_CACHE_SIZE (250)
#define BURST_SIZE (32)
.mode = RTE_FDIR_MODE_NONE,
.pballoc = RTE_FDIR_PBALLOC_64K,
.status = RTE_FDIR_REPORT_STATUS,
- .flexbytes_offset = 0x6,
.drop_queue = 127,
};
nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
if (test_params->mbuf_pool == NULL) {
- test_params->mbuf_pool = rte_mempool_create("MBUF_POOL", nb_mbuf_per_pool,
- MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private),
- rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
- rte_socket_id(), 0);
+ test_params->mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+ nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+ rte_socket_id());
TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
"rte_mempool_create failed");
}
mac_addr = (struct ether_addr *)slave_mac;
mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
- test_params->slave_port_ids[test_params->bonded_slave_count-1];
+ test_params->bonded_slave_count-1;
rte_eth_macaddr_get(
test_params->slave_port_ids[test_params->bonded_slave_count-1],
int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
BONDING_MODE_ACTIVE_BACKUP,
BONDING_MODE_BALANCE,
-#ifdef RTE_MBUF_REFCNT
BONDING_MODE_BROADCAST
-#endif
};
/* Test supported link bonding modes */
test_params->bonded_port_id);
expected_mac_addr = (struct ether_addr *)&slave_mac;
- expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
- test_params->slave_port_ids[i];
+ expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
/* Check primary slave MAC */
rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
return 0;
}
+#define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3)
+
+static int
+test_set_bonded_port_initialization_mac_assignment(void)
+{
+ int i, slave_count, bonded_port_id;
+
+ uint8_t slaves[RTE_MAX_ETHPORTS];
+ int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT];
+
+ struct ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr;
+
+ /* Initialize default values for MAC addresses */
+ memcpy(&slave_mac_addr, slave_mac, sizeof(struct ether_addr));
+ memcpy(&bonded_mac_addr, slave_mac, sizeof(struct ether_addr));
+
+ /*
+ * 1. a - Create / configure bonded / slave ethdevs
+ */
+ bonded_port_id = rte_eth_bond_create("ethdev_bond_mac_ass_test",
+ BONDING_MODE_ACTIVE_BACKUP, rte_socket_id());
+ TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device");
+
+ TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0),
+ "Failed to configure bonded ethdev");
+
+ for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
+ char pmd_name[RTE_ETH_NAME_MAX_LEN];
+
+ slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = i + 100;
+
+ snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_slave_%d", i);
+
+ slave_port_ids[i] = virtual_ethdev_create(pmd_name,
+ &slave_mac_addr, rte_socket_id(), 1);
+
+ TEST_ASSERT(slave_port_ids[i] >= 0,
+ "Failed to create slave ethdev %s", pmd_name);
+
+ TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0),
+ "Failed to configure virtual ethdev %s",
+ pmd_name);
+ }
+
+
+ /*
+ * 2. Add slave ethdevs to bonded device
+ */
+ for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
+ TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id,
+ slave_port_ids[i]),
+ "Failed to add slave (%d) to bonded port (%d).",
+ slave_port_ids[i], bonded_port_id);
+ }
+
+ slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
+ RTE_MAX_ETHPORTS);
+ TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count,
+ "Number of slaves (%d) is not as expected (%d)",
+ slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT);
+
+
+ /*
+ * 3. Set explicit MAC address on bonded ethdev
+ */
+ bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-2] = 0xFF;
+ bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0xAA;
+
+ TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
+ bonded_port_id, &bonded_mac_addr),
+ "Failed to set MAC address on bonded port (%d)",
+ bonded_port_id);
+
+
+ /* 4. a - Start bonded ethdev
+ * b - Enable slave devices
+ * c - Verify bonded/slaves ethdev MAC addresses
+ */
+ TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
+ "Failed to start bonded pmd eth device %d.",
+ bonded_port_id);
+
+ for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
+ virtual_ethdev_simulate_link_status_interrupt(
+ slave_port_ids[i], 1);
+ }
+
+ rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
+ TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
+ sizeof(read_mac_addr)),
+ "bonded port mac address not as expected");
+
+ rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
+ TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
+ sizeof(read_mac_addr)),
+ "slave port 0 mac address not as expected");
+
+ slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
+ rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
+ TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
+ sizeof(read_mac_addr)),
+ "slave port 1 mac address not as expected");
+
+ slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
+ rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
+ TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
+ sizeof(read_mac_addr)),
+ "slave port 2 mac address not as expected");
+
+
+ /* 7. a - Change primary port
+ * b - Stop / Start bonded port
+ * d - Verify slave ethdev MAC addresses
+ */
+ TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id,
+ slave_port_ids[2]),
+ "failed to set primary port on bonded device.");
+
+ rte_eth_dev_stop(bonded_port_id);
+ TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
+ "Failed to start bonded pmd eth device %d.",
+ bonded_port_id);
+
+ rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
+ TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
+ sizeof(read_mac_addr)),
+ "bonded port mac address not as expected");
+
+ slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
+ rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
+ TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
+ sizeof(read_mac_addr)),
+ "slave port 0 mac address not as expected");
+
+ slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
+ rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
+ TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
+ sizeof(read_mac_addr)),
+ "slave port 1 mac address not as expected");
+
+ rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
+ TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
+ sizeof(read_mac_addr)),
+ "slave port 2 mac address not as expected");
+
+ /* 6. a - Stop bonded ethdev
+ * b - remove slave ethdevs
+ * c - Verify slave ethdevs MACs are restored
+ */
+ rte_eth_dev_stop(bonded_port_id);
+
+ for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
+ TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id,
+ slave_port_ids[i]),
+ "Failed to remove slave %d from bonded port (%d).",
+ slave_port_ids[i], bonded_port_id);
+ }
+
+ slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
+ RTE_MAX_ETHPORTS);
+
+ TEST_ASSERT_EQUAL(slave_count, 0,
+ "Number of slaves (%d) is great than expected (%d).",
+ slave_count, 0);
+
+ slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
+ rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
+ TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
+ sizeof(read_mac_addr)),
+ "slave port 0 mac address not as expected");
+
+ slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
+ rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
+ TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
+ sizeof(read_mac_addr)),
+ "slave port 1 mac address not as expected");
+
+ slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
+ rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
+ TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
+ sizeof(read_mac_addr)),
+ "slave port 2 mac address not as expected");
+
+ return 0;
+}
+
static int
initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
{
- uint16_t pktlen, generated_burst_size;
+ uint16_t pktlen, generated_burst_size, ether_type;
void *ip_hdr;
+ if (ipv4)
+ ether_type = ETHER_TYPE_IPv4;
+ else
+ ether_type = ETHER_TYPE_IPv6;
+
if (toggle_dst_mac)
initialize_eth_header(test_params->pkt_eth_hdr,
(struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
- vlan, vlan_id);
+ ether_type, vlan, vlan_id);
else
initialize_eth_header(test_params->pkt_eth_hdr,
(struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
- vlan, vlan_id);
+ ether_type, vlan, vlan_id);
if (toggle_udp_port)
return remove_slaves_and_stop_bonded_device();
}
-#ifdef RTE_MBUF_REFCNT
static int
verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
{
}
return 0;
}
-#endif
-
static void
free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
(unsigned int)port_stats.opackets, slave_expected_tx_count);
}
-#ifdef RTE_MBUF_REFCNT
/* Verify that all mbufs have a ref value of zero */
TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
"mbufs refcnts not as expected");
-#endif
free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
/* Clean up and remove slaves from bonded device */
"Failed to initialize bonded device with slaves");
initialize_eth_header(test_params->pkt_eth_hdr,
- (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
+ (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
+ ETHER_TYPE_IPv4, 0, 0);
pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
dst_port_0, 16);
pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
"Failed to set balance xmit policy.");
initialize_eth_header(test_params->pkt_eth_hdr,
- (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
+ (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
+ ETHER_TYPE_IPv4, 0, 0);
pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
dst_port_0, 16);
pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
"failed to generate packet burst");
initialize_eth_header(test_params->pkt_eth_hdr,
- (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1, 0, 0);
+ (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
+ ETHER_TYPE_IPv4, 0, 0);
/* Generate a burst 2 of packets to transmit */
TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
(unsigned int)port_stats.opackets,
TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
-#ifdef RTE_MBUF_REFCNT
/* Verify that all mbufs have a ref value of zero */
TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
"mbufs refcnts not as expected");
-#endif
free_mbufs(&pkts_burst_1[tx_count_1],
TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
return remove_slaves_and_stop_bonded_device();
}
-#ifdef RTE_MBUF_REFCNT
-/** Broadcast Mode Tests */
-
static int
test_broadcast_tx_burst(void)
{
"Failed to intialise bonded device");
initialize_eth_header(test_params->pkt_eth_hdr,
- (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
+ (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
+ ETHER_TYPE_IPv4, 0, 0);
pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
dst_port_0, 16);
/* Clean up and remove slaves from bonded device */
return remove_slaves_and_stop_bonded_device();
}
-#endif
static int
test_reconfigure_bonded_device(void)
return remove_slaves_and_stop_bonded_device();
}
+static void
+free_virtualpmd_tx_queue(void)
+{
+ int i, slave_port, to_free_cnt;
+ struct rte_mbuf *pkts_to_free[MAX_PKT_BURST];
+
+ /* Free tx queue of virtual pmd */
+ for (slave_port = 0; slave_port < test_params->bonded_slave_count;
+ slave_port++) {
+ to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue(
+ test_params->slave_port_ids[slave_port],
+ pkts_to_free, MAX_PKT_BURST);
+ for (i = 0; i < to_free_cnt; i++)
+ rte_pktmbuf_free(pkts_to_free[i]);
+ }
+}
+
static int
test_tlb_tx_burst(void)
{
uint64_t floor_obytes = 0, ceiling_obytes = 0;
TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
- (BONDING_MODE_ADAPTIVE_TRANSMIT_LOAD_BALANCING, 1, 3, 1),
+ (BONDING_MODE_TLB, 1, 3, 1),
"Failed to initialise bonded device");
burst_size = 20 * test_params->bonded_slave_count;
if (i % 2 == 0) {
initialize_eth_header(test_params->pkt_eth_hdr,
(struct ether_addr *)src_mac,
- (struct ether_addr *)dst_mac_0, 0, 0);
+ (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
} else {
initialize_eth_header(test_params->pkt_eth_hdr,
(struct ether_addr *)test_params->default_slave_mac,
- (struct ether_addr *)dst_mac_0, 0, 0);
+ (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
}
pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
dst_port_0, 16);
burst_size);
nb_tx2 += nb_tx;
+ free_virtualpmd_tx_queue();
+
TEST_ASSERT_EQUAL(nb_tx, burst_size,
"number of packet not equal burst size");
/* Initialize bonded device with 4 slaves in transmit load balancing mode */
TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
- BONDING_MODE_ADAPTIVE_TRANSMIT_LOAD_BALANCING,
+ BONDING_MODE_TLB,
TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
"Failed to initialize bonded device");
/* Initialize bonded device with 4 slaves in transmit load balancing mode */
TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
- BONDING_MODE_ADAPTIVE_TRANSMIT_LOAD_BALANCING, 0, 4, 1),
+ BONDING_MODE_TLB, 0, 4, 1),
"Failed to initialize bonded device");
primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
/* Initialize bonded device with 2 slaves in active backup mode */
TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
- BONDING_MODE_ADAPTIVE_TRANSMIT_LOAD_BALANCING, 0, 2, 1),
+ BONDING_MODE_TLB, 0, 2, 1),
"Failed to initialize bonded device");
/* Verify that bonded MACs is that of first slave and that the other slave
/* Initialize bonded device with 4 slaves in round robin mode */
TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
- BONDING_MODE_ADAPTIVE_TRANSMIT_LOAD_BALANCING, 0,
+ BONDING_MODE_TLB, 0,
TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
"Failed to initialize bonded device with slaves");
rte_delay_us(11000);
}
- rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
- TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
- "(%d) port_stats.opackets not as expected\n",
- test_params->slave_port_ids[2]);
-
rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
"(%d) port_stats.opackets not as expected\n",
"(%d) port_stats.opackets not as expected\n",
test_params->slave_port_ids[1]);
+ rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
+ TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
+ "(%d) port_stats.opackets not as expected\n",
+ test_params->slave_port_ids[2]);
+
rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
"(%d) port_stats.opackets not as expected\n",
return remove_slaves_and_stop_bonded_device();
}
+#define TEST_ALB_SLAVE_COUNT 2
+
+static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1};
+static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2};
+static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3};
+static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4};
+
+static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0);
+static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1);
+static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2);
+static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3);
+static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4);
+
+static int
+test_alb_change_mac_in_reply_sent(void)
+{
+ struct rte_mbuf *pkt;
+ struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
+
+ struct ether_hdr *eth_pkt;
+ struct arp_hdr *arp_pkt;
+
+ int slave_idx, nb_pkts, pkt_idx;
+ int retval = 0;
+
+ struct ether_addr bond_mac, client_mac;
+ struct ether_addr *slave_mac1, *slave_mac2;
+
+ TEST_ASSERT_SUCCESS(
+ initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
+ 0, TEST_ALB_SLAVE_COUNT, 1),
+ "Failed to initialize_bonded_device_with_slaves.");
+
+ /* Flush tx queue */
+ rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
+ for (slave_idx = 0; slave_idx < test_params->bonded_slave_count;
+ slave_idx++) {
+ nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
+ test_params->slave_port_ids[slave_idx], pkts_sent,
+ MAX_PKT_BURST);
+ }
+
+ ether_addr_copy(
+ rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
+ &bond_mac);
+
+ /*
+ * Generating four packets with different mac and ip addresses and sending
+ * them through the bonding port.
+ */
+ pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+ memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
+ eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+ initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
+ 0);
+ arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+ initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1,
+ ARP_OP_REPLY);
+ rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
+
+ pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+ memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
+ eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+ initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
+ 0);
+ arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+ initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2,
+ ARP_OP_REPLY);
+ rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
+
+ pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+ memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
+ eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+ initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
+ 0);
+ arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+ initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3,
+ ARP_OP_REPLY);
+ rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
+
+ pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+ memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
+ eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+ initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
+ 0);
+ arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+ initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4,
+ ARP_OP_REPLY);
+ rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
+
+ slave_mac1 =
+ rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
+ slave_mac2 =
+ rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
+
+ /*
+ * Checking if packets are properly distributed on bonding ports. Packets
+ * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1.
+ */
+ for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
+ nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
+ test_params->slave_port_ids[slave_idx], pkts_sent,
+ MAX_PKT_BURST);
+
+ for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
+ eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
+ arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+
+ if (slave_idx%2 == 0) {
+ if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
+ retval = -1;
+ goto test_end;
+ }
+ } else {
+ if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
+ retval = -1;
+ goto test_end;
+ }
+ }
+ }
+ }
+
+test_end:
+ retval += remove_slaves_and_stop_bonded_device();
+ return retval;
+}
+
+static int
+test_alb_reply_from_client(void)
+{
+ struct ether_hdr *eth_pkt;
+ struct arp_hdr *arp_pkt;
+
+ struct rte_mbuf *pkt;
+ struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
+
+ int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0;
+ int retval = 0;
+
+ struct ether_addr bond_mac, client_mac;
+ struct ether_addr *slave_mac1, *slave_mac2;
+
+ TEST_ASSERT_SUCCESS(
+ initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
+ 0, TEST_ALB_SLAVE_COUNT, 1),
+ "Failed to initialize_bonded_device_with_slaves.");
+
+ /* Flush tx queue */
+ rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
+ for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
+ nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
+ test_params->slave_port_ids[slave_idx], pkts_sent,
+ MAX_PKT_BURST);
+ }
+
+ ether_addr_copy(
+ rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
+ &bond_mac);
+
+ /*
+ * Generating four packets with different mac and ip addresses and placing
+ * them in the rx queue to be received by the bonding driver on rx_burst.
+ */
+ pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+ memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
+ eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+ initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
+ 0);
+ arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+ initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
+ ARP_OP_REPLY);
+ virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
+ 1);
+
+ pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+ memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
+ eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+ initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
+ 0);
+ arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+ initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host,
+ ARP_OP_REPLY);
+ virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
+ 1);
+
+ pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+ memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
+ eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+ initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
+ 0);
+ arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+ initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host,
+ ARP_OP_REPLY);
+ virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
+ 1);
+
+ pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+ memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
+ eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+ initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
+ 0);
+ arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+ initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host,
+ ARP_OP_REPLY);
+ virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
+ 1);
+
+ /*
+ * Issue rx_burst and tx_burst to force bonding driver to send update ARP
+ * packets to every client in alb table.
+ */
+ rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
+ rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
+
+ slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
+ slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
+
+ /*
+ * Checking if update ARP packets were properly send on slave ports.
+ */
+ for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
+ nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
+ test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST);
+ nb_pkts_sum += nb_pkts;
+
+ for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
+ eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
+ arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+
+ if (slave_idx%2 == 0) {
+ if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
+ retval = -1;
+ goto test_end;
+ }
+ } else {
+ if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
+ retval = -1;
+ goto test_end;
+ }
+ }
+ }
+ }
+
+ /* Check if proper number of packets was send */
+ if (nb_pkts_sum < 4) {
+ retval = -1;
+ goto test_end;
+ }
+
+test_end:
+ retval += remove_slaves_and_stop_bonded_device();
+ return retval;
+}
+
+static int
+test_alb_receive_vlan_reply(void)
+{
+ struct ether_hdr *eth_pkt;
+ struct vlan_hdr *vlan_pkt;
+ struct arp_hdr *arp_pkt;
+
+ struct rte_mbuf *pkt;
+ struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
+
+ int slave_idx, nb_pkts, pkt_idx;
+ int retval = 0;
+
+ struct ether_addr bond_mac, client_mac;
+
+ TEST_ASSERT_SUCCESS(
+ initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
+ 0, TEST_ALB_SLAVE_COUNT, 1),
+ "Failed to initialize_bonded_device_with_slaves.");
+
+ /* Flush tx queue */
+ rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
+ for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
+ nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
+ test_params->slave_port_ids[slave_idx], pkts_sent,
+ MAX_PKT_BURST);
+ }
+
+ ether_addr_copy(
+ rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
+ &bond_mac);
+
+ /*
+ * Generating packet with double VLAN header and placing it in the rx queue.
+ */
+ pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+ memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
+ eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+ initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_VLAN, 0,
+ 0);
+ vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
+ vlan_pkt->vlan_tci = rte_cpu_to_be_16(1);
+ vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
+ vlan_pkt = vlan_pkt+1;
+ vlan_pkt->vlan_tci = rte_cpu_to_be_16(2);
+ vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_ARP);
+ arp_pkt = (struct arp_hdr *)((char *)(vlan_pkt + 1));
+ initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
+ ARP_OP_REPLY);
+ virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
+ 1);
+
+ rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
+ rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
+
+ /*
+ * Checking if VLAN headers in generated ARP Update packet are correct.
+ */
+ for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
+ nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
+ test_params->slave_port_ids[slave_idx], pkts_sent,
+ MAX_PKT_BURST);
+
+ for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
+ eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
+ vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
+ if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) {
+ retval = -1;
+ goto test_end;
+ }
+ if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_VLAN)) {
+ retval = -1;
+ goto test_end;
+ }
+ vlan_pkt = vlan_pkt+1;
+ if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) {
+ retval = -1;
+ goto test_end;
+ }
+ if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_ARP)) {
+ retval = -1;
+ goto test_end;
+ }
+ }
+ }
+
+test_end:
+ retval += remove_slaves_and_stop_bonded_device();
+ return retval;
+}
+
+static int
+test_alb_ipv4_tx(void)
+{
+ int burst_size, retval, pkts_send;
+ struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
+
+ retval = 0;
+
+ TEST_ASSERT_SUCCESS(
+ initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
+ 0, TEST_ALB_SLAVE_COUNT, 1),
+ "Failed to initialize_bonded_device_with_slaves.");
+
+ burst_size = 32;
+
+ /* Generate test bursts of packets to transmit */
+ if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) {
+ retval = -1;
+ goto test_end;
+ }
+
+ /*
+ * Checking if ipv4 traffic is transmitted via TLB policy.
+ */
+ pkts_send = rte_eth_tx_burst(
+ test_params->bonded_port_id, 0, pkt_burst, burst_size);
+ if (pkts_send != burst_size) {
+ retval = -1;
+ goto test_end;
+ }
+
+test_end:
+ retval += remove_slaves_and_stop_bonded_device();
+ return retval;
+}
static struct unit_test_suite link_bonding_test_suite = {
.suite_name = "Link Bonding Unit Test Suite",
TEST_CASE(test_set_bonding_mode),
TEST_CASE(test_set_primary_slave),
TEST_CASE(test_set_explicit_bonded_mac),
+ TEST_CASE(test_set_bonded_port_initialization_mac_assignment),
TEST_CASE(test_status_interrupt),
TEST_CASE(test_adding_slave_after_bonded_device_started),
TEST_CASE(test_roundrobin_tx_burst),
TEST_CASE(test_tlb_verify_mac_assignment),
TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
-#ifdef RTE_MBUF_REFCNT
+ TEST_CASE(test_alb_change_mac_in_reply_sent),
+ TEST_CASE(test_alb_reply_from_client),
+ TEST_CASE(test_alb_receive_vlan_reply),
+ TEST_CASE(test_alb_ipv4_tx),
TEST_CASE(test_broadcast_tx_burst),
TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
TEST_CASE(test_broadcast_rx_burst),
TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
TEST_CASE(test_broadcast_verify_mac_assignment),
TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
-#endif
TEST_CASE(test_reconfigure_bonded_device),
TEST_CASE(test_close_bonded_device),