All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michal Jastrzebski <michalx.k.jastrzebski-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
To: dev-VfR2kkLFssw@public.gmane.org
Subject: [PATCH v3 6/6] bond: add unit tests for link bonding mode 6.
Date: Thu, 19 Feb 2015 18:26:19 +0100	[thread overview]
Message-ID: <1424366779-14256-7-git-send-email-michalx.k.jastrzebski@intel.com> (raw)
In-Reply-To: <1424366779-14256-1-git-send-email-michalx.k.jastrzebski-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>

From: Maciej Gajdzica <maciejx.t.gajdzica-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>

Added 4 unit tests checking link bonding mode 6 behavior.

Also modified virtual_pmd so it is possible to provide packets,
that should be received with rx_burst and to inspect packets
transmitted by tx_burst.

In packet_burst_generator.c function creating eth_header is
modified, so it accepts ether_type as a parameter and function
creating arp_header is added. Updated other unit tests to get
rid of compilation errors.

Signed-off-by: Maciej Gajdzica <maciejx.t.gajdzica-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
 app/test/packet_burst_generator.c |   41 +++-
 app/test/packet_burst_generator.h |   11 +-
 app/test/test_link_bonding.c      |  439 +++++++++++++++++++++++++++++++++++--
 app/test/test_pmd_perf.c          |    3 +-
 app/test/virtual_pmd.c            |  109 +++++----
 app/test/virtual_pmd.h            |    5 +-
 6 files changed, 533 insertions(+), 75 deletions(-)

diff --git a/app/test/packet_burst_generator.c b/app/test/packet_burst_generator.c
index e9d059c..b46eed7 100644
--- a/app/test/packet_burst_generator.c
+++ b/app/test/packet_burst_generator.c
@@ -80,11 +80,10 @@ copy_buf_to_pkt(void *buf, unsigned len, struct rte_mbuf *pkt, unsigned offset)
 	copy_buf_to_pkt_segs(buf, len, pkt, offset);
 }
 
-
 void
 initialize_eth_header(struct ether_hdr *eth_hdr, struct ether_addr *src_mac,
-		struct ether_addr *dst_mac, uint8_t ipv4, uint8_t vlan_enabled,
-		uint16_t van_id)
+		struct ether_addr *dst_mac, uint16_t ether_type,
+		uint8_t vlan_enabled, uint16_t van_id)
 {
 	ether_addr_copy(dst_mac, &eth_hdr->d_addr);
 	ether_addr_copy(src_mac, &eth_hdr->s_addr);
@@ -95,19 +94,27 @@ initialize_eth_header(struct ether_hdr *eth_hdr, struct ether_addr *src_mac,
 
 		eth_hdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
 
-		if (ipv4)
-			vhdr->eth_proto =  rte_cpu_to_be_16(ETHER_TYPE_IPv4);
-		else
-			vhdr->eth_proto =  rte_cpu_to_be_16(ETHER_TYPE_IPv6);
-
+		vhdr->eth_proto =  rte_cpu_to_be_16(ether_type);
 		vhdr->vlan_tci = van_id;
 	} else {
-		if (ipv4)
-			eth_hdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
-		else
-			eth_hdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+		eth_hdr->ether_type = rte_cpu_to_be_16(ether_type);
 	}
+}
 
+void
+initialize_arp_header(struct arp_hdr *arp_hdr, struct ether_addr *src_mac,
+		struct ether_addr *dst_mac, uint32_t src_ip, uint32_t dst_ip,
+		uint32_t opcode)
+{
+	arp_hdr->arp_hrd = rte_cpu_to_be_16(ARP_HRD_ETHER);
+	arp_hdr->arp_pro = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+	arp_hdr->arp_hln = ETHER_ADDR_LEN;
+	arp_hdr->arp_pln = sizeof(uint32_t);
+	arp_hdr->arp_op = rte_cpu_to_be_16(opcode);
+	ether_addr_copy(src_mac, &arp_hdr->arp_data.arp_sha);
+	arp_hdr->arp_data.arp_sip = src_ip;
+	ether_addr_copy(dst_mac, &arp_hdr->arp_data.arp_tha);
+	arp_hdr->arp_data.arp_tip = dst_ip;
 }
 
 uint16_t
