From patchwork Wed Sep 30 17:48:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Kinzie X-Patchwork-Id: 7338 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 348928E7D; Wed, 30 Sep 2015 19:48:41 +0200 (CEST) Received: from mail-io0-f175.google.com (mail-io0-f175.google.com [209.85.223.175]) by dpdk.org (Postfix) with ESMTP id 3DF188E6D for ; Wed, 30 Sep 2015 19:48:39 +0200 (CEST) Received: by ioii196 with SMTP id i196so56618911ioi.3 for ; Wed, 30 Sep 2015 10:48:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=biqNBSgC5UIu6QjVqs6ECH1ZfuPHQhG1amnpzrTKJO4=; b=f7awpZ9OOPiOm63B/0XJD3shiPagKMzIPAHk+pE9m3cfnjdnizw/c9yxWt/DzCfxqo zO02w+08MBK8/kaTm/r16vkDMdWX+Ta4ApzJC33vscpd+ltYF+rXrTZyte1yIk3hI5ey 5urHST57Cl9Qp3dJOUpeLtw6aQ4t0hPMhPyBcwMr5upF1XDQqFWpIWEKlzKFTgvaWlku VlI2NkqTwLsziaef6Dv1LC5ha++GYVIn/0Loamjsf67rii6UYBWVPdfyJog7IIlGzLLf nBXR8z+XxrRKVdckvDF/o5CeP8gUIqMVLR5LmXW0FtztEgc12hT5Xs70sMdEj0SgN4q3 Jvzw== X-Received: by 10.107.154.211 with SMTP id c202mr5950335ioe.53.1443635318706; Wed, 30 Sep 2015 10:48:38 -0700 (PDT) Received: from buildhost2.vyatta.com. ([144.49.197.22]) by smtp.gmail.com with ESMTPSA id b10sm753288igb.9.2015.09.30.10.48.36 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 Sep 2015 10:48:37 -0700 (PDT) From: Eric Kinzie To: dev@dpdk.org Date: Wed, 30 Sep 2015 10:48:17 -0700 Message-Id: <1443635297-13106-5-git-send-email-ehkinzie@gmail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1443635297-13106-1-git-send-email-ehkinzie@gmail.com> References: <1443635297-13106-1-git-send-email-ehkinzie@gmail.com> Cc: Eric Kinzie Subject: [dpdk-dev] [PATCH v5 4/4] bond mode 4: tests for external state machine X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Eric Kinzie This adds test cases for exercising the external state machine API to the mode 4 autotest. Signed-off-by: Eric Kinzie --- app/test/test_link_bonding_mode4.c | 210 ++++++++++++++++++++++++++++++++++-- 1 file changed, 201 insertions(+), 9 deletions(-) diff --git a/app/test/test_link_bonding_mode4.c b/app/test/test_link_bonding_mode4.c index d785393..6a459cd 100644 --- a/app/test/test_link_bonding_mode4.c +++ b/app/test/test_link_bonding_mode4.c @@ -151,6 +151,8 @@ static struct rte_eth_conf default_pmd_conf = { .lpbk_mode = 0, }; +static uint8_t lacpdu_rx_count[RTE_MAX_ETHPORTS] = {0, }; + #define FOR_EACH(_i, _item, _array, _size) \ for (_i = 0, _item = &_array[0]; _i < _size && (_item = &_array[_i]); _i++) @@ -320,8 +322,26 @@ remove_slave(struct slave_conf *slave) return 0; } +static void +lacp_recv_cb(uint8_t slave_id, struct rte_mbuf *lacp_pkt) +{ + struct ether_hdr *hdr; + struct slow_protocol_frame *slow_hdr; + + RTE_VERIFY(lacp_pkt != NULL); + + hdr = rte_pktmbuf_mtod(lacp_pkt, struct ether_hdr *); + RTE_VERIFY(hdr->ether_type == rte_cpu_to_be_16(ETHER_TYPE_SLOW)); + + slow_hdr = rte_pktmbuf_mtod(lacp_pkt, struct slow_protocol_frame *); + RTE_VERIFY(slow_hdr->slow_protocol.subtype == SLOW_SUBTYPE_LACP); + + lacpdu_rx_count[slave_id]++; + rte_pktmbuf_free(lacp_pkt); +} + static int -initialize_bonded_device_with_slaves(uint8_t slave_count, uint8_t start) +initialize_bonded_device_with_slaves(uint8_t slave_count, uint8_t external_sm) { uint8_t i; @@ -337,9 +357,17 @@ initialize_bonded_device_with_slaves(uint8_t slave_count, uint8_t start) rte_eth_bond_8023ad_setup(test_params.bonded_port_id, NULL); rte_eth_promiscuous_disable(test_params.bonded_port_id); - if (start) - TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params.bonded_port_id), - "Failed to start bonded device"); + if (external_sm) { + struct rte_eth_bond_8023ad_conf conf; + + rte_eth_bond_8023ad_conf_get(test_params.bonded_port_id, &conf); + conf.slowrx_cb = lacp_recv_cb; + rte_eth_bond_8023ad_setup(test_params.bonded_port_id, &conf); + + } + + TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params.bonded_port_id), + "Failed to start bonded device"); return TEST_SUCCESS; } @@ -642,7 +670,7 @@ test_mode4_lacp(void) { int retval; - retval = initialize_bonded_device_with_slaves(TEST_LACP_SLAVE_COUT, 1); + retval = initialize_bonded_device_with_slaves(TEST_LACP_SLAVE_COUT, 0); TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); /* Test LACP handshake function */ @@ -740,7 +768,7 @@ test_mode4_rx(void) struct ether_addr dst_mac; struct ether_addr bonded_mac; - retval = initialize_bonded_device_with_slaves(TEST_PROMISC_SLAVE_COUNT, 1); + retval = initialize_bonded_device_with_slaves(TEST_PROMISC_SLAVE_COUNT, 0); TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); retval = bond_handshake(); @@ -917,7 +945,7 @@ test_mode4_tx_burst(void) struct ether_addr dst_mac = { { 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 } }; struct ether_addr bonded_mac; - retval = initialize_bonded_device_with_slaves(TEST_TX_SLAVE_COUNT, 1); + retval = initialize_bonded_device_with_slaves(TEST_TX_SLAVE_COUNT, 0); TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); retval = bond_handshake(); @@ -1101,7 +1129,7 @@ test_mode4_marker(void) uint8_t i, j; const uint16_t ethtype_slow_be = rte_be_to_cpu_16(ETHER_TYPE_SLOW); - retval = initialize_bonded_device_with_slaves(TEST_MARKER_SLAVE_COUT, 1); + retval = initialize_bonded_device_with_slaves(TEST_MARKER_SLAVE_COUT, 0); TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); /* Test LACP handshake function */ @@ -1186,7 +1214,7 @@ test_mode4_expired(void) struct rte_eth_bond_8023ad_conf conf; - retval = initialize_bonded_device_with_slaves(TEST_EXPIRED_SLAVE_COUNT, 1); + retval = initialize_bonded_device_with_slaves(TEST_EXPIRED_SLAVE_COUNT, 0); /* Set custom timeouts to make test last shorter. */ rte_eth_bond_8023ad_conf_get(test_params.bonded_port_id, &conf); conf.fast_periodic_ms = 100; @@ -1268,6 +1296,156 @@ test_mode4_expired(void) } static int +test_mode4_ext_ctrl(void) +{ + /* + * configure bonded interface without the external sm enabled + * . try to transmit lacpdu (should fail) + * . try to set collecting and distributing flags (should fail) + * reconfigure w/external sm + * . transmit one lacpdu on each slave using new api + * . make sure each slave receives one lacpdu using the callback api + * . transmit one data pdu on each slave (should fail) + * . enable distribution and collection, send one data pdu each again + */ + + int retval; + struct slave_conf *slave = NULL; + uint8_t i; + + struct rte_mbuf *lacp_tx_buf[SLAVE_COUNT]; + struct ether_addr src_mac, dst_mac; + struct lacpdu_header lacpdu = { + .lacpdu = { + .subtype = SLOW_SUBTYPE_LACP, + }, + }; + + ether_addr_copy(&parnter_system, &src_mac); + ether_addr_copy(&slow_protocol_mac_addr, &dst_mac); + + initialize_eth_header(&lacpdu.eth_hdr, &src_mac, &dst_mac, + ETHER_TYPE_SLOW, 0, 0); + + for (i = 0; i < SLAVE_COUNT; i++) { + lacp_tx_buf[i] = rte_pktmbuf_alloc(test_params.mbuf_pool); + rte_memcpy(rte_pktmbuf_mtod(lacp_tx_buf[i], char *), + &lacpdu, sizeof(lacpdu)); + rte_pktmbuf_pkt_len(lacp_tx_buf[i]) = sizeof(lacpdu); + } + + retval = initialize_bonded_device_with_slaves(TEST_TX_SLAVE_COUNT, 0); + TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); + + FOR_EACH_SLAVE(i, slave) { + TEST_ASSERT_FAIL(rte_eth_bond_8023ad_ext_slowtx( + test_params.bonded_port_id, + slave->port_id, lacp_tx_buf[i]), + "Slave should not allow manual LACP xmit"); + TEST_ASSERT_FAIL(rte_eth_bond_8023ad_ext_collect( + test_params.bonded_port_id, + slave->port_id, 1), + "Slave should not allow external state controls"); + } + + free_pkts(lacp_tx_buf, RTE_DIM(lacp_tx_buf)); + + retval = remove_slaves_and_stop_bonded_device(); + TEST_ASSERT_SUCCESS(retval, "Bonded device cleanup failed."); + + return TEST_SUCCESS; +} + + +static int +test_mode4_ext_lacp(void) +{ + int retval; + struct slave_conf *slave = NULL; + uint8_t all_slaves_done = 0, i; + uint16_t nb_pkts; + const unsigned delay = bond_get_update_timeout_ms(); + + struct rte_mbuf *lacp_tx_buf[SLAVE_COUNT]; + struct rte_mbuf *buf[SLAVE_COUNT]; + struct ether_addr src_mac, dst_mac; + struct lacpdu_header lacpdu = { + .lacpdu = { + .subtype = SLOW_SUBTYPE_LACP, + }, + }; + + ether_addr_copy(&parnter_system, &src_mac); + ether_addr_copy(&slow_protocol_mac_addr, &dst_mac); + + initialize_eth_header(&lacpdu.eth_hdr, &src_mac, &dst_mac, + ETHER_TYPE_SLOW, 0, 0); + + for (i = 0; i < SLAVE_COUNT; i++) { + lacp_tx_buf[i] = rte_pktmbuf_alloc(test_params.mbuf_pool); + rte_memcpy(rte_pktmbuf_mtod(lacp_tx_buf[i], char *), + &lacpdu, sizeof(lacpdu)); + rte_pktmbuf_pkt_len(lacp_tx_buf[i]) = sizeof(lacpdu); + } + + retval = initialize_bonded_device_with_slaves(TEST_TX_SLAVE_COUNT, 1); + TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); + + memset(lacpdu_rx_count, 0, sizeof(lacpdu_rx_count)); + + /* Wait for new settings to be applied. */ + for (i = 0; i < 30; ++i) + rte_delay_ms(delay); + + FOR_EACH_SLAVE(i, slave) { + retval = rte_eth_bond_8023ad_ext_slowtx( + test_params.bonded_port_id, + slave->port_id, lacp_tx_buf[i]); + TEST_ASSERT_SUCCESS(retval, + "Slave should allow manual LACP xmit"); + } + + nb_pkts = bond_tx(NULL, 0); + TEST_ASSERT_EQUAL(nb_pkts, 0, "Packets transmitted unexpectedly"); + + FOR_EACH_SLAVE(i, slave) { + nb_pkts = slave_get_pkts(slave, buf, RTE_DIM(buf)); + TEST_ASSERT_EQUAL(nb_pkts, 1, "found %u packets on slave %d\n", + nb_pkts, i); + slave_put_pkts(slave, buf, nb_pkts); + } + + nb_pkts = bond_rx(buf, RTE_DIM(buf)); + free_pkts(buf, nb_pkts); + TEST_ASSERT_EQUAL(nb_pkts, 0, "Packets received unexpectedly"); + + /* wait for the periodic callback to run */ + for (i = 0; i < 30 && all_slaves_done == 0; ++i) { + uint8_t s, total = 0; + + rte_delay_ms(delay); + FOR_EACH_SLAVE(s, slave) { + total += lacpdu_rx_count[slave->port_id]; + } + + if (total >= SLAVE_COUNT) + all_slaves_done = 1; + } + + FOR_EACH_SLAVE(i, slave) { + TEST_ASSERT_EQUAL(lacpdu_rx_count[slave->port_id], 1, + "Slave port %u should have received 1 lacpdu (count=%u)", + slave->port_id, + lacpdu_rx_count[slave->port_id]); + } + + retval = remove_slaves_and_stop_bonded_device(); + TEST_ASSERT_SUCCESS(retval, "Test cleanup failed."); + + return TEST_SUCCESS; +} + +static int check_environment(void) { struct slave_conf *port; @@ -1383,6 +1561,18 @@ test_mode4_expired_wrapper(void) return test_mode4_executor(&test_mode4_expired); } +static int +test_mode4_ext_ctrl_wrapper(void) +{ + return test_mode4_executor(&test_mode4_ext_ctrl); +} + +static int +test_mode4_ext_lacp_wrapper(void) +{ + return test_mode4_executor(&test_mode4_ext_lacp); +} + static struct unit_test_suite link_bonding_mode4_test_suite = { .suite_name = "Link Bonding mode 4 Unit Test Suite", .setup = test_setup, @@ -1393,6 +1583,8 @@ static struct unit_test_suite link_bonding_mode4_test_suite = { TEST_CASE_NAMED("test_mode4_tx_burst", test_mode4_tx_burst_wrapper), TEST_CASE_NAMED("test_mode4_marker", test_mode4_marker_wrapper), TEST_CASE_NAMED("test_mode4_expired", test_mode4_expired_wrapper), + TEST_CASE_NAMED("test_mode4_ext_ctrl", test_mode4_ext_ctrl_wrapper), + TEST_CASE_NAMED("test_mode4_ext_lacp", test_mode4_ext_lacp_wrapper), { NULL, NULL, NULL, NULL, NULL } /**< NULL terminate unit test array */ } };