LCOV - code coverage report
Current view: top level - app/test - test_link_bonding_mode4.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 1 513 0.2 %
Date: 2025-03-01 20:23:48 Functions: 1 36 2.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 602 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2010-2014 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <string.h>
       6                 :            : #include <stdarg.h>
       7                 :            : #include <stdio.h>
       8                 :            : #include <stdlib.h>
       9                 :            : #include <stdint.h>
      10                 :            : #include <inttypes.h>
      11                 :            : #include <errno.h>
      12                 :            : #include <rte_cycles.h>
      13                 :            : #include <sys/queue.h>
      14                 :            : 
      15                 :            : #include <rte_byteorder.h>
      16                 :            : #include <rte_common.h>
      17                 :            : #include <rte_debug.h>
      18                 :            : #include <rte_ethdev.h>
      19                 :            : #include <rte_log.h>
      20                 :            : #include <rte_lcore.h>
      21                 :            : #include <rte_memory.h>
      22                 :            : 
      23                 :            : #include <rte_string_fns.h>
      24                 :            : 
      25                 :            : #include <rte_eth_ring.h>
      26                 :            : #include <rte_errno.h>
      27                 :            : #include <rte_eth_bond.h>
      28                 :            : #include <rte_eth_bond_8023ad.h>
      29                 :            : 
      30                 :            : #include "packet_burst_generator.h"
      31                 :            : 
      32                 :            : #include "test.h"
      33                 :            : 
      34                 :            : #define MEMBER_COUNT (4)
      35                 :            : 
      36                 :            : #define RX_RING_SIZE 1024
      37                 :            : #define TX_RING_SIZE 1024
      38                 :            : 
      39                 :            : #define MBUF_CACHE_SIZE         (250)
      40                 :            : #define BURST_SIZE              (32)
      41                 :            : 
      42                 :            : #define TEST_RX_DESC_MAX        (2048)
      43                 :            : #define TEST_TX_DESC_MAX        (2048)
      44                 :            : #define MAX_PKT_BURST           (32)
      45                 :            : #define DEF_PKT_BURST           (16)
      46                 :            : 
      47                 :            : #define BONDING_DEV_NAME         ("net_bonding_m4_bond_dev")
      48                 :            : 
      49                 :            : #define MEMBER_DEV_NAME_FMT      ("net_virt_%d")
      50                 :            : #define MEMBER_RX_QUEUE_FMT      ("net_virt_%d_rx")
      51                 :            : #define MEMBER_TX_QUEUE_FMT      ("net_virt_%d_tx")
      52                 :            : 
      53                 :            : #define INVALID_SOCKET_ID       (-1)
      54                 :            : #define INVALID_PORT_ID         (0xFF)
      55                 :            : #define INVALID_BONDING_MODE    (-1)
      56                 :            : 
      57                 :            : static const struct rte_ether_addr member_mac_default = {
      58                 :            :         { 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 }
      59                 :            : };
      60                 :            : 
      61                 :            : static const struct rte_ether_addr parnter_mac_default = {
      62                 :            :         { 0x22, 0xBB, 0xFF, 0xBB, 0x00, 0x00 }
      63                 :            : };
      64                 :            : 
      65                 :            : static const struct rte_ether_addr parnter_system = {
      66                 :            :         { 0x33, 0xFF, 0xBB, 0xFF, 0x00, 0x00 }
      67                 :            : };
      68                 :            : 
      69                 :            : static const struct rte_ether_addr slow_protocol_mac_addr = {
      70                 :            :         { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x02 }
      71                 :            : };
      72                 :            : 
      73                 :            : struct member_conf {
      74                 :            :         struct rte_ring *rx_queue;
      75                 :            :         struct rte_ring *tx_queue;
      76                 :            :         uint16_t port_id;
      77                 :            :         uint8_t bonding : 1;
      78                 :            : 
      79                 :            :         uint8_t lacp_parnter_state;
      80                 :            : };
      81                 :            : 
      82                 :            : struct ether_vlan_hdr {
      83                 :            :         struct rte_ether_hdr pkt_eth_hdr;
      84                 :            :         struct rte_vlan_hdr vlan_hdr;
      85                 :            : };
      86                 :            : 
      87                 :            : struct link_bonding_unittest_params {
      88                 :            :         uint8_t bonding_port_id;
      89                 :            :         struct member_conf member_ports[MEMBER_COUNT];
      90                 :            : 
      91                 :            :         struct rte_mempool *mbuf_pool;
      92                 :            : };
      93                 :            : 
      94                 :            : #define TEST_DEFAULT_MEMBER_COUNT     RTE_DIM(test_params.member_ports)
      95                 :            : #define TEST_RX_MEMBER_COUT           TEST_DEFAULT_MEMBER_COUNT
      96                 :            : #define TEST_TX_MEMBER_COUNT          TEST_DEFAULT_MEMBER_COUNT
      97                 :            : #define TEST_MARKER_MEMBER_COUT       TEST_DEFAULT_MEMBER_COUNT
      98                 :            : #define TEST_EXPIRED_MEMBER_COUNT     TEST_DEFAULT_MEMBER_COUNT
      99                 :            : #define TEST_PROMISC_MEMBER_COUNT     TEST_DEFAULT_MEMBER_COUNT
     100                 :            : 
     101                 :            : static struct link_bonding_unittest_params test_params  = {
     102                 :            :         .bonding_port_id = INVALID_PORT_ID,
     103                 :            :         .member_ports = { [0 ... MEMBER_COUNT - 1] = { .port_id = INVALID_PORT_ID} },
     104                 :            : 
     105                 :            :         .mbuf_pool = NULL,
     106                 :            : };
     107                 :            : 
     108                 :            : static struct rte_eth_conf default_pmd_conf = {
     109                 :            :         .rxmode = {
     110                 :            :                 .mq_mode = RTE_ETH_MQ_RX_NONE,
     111                 :            :         },
     112                 :            :         .txmode = {
     113                 :            :                 .mq_mode = RTE_ETH_MQ_TX_NONE,
     114                 :            :         },
     115                 :            :         .lpbk_mode = 0,
     116                 :            : };
     117                 :            : 
     118                 :            : static uint8_t lacpdu_rx_count[RTE_MAX_ETHPORTS] = {0, };
     119                 :            : 
     120                 :            : #define FOR_EACH(_i, _item, _array, _size) \
     121                 :            :         for (_i = 0, _item = &_array[0]; _i < _size && (_item = &_array[_i]); _i++)
     122                 :            : 
     123                 :            : /* Macro for iterating over every port that can be used as a member
     124                 :            :  * in this test.
     125                 :            :  * _i variable used as an index in test_params->member_ports
     126                 :            :  * _member pointer to &test_params->member_ports[_idx]
     127                 :            :  */
     128                 :            : #define FOR_EACH_PORT(_i, _port) \
     129                 :            :         FOR_EACH(_i, _port, test_params.member_ports, \
     130                 :            :                 RTE_DIM(test_params.member_ports))
     131                 :            : 
     132                 :            : /* Macro for iterating over every port that can be used as a member
     133                 :            :  * in this test and satisfy given condition.
     134                 :            :  *
     135                 :            :  * _i variable used as an index in test_params->member_ports
     136                 :            :  * _member pointer to &test_params->member_ports[_idx]
     137                 :            :  * _condition condition that need to be checked
     138                 :            :  */
     139                 :            : #define FOR_EACH_PORT_IF(_i, _port, _condition) FOR_EACH_PORT((_i), (_port)) \
     140                 :            :         if (!!(_condition))
     141                 :            : 
     142                 :            : /* Macro for iterating over every port that is currently a member of a bonding
     143                 :            :  * device.
     144                 :            :  * _i variable used as an index in test_params->member_ports
     145                 :            :  * _member pointer to &test_params->member_ports[_idx]
     146                 :            :  * */
     147                 :            : #define FOR_EACH_MEMBER(_i, _member) \
     148                 :            :         FOR_EACH_PORT_IF(_i, _member, (_member)->bonding != 0)
     149                 :            : 
     150                 :            : /*
     151                 :            :  * Returns packets from members TX queue.
     152                 :            :  * member port
     153                 :            :  * buffer for packets
     154                 :            :  * size size of buffer
     155                 :            :  * return number of packets or negative error number
     156                 :            :  */
     157                 :            : static int
     158                 :          0 : member_get_pkts(struct member_conf *member, struct rte_mbuf **buf, uint16_t size)
     159                 :            : {
     160   [ #  #  #  #  :          0 :         return rte_ring_dequeue_burst(member->tx_queue, (void **)buf,
                      # ]
     161                 :            :                         size, NULL);
     162                 :            : }
     163                 :            : 
     164                 :            : /*
     165                 :            :  * Injects given packets into members RX queue.
     166                 :            :  * member port
     167                 :            :  * buffer for packets
     168                 :            :  * size number of packets to be injected
     169                 :            :  * return number of queued packets or negative error number
     170                 :            :  */
     171                 :            : static int
     172                 :          0 : member_put_pkts(struct member_conf *member, struct rte_mbuf **buf, uint16_t size)
     173                 :            : {
     174   [ #  #  #  #  :          0 :         return rte_ring_enqueue_burst(member->rx_queue, (void **)buf,
                      # ]
     175                 :            :                         size, NULL);
     176                 :            : }
     177                 :            : 
     178                 :            : static uint16_t
     179                 :            : bond_rx(struct rte_mbuf **buf, uint16_t size)
     180                 :            : {
     181                 :          0 :         return rte_eth_rx_burst(test_params.bonding_port_id, 0, buf, size);
     182                 :            : }
     183                 :            : 
     184                 :            : static uint16_t
     185                 :            : bond_tx(struct rte_mbuf **buf, uint16_t size)
     186                 :            : {
     187                 :          0 :         return rte_eth_tx_burst(test_params.bonding_port_id, 0, buf, size);
     188                 :            : }
     189                 :            : 
     190                 :            : static void
     191                 :            : free_pkts(struct rte_mbuf **pkts, uint16_t count)
     192                 :            : {
     193                 :            :         uint16_t i;
     194                 :            : 
     195   [ #  #  #  #  :          0 :         for (i = 0; i < count; i++) {
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     196                 :          0 :                 rte_pktmbuf_free(pkts[i]);
     197                 :            :         }
     198                 :            : }
     199                 :            : 
     200                 :            : static int
     201                 :          0 : configure_ethdev(uint16_t port_id, uint8_t start)
     202                 :            : {
     203         [ #  # ]:          0 :         TEST_ASSERT(rte_eth_dev_configure(port_id, 1, 1, &default_pmd_conf) == 0,
     204                 :            :                 "Failed to configure device %u", port_id);
     205                 :            : 
     206         [ #  # ]:          0 :         TEST_ASSERT(rte_eth_rx_queue_setup(port_id, 0, RX_RING_SIZE,
     207                 :            :                 rte_eth_dev_socket_id(port_id), NULL, test_params.mbuf_pool) == 0,
     208                 :            :                 "Failed to setup rx queue.");
     209                 :            : 
     210         [ #  # ]:          0 :         TEST_ASSERT(rte_eth_tx_queue_setup(port_id, 0, TX_RING_SIZE,
     211                 :            :                 rte_eth_dev_socket_id(port_id), NULL) == 0,
     212                 :            :                 "Failed to setup tx queue.");
     213                 :            : 
     214         [ #  # ]:          0 :         if (start) {
     215         [ #  # ]:          0 :                 TEST_ASSERT(rte_eth_dev_start(port_id) == 0,
     216                 :            :                 "Failed to start device (%d).", port_id);
     217                 :            :         }
     218                 :            :         return 0;
     219                 :            : }
     220                 :            : 
     221                 :            : static int
     222                 :          0 : add_member(struct member_conf *member, uint8_t start)
     223                 :            : {
     224                 :            :         struct rte_ether_addr addr, addr_check;
     225                 :            :         int retval;
     226                 :            : 
     227                 :            :         /* Some sanity check */
     228   [ #  #  #  # ]:          0 :         RTE_VERIFY(test_params.member_ports <= member &&
     229                 :            :                 member - test_params.member_ports < (int)RTE_DIM(test_params.member_ports));
     230         [ #  # ]:          0 :         RTE_VERIFY(member->bonding == 0);
     231         [ #  # ]:          0 :         RTE_VERIFY(member->port_id != INVALID_PORT_ID);
     232                 :            : 
     233                 :            :         rte_ether_addr_copy(&member_mac_default, &addr);
     234                 :          0 :         addr.addr_bytes[RTE_ETHER_ADDR_LEN - 1] = member->port_id;
     235                 :            : 
     236                 :          0 :         rte_eth_dev_mac_addr_remove(member->port_id, &addr);
     237                 :            : 
     238         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(rte_eth_dev_mac_addr_add(member->port_id, &addr, 0),
     239                 :            :                 "Failed to set member MAC address");
     240                 :            : 
     241         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(rte_eth_bond_member_add(test_params.bonding_port_id,
     242                 :            :                 member->port_id),
     243                 :            :                         "Failed to add member (idx=%u, id=%u) to bonding (id=%u)",
     244                 :            :                         (uint8_t)(member - test_params.member_ports), member->port_id,
     245                 :            :                         test_params.bonding_port_id);
     246                 :            : 
     247                 :          0 :         member->bonding = 1;
     248         [ #  # ]:          0 :         if (start) {
     249         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(rte_eth_dev_start(member->port_id),
     250                 :            :                         "Failed to start member %u", member->port_id);
     251                 :            :         }
     252                 :            : 
     253                 :          0 :         retval = rte_eth_macaddr_get(member->port_id, &addr_check);
     254         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Failed to get member mac address: %s",
     255                 :            :                             strerror(-retval));
     256         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(rte_is_same_ether_addr(&addr, &addr_check), 1,
     257                 :            :                         "Member MAC address is not as expected");
     258                 :            : 
     259         [ #  # ]:          0 :         RTE_VERIFY(member->lacp_parnter_state == 0);
     260                 :            :         return 0;
     261                 :            : }
     262                 :            : 
     263                 :            : static int
     264                 :          0 : remove_member(struct member_conf *member)
     265                 :            : {
     266                 :          0 :         ptrdiff_t member_idx = member - test_params.member_ports;
     267                 :            : 
     268   [ #  #  #  # ]:          0 :         RTE_VERIFY(test_params.member_ports <= member &&
     269                 :            :                 member_idx < (ptrdiff_t)RTE_DIM(test_params.member_ports));
     270                 :            : 
     271         [ #  # ]:          0 :         RTE_VERIFY(member->bonding == 1);
     272         [ #  # ]:          0 :         RTE_VERIFY(member->port_id != INVALID_PORT_ID);
     273                 :            : 
     274         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(rte_ring_count(member->rx_queue), 0,
     275                 :            :                 "Member %u tx queue not empty while removing from bonding.",
     276                 :            :                 member->port_id);
     277                 :            : 
     278         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(rte_ring_count(member->rx_queue), 0,
     279                 :            :                 "Member %u tx queue not empty while removing from bonding.",
     280                 :            :                 member->port_id);
     281                 :            : 
     282         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(rte_eth_bond_member_remove(test_params.bonding_port_id,
     283                 :            :                         member->port_id), 0,
     284                 :            :                         "Failed to remove member (idx=%u, id=%u) from bonding (id=%u)",
     285                 :            :                         (uint8_t)member_idx, member->port_id,
     286                 :            :                         test_params.bonding_port_id);
     287                 :            : 
     288                 :          0 :         member->bonding = 0;
     289                 :          0 :         member->lacp_parnter_state = 0;
     290                 :          0 :         return 0;
     291                 :            : }
     292                 :            : 
     293                 :            : static void
     294                 :          0 : lacp_recv_cb(uint16_t member_id, struct rte_mbuf *lacp_pkt)
     295                 :            : {
     296                 :            :         struct rte_ether_hdr *hdr;
     297                 :            :         struct slow_protocol_frame *slow_hdr;
     298                 :            : 
     299         [ #  # ]:          0 :         RTE_VERIFY(lacp_pkt != NULL);
     300                 :            : 
     301                 :          0 :         hdr = rte_pktmbuf_mtod(lacp_pkt, struct rte_ether_hdr *);
     302         [ #  # ]:          0 :         RTE_VERIFY(hdr->ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_SLOW));
     303                 :            : 
     304                 :            :         slow_hdr = rte_pktmbuf_mtod(lacp_pkt, struct slow_protocol_frame *);
     305         [ #  # ]:          0 :         RTE_VERIFY(slow_hdr->slow_protocol.subtype == SLOW_SUBTYPE_LACP);
     306                 :            : 
     307                 :          0 :         lacpdu_rx_count[member_id]++;
     308                 :          0 :         rte_pktmbuf_free(lacp_pkt);
     309                 :          0 : }
     310                 :            : 
     311                 :            : static int
     312                 :          0 : initialize_bonding_device_with_members(uint16_t member_count, uint8_t external_sm)
     313                 :            : {
     314                 :            :         uint8_t i;
     315                 :            :         int ret;
     316                 :            : 
     317         [ #  # ]:          0 :         RTE_VERIFY(test_params.bonding_port_id != INVALID_PORT_ID);
     318                 :            : 
     319         [ #  # ]:          0 :         for (i = 0; i < member_count; i++) {
     320         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(add_member(&test_params.member_ports[i], 1),
     321                 :            :                         "Failed to add port %u to bonding device.\n",
     322                 :            :                         test_params.member_ports[i].port_id);
     323                 :            :         }
     324                 :            : 
     325                 :            :         /* Reset mode 4 configuration */
     326                 :          0 :         rte_eth_bond_8023ad_setup(test_params.bonding_port_id, NULL);
     327                 :          0 :         ret = rte_eth_promiscuous_disable(test_params.bonding_port_id);
     328         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(ret,
     329                 :            :                 "Failed disable promiscuous mode for port %d: %s",
     330                 :            :                 test_params.bonding_port_id, rte_strerror(-ret));
     331                 :            : 
     332         [ #  # ]:          0 :         if (external_sm) {
     333                 :            :                 struct rte_eth_bond_8023ad_conf conf;
     334                 :            : 
     335                 :          0 :                 rte_eth_bond_8023ad_conf_get(test_params.bonding_port_id, &conf);
     336                 :          0 :                 conf.slowrx_cb = lacp_recv_cb;
     337                 :          0 :                 rte_eth_bond_8023ad_setup(test_params.bonding_port_id, &conf);
     338                 :            : 
     339                 :            :         }
     340                 :            : 
     341         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params.bonding_port_id),
     342                 :            :                 "Failed to start bonding device");
     343                 :            : 
     344                 :            :         return TEST_SUCCESS;
     345                 :            : }
     346                 :            : 
     347                 :            : static int
     348                 :          0 : remove_members_and_stop_bonding_device(void)
     349                 :            : {
     350                 :            :         struct member_conf *member;
     351                 :            :         int retval;
     352                 :            :         uint16_t members[RTE_MAX_ETHPORTS];
     353                 :            :         uint16_t i;
     354                 :            : 
     355         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params.bonding_port_id),
     356                 :            :                         "Failed to stop bonding port %u",
     357                 :            :                         test_params.bonding_port_id);
     358                 :            : 
     359   [ #  #  #  # ]:          0 :         FOR_EACH_MEMBER(i, member)
     360                 :          0 :                 remove_member(member);
     361                 :            : 
     362                 :          0 :         retval = rte_eth_bond_members_get(test_params.bonding_port_id, members,
     363                 :            :                 RTE_DIM(members));
     364                 :            : 
     365         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(retval, 0,
     366                 :            :                 "Expected bonding device %u have 0 members but returned %d.",
     367                 :            :                         test_params.bonding_port_id, retval);
     368                 :            : 
     369         [ #  # ]:          0 :         FOR_EACH_PORT(i, member) {
     370         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(member->port_id),
     371                 :            :                                 "Failed to stop bonding port %u",
     372                 :            :                                 member->port_id);
     373                 :            : 
     374         [ #  # ]:          0 :                 TEST_ASSERT(member->bonding == 0,
     375                 :            :                         "Port id=%u is still marked as enmemberd.", member->port_id);
     376                 :            :         }
     377                 :            : 
     378                 :            :         return TEST_SUCCESS;
     379                 :            : }
     380                 :            : 
     381                 :            : static int
     382                 :          0 : test_setup(void)
     383                 :            : {
     384                 :            :         int retval, nb_mbuf_per_pool;
     385                 :            :         char name[RTE_ETH_NAME_MAX_LEN];
     386                 :            :         struct member_conf *port;
     387                 :          0 :         const uint8_t socket_id = rte_socket_id();
     388                 :            :         uint16_t i;
     389                 :            : 
     390         [ #  # ]:          0 :         if (test_params.mbuf_pool == NULL) {
     391                 :            :                 nb_mbuf_per_pool = TEST_RX_DESC_MAX + DEF_PKT_BURST +
     392                 :            :                                         TEST_TX_DESC_MAX + MAX_PKT_BURST;
     393                 :          0 :                 test_params.mbuf_pool = rte_pktmbuf_pool_create("TEST_MODE4",
     394                 :            :                         nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0,
     395                 :            :                         RTE_MBUF_DEFAULT_BUF_SIZE, socket_id);
     396                 :            : 
     397         [ #  # ]:          0 :                 TEST_ASSERT(test_params.mbuf_pool != NULL,
     398                 :            :                         "rte_mempool_create failed\n");
     399                 :            :         }
     400                 :            : 
     401                 :            :         /* Create / initialize ring eth devs. */
     402         [ #  # ]:          0 :         FOR_EACH_PORT(i, port) {
     403                 :            :                 port = &test_params.member_ports[i];
     404                 :            : 
     405         [ #  # ]:          0 :                 if (port->rx_queue == NULL) {
     406                 :            :                         retval = snprintf(name, RTE_DIM(name), MEMBER_RX_QUEUE_FMT, i);
     407         [ #  # ]:          0 :                         TEST_ASSERT(retval <= (int)RTE_DIM(name) - 1, "Name too long");
     408                 :          0 :                         port->rx_queue = rte_ring_create(name, RX_RING_SIZE, socket_id, 0);
     409         [ #  # ]:          0 :                         TEST_ASSERT(port->rx_queue != NULL,
     410                 :            :                                 "Failed to allocate rx ring '%s': %s", name,
     411                 :            :                                 rte_strerror(rte_errno));
     412                 :            :                 }
     413                 :            : 
     414         [ #  # ]:          0 :                 if (port->tx_queue == NULL) {
     415                 :            :                         retval = snprintf(name, RTE_DIM(name), MEMBER_TX_QUEUE_FMT, i);
     416         [ #  # ]:          0 :                         TEST_ASSERT(retval <= (int)RTE_DIM(name) - 1, "Name too long");
     417                 :          0 :                         port->tx_queue = rte_ring_create(name, TX_RING_SIZE, socket_id, 0);
     418         [ #  # ]:          0 :                         TEST_ASSERT_NOT_NULL(port->tx_queue,
     419                 :            :                                 "Failed to allocate tx ring '%s': %s", name,
     420                 :            :                                 rte_strerror(rte_errno));
     421                 :            :                 }
     422                 :            : 
     423         [ #  # ]:          0 :                 if (port->port_id == INVALID_PORT_ID) {
     424                 :            :                         retval = snprintf(name, RTE_DIM(name), MEMBER_DEV_NAME_FMT, i);
     425         [ #  # ]:          0 :                         TEST_ASSERT(retval < (int)RTE_DIM(name) - 1, "Name too long");
     426                 :          0 :                         retval = rte_eth_from_rings(name, &port->rx_queue, 1,
     427                 :          0 :                                         &port->tx_queue, 1, socket_id);
     428         [ #  # ]:          0 :                         TEST_ASSERT(retval >= 0,
     429                 :            :                                 "Failed to create ring ethdev '%s'\n", name);
     430                 :            : 
     431                 :          0 :                         port->port_id = rte_eth_dev_count_avail() - 1;
     432                 :            :                 }
     433                 :            : 
     434                 :          0 :                 retval = configure_ethdev(port->port_id, 1);
     435         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(retval, "Failed to configure virtual ethdev %s\n",
     436                 :            :                         name);
     437                 :            :         }
     438                 :            : 
     439         [ #  # ]:          0 :         if (test_params.bonding_port_id == INVALID_PORT_ID) {
     440                 :          0 :                 retval = rte_eth_bond_create(BONDING_DEV_NAME, BONDING_MODE_8023AD,
     441                 :            :                                 socket_id);
     442                 :            : 
     443         [ #  # ]:          0 :                 TEST_ASSERT(retval >= 0, "Failed to create bonding ethdev %s",
     444                 :            :                                 BONDING_DEV_NAME);
     445                 :            : 
     446                 :          0 :                 test_params.bonding_port_id = retval;
     447         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(configure_ethdev(test_params.bonding_port_id, 0),
     448                 :            :                                 "Failed to configure bonding ethdev %s", BONDING_DEV_NAME);
     449         [ #  # ]:          0 :         } else if (rte_eth_bond_mode_get(test_params.bonding_port_id) !=
     450                 :            :                         BONDING_MODE_8023AD) {
     451         [ #  # ]:          0 :                 TEST_ASSERT(rte_eth_bond_mode_set(test_params.bonding_port_id,
     452                 :            :                         BONDING_MODE_8023AD) == 0,
     453                 :            :                         "Failed to set ethdev %d to mode %d",
     454                 :            :                         test_params.bonding_port_id, BONDING_MODE_8023AD);
     455                 :            :         }
     456                 :            : 
     457                 :            :         return 0;
     458                 :            : }
     459                 :            : 
     460                 :            : static void
     461                 :          0 : testsuite_teardown(void)
     462                 :            : {
     463                 :            :         struct member_conf *port;
     464                 :            :         uint8_t i;
     465                 :            : 
     466                 :            :         /* Only stop ports.
     467                 :            :          * Any cleanup/reset state is done when particular test is
     468                 :            :          * started. */
     469                 :            : 
     470                 :          0 :         rte_eth_dev_stop(test_params.bonding_port_id);
     471                 :            : 
     472         [ #  # ]:          0 :         FOR_EACH_PORT(i, port)
     473                 :          0 :                 rte_eth_dev_stop(port->port_id);
     474                 :          0 : }
     475                 :            : 
     476                 :            : /*
     477                 :            :  * Check if given LACP packet. If it is, make make replay packet to force
     478                 :            :  * COLLECTING state.
     479                 :            :  * return 0 when pkt is LACP frame, 1 if it is not slow frame, 2 if it is slow
     480                 :            :  * frame but not LACP
     481                 :            :  */
     482                 :            : static int
     483                 :          0 : make_lacp_reply(struct member_conf *member, struct rte_mbuf *pkt)
     484                 :            : {
     485                 :            :         struct rte_ether_hdr *hdr;
     486                 :            :         struct slow_protocol_frame *slow_hdr;
     487                 :            :         struct lacpdu *lacp;
     488                 :            : 
     489                 :            :         /* look for LACP */
     490                 :          0 :         hdr = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
     491         [ #  # ]:          0 :         if (hdr->ether_type != rte_cpu_to_be_16(RTE_ETHER_TYPE_SLOW))
     492                 :            :                 return 1;
     493                 :            : 
     494                 :            :         slow_hdr = rte_pktmbuf_mtod(pkt, struct slow_protocol_frame *);
     495                 :            :         /* ignore packets of other types */
     496         [ #  # ]:          0 :         if (slow_hdr->slow_protocol.subtype != SLOW_SUBTYPE_LACP)
     497                 :            :                 return 2;
     498                 :            : 
     499                 :            :         slow_hdr = rte_pktmbuf_mtod(pkt, struct slow_protocol_frame *);
     500                 :            : 
     501                 :            :         /* Change source address to partner address */
     502                 :            :         rte_ether_addr_copy(&parnter_mac_default, &slow_hdr->eth_hdr.src_addr);
     503                 :          0 :         slow_hdr->eth_hdr.src_addr.addr_bytes[RTE_ETHER_ADDR_LEN - 1] =
     504                 :          0 :                 member->port_id;
     505                 :            : 
     506                 :            :         lacp = (struct lacpdu *) &slow_hdr->slow_protocol;
     507                 :            :         /* Save last received state */
     508                 :          0 :         member->lacp_parnter_state = lacp->actor.state;
     509                 :            :         /* Change it into LACP replay by matching parameters. */
     510                 :          0 :         memcpy(&lacp->partner.port_params, &lacp->actor.port_params,
     511                 :            :                 sizeof(struct port_params));
     512                 :            : 
     513                 :          0 :         lacp->partner.state = lacp->actor.state;
     514                 :            : 
     515                 :            :         rte_ether_addr_copy(&parnter_system, &lacp->actor.port_params.system);
     516                 :          0 :         lacp->actor.state = STATE_LACP_ACTIVE |
     517                 :            :                                                 STATE_SYNCHRONIZATION |
     518                 :            :                                                 STATE_AGGREGATION |
     519                 :            :                                                 STATE_COLLECTING |
     520                 :            :                                                 STATE_DISTRIBUTING;
     521                 :            : 
     522                 :          0 :         return 0;
     523                 :            : }
     524                 :            : 
     525                 :            : /*
     526                 :            :  * Reads packets from given member, search for LACP packet and reply them.
     527                 :            :  *
     528                 :            :  * Receives burst of packets from member. Looks for LACP packet. Drops
     529                 :            :  * all other packets. Prepares response LACP and sends it back.
     530                 :            :  *
     531                 :            :  * return number of LACP received and replied, -1 on error.
     532                 :            :  */
     533                 :            : static int
     534                 :          0 : bond_handshake_reply(struct member_conf *member)
     535                 :            : {
     536                 :            :         int retval;
     537                 :            :         struct rte_mbuf *rx_buf[MAX_PKT_BURST];
     538                 :            :         struct rte_mbuf *lacp_tx_buf[MAX_PKT_BURST];
     539                 :            :         uint16_t lacp_tx_buf_cnt = 0, i;
     540                 :            : 
     541                 :          0 :         retval = member_get_pkts(member, rx_buf, RTE_DIM(rx_buf));
     542         [ #  # ]:          0 :         TEST_ASSERT(retval >= 0, "Getting member %u packets failed.",
     543                 :            :                         member->port_id);
     544                 :            : 
     545         [ #  # ]:          0 :         for (i = 0; i < (uint16_t)retval; i++) {
     546         [ #  # ]:          0 :                 if (make_lacp_reply(member, rx_buf[i]) == 0) {
     547                 :            :                         /* reply with actor's LACP */
     548                 :          0 :                         lacp_tx_buf[lacp_tx_buf_cnt++] = rx_buf[i];
     549                 :            :                 } else
     550                 :          0 :                         rte_pktmbuf_free(rx_buf[i]);
     551                 :            :         }
     552                 :            : 
     553         [ #  # ]:          0 :         if (lacp_tx_buf_cnt == 0)
     554                 :            :                 return 0;
     555                 :            : 
     556                 :          0 :         retval = member_put_pkts(member, lacp_tx_buf, lacp_tx_buf_cnt);
     557         [ #  # ]:          0 :         if (retval <= lacp_tx_buf_cnt) {
     558                 :            :                 /* retval might be negative */
     559         [ #  # ]:          0 :                 for (i = RTE_MAX(0, retval); retval < lacp_tx_buf_cnt; retval++)
     560                 :          0 :                         rte_pktmbuf_free(lacp_tx_buf[i]);
     561                 :            :         }
     562                 :            : 
     563         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(retval, lacp_tx_buf_cnt,
     564                 :            :                 "Failed to equeue lacp packets into member %u tx queue.",
     565                 :            :                 member->port_id);
     566                 :            : 
     567                 :            :         return lacp_tx_buf_cnt;
     568                 :            : }
     569                 :            : 
     570                 :            : /*
     571                 :            :  * Function check if given member tx queue contains packets that make mode 4
     572                 :            :  * handshake complete. It will drain member queue.
     573                 :            :  * return 0 if handshake not completed, 1 if handshake was complete,
     574                 :            :  */
     575                 :            : static int
     576                 :            : bond_handshake_done(struct member_conf *member)
     577                 :            : {
     578                 :            :         const uint8_t expected_state = STATE_LACP_ACTIVE | STATE_SYNCHRONIZATION |
     579                 :            :                         STATE_AGGREGATION | STATE_COLLECTING | STATE_DISTRIBUTING;
     580                 :            : 
     581                 :          0 :         return member->lacp_parnter_state == expected_state;
     582                 :            : }
     583                 :            : 
     584                 :            : static unsigned
     585                 :          0 : bond_get_update_timeout_ms(void)
     586                 :            : {
     587                 :            :         struct rte_eth_bond_8023ad_conf conf;
     588                 :            : 
     589         [ #  # ]:          0 :         if (rte_eth_bond_8023ad_conf_get(test_params.bonding_port_id, &conf) < 0) {
     590                 :          0 :                 RTE_LOG(DEBUG, EAL, "Failed to get bonding configuration: "
     591                 :            :                                     "%s at %d\n", __func__, __LINE__);
     592                 :            :                 RTE_TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__);
     593                 :          0 :                 return 0;
     594                 :            :         }
     595                 :            : 
     596                 :          0 :         return conf.update_timeout_ms;
     597                 :            : }
     598                 :            : 
     599                 :            : /*
     600                 :            :  * Exchanges LACP packets with partner to achieve dynamic port configuration.
     601                 :            :  * return TEST_SUCCESS if initial handshake succeed, TEST_FAILED otherwise.
     602                 :            :  */
     603                 :            : static int
     604                 :          0 : bond_handshake(void)
     605                 :            : {
     606                 :            :         struct member_conf *member;
     607                 :            :         struct rte_mbuf *buf[MAX_PKT_BURST];
     608                 :            :         uint16_t nb_pkts;
     609                 :            :         uint8_t all_members_done, i, j;
     610                 :          0 :         uint8_t status[RTE_DIM(test_params.member_ports)] = { 0 };
     611                 :          0 :         const unsigned delay = bond_get_update_timeout_ms();
     612                 :            : 
     613                 :            :         /* Exchange LACP frames */
     614                 :            :         all_members_done = 0;
     615         [ #  # ]:          0 :         for (i = 0; i < 30 && all_members_done == 0; ++i) {
     616                 :            :                 rte_delay_ms(delay);
     617                 :            : 
     618                 :            :                 all_members_done = 1;
     619   [ #  #  #  # ]:          0 :                 FOR_EACH_MEMBER(j, member) {
     620                 :            :                         /* If response already send, skip member */
     621         [ #  # ]:          0 :                         if (status[j] != 0)
     622                 :          0 :                                 continue;
     623                 :            : 
     624         [ #  # ]:          0 :                         if (bond_handshake_reply(member) < 0) {
     625                 :            :                                 all_members_done = 0;
     626                 :            :                                 break;
     627                 :            :                         }
     628                 :            : 
     629                 :          0 :                         status[j] = bond_handshake_done(member);
     630         [ #  # ]:          0 :                         if (status[j] == 0)
     631                 :            :                                 all_members_done = 0;
     632                 :            :                 }
     633                 :            : 
     634                 :            :                 nb_pkts = bond_tx(NULL, 0);
     635         [ #  # ]:          0 :                 TEST_ASSERT_EQUAL(nb_pkts, 0, "Packets transmitted unexpectedly");
     636                 :            : 
     637                 :            :                 nb_pkts = bond_rx(buf, RTE_DIM(buf));
     638                 :            :                 free_pkts(buf, nb_pkts);
     639         [ #  # ]:          0 :                 TEST_ASSERT_EQUAL(nb_pkts, 0, "Packets received unexpectedly");
     640                 :            :         }
     641                 :            :         /* If response didn't send - report failure */
     642         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(all_members_done, 1, "Bond handshake failed\n");
     643                 :            : 
     644                 :            :         return TEST_SUCCESS;
     645                 :            : }
     646                 :            : 
     647                 :            : #define TEST_LACP_MEMBER_COUT RTE_DIM(test_params.member_ports)
     648                 :            : static int
     649                 :          0 : test_mode4_lacp(void)
     650                 :            : {
     651                 :            :         int retval;
     652                 :            : 
     653                 :          0 :         retval = initialize_bonding_device_with_members(TEST_LACP_MEMBER_COUT, 0);
     654         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonding device");
     655                 :            : 
     656                 :            :         /* Test LACP handshake function */
     657                 :          0 :         retval = bond_handshake();
     658         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Initial handshake failed");
     659                 :            : 
     660                 :          0 :         retval = remove_members_and_stop_bonding_device();
     661         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Test cleanup failed.");
     662                 :            : 
     663                 :            :         return TEST_SUCCESS;
     664                 :            : }
     665                 :            : static int
     666                 :          0 : test_mode4_agg_mode_selection(void)
     667                 :            : {
     668                 :            :         int retval;
     669                 :            :         /* Test and verify for Stable mode */
     670                 :          0 :         retval = initialize_bonding_device_with_members(TEST_LACP_MEMBER_COUT, 0);
     671         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonding device");
     672                 :            : 
     673                 :            : 
     674                 :          0 :         retval = rte_eth_bond_8023ad_agg_selection_set(
     675                 :          0 :                         test_params.bonding_port_id, AGG_STABLE);
     676         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Failed to initialize bond aggregation mode");
     677                 :          0 :         retval = bond_handshake();
     678         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Initial handshake failed");
     679                 :            : 
     680                 :            : 
     681                 :          0 :         retval = rte_eth_bond_8023ad_agg_selection_get(
     682                 :          0 :                         test_params.bonding_port_id);
     683         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(retval, AGG_STABLE,
     684                 :            :                         "Wrong agg mode received from bonding device");
     685                 :            : 
     686                 :          0 :         retval = remove_members_and_stop_bonding_device();
     687         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Test cleanup failed.");
     688                 :            : 
     689                 :            : 
     690                 :            :         /* test and verify for Bandwidth mode */
     691                 :          0 :         retval = initialize_bonding_device_with_members(TEST_LACP_MEMBER_COUT, 0);
     692         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonding device");
     693                 :            : 
     694                 :            : 
     695                 :          0 :         retval = rte_eth_bond_8023ad_agg_selection_set(
     696                 :          0 :                         test_params.bonding_port_id,
     697                 :            :                         AGG_BANDWIDTH);
     698         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval,
     699                 :            :                         "Failed to initialize bond aggregation mode");
     700                 :          0 :         retval = bond_handshake();
     701         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Initial handshake failed");
     702                 :            : 
     703                 :          0 :         retval = rte_eth_bond_8023ad_agg_selection_get(
     704                 :          0 :                         test_params.bonding_port_id);
     705         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(retval, AGG_BANDWIDTH,
     706                 :            :                         "Wrong agg mode received from bonding device");
     707                 :            : 
     708                 :          0 :         retval = remove_members_and_stop_bonding_device();
     709         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Test cleanup failed.");
     710                 :            : 
     711                 :            :         /* test and verify selection for count mode */
     712                 :          0 :         retval = initialize_bonding_device_with_members(TEST_LACP_MEMBER_COUT, 0);
     713         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonding device");
     714                 :            : 
     715                 :            : 
     716                 :          0 :         retval = rte_eth_bond_8023ad_agg_selection_set(
     717                 :          0 :                         test_params.bonding_port_id, AGG_COUNT);
     718         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval,
     719                 :            :                         "Failed to initialize bond aggregation mode");
     720                 :          0 :         retval = bond_handshake();
     721         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Initial handshake failed");
     722                 :            : 
     723                 :          0 :         retval = rte_eth_bond_8023ad_agg_selection_get(
     724                 :          0 :                         test_params.bonding_port_id);
     725         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(retval, AGG_COUNT,
     726                 :            :                         "Wrong agg mode received from bonding device");
     727                 :            : 
     728                 :          0 :         retval = remove_members_and_stop_bonding_device();
     729         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Test cleanup failed.");
     730                 :            : 
     731                 :            :         return TEST_SUCCESS;
     732                 :            : }
     733                 :            : 
     734                 :            : static int
     735                 :          0 : generate_packets(struct rte_ether_addr *src_mac,
     736                 :            :         struct rte_ether_addr *dst_mac, uint16_t count, struct rte_mbuf **buf)
     737                 :            : {
     738                 :            :         uint16_t pktlen = PACKET_BURST_GEN_PKT_LEN;
     739                 :            :         uint8_t vlan_enable = 0;
     740                 :            :         uint16_t vlan_id = 0;
     741                 :            :         uint8_t ip4_type = 1; /* 0 - ipv6 */
     742                 :            : 
     743                 :            :         uint16_t src_port = 10, dst_port = 20;
     744                 :            : 
     745                 :            :         uint32_t ip_src[4] = { [0 ... 2] = 0xDEADBEEF, [3] = RTE_IPV4(192, 168, 0, 1) };
     746                 :            :         uint32_t ip_dst[4] = { [0 ... 2] = 0xFEEDFACE, [3] = RTE_IPV4(192, 168, 0, 2) };
     747                 :            : 
     748                 :            :         struct rte_ether_hdr pkt_eth_hdr;
     749                 :            :         struct rte_udp_hdr pkt_udp_hdr;
     750                 :            :         union {
     751                 :            :                 struct rte_ipv4_hdr v4;
     752                 :            :                 struct rte_ipv6_hdr v6;
     753                 :            :         } pkt_ip_hdr;
     754                 :            : 
     755                 :            :         int retval;
     756                 :            : 
     757                 :          0 :         initialize_eth_header(&pkt_eth_hdr, src_mac, dst_mac, ip4_type,
     758                 :            :                         vlan_enable, vlan_id);
     759                 :            : 
     760                 :            :         if (ip4_type)
     761                 :          0 :                 initialize_ipv4_header(&pkt_ip_hdr.v4, ip_src[3], ip_dst[3], pktlen);
     762                 :            :         else
     763                 :            :                 initialize_ipv6_header(&pkt_ip_hdr.v6, (uint8_t *)ip_src,
     764                 :            :                         (uint8_t *)&ip_dst, pktlen);
     765                 :            : 
     766                 :          0 :         initialize_udp_header(&pkt_udp_hdr, src_port, dst_port, 16);
     767                 :            : 
     768                 :          0 :         retval = generate_packet_burst(test_params.mbuf_pool, buf,
     769                 :            :                         &pkt_eth_hdr, vlan_enable, &pkt_ip_hdr, 1, &pkt_udp_hdr,
     770                 :            :                         count, pktlen, 1);
     771                 :            : 
     772   [ #  #  #  # ]:          0 :         if (retval > 0 && retval != count)
     773                 :          0 :                 free_pkts(&buf[count - retval], retval);
     774                 :            : 
     775         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(retval, count, "Failed to generate %u packets",
     776                 :            :                 count);
     777                 :            : 
     778                 :            :         return count;
     779                 :            : }
     780                 :            : 
     781                 :            : static int
     782                 :          0 : generate_and_put_packets(struct member_conf *member,
     783                 :            :                         struct rte_ether_addr *src_mac,
     784                 :            :                         struct rte_ether_addr *dst_mac, uint16_t count)
     785                 :            : {
     786                 :            :         struct rte_mbuf *pkts[MAX_PKT_BURST];
     787                 :            :         int retval;
     788                 :            : 
     789                 :          0 :         retval = generate_packets(src_mac, dst_mac, count, pkts);
     790         [ #  # ]:          0 :         if (retval != (int)count)
     791                 :            :                 return retval;
     792                 :            : 
     793                 :          0 :         retval = member_put_pkts(member, pkts, count);
     794   [ #  #  #  # ]:          0 :         if (retval > 0 && retval != count)
     795                 :          0 :                 free_pkts(&pkts[retval], count - retval);
     796                 :            : 
     797         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(retval, count,
     798                 :            :                 "Failed to enqueue packets into member %u RX queue", member->port_id);
     799                 :            : 
     800                 :            :         return TEST_SUCCESS;
     801                 :            : }
     802                 :            : 
     803                 :            : static int
     804                 :          0 : test_mode4_rx(void)
     805                 :            : {
     806                 :            :         struct member_conf *member;
     807                 :            :         uint16_t i, j;
     808                 :            : 
     809                 :            :         uint16_t expected_pkts_cnt;
     810                 :            :         struct rte_mbuf *pkts[MAX_PKT_BURST];
     811                 :            :         int retval;
     812                 :            :         unsigned delay;
     813                 :            : 
     814                 :            :         struct rte_ether_hdr *hdr;
     815                 :            : 
     816                 :          0 :         struct rte_ether_addr src_mac = {
     817                 :            :                 { 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 } };
     818                 :            :         struct rte_ether_addr dst_mac;
     819                 :            :         struct rte_ether_addr bonding_mac;
     820                 :            : 
     821                 :          0 :         retval = initialize_bonding_device_with_members(TEST_PROMISC_MEMBER_COUNT,
     822                 :            :                                                       0);
     823         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonding device");
     824                 :            : 
     825                 :          0 :         retval = bond_handshake();
     826         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Initial handshake failed");
     827                 :            : 
     828                 :          0 :         retval = rte_eth_macaddr_get(test_params.bonding_port_id, &bonding_mac);
     829         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Failed to get mac address: %s",
     830                 :            :                             strerror(-retval));
     831                 :            :         rte_ether_addr_copy(&bonding_mac, &dst_mac);
     832                 :            : 
     833                 :            :         /* Assert that dst address is not bonding address.  Do not set the
     834                 :            :          * least significant bit of the zero byte as this would create a
     835                 :            :          * multicast address.
     836                 :            :          */
     837                 :          0 :         dst_mac.addr_bytes[0] += 2;
     838                 :            : 
     839                 :            :         /* First try with promiscuous mode enabled.
     840                 :            :          * Add 2 packets to each member. First with bonding MAC address, second with
     841                 :            :          * different. Check if we received all of them. */
     842                 :          0 :         retval = rte_eth_promiscuous_enable(test_params.bonding_port_id);
     843         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval,
     844                 :            :                         "Failed to enable promiscuous mode for port %d: %s",
     845                 :            :                         test_params.bonding_port_id, rte_strerror(-retval));
     846                 :            : 
     847                 :            :         expected_pkts_cnt = 0;
     848   [ #  #  #  # ]:          0 :         FOR_EACH_MEMBER(i, member) {
     849                 :          0 :                 retval = generate_and_put_packets(member, &src_mac, &bonding_mac, 1);
     850         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(retval, "Failed to enqueue packets to member %u",
     851                 :            :                         member->port_id);
     852                 :            : 
     853                 :          0 :                 retval = generate_and_put_packets(member, &src_mac, &dst_mac, 1);
     854         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(retval, "Failed to enqueue packets to member %u",
     855                 :            :                         member->port_id);
     856                 :            : 
     857                 :            :                 /* Expect 2 packets per member */
     858                 :          0 :                 expected_pkts_cnt += 2;
     859                 :            :         }
     860                 :            : 
     861                 :          0 :         retval = rte_eth_rx_burst(test_params.bonding_port_id, 0, pkts,
     862                 :            :                 RTE_DIM(pkts));
     863                 :            : 
     864         [ #  # ]:          0 :         if (retval == expected_pkts_cnt) {
     865                 :          0 :                 int cnt[2] = { 0, 0 };
     866                 :            : 
     867         [ #  # ]:          0 :                 for (i = 0; i < expected_pkts_cnt; i++) {
     868                 :          0 :                         hdr = rte_pktmbuf_mtod(pkts[i], struct rte_ether_hdr *);
     869                 :          0 :                         cnt[rte_is_same_ether_addr(&hdr->dst_addr,
     870                 :          0 :                                                         &bonding_mac)]++;
     871                 :            :                 }
     872                 :            : 
     873                 :            :                 free_pkts(pkts, expected_pkts_cnt);
     874                 :            : 
     875                 :            :                 /* For division by 2 expected_pkts_cnt must be even */
     876                 :            :                 RTE_VERIFY((expected_pkts_cnt & 1) == 0);
     877   [ #  #  #  # ]:          0 :                 TEST_ASSERT(cnt[0] == expected_pkts_cnt / 2 &&
     878                 :            :                         cnt[1] == expected_pkts_cnt / 2,
     879                 :            :                         "Expected %u packets with the same MAC and %u with different but "
     880                 :            :                         "got %u with the same and %u with different MAC",
     881                 :            :                         expected_pkts_cnt / 2, expected_pkts_cnt / 2, cnt[1], cnt[0]);
     882         [ #  # ]:          0 :         } else if (retval > 0)
     883                 :            :                 free_pkts(pkts, retval);
     884                 :            : 
     885         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(retval, expected_pkts_cnt,
     886                 :            :                 "Expected %u packets but received only %d", expected_pkts_cnt, retval);
     887                 :            : 
     888                 :            :         /* Now, disable promiscuous mode. When promiscuous mode is disabled we
     889                 :            :          * expect to receive only packets that are directed to bonding port. */
     890                 :          0 :         retval = rte_eth_promiscuous_disable(test_params.bonding_port_id);
     891         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval,
     892                 :            :                 "Failed to disable promiscuous mode for port %d: %s",
     893                 :            :                 test_params.bonding_port_id, rte_strerror(-retval));
     894                 :            : 
     895                 :            :         expected_pkts_cnt = 0;
     896   [ #  #  #  # ]:          0 :         FOR_EACH_MEMBER(i, member) {
     897                 :          0 :                 retval = generate_and_put_packets(member, &src_mac, &bonding_mac, 1);
     898         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(retval, "Failed to enqueue packets to member %u",
     899                 :            :                         member->port_id);
     900                 :            : 
     901                 :          0 :                 retval = generate_and_put_packets(member, &src_mac, &dst_mac, 1);
     902         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(retval, "Failed to enqueue packets to member %u",
     903                 :            :                         member->port_id);
     904                 :            : 
     905                 :            :                 /* Expect only one packet per member */
     906                 :          0 :                 expected_pkts_cnt += 1;
     907                 :            :         }
     908                 :            : 
     909                 :          0 :         retval = rte_eth_rx_burst(test_params.bonding_port_id, 0, pkts,
     910                 :            :                 RTE_DIM(pkts));
     911                 :            : 
     912         [ #  # ]:          0 :         if (retval == expected_pkts_cnt) {
     913                 :            :                 int eq_cnt = 0;
     914                 :            : 
     915         [ #  # ]:          0 :                 for (i = 0; i < expected_pkts_cnt; i++) {
     916                 :          0 :                         hdr = rte_pktmbuf_mtod(pkts[i], struct rte_ether_hdr *);
     917                 :          0 :                         eq_cnt += rte_is_same_ether_addr(&hdr->dst_addr,
     918                 :            :                                                         &bonding_mac);
     919                 :            :                 }
     920                 :            : 
     921                 :            :                 free_pkts(pkts, expected_pkts_cnt);
     922         [ #  # ]:          0 :                 TEST_ASSERT_EQUAL(eq_cnt, expected_pkts_cnt, "Packet address mismatch");
     923         [ #  # ]:          0 :         } else if (retval > 0)
     924                 :            :                 free_pkts(pkts, retval);
     925                 :            : 
     926         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(retval, expected_pkts_cnt,
     927                 :            :                 "Expected %u packets but received only %d", expected_pkts_cnt, retval);
     928                 :            : 
     929                 :            :         /* Link down test: simulate link down for first member. */
     930                 :          0 :         delay = bond_get_update_timeout_ms();
     931                 :            : 
     932                 :            :         uint8_t member_down_id = INVALID_PORT_ID;
     933                 :            : 
     934                 :            :         /* Find first member and make link down on it*/
     935   [ #  #  #  # ]:          0 :         FOR_EACH_MEMBER(i, member) {
     936                 :          0 :                 rte_eth_dev_set_link_down(member->port_id);
     937                 :          0 :                 member_down_id = member->port_id;
     938                 :          0 :                 break;
     939                 :            :         }
     940                 :            : 
     941         [ #  # ]:          0 :         RTE_VERIFY(member_down_id != INVALID_PORT_ID);
     942                 :            : 
     943                 :            :         /* Give some time to rearrange bonding */
     944         [ #  # ]:          0 :         for (i = 0; i < 3; i++) {
     945                 :            :                 rte_delay_ms(delay);
     946                 :          0 :                 bond_handshake();
     947                 :            :         }
     948                 :            : 
     949         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(bond_handshake(), "Handshake after link down failed");
     950                 :            : 
     951                 :            :         /* Put packet to each member */
     952   [ #  #  #  # ]:          0 :         FOR_EACH_MEMBER(i, member) {
     953                 :          0 :                 void *pkt = NULL;
     954                 :            : 
     955                 :          0 :                 dst_mac.addr_bytes[RTE_ETHER_ADDR_LEN - 1] = member->port_id;
     956                 :          0 :                 retval = generate_and_put_packets(member, &src_mac, &dst_mac, 1);
     957         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(retval, "Failed to generate test packet burst.");
     958                 :            : 
     959                 :          0 :                 src_mac.addr_bytes[RTE_ETHER_ADDR_LEN - 1] = member->port_id;
     960                 :          0 :                 retval = generate_and_put_packets(member, &src_mac, &bonding_mac, 1);
     961         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(retval, "Failed to generate test packet burst.");
     962                 :            : 
     963                 :          0 :                 retval = bond_rx(pkts, RTE_DIM(pkts));
     964                 :            : 
     965                 :            :                 /* Clean anything */
     966         [ #  # ]:          0 :                 if (retval > 0)
     967                 :            :                         free_pkts(pkts, retval);
     968                 :            : 
     969   [ #  #  #  #  :          0 :                 while (rte_ring_dequeue(member->rx_queue, (void **)&pkt) == 0)
                      # ]
     970                 :          0 :                         rte_pktmbuf_free(pkt);
     971                 :            : 
     972         [ #  # ]:          0 :                 if (member_down_id == member->port_id)
     973         [ #  # ]:          0 :                         TEST_ASSERT_EQUAL(retval, 0, "Packets received unexpectedly.");
     974                 :            :                 else
     975         [ #  # ]:          0 :                         TEST_ASSERT_NOT_EQUAL(retval, 0,
     976                 :            :                                 "Expected to receive some packets on member %u.",
     977                 :            :                                 member->port_id);
     978                 :          0 :                 rte_eth_dev_start(member->port_id);
     979                 :            : 
     980         [ #  # ]:          0 :                 for (j = 0; j < 5; j++) {
     981         [ #  # ]:          0 :                         TEST_ASSERT(bond_handshake_reply(member) >= 0,
     982                 :            :                                 "Handshake after link up");
     983                 :            : 
     984         [ #  # ]:          0 :                         if (bond_handshake_done(member) == 1)
     985                 :            :                                 break;
     986                 :            :                 }
     987                 :            : 
     988         [ #  # ]:          0 :                 TEST_ASSERT(j < 5, "Failed to aggregate member after link up");
     989                 :            :         }
     990                 :            : 
     991                 :          0 :         remove_members_and_stop_bonding_device();
     992                 :          0 :         return TEST_SUCCESS;
     993                 :            : }
     994                 :            : 
     995                 :            : static int
     996                 :          0 : test_mode4_tx_burst(void)
     997                 :            : {
     998                 :            :         struct member_conf *member;
     999                 :            :         uint16_t i, j;
    1000                 :            : 
    1001                 :            :         uint16_t exp_pkts_cnt, pkts_cnt = 0;
    1002                 :            :         struct rte_mbuf *pkts[MAX_PKT_BURST];
    1003                 :            :         int retval;
    1004                 :            :         unsigned delay;
    1005                 :            : 
    1006                 :          0 :         struct rte_ether_addr dst_mac = {
    1007                 :            :                 { 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 } };
    1008                 :            :         struct rte_ether_addr bonding_mac;
    1009                 :            : 
    1010                 :          0 :         retval = initialize_bonding_device_with_members(TEST_TX_MEMBER_COUNT, 0);
    1011         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonding device");
    1012                 :            : 
    1013                 :          0 :         retval = bond_handshake();
    1014         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Initial handshake failed");
    1015                 :            : 
    1016                 :          0 :         retval = rte_eth_macaddr_get(test_params.bonding_port_id, &bonding_mac);
    1017         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Failed to get mac address: %s",
    1018                 :            :                             strerror(-retval));
    1019                 :            :         /* Prepare burst */
    1020         [ #  # ]:          0 :         for (pkts_cnt = 0; pkts_cnt < RTE_DIM(pkts); pkts_cnt++) {
    1021                 :          0 :                 dst_mac.addr_bytes[RTE_ETHER_ADDR_LEN - 1] = pkts_cnt;
    1022                 :          0 :                 retval = generate_packets(&bonding_mac, &dst_mac, 1, &pkts[pkts_cnt]);
    1023                 :            : 
    1024         [ #  # ]:          0 :                 if (retval != 1)
    1025                 :            :                         free_pkts(pkts, pkts_cnt);
    1026                 :            : 
    1027         [ #  # ]:          0 :                 TEST_ASSERT_EQUAL(retval, 1, "Failed to generate packet %u", pkts_cnt);
    1028                 :            :         }
    1029                 :            :         exp_pkts_cnt = pkts_cnt;
    1030                 :            : 
    1031                 :            :         /* Transmit packets on bonding device */
    1032                 :          0 :         retval = bond_tx(pkts, pkts_cnt);
    1033   [ #  #  #  # ]:          0 :         if (retval > 0 && retval < pkts_cnt)
    1034                 :          0 :                 free_pkts(&pkts[retval], pkts_cnt - retval);
    1035                 :            : 
    1036         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(retval, pkts_cnt, "TX on bonding device failed");
    1037                 :            : 
    1038                 :            :         /* Check if packets were transmitted properly. Every member should have
    1039                 :            :          * at least one packet, and sum must match. Under normal operation
    1040                 :            :          * there should be no LACP nor MARKER frames. */
    1041                 :            :         pkts_cnt = 0;
    1042   [ #  #  #  # ]:          0 :         FOR_EACH_MEMBER(i, member) {
    1043                 :            :                 uint16_t normal_cnt, slow_cnt;
    1044                 :            : 
    1045                 :          0 :                 retval = member_get_pkts(member, pkts, RTE_DIM(pkts));
    1046                 :            :                 normal_cnt = 0;
    1047                 :            :                 slow_cnt = 0;
    1048                 :            : 
    1049         [ #  # ]:          0 :                 for (j = 0; j < retval; j++) {
    1050         [ #  # ]:          0 :                         if (make_lacp_reply(member, pkts[j]) == 1)
    1051                 :          0 :                                 normal_cnt++;
    1052                 :            :                         else
    1053                 :          0 :                                 slow_cnt++;
    1054                 :            :                 }
    1055                 :            : 
    1056                 :          0 :                 free_pkts(pkts, normal_cnt + slow_cnt);
    1057         [ #  # ]:          0 :                 TEST_ASSERT_EQUAL(slow_cnt, 0,
    1058                 :            :                         "member %u unexpectedly transmitted %d SLOW packets", member->port_id,
    1059                 :            :                         slow_cnt);
    1060                 :            : 
    1061         [ #  # ]:          0 :                 TEST_ASSERT_NOT_EQUAL(normal_cnt, 0,
    1062                 :            :                         "member %u did not transmitted any packets", member->port_id);
    1063                 :            : 
    1064                 :          0 :                 pkts_cnt += normal_cnt;
    1065                 :            :         }
    1066                 :            : 
    1067         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(exp_pkts_cnt, pkts_cnt,
    1068                 :            :                 "Expected %u packets but transmitted only %d", exp_pkts_cnt, pkts_cnt);
    1069                 :            : 
    1070                 :            :         /*
    1071                 :            :          * Link down test:
    1072                 :            :          * simulate link down for first member.
    1073                 :            :          */
    1074                 :          0 :         delay = bond_get_update_timeout_ms();
    1075                 :            : 
    1076                 :            :         uint8_t member_down_id = INVALID_PORT_ID;
    1077                 :            : 
    1078   [ #  #  #  # ]:          0 :         FOR_EACH_MEMBER(i, member) {
    1079                 :          0 :                 rte_eth_dev_set_link_down(member->port_id);
    1080                 :          0 :                 member_down_id = member->port_id;
    1081                 :          0 :                 break;
    1082                 :            :         }
    1083                 :            : 
    1084         [ #  # ]:          0 :         RTE_VERIFY(member_down_id != INVALID_PORT_ID);
    1085                 :            : 
    1086                 :            :         /* Give some time to rearrange bonding. */
    1087         [ #  # ]:          0 :         for (i = 0; i < 3; i++) {
    1088                 :          0 :                 bond_handshake();
    1089                 :            :                 rte_delay_ms(delay);
    1090                 :            :         }
    1091                 :            : 
    1092         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(bond_handshake(), "Handshake after link down failed");
    1093                 :            : 
    1094                 :            :         /* Prepare burst. */
    1095         [ #  # ]:          0 :         for (pkts_cnt = 0; pkts_cnt < RTE_DIM(pkts); pkts_cnt++) {
    1096                 :          0 :                 dst_mac.addr_bytes[RTE_ETHER_ADDR_LEN - 1] = pkts_cnt;
    1097                 :          0 :                 retval = generate_packets(&bonding_mac, &dst_mac, 1, &pkts[pkts_cnt]);
    1098                 :            : 
    1099         [ #  # ]:          0 :                 if (retval != 1)
    1100                 :            :                         free_pkts(pkts, pkts_cnt);
    1101                 :            : 
    1102         [ #  # ]:          0 :                 TEST_ASSERT_EQUAL(retval, 1, "Failed to generate test packet %u",
    1103                 :            :                         pkts_cnt);
    1104                 :            :         }
    1105                 :            :         exp_pkts_cnt = pkts_cnt;
    1106                 :            : 
    1107                 :            :         /* Transmit packets on bonding device. */
    1108                 :          0 :         retval = bond_tx(pkts, pkts_cnt);
    1109   [ #  #  #  # ]:          0 :         if (retval > 0 && retval < pkts_cnt)
    1110                 :          0 :                 free_pkts(&pkts[retval], pkts_cnt - retval);
    1111                 :            : 
    1112         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(retval, pkts_cnt, "TX on bonding device failed");
    1113                 :            : 
    1114                 :            :         /* Check if packets was transmitted properly. Every member should have
    1115                 :            :          * at least one packet, and sum must match. Under normal operation
    1116                 :            :          * there should be no LACP nor MARKER frames. */
    1117                 :            :         pkts_cnt = 0;
    1118   [ #  #  #  # ]:          0 :         FOR_EACH_MEMBER(i, member) {
    1119                 :            :                 uint16_t normal_cnt, slow_cnt;
    1120                 :            : 
    1121                 :          0 :                 retval = member_get_pkts(member, pkts, RTE_DIM(pkts));
    1122                 :            :                 normal_cnt = 0;
    1123                 :            :                 slow_cnt = 0;
    1124                 :            : 
    1125         [ #  # ]:          0 :                 for (j = 0; j < retval; j++) {
    1126         [ #  # ]:          0 :                         if (make_lacp_reply(member, pkts[j]) == 1)
    1127                 :          0 :                                 normal_cnt++;
    1128                 :            :                         else
    1129                 :          0 :                                 slow_cnt++;
    1130                 :            :                 }
    1131                 :            : 
    1132                 :          0 :                 free_pkts(pkts, normal_cnt + slow_cnt);
    1133                 :            : 
    1134         [ #  # ]:          0 :                 if (member_down_id == member->port_id) {
    1135         [ #  # ]:          0 :                         TEST_ASSERT_EQUAL(normal_cnt + slow_cnt, 0,
    1136                 :            :                                 "member %u enexpectedly transmitted %u packets",
    1137                 :            :                                 normal_cnt + slow_cnt, member->port_id);
    1138                 :            :                 } else {
    1139         [ #  # ]:          0 :                         TEST_ASSERT_EQUAL(slow_cnt, 0,
    1140                 :            :                                 "member %u unexpectedly transmitted %d SLOW packets",
    1141                 :            :                                 member->port_id, slow_cnt);
    1142                 :            : 
    1143         [ #  # ]:          0 :                         TEST_ASSERT_NOT_EQUAL(normal_cnt, 0,
    1144                 :            :                                 "member %u did not transmitted any packets", member->port_id);
    1145                 :            :                 }
    1146                 :            : 
    1147                 :          0 :                 pkts_cnt += normal_cnt;
    1148                 :            :         }
    1149                 :            : 
    1150         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(exp_pkts_cnt, pkts_cnt,
    1151                 :            :                 "Expected %u packets but transmitted only %d", exp_pkts_cnt, pkts_cnt);
    1152                 :            : 
    1153                 :          0 :         return remove_members_and_stop_bonding_device();
    1154                 :            : }
    1155                 :            : 
    1156                 :            : static void
    1157                 :            : init_marker(struct rte_mbuf *pkt, struct member_conf *member)
    1158                 :            : {
    1159                 :          0 :         struct marker_header *marker_hdr = rte_pktmbuf_mtod(pkt,
    1160                 :            :                         struct marker_header *);
    1161                 :            : 
    1162                 :            :         /* Copy multicast destination address */
    1163                 :            :         rte_ether_addr_copy(&slow_protocol_mac_addr,
    1164                 :            :                         &marker_hdr->eth_hdr.dst_addr);
    1165                 :            : 
    1166                 :            :         /* Init source address */
    1167                 :            :         rte_ether_addr_copy(&parnter_mac_default,
    1168                 :            :                         &marker_hdr->eth_hdr.src_addr);
    1169                 :          0 :         marker_hdr->eth_hdr.src_addr.addr_bytes[RTE_ETHER_ADDR_LEN - 1] =
    1170                 :          0 :                 member->port_id;
    1171                 :            : 
    1172                 :          0 :         marker_hdr->eth_hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_SLOW);
    1173                 :            : 
    1174                 :          0 :         marker_hdr->marker.subtype = SLOW_SUBTYPE_MARKER;
    1175                 :          0 :         marker_hdr->marker.version_number = 1;
    1176                 :          0 :         marker_hdr->marker.tlv_type_marker = MARKER_TLV_TYPE_INFO;
    1177                 :          0 :         marker_hdr->marker.info_length =
    1178                 :            :                         offsetof(struct marker, reserved_90) -
    1179                 :            :                         offsetof(struct marker, requester_port);
    1180                 :            :         RTE_VERIFY(marker_hdr->marker.info_length == 16);
    1181                 :          0 :         marker_hdr->marker.requester_port = member->port_id + 1;
    1182                 :          0 :         marker_hdr->marker.tlv_type_terminator = TLV_TYPE_TERMINATOR_INFORMATION;
    1183                 :          0 :         marker_hdr->marker.terminator_length = 0;
    1184                 :            : }
    1185                 :            : 
    1186                 :            : static int
    1187                 :          0 : test_mode4_marker(void)
    1188                 :            : {
    1189                 :            :         struct member_conf *member;
    1190                 :            :         struct rte_mbuf *pkts[MAX_PKT_BURST];
    1191                 :            :         struct rte_mbuf *marker_pkt;
    1192                 :            :         struct marker_header *marker_hdr;
    1193                 :            : 
    1194                 :            :         unsigned delay;
    1195                 :            :         int retval;
    1196                 :            :         uint16_t nb_pkts;
    1197                 :            :         uint8_t i, j;
    1198                 :            :         const uint16_t ethtype_slow_be = rte_be_to_cpu_16(RTE_ETHER_TYPE_SLOW);
    1199                 :            : 
    1200                 :          0 :         retval = initialize_bonding_device_with_members(TEST_MARKER_MEMBER_COUT,
    1201                 :            :                                                       0);
    1202         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonding device");
    1203                 :            : 
    1204                 :            :         /* Test LACP handshake function */
    1205                 :          0 :         retval = bond_handshake();
    1206         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Initial handshake failed");
    1207                 :            : 
    1208                 :          0 :         delay = bond_get_update_timeout_ms();
    1209   [ #  #  #  # ]:          0 :         FOR_EACH_MEMBER(i, member) {
    1210                 :          0 :                 marker_pkt = rte_pktmbuf_alloc(test_params.mbuf_pool);
    1211         [ #  # ]:          0 :                 TEST_ASSERT_NOT_NULL(marker_pkt, "Failed to allocate marker packet");
    1212                 :            :                 init_marker(marker_pkt, member);
    1213                 :            : 
    1214                 :          0 :                 retval = member_put_pkts(member, &marker_pkt, 1);
    1215         [ #  # ]:          0 :                 if (retval != 1)
    1216                 :          0 :                         rte_pktmbuf_free(marker_pkt);
    1217                 :            : 
    1218         [ #  # ]:          0 :                 TEST_ASSERT_EQUAL(retval, 1,
    1219                 :            :                         "Failed to send marker packet to member %u", member->port_id);
    1220                 :            : 
    1221         [ #  # ]:          0 :                 for (j = 0; j < 20; ++j) {
    1222                 :            :                         rte_delay_ms(delay);
    1223                 :          0 :                         retval = rte_eth_rx_burst(test_params.bonding_port_id, 0, pkts,
    1224                 :            :                                 RTE_DIM(pkts));
    1225                 :            : 
    1226         [ #  # ]:          0 :                         if (retval > 0)
    1227                 :            :                                 free_pkts(pkts, retval);
    1228                 :            : 
    1229         [ #  # ]:          0 :                         TEST_ASSERT_EQUAL(retval, 0, "Received packets unexpectedly");
    1230                 :            : 
    1231                 :          0 :                         retval = rte_eth_tx_burst(test_params.bonding_port_id, 0, NULL, 0);
    1232         [ #  # ]:          0 :                         TEST_ASSERT_EQUAL(retval, 0,
    1233                 :            :                                 "Requested TX of 0 packets but %d transmitted", retval);
    1234                 :            : 
    1235                 :            :                         /* Check if LACP packet was send by state machines
    1236                 :            :                            First and only packet must be a maker response */
    1237                 :          0 :                         retval = member_get_pkts(member, pkts, MAX_PKT_BURST);
    1238         [ #  # ]:          0 :                         if (retval == 0)
    1239                 :            :                                 continue;
    1240         [ #  # ]:          0 :                         if (retval > 1)
    1241                 :          0 :                                 free_pkts(pkts, retval);
    1242                 :            : 
    1243         [ #  # ]:          0 :                         TEST_ASSERT_EQUAL(retval, 1, "failed to get member packets");
    1244                 :            :                         nb_pkts = retval;
    1245                 :            : 
    1246                 :          0 :                         marker_hdr = rte_pktmbuf_mtod(pkts[0], struct marker_header *);
    1247                 :            :                         /* Check if it's slow packet*/
    1248         [ #  # ]:          0 :                         if (marker_hdr->eth_hdr.ether_type != ethtype_slow_be)
    1249                 :            :                                 retval = -1;
    1250                 :            :                         /* Check if it's marker packet */
    1251         [ #  # ]:          0 :                         else if (marker_hdr->marker.subtype != SLOW_SUBTYPE_MARKER)
    1252                 :            :                                 retval = -2;
    1253         [ #  # ]:          0 :                         else if (marker_hdr->marker.tlv_type_marker != MARKER_TLV_TYPE_RESP)
    1254                 :            :                                 retval = -3;
    1255                 :            : 
    1256                 :            :                         free_pkts(pkts, nb_pkts);
    1257                 :            : 
    1258         [ #  # ]:          0 :                         TEST_ASSERT_NOT_EQUAL(retval, -1, "Unexpected protocol type");
    1259         [ #  # ]:          0 :                         TEST_ASSERT_NOT_EQUAL(retval, -2, "Unexpected sub protocol type");
    1260         [ #  # ]:          0 :                         TEST_ASSERT_NOT_EQUAL(retval, -3, "Unexpected marker type");
    1261                 :            :                         break;
    1262                 :            :                 }
    1263                 :            : 
    1264         [ #  # ]:          0 :                 TEST_ASSERT(j < 20, "Marker response not found");
    1265                 :            :         }
    1266                 :            : 
    1267                 :          0 :         retval = remove_members_and_stop_bonding_device();
    1268         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval,     "Test cleanup failed.");
    1269                 :            : 
    1270                 :            :         return TEST_SUCCESS;
    1271                 :            : }
    1272                 :            : 
    1273                 :            : static int
    1274                 :          0 : test_mode4_expired(void)
    1275                 :            : {
    1276                 :            :         struct member_conf *member, *exp_member = NULL;
    1277                 :            :         struct rte_mbuf *pkts[MAX_PKT_BURST];
    1278                 :            :         int retval;
    1279                 :            :         uint32_t old_delay;
    1280                 :            : 
    1281                 :            :         uint8_t i;
    1282                 :            :         uint16_t j;
    1283                 :            : 
    1284                 :            :         struct rte_eth_bond_8023ad_conf conf;
    1285                 :            : 
    1286                 :          0 :         retval = initialize_bonding_device_with_members(TEST_EXPIRED_MEMBER_COUNT,
    1287                 :            :                                                       0);
    1288                 :            :         /* Set custom timeouts to make test last shorter. */
    1289                 :          0 :         rte_eth_bond_8023ad_conf_get(test_params.bonding_port_id, &conf);
    1290                 :          0 :         conf.fast_periodic_ms = 100;
    1291                 :          0 :         conf.slow_periodic_ms = 600;
    1292                 :          0 :         conf.short_timeout_ms = 300;
    1293                 :          0 :         conf.long_timeout_ms = 900;
    1294                 :          0 :         conf.aggregate_wait_timeout_ms = 200;
    1295                 :          0 :         conf.tx_period_ms = 100;
    1296                 :          0 :         old_delay = conf.update_timeout_ms;
    1297                 :          0 :         conf.update_timeout_ms = 10;
    1298                 :          0 :         rte_eth_bond_8023ad_setup(test_params.bonding_port_id, &conf);
    1299                 :            : 
    1300                 :            :         /* Wait for new settings to be applied. */
    1301         [ #  # ]:          0 :         for (i = 0; i < old_delay/conf.update_timeout_ms * 2; i++) {
    1302   [ #  #  #  # ]:          0 :                 FOR_EACH_MEMBER(j, member)
    1303                 :          0 :                         bond_handshake_reply(member);
    1304                 :            : 
    1305                 :          0 :                 rte_delay_ms(conf.update_timeout_ms);
    1306                 :            :         }
    1307                 :            : 
    1308                 :          0 :         retval = bond_handshake();
    1309         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Initial handshake failed");
    1310                 :            : 
    1311                 :            :         /* Find first member */
    1312   [ #  #  #  # ]:          0 :         FOR_EACH_MEMBER(i, member) {
    1313                 :            :                 exp_member = member;
    1314                 :            :                 break;
    1315                 :            :         }
    1316                 :            : 
    1317         [ #  # ]:          0 :         RTE_VERIFY(exp_member != NULL);
    1318                 :            : 
    1319                 :            :         /* When one of partners do not send or respond to LACP frame in
    1320                 :            :          * conf.long_timeout_ms time, internal state machines should detect this
    1321                 :            :          * and transit to expired state. */
    1322         [ #  # ]:          0 :         for (j = 0; j < conf.long_timeout_ms/conf.update_timeout_ms + 2; j++) {
    1323                 :            :                 rte_delay_ms(conf.update_timeout_ms);
    1324                 :            : 
    1325                 :          0 :                 retval = bond_tx(NULL, 0);
    1326         [ #  # ]:          0 :                 TEST_ASSERT_EQUAL(retval, 0, "Unexpectedly received %d packets",
    1327                 :            :                         retval);
    1328                 :            : 
    1329   [ #  #  #  # ]:          0 :                 FOR_EACH_MEMBER(i, member) {
    1330                 :          0 :                         retval = bond_handshake_reply(member);
    1331         [ #  # ]:          0 :                         TEST_ASSERT(retval >= 0, "Handshake failed");
    1332                 :            : 
    1333                 :            :                         /* Remove replay for member that suppose to be expired. */
    1334         [ #  # ]:          0 :                         if (member == exp_member) {
    1335         [ #  # ]:          0 :                                 while (rte_ring_count(member->rx_queue) > 0) {
    1336   [ #  #  #  #  :          0 :                                         void *pkt = NULL;
                      # ]
    1337                 :            : 
    1338                 :            :                                         rte_ring_dequeue(member->rx_queue, &pkt);
    1339                 :          0 :                                         rte_pktmbuf_free(pkt);
    1340                 :            :                                 }
    1341                 :            :                         }
    1342                 :            :                 }
    1343                 :            : 
    1344                 :          0 :                 retval = bond_rx(pkts, RTE_DIM(pkts));
    1345         [ #  # ]:          0 :                 if (retval > 0)
    1346                 :            :                         free_pkts(pkts, retval);
    1347                 :            : 
    1348         [ #  # ]:          0 :                 TEST_ASSERT_EQUAL(retval, 0, "Unexpectedly received %d packets",
    1349                 :            :                         retval);
    1350                 :            :         }
    1351                 :            : 
    1352                 :            :         /* After test only expected member should be in EXPIRED state */
    1353   [ #  #  #  # ]:          0 :         FOR_EACH_MEMBER(i, member) {
    1354         [ #  # ]:          0 :                 if (member == exp_member)
    1355         [ #  # ]:          0 :                         TEST_ASSERT(member->lacp_parnter_state & STATE_EXPIRED,
    1356                 :            :                                 "Member %u should be in expired.", member->port_id);
    1357                 :            :                 else
    1358         [ #  # ]:          0 :                         TEST_ASSERT_EQUAL(bond_handshake_done(member), 1,
    1359                 :            :                                 "Member %u should be operational.", member->port_id);
    1360                 :            :         }
    1361                 :            : 
    1362                 :          0 :         retval = remove_members_and_stop_bonding_device();
    1363         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Test cleanup failed.");
    1364                 :            : 
    1365                 :            :         return TEST_SUCCESS;
    1366                 :            : }
    1367                 :            : 
    1368                 :            : static int
    1369                 :          0 : test_mode4_ext_ctrl(void)
    1370                 :            : {
    1371                 :            :         /*
    1372                 :            :          * configure bonding interface without the external sm enabled
    1373                 :            :          *   . try to transmit lacpdu (should fail)
    1374                 :            :          *   . try to set collecting and distributing flags (should fail)
    1375                 :            :          * reconfigure w/external sm
    1376                 :            :          *   . transmit one lacpdu on each member using new api
    1377                 :            :          *   . make sure each member receives one lacpdu using the callback api
    1378                 :            :          *   . transmit one data pdu on each member (should fail)
    1379                 :            :          *   . enable distribution and collection, send one data pdu each again
    1380                 :            :          */
    1381                 :            : 
    1382                 :            :         int retval;
    1383                 :            :         struct member_conf *member = NULL;
    1384                 :            :         uint8_t i;
    1385                 :            : 
    1386                 :            :         struct rte_mbuf *lacp_tx_buf[MEMBER_COUNT];
    1387                 :            :         struct rte_ether_addr src_mac, dst_mac;
    1388                 :          0 :         struct lacpdu_header lacpdu = {
    1389                 :            :                 .lacpdu = {
    1390                 :            :                         .subtype = SLOW_SUBTYPE_LACP,
    1391                 :            :                 },
    1392                 :            :         };
    1393                 :            : 
    1394                 :            :         rte_ether_addr_copy(&parnter_system, &src_mac);
    1395                 :            :         rte_ether_addr_copy(&slow_protocol_mac_addr, &dst_mac);
    1396                 :            : 
    1397                 :          0 :         initialize_eth_header(&lacpdu.eth_hdr, &src_mac, &dst_mac,
    1398                 :            :                               RTE_ETHER_TYPE_SLOW, 0, 0);
    1399                 :            : 
    1400         [ #  # ]:          0 :         for (i = 0; i < MEMBER_COUNT; i++) {
    1401                 :          0 :                 lacp_tx_buf[i] = rte_pktmbuf_alloc(test_params.mbuf_pool);
    1402         [ #  # ]:          0 :                 rte_memcpy(rte_pktmbuf_mtod(lacp_tx_buf[i], char *),
    1403                 :            :                            &lacpdu, sizeof(lacpdu));
    1404                 :          0 :                 rte_pktmbuf_pkt_len(lacp_tx_buf[i]) = sizeof(lacpdu);
    1405                 :            :         }
    1406                 :            : 
    1407                 :          0 :         retval = initialize_bonding_device_with_members(TEST_TX_MEMBER_COUNT, 0);
    1408         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonding device");
    1409                 :            : 
    1410   [ #  #  #  # ]:          0 :         FOR_EACH_MEMBER(i, member) {
    1411         [ #  # ]:          0 :                 TEST_ASSERT_FAIL(rte_eth_bond_8023ad_ext_slowtx(
    1412                 :            :                                                 test_params.bonding_port_id,
    1413                 :            :                                                 member->port_id, lacp_tx_buf[i]),
    1414                 :            :                                  "Member should not allow manual LACP xmit");
    1415         [ #  # ]:          0 :                 TEST_ASSERT_FAIL(rte_eth_bond_8023ad_ext_collect(
    1416                 :            :                                                 test_params.bonding_port_id,
    1417                 :            :                                                 member->port_id, 1),
    1418                 :            :                                  "Member should not allow external state controls");
    1419                 :            :         }
    1420                 :            : 
    1421                 :            :         free_pkts(lacp_tx_buf, RTE_DIM(lacp_tx_buf));
    1422                 :            : 
    1423                 :          0 :         retval = remove_members_and_stop_bonding_device();
    1424         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Bonding device cleanup failed.");
    1425                 :            : 
    1426                 :            :         return TEST_SUCCESS;
    1427                 :            : }
    1428                 :            : 
    1429                 :            : 
    1430                 :            : static int
    1431                 :          0 : test_mode4_ext_lacp(void)
    1432                 :            : {
    1433                 :            :         int retval;
    1434                 :            :         struct member_conf *member = NULL;
    1435                 :            :         uint8_t all_members_done = 0, i;
    1436                 :            :         uint16_t nb_pkts;
    1437                 :          0 :         const unsigned int delay = bond_get_update_timeout_ms();
    1438                 :            : 
    1439                 :            :         struct rte_mbuf *lacp_tx_buf[MEMBER_COUNT];
    1440                 :            :         struct rte_mbuf *buf[MEMBER_COUNT];
    1441                 :            :         struct rte_ether_addr src_mac, dst_mac;
    1442                 :          0 :         struct lacpdu_header lacpdu = {
    1443                 :            :                 .lacpdu = {
    1444                 :            :                         .subtype = SLOW_SUBTYPE_LACP,
    1445                 :            :                 },
    1446                 :            :         };
    1447                 :            : 
    1448                 :            :         rte_ether_addr_copy(&parnter_system, &src_mac);
    1449                 :            :         rte_ether_addr_copy(&slow_protocol_mac_addr, &dst_mac);
    1450                 :            : 
    1451                 :          0 :         initialize_eth_header(&lacpdu.eth_hdr, &src_mac, &dst_mac,
    1452                 :            :                               RTE_ETHER_TYPE_SLOW, 0, 0);
    1453                 :            : 
    1454         [ #  # ]:          0 :         for (i = 0; i < MEMBER_COUNT; i++) {
    1455                 :          0 :                 lacp_tx_buf[i] = rte_pktmbuf_alloc(test_params.mbuf_pool);
    1456         [ #  # ]:          0 :                 rte_memcpy(rte_pktmbuf_mtod(lacp_tx_buf[i], char *),
    1457                 :            :                            &lacpdu, sizeof(lacpdu));
    1458                 :          0 :                 rte_pktmbuf_pkt_len(lacp_tx_buf[i]) = sizeof(lacpdu);
    1459                 :            :         }
    1460                 :            : 
    1461                 :          0 :         retval = initialize_bonding_device_with_members(TEST_TX_MEMBER_COUNT, 1);
    1462         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonding device");
    1463                 :            : 
    1464                 :            :         memset(lacpdu_rx_count, 0, sizeof(lacpdu_rx_count));
    1465                 :            : 
    1466                 :            :         /* Wait for new settings to be applied. */
    1467         [ #  # ]:          0 :         for (i = 0; i < 30; ++i)
    1468                 :            :                 rte_delay_ms(delay);
    1469                 :            : 
    1470   [ #  #  #  # ]:          0 :         FOR_EACH_MEMBER(i, member) {
    1471                 :          0 :                 retval = rte_eth_bond_8023ad_ext_slowtx(
    1472                 :          0 :                                                 test_params.bonding_port_id,
    1473                 :          0 :                                                 member->port_id, lacp_tx_buf[i]);
    1474         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(retval,
    1475                 :            :                                     "Member should allow manual LACP xmit");
    1476                 :            :         }
    1477                 :            : 
    1478                 :            :         nb_pkts = bond_tx(NULL, 0);
    1479         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(nb_pkts, 0, "Packets transmitted unexpectedly");
    1480                 :            : 
    1481   [ #  #  #  # ]:          0 :         FOR_EACH_MEMBER(i, member) {
    1482                 :          0 :                 nb_pkts = member_get_pkts(member, buf, RTE_DIM(buf));
    1483         [ #  # ]:          0 :                 TEST_ASSERT_EQUAL(nb_pkts, 1, "found %u packets on member %d\n",
    1484                 :            :                                   nb_pkts, i);
    1485                 :          0 :                 member_put_pkts(member, buf, nb_pkts);
    1486                 :            :         }
    1487                 :            : 
    1488                 :            :         nb_pkts = bond_rx(buf, RTE_DIM(buf));
    1489                 :            :         free_pkts(buf, nb_pkts);
    1490         [ #  # ]:          0 :         TEST_ASSERT_EQUAL(nb_pkts, 0, "Packets received unexpectedly");
    1491                 :            : 
    1492                 :            :         /* wait for the periodic callback to run */
    1493         [ #  # ]:          0 :         for (i = 0; i < 30 && all_members_done == 0; ++i) {
    1494                 :            :                 uint8_t s, total = 0;
    1495                 :            : 
    1496                 :            :                 rte_delay_ms(delay);
    1497   [ #  #  #  # ]:          0 :                 FOR_EACH_MEMBER(s, member) {
    1498                 :          0 :                         total += lacpdu_rx_count[member->port_id];
    1499                 :            :                 }
    1500                 :            : 
    1501         [ #  # ]:          0 :                 if (total >= MEMBER_COUNT)
    1502                 :            :                         all_members_done = 1;
    1503                 :            :         }
    1504                 :            : 
    1505   [ #  #  #  # ]:          0 :         FOR_EACH_MEMBER(i, member) {
    1506         [ #  # ]:          0 :                 TEST_ASSERT_EQUAL(lacpdu_rx_count[member->port_id], 1,
    1507                 :            :                                   "Member port %u should have received 1 lacpdu (count=%u)",
    1508                 :            :                                   member->port_id,
    1509                 :            :                                   lacpdu_rx_count[member->port_id]);
    1510                 :            :         }
    1511                 :            : 
    1512                 :          0 :         retval = remove_members_and_stop_bonding_device();
    1513         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(retval, "Test cleanup failed.");
    1514                 :            : 
    1515                 :            :         return TEST_SUCCESS;
    1516                 :            : }
    1517                 :            : 
    1518                 :            : static int
    1519                 :          0 : check_environment(void)
    1520                 :            : {
    1521                 :            :         struct member_conf *port;
    1522                 :            :         uint8_t i, env_state;
    1523                 :            :         uint16_t members[RTE_DIM(test_params.member_ports)];
    1524                 :            :         int members_count;
    1525                 :            : 
    1526                 :            :         env_state = 0;
    1527         [ #  # ]:          0 :         FOR_EACH_PORT(i, port) {
    1528         [ #  # ]:          0 :                 if (rte_ring_count(port->rx_queue) != 0)
    1529                 :            :                         env_state |= 0x01;
    1530                 :            : 
    1531         [ #  # ]:          0 :                 if (rte_ring_count(port->tx_queue) != 0)
    1532                 :          0 :                         env_state |= 0x02;
    1533                 :            : 
    1534         [ #  # ]:          0 :                 if (port->bonding != 0)
    1535                 :          0 :                         env_state |= 0x04;
    1536                 :            : 
    1537         [ #  # ]:          0 :                 if (port->lacp_parnter_state != 0)
    1538                 :          0 :                         env_state |= 0x08;
    1539                 :            : 
    1540         [ #  # ]:          0 :                 if (env_state != 0)
    1541                 :            :                         break;
    1542                 :            :         }
    1543                 :            : 
    1544                 :          0 :         members_count = rte_eth_bond_members_get(test_params.bonding_port_id,
    1545                 :            :                         members, RTE_DIM(members));
    1546                 :            : 
    1547         [ #  # ]:          0 :         if (members_count != 0)
    1548                 :          0 :                 env_state |= 0x10;
    1549                 :            : 
    1550   [ #  #  #  #  :          0 :         TEST_ASSERT_EQUAL(env_state, 0,
          #  #  #  #  #  
                      # ]
    1551                 :            :                 "Environment not clean (port %u):%s%s%s%s%s",
    1552                 :            :                 port->port_id,
    1553                 :            :                 env_state & 0x01 ? " member rx queue not clean" : "",
    1554                 :            :                 env_state & 0x02 ? " member tx queue not clean" : "",
    1555                 :            :                 env_state & 0x04 ? " port marked as enmemberd" : "",
    1556                 :            :                 env_state & 0x80 ? " member state is not reset" : "",
    1557                 :            :                 env_state & 0x10 ? " member count not equal 0" : ".");
    1558                 :            : 
    1559                 :            : 
    1560                 :            :         return TEST_SUCCESS;
    1561                 :            : }
    1562                 :            : 
    1563                 :            : static int
    1564                 :          0 : test_mode4_executor(int (*test_func)(void))
    1565                 :            : {
    1566                 :            :         struct member_conf *port;
    1567                 :            :         int test_result;
    1568                 :            :         uint8_t i;
    1569                 :            :         void *pkt;
    1570                 :            : 
    1571                 :            :         /* Check if environment is clean. Fail to launch a test if there was
    1572                 :            :          * a critical error before that prevented to reset environment. */
    1573         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(check_environment(),
    1574                 :            :                 "Refusing to launch test in dirty environment.");
    1575                 :            : 
    1576         [ #  # ]:          0 :         RTE_VERIFY(test_func != NULL);
    1577                 :          0 :         test_result = (*test_func)();
    1578                 :            : 
    1579                 :            :         /* If test succeed check if environment wast left in good condition. */
    1580         [ #  # ]:          0 :         if (test_result == TEST_SUCCESS)
    1581                 :          0 :                 test_result = check_environment();
    1582                 :            : 
    1583                 :            :         /* Reset environment in case test failed to do that. */
    1584         [ #  # ]:          0 :         if (test_result != TEST_SUCCESS) {
    1585         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(remove_members_and_stop_bonding_device(),
    1586                 :            :                         "Failed to stop bonding device");
    1587                 :            : 
    1588         [ #  # ]:          0 :                 FOR_EACH_PORT(i, port) {
    1589         [ #  # ]:          0 :                         while (rte_ring_count(port->rx_queue) != 0) {
    1590                 :            :                                 if (rte_ring_dequeue(port->rx_queue, &pkt) == 0)
    1591                 :          0 :                                         rte_pktmbuf_free(pkt);
    1592                 :            :                         }
    1593                 :            : 
    1594         [ #  # ]:          0 :                         while (rte_ring_count(port->tx_queue) != 0) {
    1595                 :            :                                 if (rte_ring_dequeue(port->tx_queue, &pkt) == 0)
    1596                 :          0 :                                         rte_pktmbuf_free(pkt);
    1597                 :            :                         }
    1598                 :            :                 }
    1599                 :            :         }
    1600                 :            : 
    1601                 :            :         return test_result;
    1602                 :            : }
    1603                 :            : 
    1604                 :            : static int
    1605                 :          0 : test_mode4_agg_mode_selection_wrapper(void){
    1606                 :          0 :         return test_mode4_executor(&test_mode4_agg_mode_selection);
    1607                 :            : }
    1608                 :            : 
    1609                 :            : static int
    1610                 :          0 : test_mode4_lacp_wrapper(void)
    1611                 :            : {
    1612                 :          0 :         return test_mode4_executor(&test_mode4_lacp);
    1613                 :            : }
    1614                 :            : 
    1615                 :            : static int
    1616                 :          0 : test_mode4_marker_wrapper(void)
    1617                 :            : {
    1618                 :          0 :         return test_mode4_executor(&test_mode4_marker);
    1619                 :            : }
    1620                 :            : 
    1621                 :            : static int
    1622                 :          0 : test_mode4_rx_wrapper(void)
    1623                 :            : {
    1624                 :          0 :         return test_mode4_executor(&test_mode4_rx);
    1625                 :            : }
    1626                 :            : 
    1627                 :            : static int
    1628                 :          0 : test_mode4_tx_burst_wrapper(void)
    1629                 :            : {
    1630                 :          0 :         return test_mode4_executor(&test_mode4_tx_burst);
    1631                 :            : }
    1632                 :            : 
    1633                 :            : static int
    1634                 :          0 : test_mode4_expired_wrapper(void)
    1635                 :            : {
    1636                 :          0 :         return test_mode4_executor(&test_mode4_expired);
    1637                 :            : }
    1638                 :            : 
    1639                 :            : static int
    1640                 :          0 : test_mode4_ext_ctrl_wrapper(void)
    1641                 :            : {
    1642                 :          0 :         return test_mode4_executor(&test_mode4_ext_ctrl);
    1643                 :            : }
    1644                 :            : 
    1645                 :            : static int
    1646                 :          0 : test_mode4_ext_lacp_wrapper(void)
    1647                 :            : {
    1648                 :          0 :         return test_mode4_executor(&test_mode4_ext_lacp);
    1649                 :            : }
    1650                 :            : 
    1651                 :            : static struct unit_test_suite link_bonding_mode4_test_suite  = {
    1652                 :            :         .suite_name = "Link Bonding mode 4 Unit Test Suite",
    1653                 :            :         .setup = test_setup,
    1654                 :            :         .teardown = testsuite_teardown,
    1655                 :            :         .unit_test_cases = {
    1656                 :            :                 TEST_CASE_NAMED("test_mode4_agg_mode_selection",
    1657                 :            :                                 test_mode4_agg_mode_selection_wrapper),
    1658                 :            :                 TEST_CASE_NAMED("test_mode4_lacp", test_mode4_lacp_wrapper),
    1659                 :            :                 TEST_CASE_NAMED("test_mode4_rx", test_mode4_rx_wrapper),
    1660                 :            :                 TEST_CASE_NAMED("test_mode4_tx_burst", test_mode4_tx_burst_wrapper),
    1661                 :            :                 TEST_CASE_NAMED("test_mode4_marker", test_mode4_marker_wrapper),
    1662                 :            :                 TEST_CASE_NAMED("test_mode4_expired", test_mode4_expired_wrapper),
    1663                 :            :                 TEST_CASE_NAMED("test_mode4_ext_ctrl",
    1664                 :            :                                 test_mode4_ext_ctrl_wrapper),
    1665                 :            :                 TEST_CASE_NAMED("test_mode4_ext_lacp",
    1666                 :            :                                 test_mode4_ext_lacp_wrapper),
    1667                 :            : 
    1668                 :            :                 TEST_CASES_END() /**< NULL terminate unit test array */
    1669                 :            :         }
    1670                 :            : };
    1671                 :            : 
    1672                 :            : static int
    1673                 :          0 : test_link_bonding_mode4(void)
    1674                 :            : {
    1675                 :          0 :         return unit_test_suite_runner(&link_bonding_mode4_test_suite);
    1676                 :            : }
    1677                 :            : 
    1678                 :        252 : REGISTER_DRIVER_TEST(link_bonding_mode4_autotest, test_link_bonding_mode4);

Generated by: LCOV version 1.14