@@ -265,9 +272,19 @@ nomore_mbuf:
 		if (ipv4) {
 			pkt->vlan_tci  = ETHER_TYPE_IPv4;
 			pkt->l3_len = sizeof(struct ipv4_hdr);
+
+			if (vlan_enabled)
+				pkt->ol_flags = PKT_RX_IPV4_HDR | PKT_RX_VLAN_PKT;
+			else
+				pkt->ol_flags = PKT_RX_IPV4_HDR;
 		} else {
 			pkt->vlan_tci  = ETHER_TYPE_IPv6;
 			pkt->l3_len = sizeof(struct ipv6_hdr);
+
+			if (vlan_enabled)
+				pkt->ol_flags = PKT_RX_IPV6_HDR | PKT_RX_VLAN_PKT;
+			else
+				pkt->ol_flags = PKT_RX_IPV6_HDR;
 		}
 
 		pkts_burst[nb_pkt] = pkt;
diff --git a/app/test/packet_burst_generator.h b/app/test/packet_burst_generator.h
index 666cc8e..edc1044 100644
--- a/app/test/packet_burst_generator.h
+++ b/app/test/packet_burst_generator.h
@@ -40,6 +40,7 @@ extern "C" {
 
 #include <rte_mbuf.h>
 #include <rte_ether.h>
+#include <rte_arp.h>
 #include <rte_ip.h>
 #include <rte_udp.h>
 
@@ -50,11 +51,15 @@ extern "C" {
 #define PACKET_BURST_GEN_PKT_LEN 60
 #define PACKET_BURST_GEN_PKT_LEN_128 128
 
-
 void
 initialize_eth_header(struct ether_hdr *eth_hdr, struct ether_addr *src_mac,
-		struct ether_addr *dst_mac, uint8_t ipv4, uint8_t vlan_enabled,
-		uint16_t van_id);
+		struct ether_addr *dst_mac, uint16_t ether_type,
+		uint8_t vlan_enabled, uint16_t van_id);
+
+void
+initialize_arp_header(struct arp_hdr *arp_hdr, struct ether_addr *src_mac,
+		struct ether_addr *dst_mac, uint32_t src_ip, uint32_t dst_ip,
+		uint32_t opcode);
 
 uint16_t
 initialize_udp_header(struct udp_hdr *udp_hdr, uint16_t src_port,
diff --git a/app/test/test_link_bonding.c b/app/test/test_link_bonding.c
index dd6e357..0a37125 100644
--- a/app/test/test_link_bonding.c
+++ b/app/test/test_link_bonding.c
@@ -1313,17 +1313,22 @@ generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
 		uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
 		uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
 {
-	uint16_t pktlen, generated_burst_size;
+	uint16_t pktlen, generated_burst_size, ether_type;
 	void *ip_hdr;
 
+	if (ipv4)
+		ether_type = ETHER_TYPE_IPv4;
+	else
+		ether_type = ETHER_TYPE_IPv6;
+
 	if (toggle_dst_mac)
 		initialize_eth_header(test_params->pkt_eth_hdr,
 				(struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
-				ipv4, vlan, vlan_id);
+				ether_type, vlan, vlan_id);
 	else
 		initialize_eth_header(test_params->pkt_eth_hdr,
 				(struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
-				ipv4, vlan, vlan_id);
+				ether_type, vlan, vlan_id);
 
 
 	if (toggle_udp_port)
@@ -2094,7 +2099,8 @@ test_activebackup_tx_burst(void)
 			"Failed to initialize bonded device with slaves");
 
 	initialize_eth_header(test_params->pkt_eth_hdr,
-			(struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 1, 0, 0);
+			(struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
+			ETHER_TYPE_IPv4,  0, 0);
 	pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
 			dst_port_0, 16);
 	pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
@@ -2637,7 +2643,8 @@ test_balance_l2_tx_burst(void)
 			"Failed to set balance xmit policy.");
 
 	initialize_eth_header(test_params->pkt_eth_hdr,
-			(struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 1, 0, 0);
+			(struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
+			ETHER_TYPE_IPv4, 0, 0);
 	pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
 			dst_port_0, 16);
 	pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
@@ -2651,7 +2658,8 @@ test_balance_l2_tx_burst(void)
 			"failed to generate packet burst");
 
 	initialize_eth_header(test_params->pkt_eth_hdr,
-			(struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1, 1, 0, 0);
+			(struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
+			ETHER_TYPE_IPv4, 0, 0);
 
 	/* Generate a burst 2 of packets to transmit */
 	TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
@@ -3488,7 +3496,8 @@ test_broadcast_tx_burst(void)
 			"Failed to intialise bonded device");
 
 	initialize_eth_header(test_params->pkt_eth_hdr,
-			(struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 1, 0, 0);
+			(struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
+			ETHER_TYPE_IPv4, 0, 0);
 
 	pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
 			dst_port_0, 16);
@@ -4041,6 +4050,23 @@ testsuite_teardown(void)
 	return remove_slaves_and_stop_bonded_device();
 }
 
+static void
+free_virtualpmd_tx_queue(void)
+{
+	int i, slave_port, to_free_cnt;
+	struct rte_mbuf *pkts_to_free[MAX_PKT_BURST];
+
+	/* Free tx queue of virtual pmd */
+	for (slave_port = 0; slave_port < test_params->bonded_slave_count;
+			slave_port++) {
+		to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue(
+				test_params->slave_port_ids[slave_port],
+				pkts_to_free, MAX_PKT_BURST);
+		for (i = 0; i < to_free_cnt; i++)
+			rte_pktmbuf_free(pkts_to_free[i]);
+	}
+}
+
 static int
 test_tlb_tx_burst(void)
 {
@@ -4068,11 +4094,11 @@ test_tlb_tx_burst(void)
 		if (i % 2 == 0) {
 			initialize_eth_header(test_params->pkt_eth_hdr,
 					(struct ether_addr *)src_mac,
-					(struct ether_addr *)dst_mac_0, 1, 0, 0);
+					(struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
 		} else {
 			initialize_eth_header(test_params->pkt_eth_hdr,
 					(struct ether_addr *)test_params->default_slave_mac,
-					(struct ether_addr *)dst_mac_0, 1, 0, 0);
+					(struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
 		}
 		pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
 				dst_port_0, 16);
@@ -4086,6 +4112,8 @@ test_tlb_tx_burst(void)
 				burst_size);
 		nb_tx2 += nb_tx;
 
+		free_virtualpmd_tx_queue();
+
 		TEST_ASSERT_EQUAL(nb_tx, burst_size,
 				"number of packet not equal burst size");
 
@@ -4474,14 +4502,13 @@ test_tlb_verify_slave_link_status_change_failover(void)
 
 	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
 	TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
-				"(%d) port_stats.opackets not as expected\n",
-				test_params->slave_port_ids[0]);
+			"(%d) port_stats.opackets not as expected\n",
+			test_params->slave_port_ids[0]);
 
 	rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
 	TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
-					"(%d) port_stats.opackets not as expected\n",
-					test_params->slave_port_ids[1]);
-
+			"(%d) port_stats.opackets not as expected\n",
+			test_params->slave_port_ids[1]);
 
 	rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
 	TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
@@ -4534,6 +4561,386 @@ test_tlb_verify_slave_link_status_change_failover(void)
 	return remove_slaves_and_stop_bonded_device();
 }
 
+#define TEST_ALB_SLAVE_COUNT	2
+
+static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1};
+static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2};
+static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3};
+static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4};
+
+static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0);
+static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1);
+static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2);
+static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3);
+static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4);
+
+static int
+test_alb_change_mac_in_reply_sent(void)
+{
+	struct rte_mbuf *pkt;
+	struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
+
+	struct ether_hdr *eth_pkt;
+	struct arp_hdr *arp_pkt;
+
+	int slave_idx, nb_pkts, pkt_idx;
+	int retval = 0;
+
+	struct ether_addr bond_mac, client_mac;
+	struct ether_addr *slave_mac1, *slave_mac2;
+
+	TEST_ASSERT_SUCCESS(
+			initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
+					0, TEST_ALB_SLAVE_COUNT, 1),
+			"Failed to initialize_bonded_device_with_slaves.");
+
+	/* Flush tx queue */
+	rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
+	for (slave_idx = 0; slave_idx < test_params->bonded_slave_count;
+			slave_idx++) {
+		nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
+				test_params->slave_port_ids[slave_idx], pkts_sent,
+				MAX_PKT_BURST);
+	}
+
+	ether_addr_copy(
+			rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
+			&bond_mac);
+
+	/*
+	 * Generating four packets with different mac and ip addresses and sending
+	 * them through the bonding port.
+	 */
+	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+	memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
+	eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+	initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
+			0);
+	arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+	initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1,
+			ARP_OP_REPLY);
+	rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
+
+	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+	memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
+	eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+	initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
+			0);
+	arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+	initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2,
+			ARP_OP_REPLY);
+	rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
+
+	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+	memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
+	eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+	initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
+			0);
+	arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+	initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3,
+			ARP_OP_REPLY);
+	rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
+
+	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+	memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
+	eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+	initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
+			0);
+	arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+	initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4,
+			ARP_OP_REPLY);
+	rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
+
+	slave_mac1 =
+			rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
+	slave_mac2 =
+			rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
+
+	/*
+	 * Checking if packets are properly distributed on bonding ports. Packets
+	 * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1.
+	 */
+	for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
+		nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
+				test_params->slave_port_ids[slave_idx], pkts_sent,
+				MAX_PKT_BURST);
+
+		for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
+			eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
+			arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+
+			if (slave_idx%2 == 0) {
+				if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
+					retval = -1;
+					goto test_end;
+				}
+			} else {
+				if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
+					retval = -1;
+					goto test_end;
+				}
+			}
+		}
+	}
+
+test_end:
+	retval += remove_slaves_and_stop_bonded_device();
+	return retval;
+}
+
+static int
+test_alb_reply_from_client(void)
+{
+	struct ether_hdr *eth_pkt;
+	struct arp_hdr *arp_pkt;
+
+	struct rte_mbuf *pkt;
+	struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
+
+	int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0;
+	int retval = 0;
+
+	struct ether_addr bond_mac, client_mac;
+	struct ether_addr *slave_mac1, *slave_mac2;
+
+	TEST_ASSERT_SUCCESS(
+			initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
+					0, TEST_ALB_SLAVE_COUNT, 1),
+			"Failed to initialize_bonded_device_with_slaves.");
+
+	/* Flush tx queue */
+	rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
+	for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
+		nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
+				test_params->slave_port_ids[slave_idx], pkts_sent,
+				MAX_PKT_BURST);
+	}
+
+	ether_addr_copy(
+			rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
+			&bond_mac);
+
+	/*
+	 * Generating four packets with different mac and ip addresses and placing
+	 * them in the rx queue to be received by the bonding driver on rx_burst.
+	 */
+	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+	memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
+	eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+	initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
+			0);
+	arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+	initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
+			ARP_OP_REPLY);
+	virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
+			1);
+
+	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+	memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
+	eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+	initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
+			0);
+	arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+	initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host,
+			ARP_OP_REPLY);
+	virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
+			1);
+
+	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+	memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
+	eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+	initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
+			0);
+	arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+	initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host,
+			ARP_OP_REPLY);
+	virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
+			1);
+
+	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+	memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
+	eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+	initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
+			0);
+	arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+	initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host,
+			ARP_OP_REPLY);
+	virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
+			1);
+
+	/*
+	 * Issue rx_burst and tx_burst to force bonding driver to send update ARP
+	 * packets to every client in alb table.
+	 */
+	rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
+	rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
+
+	slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
+	slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
+
+	/*
+	 * Checking if update ARP packets were properly send on slave ports.
+	 */
+	for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
+		nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
+				test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST);
+		nb_pkts_sum += nb_pkts;
+
+		for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
+			eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
+			arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
+
+			if (slave_idx%2 == 0) {
+				if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
+					retval = -1;
+					goto test_end;
+				}
+			} else {
+				if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
+					retval = -1;
+					goto test_end;
+				}
+			}
+		}
+	}
+
+	/* Check if proper number of packets was send */
+	if (nb_pkts_sum < 4) {
+		retval = -1;
+		goto test_end;
+	}
+
+test_end:
+	retval += remove_slaves_and_stop_bonded_device();
+	return retval;
+}
+
+static int
+test_alb_receive_vlan_reply(void)
+{
+	struct ether_hdr *eth_pkt;
+	struct vlan_hdr *vlan_pkt;
+	struct arp_hdr *arp_pkt;
+
+	struct rte_mbuf *pkt;
+	struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
+
+	int slave_idx, nb_pkts, pkt_idx;
+	int retval = 0;
+
+	struct ether_addr bond_mac, client_mac;
+
+	TEST_ASSERT_SUCCESS(
+			initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
+					0, TEST_ALB_SLAVE_COUNT, 1),
+			"Failed to initialize_bonded_device_with_slaves.");
+
+	/* Flush tx queue */
+	rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
+	for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
+		nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
+				test_params->slave_port_ids[slave_idx], pkts_sent,
+				MAX_PKT_BURST);
+	}
+
+	ether_addr_copy(
+			rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
+			&bond_mac);
+
+	/*
+	 * Generating packet with double VLAN header and placing it in the rx queue.
+	 */
+	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
+	memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
+	eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+	initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_VLAN, 0,
+			0);
+	vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
+	vlan_pkt->vlan_tci = rte_cpu_to_be_16(1);
+	vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
+	vlan_pkt = vlan_pkt+1;
+	vlan_pkt->vlan_tci = rte_cpu_to_be_16(2);
+	vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_ARP);
+	arp_pkt = (struct arp_hdr *)((char *)(vlan_pkt + 1));
+	initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
+			ARP_OP_REPLY);
+	virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
+			1);
+
+	rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
+	rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
+
+	/*
+	 * Checking if VLAN headers in generated ARP Update packet are correct.
+	 */
+	for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
+		nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
+				test_params->slave_port_ids[slave_idx], pkts_sent,
+				MAX_PKT_BURST);
+
+		for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
+			eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
+			vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
+			if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) {
+				retval = -1;
+				goto test_end;
+			}
+			if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_VLAN)) {
+				retval = -1;
+				goto test_end;
+			}
+			vlan_pkt = vlan_pkt+1;
+			if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) {
+				retval = -1;
+				goto test_end;
+			}
+			if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_ARP)) {
+				retval = -1;
+				goto test_end;
+			}
+		}
+	}
+
+test_end:
+	retval += remove_slaves_and_stop_bonded_device();
+	return retval;
+}
+
+static int
+test_alb_ipv4_tx(void)
+{
+	int burst_size, retval, pkts_send;
+	struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
+
+	retval = 0;
+
+	TEST_ASSERT_SUCCESS(
+			initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
+					0, TEST_ALB_SLAVE_COUNT, 1),
+			"Failed to initialize_bonded_device_with_slaves.");
+
+	burst_size = 32;
+
+	/* Generate test bursts of packets to transmit */
+	if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) {
+		retval = -1;
+		goto test_end;
+	}
+
+	/*
+	 * Checking if ipv4 traffic is transmitted via TLB policy.
+	 */
+	pkts_send = rte_eth_tx_burst(
+			test_params->bonded_port_id, 0, pkt_burst, burst_size);
+	if (pkts_send != burst_size) {
+		retval = -1;
+		goto test_end;
+	}
+
+test_end:
+	retval += remove_slaves_and_stop_bonded_device();
+	return retval;
+}
 
 static struct unit_test_suite link_bonding_test_suite  = {
 	.suite_name = "Link Bonding Unit Test Suite",
@@ -4593,6 +5000,10 @@ static struct unit_test_suite link_bonding_test_suite  = {
 		TEST_CASE(test_tlb_verify_mac_assignment),
 		TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
 		TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
+		TEST_CASE(test_alb_change_mac_in_reply_sent),
+		TEST_CASE(test_alb_reply_from_client),
+		TEST_CASE(test_alb_receive_vlan_reply),
+		TEST_CASE(test_alb_ipv4_tx),
 #ifdef RTE_MBUF_REFCNT
 		TEST_CASE(test_broadcast_tx_burst),
 		TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index bad9503..d6a4a45 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -235,8 +235,7 @@ init_traffic(struct rte_mempool *mp,
 
 	initialize_eth_header(&pkt_eth_hdr,
 		(struct ether_addr *)src_mac,
-		(struct ether_addr *)dst_mac, 1, 0, 0);
-	pkt_eth_hdr.ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+		(struct ether_addr *)dst_mac, ETHER_TYPE_IPv4, 0, 0);
 
 	pktlen = initialize_ipv4_header(&pkt_ipv4_hdr,
 					IPV4_ADDR(10, 0, 0, 1),
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index 9fac95d..cd9faf3 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -36,6 +36,7 @@
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_memory.h>
+#include <rte_ring.h>
 
 #include "virtual_pmd.h"
 
@@ -46,8 +47,8 @@ static const char *virtual_ethdev_driver_name = "Virtual PMD";
 struct virtual_ethdev_private {
 	struct rte_eth_stats eth_stats;
 
-	struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST];
-	int rx_pkt_burst_len;
+	struct rte_ring *rx_queue;
+	struct rte_ring *tx_queue;
 
 	int tx_burst_fail_count;
 };
@@ -74,8 +75,16 @@ virtual_ethdev_start_fail(struct rte_eth_dev *eth_dev __rte_unused)
 }
 static void  virtual_ethdev_stop(struct rte_eth_dev *eth_dev __rte_unused)
 {
+	struct rte_mbuf *pkt = NULL;
+	struct virtual_ethdev_private *prv = eth_dev->data->dev_private;
+
 	eth_dev->data->dev_link.link_status = 0;
 	eth_dev->data->dev_started = 0;
+	while (rte_ring_dequeue(prv->rx_queue, (void **)&pkt) != -ENOENT)
+		rte_pktmbuf_free(pkt);
+
+	while (rte_ring_dequeue(prv->tx_queue, (void **)&pkt) != -ENOENT)
+		rte_pktmbuf_free(pkt);
 }
 
 static void
@@ -214,8 +223,10 @@ static void
 virtual_ethdev_stats_reset(struct rte_eth_dev *dev)
 {
 	struct virtual_ethdev_private *dev_private = dev->data->dev_private;
+	struct rte_mbuf *pkt = NULL;
 
-	dev_private->rx_pkt_burst_len = 0;
+	while (rte_ring_dequeue(dev_private->tx_queue, (void **)&pkt) == -ENOBUFS)
+			rte_pktmbuf_free(pkt);
 
 	/* Reset internal statistics */
 	memset(&dev_private->eth_stats, 0, sizeof(dev_private->eth_stats));
@@ -318,29 +329,23 @@ virtual_ethdev_rx_burst_success(void *queue __rte_unused,
 	struct virtual_ethdev_queue *pq_map;
 	struct virtual_ethdev_private *dev_private;
 
-	int i;
+	int rx_count, i;
 
 	pq_map = (struct virtual_ethdev_queue *)queue;
-
 	vrtl_eth_dev = &rte_eth_devices[pq_map->port_id];
-
 	dev_private = vrtl_eth_dev->data->dev_private;
 
-	if (dev_private->rx_pkt_burst_len > 0) {
-		if (dev_private->rx_pkt_burst_len < nb_pkts) {
+	rx_count = rte_ring_dequeue_burst(dev_private->rx_queue, (void **) bufs,
+			nb_pkts);
 
-			for (i = 0; i < dev_private->rx_pkt_burst_len; i++) {
-				bufs[i] = dev_private->rx_pkt_burst[i];
-				dev_private->rx_pkt_burst[i] = NULL;
-			}
+	/* increments ipackets count */
+	dev_private->eth_stats.ipackets += rx_count;
 
-			dev_private->eth_stats.ipackets = dev_private->rx_pkt_burst_len;
-		}
-		/* reset private burst values */
-		dev_private->rx_pkt_burst_len = 0;
-	}
+	/* increments ibytes count */
+	for (i = 0; i < rx_count; i++)
+		dev_private->eth_stats.ibytes += rte_pktmbuf_pkt_len(bufs[i]);
 
-	return dev_private->eth_stats.ipackets;
+	return rx_count;
 }
 
 static uint16_t
@@ -359,26 +364,26 @@ virtual_ethdev_tx_burst_success(void *queue, struct rte_mbuf **bufs,
 
 	struct rte_eth_dev *vrtl_eth_dev;
 	struct virtual_ethdev_private *dev_private;
-	uint64_t obytes = 0;
+
 	int i;
 
-	for (i = 0; i < nb_pkts; i++)
-		obytes += rte_pktmbuf_pkt_len(bufs[i]);
 	vrtl_eth_dev = &rte_eth_devices[tx_q->port_id];
 	dev_private = vrtl_eth_dev->data->dev_private;
 
-	if (vrtl_eth_dev->data->dev_link.link_status) {
-		/* increment opacket count */
-		dev_private->eth_stats.opackets += nb_pkts;
-		dev_private->eth_stats.obytes += obytes;
-		/* free packets in burst */
-		for (i = 0; i < nb_pkts; i++)
-			rte_pktmbuf_free(bufs[i]);
+	if (!vrtl_eth_dev->data->dev_link.link_status)
+		nb_pkts = 0;
+	else
+		nb_pkts = rte_ring_enqueue_burst(dev_private->tx_queue, (void **)bufs,
+				nb_pkts);
 
-		return nb_pkts;
-	}
+	/* increment opacket count */
+	dev_private->eth_stats.opackets += nb_pkts;
 
-	return 0;
+	/* increment obytes count */
+	for (i = 0; i < nb_pkts; i++)
+		dev_private->eth_stats.obytes += rte_pktmbuf_pkt_len(bufs[i]);
+
+	return nb_pkts;
 }
 
 static uint16_t
@@ -476,23 +481,28 @@ virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id,
 	_rte_eth_dev_callback_process(vrtl_eth_dev, RTE_ETH_EVENT_INTR_LSC);
 }
 
-
-
-void
+int
 virtual_ethdev_add_mbufs_to_rx_queue(uint8_t port_id,
 		struct rte_mbuf **pkt_burst, int burst_length)
 {
-	struct virtual_ethdev_private *dev_private = NULL;
 	struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id];
+	struct virtual_ethdev_private *dev_private =
+			vrtl_eth_dev->data->dev_private;
 
-	int i;
-
-	dev_private = vrtl_eth_dev->data->dev_private;
+	return rte_ring_enqueue_burst(dev_private->rx_queue, (void **)pkt_burst,
+			burst_length);
+}
 
-	for (i = 0; i < burst_length; i++)
-		dev_private->rx_pkt_burst[i] = pkt_burst[i];
+int
+virtual_ethdev_get_mbufs_from_tx_queue(uint8_t port_id,
+		struct rte_mbuf **pkt_burst, int burst_length)
+{
+	struct virtual_ethdev_private *dev_private;
+	struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id];
 
-	dev_private->rx_pkt_burst_len = burst_length;
+	dev_private = vrtl_eth_dev->data->dev_private;
+	return rte_ring_dequeue_burst(dev_private->tx_queue, (void **)pkt_burst,
+		burst_length);
 }
 
 static uint8_t
@@ -510,7 +520,6 @@ get_number_of_sockets(void)
 	return ++sockets;
 }
 
-
 int
 virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 		uint8_t socket_id, uint8_t isr_support)
@@ -522,6 +531,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 	struct eth_dev_ops *dev_ops = NULL;
 	struct rte_pci_id *id_table = NULL;
 	struct virtual_ethdev_private *dev_private = NULL;
+	char name_buf[RTE_RING_NAMESIZE];
 
 
 	/* now do all data allocation - for eth_dev structure, dummy pci driver
@@ -555,6 +565,20 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 	if (dev_private == NULL)
 		goto err;
 
+	memset(dev_private, 0, sizeof(*dev_private));
+
+	snprintf(name_buf, sizeof(name_buf), "%s_rxQ", name);
+	dev_private->rx_queue = rte_ring_create(name_buf, MAX_PKT_BURST, socket_id,
+			0);
+	if (dev_private->rx_queue == NULL)
+		goto err;
+
+	snprintf(name_buf, sizeof(name_buf), "%s_txQ", name);
+	dev_private->tx_queue = rte_ring_create(name_buf, MAX_PKT_BURST, socket_id,
+			0);
+	if (dev_private->tx_queue == NULL)
+		goto err;
+
 	/* reserve an ethdev entry */
 	eth_dev = rte_eth_dev_allocate(name);
 	if (eth_dev == NULL)
@@ -594,7 +618,6 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 	eth_dev->data->scattered_rx = 0;
 	eth_dev->data->all_multicast = 0;
 
-	memset(dev_private, 0, sizeof(*dev_private));
 	eth_dev->data->dev_private = dev_private;
 
 	eth_dev->dev_ops = dev_ops;
diff --git a/app/test/virtual_pmd.h b/app/test/virtual_pmd.h
index 2462853..de00188 100644
--- a/app/test/virtual_pmd.h
+++ b/app/test/virtual_pmd.h
@@ -54,10 +54,13 @@ void
 virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id,
 		uint8_t link_status);
 
-void
+int
 virtual_ethdev_add_mbufs_to_rx_queue(uint8_t port_id,
 		struct rte_mbuf **pkts_burst, int burst_length);
 
+int
+virtual_ethdev_get_mbufs_from_tx_queue(uint8_t port_id,
+		struct rte_mbuf **pkt_burst, int burst_length);
 
 /** Control methods for the dev_ops functions pointer to control the behavior
  *  of the Virtual PMD */
-- 
1.7.9.5

  parent reply	other threads:[~2015-02-19 17:26 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-13 15:16 [PATCH v2 0/6] Link Bonding mode 6 support (ALB) Michal Jastrzebski
     [not found] ` <1423840570-6452-1-git-send-email-michalx.k.jastrzebski-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-02-13 15:16   ` [PATCH v2 1/6] net: changed arp_hdr struct declaration Michal Jastrzebski
2015-02-13 15:16   ` [PATCH v2 2/6] bond: add link bonding mode 6 implementation Michal Jastrzebski
2015-02-13 15:16   ` [PATCH v2 3/6] bond: add debug info for mode 6 link bonding Michal Jastrzebski
2015-02-13 15:16   ` [PATCH v2 4/6] bond: add example application for link bonding mode 6 Michal Jastrzebski
2015-02-13 15:16   ` [PATCH v2 5/6] bond: modify TLB unit tests Michal Jastrzebski
2015-02-13 15:16   ` [PATCH v2 6/6] bond: add unit tests for link bonding mode 6 Michal Jastrzebski
2015-02-13 16:12   ` [PATCH v2 0/6] Link Bonding mode 6 support (ALB) Declan Doherty
     [not found]     ` <54DE2285.8000507-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-02-18 19:10       ` Thomas Monjalon
2015-02-19  9:18         ` Jastrzebski, MichalX K
     [not found]           ` <60ABE07DBB3A454EB7FAD707B4BB1582138EA984-kPTMFJFq+rHjxeytcECX8bfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2015-02-19  9:39             ` Thomas Monjalon
2015-02-19 10:14               ` Jastrzebski, MichalX K
     [not found]                 ` <60ABE07DBB3A454EB7FAD707B4BB1582138EAA30-kPTMFJFq+rHjxeytcECX8bfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2015-02-19 10:27                   ` Thomas Monjalon
2015-02-19 17:26   ` [PATCH v3 " Michal Jastrzebski
     [not found]     ` <1424366779-14256-1-git-send-email-michalx.k.jastrzebski-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-02-19 17:26       ` [PATCH v3 1/6] net: changed arp_hdr struct declaration Michal Jastrzebski
     [not found]         ` <1424366779-14256-2-git-send-email-michalx.k.jastrzebski-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-02-20 14:30           ` Thomas Monjalon
2015-02-20 14:54             ` Gajdzica, MaciejX T
     [not found]               ` <9CC680510C0AC140A846FED2EF7F962812E5F82E-kPTMFJFq+rFP9JyJpTNKArfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2015-02-20 15:22                 ` Thomas Monjalon
2015-02-19 17:26       ` [PATCH v3 2/6] bond: add link bonding mode 6 implementation Michal Jastrzebski
2015-02-19 17:26       ` [PATCH v3 3/6] bond: add debug info for mode 6 link bonding Michal Jastrzebski
2015-02-19 17:26       ` [PATCH v3 4/6] bond: add example application for link bonding mode 6 Michal Jastrzebski
     [not found]         ` <1424366779-14256-5-git-send-email-michalx.k.jastrzebski-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-02-20 14:42           ` Thomas Monjalon
2015-02-20 16:12             ` Jastrzebski, MichalX K
2015-02-19 17:26       ` [PATCH v3 5/6] bond: modify TLB unit tests Michal Jastrzebski
2015-02-19 17:26       ` Michal Jastrzebski [this message]
2015-02-20 16:09   ` [PATCH v4 0/6] Link Bonding mode 6 support (ALB) Michal Jastrzebski
     [not found]     ` <1424448563-8680-1-git-send-email-michalx.k.jastrzebski-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-02-20 16:09       ` [PATCH v4 1/6] net: changed arp_hdr struct declaration Michal Jastrzebski
2015-02-20 16:09       ` [PATCH v4 2/6] bond: add link bonding mode 6 implementation Michal Jastrzebski
2015-02-20 16:09       ` [PATCH v4 3/6] bond: add debug info for mode 6 link bonding Michal Jastrzebski
2015-02-20 16:09       ` [PATCH v4 4/6] bond: add example application for link bonding mode 6 Michal Jastrzebski
2015-02-20 16:09       ` [PATCH v4 5/6] bond: modify TLB unit tests Michal Jastrzebski
2015-02-20 16:09       ` [PATCH v4 6/6] bond: add unit tests for link bonding mode 6 Michal Jastrzebski
2015-02-20 17:44       ` [PATCH v4 0/6] Link Bonding mode 6 support (ALB) Declan Doherty
     [not found]         ` <54E7728E.3090208-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-02-20 21:58           ` Thomas Monjalon
2015-03-04  3:53           ` Jiajia, SunX

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1424366779-14256-7-git-send-email-michalx.k.jastrzebski@intel.com \
    --to=michalx.k.jastrzebski-ral2jqcrhueavxtiumwx3w@public.gmane.org \
    --cc=dev-VfR2kkLFssw@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.