All of lore.kernel.org
 help / color / mirror / Atom feed
From: Declan Doherty <declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
To: dev-VfR2kkLFssw@public.gmane.org
Subject: [PATCH v10 1/5] bond: new link bonding library
Date: Fri, 27 Jun 2014 11:18:40 +0100	[thread overview]
Message-ID: <1403864324-12022-2-git-send-email-declan.doherty@intel.com> (raw)
In-Reply-To: <1403827075-9192-1-git-send-email-thomas.monjalon-pdR9zngts4EAvxtiuMwx3w@public.gmane.org>

Initial release with support for
 Mode 0 - Round Robin
 Mode 1 - Active Backup
 Mode 2 - Balance -> Supports 3 transmit polices (layer 2, layer 2+3, layer 3+4)
 Mode 3 - Broadcast

Signed-off-by: Declan Doherty <declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Acked-by: Pablo de Lara <pablo.de.lara.guarch-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
 config/common_bsdapp                       |    5 +
 config/common_linuxapp                     |    5 +
 doc/doxy-api-index.md                      |    1 +
 doc/doxy-api.conf                          |    1 +
 lib/Makefile                               |    1 +
 lib/librte_pmd_bond/Makefile               |   61 ++
 lib/librte_pmd_bond/rte_eth_bond.h         |  255 ++++++
 lib/librte_pmd_bond/rte_eth_bond_api.c     |  662 +++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond_args.c    |  252 ++++++
 lib/librte_pmd_bond/rte_eth_bond_pmd.c     | 1212 ++++++++++++++++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond_private.h |  215 +++++
 mk/rte.app.mk                              |    4 +
 12 files changed, 2674 insertions(+), 0 deletions(-)
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_api.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_args.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_pmd.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_private.h

diff --git a/config/common_bsdapp b/config/common_bsdapp
index d5db4ab..c243b0c 100644
--- a/config/common_bsdapp
+++ b/config/common_bsdapp
@@ -206,6 +206,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=y
 
 #
+# Compile link bonding PMD library
+#
+CONFIG_RTE_LIBRTE_PMD_BOND=y
+
+#
 # Do prefetch of packet data within PMD driver receive function
 #
 CONFIG_RTE_PMD_PACKET_PREFETCH=y
diff --git a/config/common_linuxapp b/config/common_linuxapp
index c5c0cb6..6237ce5 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -244,6 +244,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=n
 
 #
+# Compile link bonding PMD library
+#
+CONFIG_RTE_LIBRTE_PMD_BOND=y
+
+#
 # Compile Xen PMD
 #
 CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
diff --git a/doc/doxy-api-index.md b/doc/doxy-api-index.md
index 7b26e98..d72659a 100644
--- a/doc/doxy-api-index.md
+++ b/doc/doxy-api-index.md
@@ -38,6 +38,7 @@ There are many libraries, so their headers may be grouped by topics:
 - **device**:
   [ethdev]             (@ref rte_ethdev.h),
   [devargs]            (@ref rte_devargs.h),
+  [bond]               (@ref rte_eth_bond.h),
   [KNI]                (@ref rte_kni.h),
   [PCI]                (@ref rte_pci.h),
   [PCI IDs]            (@ref rte_pci_dev_ids.h)
diff --git a/doc/doxy-api.conf b/doc/doxy-api.conf
index f380d9a..1fd4492 100644
--- a/doc/doxy-api.conf
+++ b/doc/doxy-api.conf
@@ -47,6 +47,7 @@ INPUT                   = doc/doxy-api-index.md \
                           lib/librte_pipeline \
                           lib/librte_port \
                           lib/librte_power \
+                          lib/librte_pmd_bond \
                           lib/librte_ring \
                           lib/librte_sched \
                           lib/librte_table \
diff --git a/lib/Makefile b/lib/Makefile
index c58c0c9..10c5bb3 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -44,6 +44,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
 DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += librte_pmd_e1000
 DIRS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += librte_pmd_ixgbe
 DIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += librte_pmd_i40e
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += librte_pmd_bond
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_RING) += librte_pmd_ring
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += librte_pmd_pcap
 DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += librte_pmd_virtio
diff --git a/lib/librte_pmd_bond/Makefile b/lib/librte_pmd_bond/Makefile
new file mode 100644
index 0000000..21998f7
--- /dev/null
+++ b/lib/librte_pmd_bond/Makefile
@@ -0,0 +1,61 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_bond.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += rte_eth_bond_api.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += rte_eth_bond_pmd.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += rte_eth_bond_vargs.c
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_eth_bond.h
+
+# this lib depends upon:
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_mbuf
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_malloc
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_kvargs
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_pmd_bond/rte_eth_bond.h b/lib/librte_pmd_bond/rte_eth_bond.h
new file mode 100644
index 0000000..95a4fa9
--- /dev/null
+++ b/lib/librte_pmd_bond/rte_eth_bond.h
@@ -0,0 +1,255 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_ETH_BOND_H_
+#define _RTE_ETH_BOND_H_
+
+/**
+ * @file rte_bond.h
+ *
+ * RTE Link Bonding Ethernet Device
+ * Link Bonding for 1GbE and 10GbE ports to allow the aggregation of multiple
+ * (slave) NICs into a single logical interface. The bonded device processes
+ * these interfaces based on the mode of operation specified and supported.
+ * This implementation supports 4 modes of operation round robin, active backup
+ * balance and broadcast. Providing redundant links, fault tolerance and/or
+ * load balancing of network ports
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_ether.h>
+
+/* Supported modes of operation of link bonding library  */
+
+#define BONDING_MODE_ROUND_ROBIN		(0)
+/**< Round Robin (Mode 0).
+ * In this mode all transmitted packets will be balanced equally across all
+ * active slaves of the bonded in a round robin fashion. */
+#define BONDING_MODE_ACTIVE_BACKUP		(1)
+/**< Active Backup (Mode 1).
+ * In this mode all packets transmitted will be transmitted on the primary
+ * slave until such point as the primary slave is no longer available and then
+ * transmitted packets will be sent on the next available slaves. The primary
+ * slave can be defined by the user but defaults to the first active slave
+ * available if not specified. */
+#define BONDING_MODE_BALANCE			(2)
+/**< Balance (Mode 2).
+ * In this mode all packets transmitted will be balanced across the available
+ * slaves using one of three available transmit policies - l2, l2+3 or l3+4.
+ * See BALANCE_XMIT_POLICY macros definitions for further details on transmit
+ * policies. */
+#define BONDING_MODE_BROADCAST			(3)
+/**< Broadcast (Mode 3).
+ * In this mode all transmitted packets will be transmitted on all available
+ * active slaves of the bonded. */
+
+/* Balance Mode Transmit Policies */
+#define BALANCE_XMIT_POLICY_LAYER2		(0)
+/**< Layer 2 (Ethernet MAC) */
+#define BALANCE_XMIT_POLICY_LAYER23		(1)
+/**< Layer 2+3 (Ethernet MAC + IP Addresses) transmit load balancing */
+#define BALANCE_XMIT_POLICY_LAYER34		(2)
+/**< Layer 3+4 (IP Addresses + UDP Ports) transmit load balancing */
+
+/**
+ * Create a bonded rte_eth_dev device
+ *
+ * @param name			Name of new link bonding device.
+ * @param mode			Mode to initialize bonding device in.
+ * @param socket_id		Socket Id on which to allocate eth_dev resources.
+ *
+ * @return
+ *	Port Id of created rte_eth_dev on success, negative value otherwise
+ */
+int
+rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id);
+
+/**
+ * Add a rte_eth_dev device as a slave to the bonded device
+ *
+ * @param bonded_port_id	Port ID of bonded device.
+ * @param slave_port_id		Port ID of slave device.
+ *
+ * @return
+ *	0 on success, negative value otherwise
+ */
+int
+rte_eth_bond_slave_add(uint8_t bonded_port_id, uint8_t slave_port_id);
+
+/**
+ * Remove a slave rte_eth_dev device from the bonded device
+ *
+ * @param bonded_port_id	Port ID of bonded device.
+ * @param slave_port_id		Port ID of slave device.
+ *
+ * @return
+ *	0 on success, negative value otherwise
+ */
+int
+rte_eth_bond_slave_remove(uint8_t bonded_port_id, uint8_t slave_port_id);
+
+/**
+ * Set link bonding mode of bonded device
+ *
+ * @param bonded_port_id	Port ID of bonded device.
+ * @param mode				Bonding mode to set
+ *
+ * @return
+ *	0 on success, negative value otherwise
+ */
+int
+rte_eth_bond_mode_set(uint8_t bonded_port_id, uint8_t mode);
+
+/**
+ * Get link bonding mode of bonded device
+ *
+ * @param bonded_port_id	Port ID of bonded device.
+ *
+ * @return
+ *	link bonding mode on success, negative value otherwise
+ */
+int
+rte_eth_bond_mode_get(uint8_t bonded_port_id);
+
+/**
+ * Set slave rte_eth_dev as primary slave of bonded device
+ *
+ * @param bonded_port_id	Port ID of bonded device.
+ * @param slave_port_id		Port ID of slave device.
+ *
+ * @return
+ *	0 on success, negative value otherwise
+ */
+int
+rte_eth_bond_primary_set(uint8_t bonded_port_id, uint8_t slave_port_id);
+
+/**
+ * Get primary slave of bonded device
+ *
+ * @param bonded_port_id	Port ID of bonded device.
+ *
+ * @return
+ *	Port Id of primary slave on success, -1 on failure
+ */
+int
+rte_eth_bond_primary_get(uint8_t bonded_port_id);
+
+/**
+ * Populate an array with list of the slaves port id's of the bonded device
+ *
+ * @param bonded_port_id	Port ID of bonded eth_dev to interrogate
+ * @param slaves			Array to be populated with the current active slaves
+ * @param len				Length of slaves array
+ *
+ * @return
+ *	Number of slaves associated with bonded device on success,
+ *	negative value otherwise
+ */
+int
+rte_eth_bond_slaves_get(uint8_t bonded_port_id, uint8_t slaves[], uint8_t len);
+
+/**
+ * Populate an array with list of the active slaves port id's of the bonded
+ * device.
+ *
+ * @param bonded_port_id	Port ID of bonded eth_dev to interrogate
+ * @param slaves			Array to be populated with the current active slaves
+ * @param len				Length of slaves array
+ *
+ * @return
+ *	Number of active slaves associated with bonded device on success,
+ *	negative value otherwise
+ */
+int
+rte_eth_bond_active_slaves_get(uint8_t bonded_port_id, uint8_t slaves[],
+		uint8_t len);
+
+/**
+ * Set explicit MAC address to use on bonded device and it's slaves.
+ *
+ * @param bonded_port_id	Port ID of bonded device.
+ * @param mac_addr			MAC Address to use on bonded device overriding
+ *							slaves MAC addresses
+ *
+ * @return
+ *	0 on success, negative value otherwise
+ */
+int
+rte_eth_bond_mac_address_set(uint8_t bonded_port_id,
+		struct ether_addr *mac_addr);
+
+/**
+ * Reset bonded device to use MAC from primary slave on bonded device and it's
+ * slaves.
+ *
+ * @param bonded_port_id	Port ID of bonded device.
+ *
+ * @return
+ *	0 on success, negative value otherwise
+ */
+int
+rte_eth_bond_mac_address_reset(uint8_t bonded_port_id);
+
+/**
+ * Set the transmit policy for bonded device to use when it is operating in
+ * balance mode, this parameter is otherwise ignored in other modes of
+ * operation.
+ *
+ * @param bonded_port_id	Port ID of bonded device.
+ * @param policy			Balance mode transmission policy.
+ *
+ * @return
+ *	0 on success, negative value otherwise.
+ */
+int
+rte_eth_bond_xmit_policy_set(uint8_t bonded_port_id, uint8_t policy);
+
+/**
+ * Get the transmit policy set on bonded device for balance mode operation
+ *
+ * @param bonded_port_id	Port ID of bonded device.
+ *
+ * @return
+ *	Balance transmit policy on success, negative value otherwise.
+ */
+int
+rte_eth_bond_xmit_policy_get(uint8_t bonded_port_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/librte_pmd_bond/rte_eth_bond_api.c b/lib/librte_pmd_bond/rte_eth_bond_api.c
new file mode 100644
index 0000000..9be5f72
--- /dev/null
+++ b/lib/librte_pmd_bond/rte_eth_bond_api.c
@@ -0,0 +1,662 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/queue.h>
+#include <linux/binfmts.h>
+
+#include <rte_mbuf.h>
+#include <rte_cycles.h>
+#include <rte_dev.h>
+#include <rte_devargs.h>
+#include <rte_ethdev.h>
+#include <rte_ip.h>
+#include <rte_kvargs.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+#include <rte_memory.h>
+#include <rte_udp.h>
+
+#include "rte_eth_bond.h"
+#include "rte_eth_bond_private.h"
+
+int
+valid_bonded_ethdev(struct rte_eth_dev *eth_dev)
+{
+	size_t len;
+
+	/* Check valid pointer */
+	if (eth_dev->driver->pci_drv.name == NULL || driver_name == NULL)
+		return -1;
+
+	/* Check string lengths are equal */
+	len = strlen(driver_name);
+	if (strlen(eth_dev->driver->pci_drv.name) != len)
+		return -1;
+
+	/* Compare strings */
+	return strncmp(eth_dev->driver->pci_drv.name, driver_name, len);
+}
+
+int
+valid_port_id(uint8_t port_id)
+{
+	/* Verify that port id is valid */
+	int ethdev_count = rte_eth_dev_count();
+	if (port_id >= ethdev_count) {
+		RTE_LOG(ERR, PMD,
+				"%s: port Id %d is greater than rte_eth_dev_count %d\n",
+				__func__, port_id, ethdev_count);
+		return -1;
+	}
+
+	return 0;
+}
+
+int
+valid_bonded_port_id(uint8_t port_id)
+{
+	/* Verify that port id's are valid */
+	if (valid_port_id(port_id))
+		return -1;
+
+	/* Verify that bonded_port_id refers to a bonded port */
+	if (valid_bonded_ethdev(&rte_eth_devices[port_id])) {
+		RTE_LOG(ERR, PMD,
+				"%s: Specified port Id %d is not a bonded eth_dev device\n",
+				__func__, port_id);
+		return -1;
+	}
+
+	return 0;
+}
+
+int
+valid_slave_port_id(uint8_t port_id)
+{
+	/* Verify that port id's are valid */
+	if (valid_port_id(port_id))
+		return -1;
+
+	/* Verify that port_id refers to a non bonded port */
+	if (!valid_bonded_ethdev(&rte_eth_devices[port_id]))
+		return -1;
+
+	return 0;
+}
+
+uint8_t
+number_of_sockets(void)
+{
+	int sockets = 0;
+	int i;
+	const struct rte_memseg *ms = rte_eal_get_physmem_layout();
+
+	for (i = 0; ((i < RTE_MAX_MEMSEG) && (ms[i].addr != NULL)); i++) {
+		if (sockets < ms[i].socket_id)
+			sockets = ms[i].socket_id;
+	}
+
+	/* Number of sockets = maximum socket_id + 1 */
+	return ++sockets;
+}
+
+const char *driver_name = "Link Bonding PMD";
+
+int
+rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id)
+{
+	struct rte_pci_device *pci_dev = NULL;
+	struct bond_dev_private *internals = NULL;
+	struct rte_eth_dev *eth_dev = NULL;
+	struct eth_driver *eth_drv = NULL;
+	struct rte_pci_driver *pci_drv = NULL;
+	struct rte_pci_id *pci_id_table = NULL;
+	/* now do all data allocation - for eth_dev structure, dummy pci driver
+	 * and internal (private) data
+	 */
+
+	if (name == NULL) {
+		RTE_LOG(ERR, PMD, "Invalid name specified\n");
+		goto err;
+	}
+
+	if (socket_id >= number_of_sockets()) {
+		RTE_LOG(ERR, PMD,
+				"%s: invalid socket id specified to create bonded device on.\n",
+				__func__);
+		goto err;
+	}
+
+	pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, socket_id);
+	if (pci_dev == NULL) {
+		RTE_LOG(ERR, PMD, "Unable to malloc pci dev on socket\n");
+		goto err;
+	}
+
+	eth_drv = rte_zmalloc_socket(name, sizeof(*eth_drv), 0, socket_id);
+	if (eth_drv == NULL) {
+		RTE_LOG(ERR, PMD, "Unable to malloc eth_drv on socket\n");
+		goto err;
+	}
+
+	pci_drv = rte_zmalloc_socket(name, sizeof(*pci_drv), 0, socket_id);
+	if (pci_drv == NULL) {
+		RTE_LOG(ERR, PMD, "Unable to malloc pci_drv on socket\n");
+		goto err;
+	}
+	pci_id_table = rte_zmalloc_socket(name, sizeof(*pci_id_table), 0, socket_id);
+	if (pci_drv == NULL) {
+		RTE_LOG(ERR, PMD, "Unable to malloc pci_id_table on socket\n");
+		goto err;
+	}
+
+	pci_drv->id_table = pci_id_table;
+
+	pci_drv->id_table->device_id = PCI_ANY_ID;
+	pci_drv->id_table->subsystem_device_id = PCI_ANY_ID;
+	pci_drv->id_table->vendor_id = PCI_ANY_ID;
+	pci_drv->id_table->subsystem_vendor_id = PCI_ANY_ID;
+
+	internals = rte_zmalloc_socket(name, sizeof(*internals), 0, socket_id);
+	if (internals == NULL) {
+		RTE_LOG(ERR, PMD, "Unable to malloc internals on socket\n");
+		goto err;
+	}
+
+	/* reserve an ethdev entry */
+	eth_dev = rte_eth_dev_allocate(name);
+	if (eth_dev == NULL) {
+		RTE_LOG(ERR, PMD, "Unable to allocate rte_eth_dev\n");
+		goto err;
+	}
+
+	pci_dev->numa_node = socket_id;
+	pci_drv->name = driver_name;
+
+	eth_drv->pci_drv = (struct rte_pci_driver)(*pci_drv);
+	eth_dev->driver = eth_drv;
+
+	eth_dev->data->dev_private = internals;
+	eth_dev->data->nb_rx_queues = (uint16_t)1;
+	eth_dev->data->nb_tx_queues = (uint16_t)1;
+
+	eth_dev->data->dev_link.link_status = 0;
+
+	eth_dev->data->mac_addrs = rte_zmalloc_socket(name, ETHER_ADDR_LEN, 0,
+			socket_id);
+
+	eth_dev->data->dev_started = 0;
+	eth_dev->data->promiscuous = 0;
+	eth_dev->data->scattered_rx = 0;
+	eth_dev->data->all_multicast = 0;
+
+	eth_dev->dev_ops = &default_dev_ops;
+	eth_dev->pci_dev = pci_dev;
+
+	if (bond_ethdev_mode_set(eth_dev, mode)) {
+		RTE_LOG(ERR, PMD,
+				"%s: failed to set bonded device %d mode too %d\n",
+				__func__, eth_dev->data->port_id, mode);
+		goto err;
+	}
+
+	internals->current_primary_port = 0;
+	internals->balance_xmit_policy = BALANCE_XMIT_POLICY_LAYER2;
+	internals->user_defined_mac = 0;
+	internals->link_props_set = 0;
+	internals->slave_count = 0;
+	internals->active_slave_count = 0;
+
+	memset(internals->active_slaves, 0, sizeof(internals->active_slaves));
+	memset(internals->slaves, 0, sizeof(internals->slaves));
+
+	memset(internals->presisted_slaves_conf, 0,
+			sizeof(internals->presisted_slaves_conf));
+
+	return eth_dev->data->port_id;
+
+err:
+	if (pci_dev)
+		rte_free(pci_dev);
+	if (pci_drv)
+		rte_free(pci_drv);
+	if (pci_id_table)
+		rte_free(pci_id_table);
+	if (eth_drv)
+		rte_free(eth_drv);
+	if (internals)
+		rte_free(internals);
+	return -1;
+}
+
+int
+rte_eth_bond_slave_add(uint8_t bonded_port_id, uint8_t slave_port_id)
+{
+	struct rte_eth_dev *bonded_eth_dev, *slave_eth_dev;
+	struct bond_dev_private *internals;
+	struct bond_dev_private *temp_internals;
+	struct rte_eth_link link_props;
+
+	int i, j;
+
+	/* Verify that port id's are valid bonded and slave ports */
+	if (valid_bonded_port_id(bonded_port_id) != 0)
+		goto err_add;
+
+	if (valid_slave_port_id(slave_port_id) != 0)
+		goto err_add;
+
+	/*
+	 * Verify that new slave device is not already a slave of another bonded
+	 * device */
+	for (i = rte_eth_dev_count()-1; i >= 0; i--) {
+		if (valid_bonded_ethdev(&rte_eth_devices[i]) == 0) {
+			temp_internals = rte_eth_devices[i].data->dev_private;
+			for (j = 0; j < temp_internals->slave_count; j++) {
+				/* Device already a slave of a bonded device */
+				if (temp_internals->slaves[j] == slave_port_id)
+					goto err_add;
+			}
+		}
+	}
+
+	bonded_eth_dev = &rte_eth_devices[bonded_port_id];
+	internals = bonded_eth_dev->data->dev_private;
+
+	slave_eth_dev = &rte_eth_devices[slave_port_id];
+
+	if (internals->slave_count > 0) {
+		/* Check that new slave device is the same type as the other slaves
+		 * and not repetitive */
+		for (i = 0; i < internals->slave_count; i++) {
+			if (slave_eth_dev->pci_dev->driver->id_table->device_id !=
+					rte_eth_devices[internals->slaves[i]].pci_dev->driver->id_table->device_id ||
+				internals->slaves[i] == slave_port_id)
+				goto err_add;
+		}
+	}
+
+	/* Add slave details to bonded device */
+	internals->slaves[internals->slave_count] = slave_port_id;
+
+	slave_config_store(internals, slave_eth_dev);
+
+	if (internals->slave_count < 1) {
+		/* if MAC is not user defined then use MAC of first slave add to bonded
+		 * device */
+		if (!internals->user_defined_mac)
+			mac_address_set(bonded_eth_dev, slave_eth_dev->data->mac_addrs);
+
+		/* Inherit eth dev link properties from first slave */
+		link_properties_set(bonded_eth_dev, &(slave_eth_dev->data->dev_link));
+
+		/* Make primary slave */
+		internals->primary_port = slave_port_id;
+	} else {
+		/* Check slave link properties are supported if props are set,
+		 * all slaves must be the same */
+		if (internals->link_props_set) {
+			if (link_properties_valid(&(bonded_eth_dev->data->dev_link),
+									  &(slave_eth_dev->data->dev_link))) {
+				RTE_LOG(ERR, PMD,
+						"%s: Slave port %d link speed/duplex not supported\n",
+						__func__, slave_port_id);
+				goto err_add;
+			}
+		} else {
+			link_properties_set(bonded_eth_dev,
+					&(slave_eth_dev->data->dev_link));
+		}
+	}
+
+	internals->slave_count++;
+
+	/* Update all slave devices MACs*/
+	mac_address_slaves_update(bonded_eth_dev);
+
+	if (bonded_eth_dev->data->dev_started) {
+		if (slave_configure(bonded_eth_dev, slave_eth_dev) != 0) {
+			RTE_LOG(ERR, PMD, "rte_bond_slaves_configure: port=%d\n",
+					slave_port_id);
+			goto err_add;
+		}
+	}
+
+	/* Register link status change callback with bonded device pointer as
+	 * argument*/
+	rte_eth_dev_callback_register(slave_port_id, RTE_ETH_EVENT_INTR_LSC,
+			bond_ethdev_lsc_event_callback, &bonded_eth_dev->data->port_id);
+
+	/* If bonded device is started then we can add the slave to our active
+	 * slave array */
+	if (bonded_eth_dev->data->dev_started) {
+		rte_eth_link_get_nowait(slave_port_id, &link_props);
+
+		 if (link_props.link_status == 1) {
+			internals->active_slaves[internals->active_slave_count++] =
+					slave_port_id;
+		}
+	}
+
+	return 0;
+
+err_add:
+	RTE_LOG(ERR, PMD, "Failed to add port %d as slave\n", slave_port_id);
+	return -1;
+
+}
+
+int
+rte_eth_bond_slave_remove(uint8_t bonded_port_id, uint8_t slave_port_id)
+{
+	struct bond_dev_private *internals;
+	struct slave_conf *slave_conf;
+
+	int i;
+	int pos = -1;
+
+	/* Verify that port id's are valid bonded and slave ports */
+	if (valid_bonded_port_id(bonded_port_id) != 0)
+		goto err_del;
+
+	if (valid_slave_port_id(slave_port_id) != 0)
+		goto err_del;
+
+	internals = rte_eth_devices[bonded_port_id].data->dev_private;
+
+	/* first remove from active slave list */
+	for (i = 0; i < internals->active_slave_count; i++) {
+		if (internals->active_slaves[i] == slave_port_id)
+			pos = i;
+
+		/* shift active slaves up active array list */
+		if (pos >= 0 && i < (internals->active_slave_count - 1))
+			internals->active_slaves[i] = internals->active_slaves[i+1];
+	}
+
+	if (pos >= 0)
+		internals->active_slave_count--;
+
+	pos = -1;
+	/* now remove from slave list */
+	for (i = 0; i < internals->slave_count; i++) {
+		if (internals->slaves[i] == slave_port_id)
+			pos = i;
+
+		/* shift slaves up list */
+		if (pos >= 0 && i < internals->slave_count)
+			internals->slaves[i] = internals->slaves[i+1];
+	}
+
+	if (pos < 0)
+		goto err_del;
+
+	/* Un-register link status change callback with bonded device pointer as
+	 * argument*/
+	rte_eth_dev_callback_unregister(slave_port_id, RTE_ETH_EVENT_INTR_LSC,
+			bond_ethdev_lsc_event_callback,
+			&rte_eth_devices[bonded_port_id].data->port_id);
+
+	/* Restore original MAC address of slave device */
+	slave_conf = slave_config_get(internals, slave_port_id);
+
+	mac_address_set(&rte_eth_devices[slave_port_id], &(slave_conf->mac_addr));
+
+	slave_config_clear(internals, &rte_eth_devices[slave_port_id]);
+
+	internals->slave_count--;
+
+	/*  first slave in the active list will be the primary by default,
+	 *  otherwise use first device in list */
+	if (internals->current_primary_port == slave_port_id) {
+		if (internals->active_slave_count > 0)
+			internals->current_primary_port = internals->active_slaves[0];
+		else if (internals->slave_count > 0)
+			internals->current_primary_port = internals->slaves[0];
+		else
+			internals->primary_port = 0;
+	}
+
+	if (internals->active_slave_count < 1) {
+		/* reset device link properties as no slaves are active */
+		link_properties_reset(&rte_eth_devices[bonded_port_id]);
+
+		/* if no slaves are any longer attached to bonded device and MAC is not
+		 * user defined then clear MAC of bonded device as it will be reset
+		 * when a new slave is added */
+		if (internals->slave_count < 1 && !internals->user_defined_mac)
+			memset(rte_eth_devices[bonded_port_id].data->mac_addrs, 0,
+					sizeof(*(rte_eth_devices[bonded_port_id].data->mac_addrs)));
+	}
+
+	return 0;
+
+err_del:
+	RTE_LOG(ERR, PMD,
+			"Cannot remove slave device (not present in bonded device)\n");
+	return -1;
+
+}
+
+int
+rte_eth_bond_mode_set(uint8_t bonded_port_id, uint8_t mode)
+{
+	if (valid_bonded_port_id(bonded_port_id) != 0)
+		return -1;
+
+	return bond_ethdev_mode_set(&rte_eth_devices[bonded_port_id], mode);
+}
+
+int
+rte_eth_bond_mode_get(uint8_t bonded_port_id)
+{
+	struct bond_dev_private *internals;
+
+	if (valid_bonded_port_id(bonded_port_id) != 0)
+		return -1;
+
+	internals = rte_eth_devices[bonded_port_id].data->dev_private;
+
+	return internals->mode;
+}
+
+int
+rte_eth_bond_primary_set(uint8_t bonded_port_id, uint8_t slave_port_id)
+{
+	struct bond_dev_private *internals;
+
+	if (valid_bonded_port_id(bonded_port_id) != 0)
+		return -1;
+
+	if (valid_slave_port_id(slave_port_id) != 0)
+		return -1;
+
+	internals =  rte_eth_devices[bonded_port_id].data->dev_private;
+
+	internals->user_defined_primary_port = 1;
+	internals->primary_port = slave_port_id;
+
+	bond_ethdev_primary_set(internals, slave_port_id);
+
+	return 0;
+}
+
+int
+rte_eth_bond_primary_get(uint8_t bonded_port_id)
+{
+	struct bond_dev_private *internals;
+
+	if (valid_bonded_port_id(bonded_port_id) != 0)
+		return -1;
+
+	internals = rte_eth_devices[bonded_port_id].data->dev_private;
+
+	if (internals->slave_count < 1)
+		return -1;
+
+	return internals->current_primary_port;
+}
+int
+rte_eth_bond_slaves_get(uint8_t bonded_port_id, uint8_t slaves[], uint8_t len)
+{
+	struct bond_dev_private *internals;
+
+	if (valid_bonded_port_id(bonded_port_id) != 0)
+		return -1;
+
+	if (slaves == NULL)
+		return -1;
+
+	internals = rte_eth_devices[bonded_port_id].data->dev_private;
+
+	if (internals->slave_count > len)
+		return -1;
+
+	memcpy(slaves, internals->slaves, internals->slave_count);
+
+	return internals->slave_count;
+
+}
+
+int
+rte_eth_bond_active_slaves_get(uint8_t bonded_port_id, uint8_t slaves[],
+		uint8_t len)
+{
+	struct bond_dev_private *internals;
+
+	if (valid_bonded_port_id(bonded_port_id) != 0)
+		return -1;
+
+	if (slaves == NULL)
+		return -1;
+
+	internals = rte_eth_devices[bonded_port_id].data->dev_private;
+
+	if (internals->active_slave_count > len)
+		return -1;
+
+	memcpy(slaves, internals->active_slaves, internals->active_slave_count);
+
+	return internals->active_slave_count;
+}
+
+int
+rte_eth_bond_mac_address_set(uint8_t bonded_port_id,
+		struct ether_addr *mac_addr)
+{
+	struct rte_eth_dev *bonded_eth_dev;
+	struct bond_dev_private *internals;
+
+	if (valid_bonded_port_id(bonded_port_id) != 0)
+		return -1;
+
+	bonded_eth_dev = &rte_eth_devices[bonded_port_id];
+	internals = bonded_eth_dev->data->dev_private;
+
+	/* Set MAC Address of Bonded Device */
+	if (mac_address_set(bonded_eth_dev, mac_addr))
+		return -1;
+
+	internals->user_defined_mac = 1;
+
+	/* Update all slave devices MACs*/
+	if (internals->slave_count > 0)
+		return mac_address_slaves_update(bonded_eth_dev);
+
+	return 0;
+}
+
+int
+rte_eth_bond_mac_address_reset(uint8_t bonded_port_id)
+{
+	struct rte_eth_dev *bonded_eth_dev;
+	struct bond_dev_private *internals;
+
+	if (valid_bonded_port_id(bonded_port_id) != 0)
+		return -1;
+
+	bonded_eth_dev = &rte_eth_devices[bonded_port_id];
+	internals = bonded_eth_dev->data->dev_private;
+
+	internals->user_defined_mac = 0;
+
+	if (internals->slave_count > 0) {
+		struct slave_conf *conf;
+		conf = slave_config_get(internals, internals->primary_port);
+
+		/* Set MAC Address of Bonded Device */
+		if (mac_address_set(bonded_eth_dev, &conf->mac_addr) != 0)
+			return -1;
+
+		/* Update all slave devices MAC addresses */
+		return mac_address_slaves_update(bonded_eth_dev);
+	}
+	/* No need to update anything as no slaves present */
+	return 0;
+}
+
+int
+rte_eth_bond_xmit_policy_set(uint8_t bonded_port_id, uint8_t policy)
+{
+	struct bond_dev_private *internals;
+
+	if (valid_bonded_port_id(bonded_port_id) != 0)
+		return -1;
+
+	internals = rte_eth_devices[bonded_port_id].data->dev_private;
+
+	switch (policy) {
+	case BALANCE_XMIT_POLICY_LAYER2:
+	case BALANCE_XMIT_POLICY_LAYER23:
+	case BALANCE_XMIT_POLICY_LAYER34:
+		internals->balance_xmit_policy = policy;
+		break;
+
+	default:
+		return -1;
+	}
+	return 0;
+}
+
+int
+rte_eth_bond_xmit_policy_get(uint8_t bonded_port_id)
+{
+	struct bond_dev_private *internals;
+
+	if (valid_bonded_port_id(bonded_port_id) != 0)
+		return -1;
+
+	internals = rte_eth_devices[bonded_port_id].data->dev_private;
+
+	return internals->balance_xmit_policy;
+}
diff --git a/lib/librte_pmd_bond/rte_eth_bond_args.c b/lib/librte_pmd_bond/rte_eth_bond_args.c
new file mode 100644
index 0000000..11d9816
--- /dev/null
+++ b/lib/librte_pmd_bond/rte_eth_bond_args.c
@@ -0,0 +1,252 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_devargs.h>
+#include <rte_kvargs.h>
+
+#include <cmdline_parse.h>
+#include <cmdline_parse_etheraddr.h>
+
+#include "rte_eth_bond.h"
+#include "rte_eth_bond_private.h"
+
+const char *pmd_bond_init_valid_arguments[] = {
+	PMD_BOND_SLAVE_PORT_KVARG,
+	PMD_BOND_PRIMARY_SLAVE_KVARG,
+	PMD_BOND_MODE_KVARG,
+	PMD_BOND_XMIT_POLICY_KVARG,
+	PMD_BOND_SOCKET_ID_KVARG,
+	PMD_BOND_MAC_ADDR_KVARG,
+
+	NULL
+};
+
+static inline int
+find_port_id_by_pci_addr(const struct rte_pci_addr *pci_addr)
+{
+	struct rte_pci_addr *eth_pci_addr;
+	unsigned i;
+
+	for (i = 0; i < rte_eth_dev_count(); i++) {
+
+		if (rte_eth_devices[i].pci_dev == NULL)
+			continue;
+
+		eth_pci_addr = &(rte_eth_devices[i].pci_dev->addr);
+
+		if (pci_addr->bus == eth_pci_addr->bus &&
+			pci_addr->devid == eth_pci_addr->devid &&
+			pci_addr->domain == eth_pci_addr->domain &&
+			pci_addr->function == eth_pci_addr->function)
+			return i;
+	}
+	return -1;
+}
+
+static inline int
+find_port_id_by_dev_name(const char *name)
+{
+	unsigned i;
+
+	for (i = 0; i < rte_eth_dev_count(); i++) {
+		if (rte_eth_devices[i].data == NULL)
+			continue;
+
+		if (strcmp(rte_eth_devices[i].data->name, name) == 0)
+			return i;
+	}
+	return -1;
+}
+
+/**
+ * Parses a port identifier string to a port id by pci address, then by name,
+ * and finally port id.
+ */
+static inline int
+parse_port_id(const char *port_str)
+{
+	struct rte_pci_addr dev_addr;
+	int port_id;
+
+	/* try parsing as pci address, physical devices */
+	if (eal_parse_pci_DomBDF(port_str, &dev_addr) == 0) {
+		port_id = find_port_id_by_pci_addr(&dev_addr);
+		if (port_id < 0)
+			return -1;
+	} else {
+		/* try parsing as device name, virtual devices */
+		port_id = find_port_id_by_dev_name(port_str);
+		if (port_id < 0) {
+			char *end;
+			errno = 0;
+
+			/* try parsing as port id */
+			port_id = strtol(port_str, &end, 10);
+			if (*end != 0 || errno != 0)
+				return -1;
+		}
+	}
+
+	if (port_id < 0 || port_id > RTE_MAX_ETHPORTS) {
+		RTE_LOG(ERR, PMD, "Invalid slave port value (%s) specified.\n",
+				port_str);
+		return -1;
+	}
+	return port_id;
+}
+
+int
+bond_ethdev_parse_slave_port_kvarg(const char *key __rte_unused,
+		const char *value, void *extra_args)
+{
+	struct bond_ethdev_slave_ports *slave_ports;
+
+	if (value == NULL || extra_args == NULL)
+		return -1;
+
+	slave_ports = extra_args;
+
+	if (strcmp(key, PMD_BOND_SLAVE_PORT_KVARG) == 0) {
+		int port_id = parse_port_id(value);
+		if (port_id < 0)
+			return -1;
+		else
+			slave_ports->slaves[slave_ports->slave_count++] =
+					(uint8_t)port_id;
+	}
+	return 0;
+}
+
+int
+bond_ethdev_parse_slave_mode_kvarg(const char *key __rte_unused,
+		const char *value, void *extra_args)
+{
+	uint8_t *mode;
+	char *endptr;
+
+	if (value == NULL || extra_args == NULL)
+		return -1;
+
+	mode = extra_args;
+
+	errno = 0;
+	*mode = strtol(value, &endptr, 10);
+	if (*endptr != 0 || errno != 0)
+		return -1;
+
+	/* validate mode value */
+	switch (*mode) {
+	case BONDING_MODE_ROUND_ROBIN:
+	case BONDING_MODE_ACTIVE_BACKUP:
+	case BONDING_MODE_BALANCE:
+	case BONDING_MODE_BROADCAST:
+		return 0;
+	default:
+		return -1;
+	}
+}
+
+int
+bond_ethdev_parse_socket_id_kvarg(const char *key __rte_unused,
+		const char *value, void *extra_args)
+{
+	int socket_id;
+	char *endptr;
+
+	if (value == NULL || extra_args == NULL)
+		return -1;
+
+	errno = 0;
+	socket_id = (uint8_t)strtol(value, &endptr, 10);
+	if (*endptr != 0 || errno != 0)
+		return -1;
+
+	/* validate mode value */
+	if (socket_id >= 0 && socket_id < number_of_sockets()) {
+		*(uint8_t *)extra_args = (uint8_t)socket_id;
+		return 0;
+	}
+	return -1;
+}
+
+int
+bond_ethdev_parse_primary_slave_port_id_kvarg(const char *key __rte_unused,
+		const char *value, void *extra_args)
+{
+	int primary_slave_port_id;
+
+	if (value == NULL || extra_args == NULL)
+		return -1;
+
+	primary_slave_port_id = parse_port_id(value);
+	if (primary_slave_port_id < 0)
+		return -1;
+
+	*(uint8_t *)extra_args = (uint8_t)primary_slave_port_id;
+
+	return 0;
+}
+
+int
+bond_ethdev_parse_balance_xmit_policy_kvarg(const char *key __rte_unused,
+		const char *value, void *extra_args)
+{
+	uint8_t *xmit_policy;
+
+	if (value == NULL || extra_args == NULL)
+		return -1;
+
+	xmit_policy = extra_args;
+
+	if (strcmp(PMD_BOND_XMIT_POLICY_LAYER2_KVARG, value) == 0)
+		*xmit_policy = BALANCE_XMIT_POLICY_LAYER2;
+	else if (strcmp(PMD_BOND_XMIT_POLICY_LAYER23_KVARG, value) == 0)
+		*xmit_policy = BALANCE_XMIT_POLICY_LAYER23;
+	else if (strcmp(PMD_BOND_XMIT_POLICY_LAYER34_KVARG, value) == 0)
+		*xmit_policy = BALANCE_XMIT_POLICY_LAYER34;
+	else
+		return -1;
+
+	return 0;
+}
+
+int
+bond_ethdev_parse_bond_mac_addr_kvarg(const char *key __rte_unused,
+		const char *value, void *extra_args)
+{
+	if (value == NULL || extra_args == NULL)
+		return -1;
+
+	/* Parse MAC */
+	return cmdline_parse_etheraddr(NULL, value, extra_args);
+}
diff --git a/lib/librte_pmd_bond/rte_eth_bond_pmd.c b/lib/librte_pmd_bond/rte_eth_bond_pmd.c
new file mode 100644
index 0000000..18fa54a
--- /dev/null
+++ b/lib/librte_pmd_bond/rte_eth_bond_pmd.c
@@ -0,0 +1,1212 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/queue.h>
+#include <linux/binfmts.h>
+
+#include <rte_mbuf.h>
+#include <rte_cycles.h>
+#include <rte_dev.h>
+#include <rte_devargs.h>
+#include <rte_ethdev.h>
+#include <rte_ip.h>
+#include <rte_kvargs.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+#include <rte_memory.h>
+#include <rte_udp.h>
+
+#include "rte_eth_bond.h"
+#include "rte_eth_bond_private.h"
+
+static uint16_t
+bond_ethdev_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
+{
+	struct bond_dev_private *internals;
+
+	uint16_t num_rx_slave = 0;
+	uint16_t num_rx_total = 0;
+
+	int i;
+
+	/* Cast to structure, containing bonded device's port id and queue id */
+	struct bond_rx_queue *bd_rx_q = (struct bond_rx_queue *)queue;
+
+	internals = bd_rx_q->dev_private;
+
+	switch (internals->mode) {
+	case BONDING_MODE_ROUND_ROBIN:
+	case BONDING_MODE_BROADCAST:
+	case BONDING_MODE_BALANCE:
+		for (i = 0; i < internals->active_slave_count; i++) {
+			/* Offset of pointer to *bufs increases as packets are received
+			 * from other slaves */
+			num_rx_slave = rte_eth_rx_burst(internals->active_slaves[i],
+					bd_rx_q->queue_id, bufs + num_rx_total, nb_pkts);
+			if (num_rx_slave)
+				num_rx_total += num_rx_slave;
+		}
+		break;
+	case BONDING_MODE_ACTIVE_BACKUP:
+		num_rx_slave = rte_eth_rx_burst(internals->current_primary_port,
+				bd_rx_q->queue_id, bufs, nb_pkts);
+		if (num_rx_slave)
+			num_rx_total = num_rx_slave;
+		break;
+	}
+	return num_rx_total;
+}
+
+static uint16_t
+bond_ethdev_tx_round_robin(void *queue, struct rte_mbuf **bufs,
+		uint16_t nb_pkts)
+{
+	struct bond_dev_private *dev_private;
+	struct bond_tx_queue *bd_tx_q;
+
+	struct rte_mbuf *slave_bufs[RTE_MAX_ETHPORTS][nb_pkts];
+	uint16_t slave_nb_pkts[RTE_MAX_ETHPORTS] = { 0 };
+
+	uint8_t num_of_slaves;
+	uint8_t slaves[RTE_MAX_ETHPORTS];
+
+	uint16_t num_tx_total = 0;
+
+	static int slave_idx = 0;
+	int i, cs_idx = 0;
+
+	bd_tx_q = (struct bond_tx_queue *)queue;
+	dev_private = bd_tx_q->dev_private;
+
+	/* Copy slave list to protect against slave up/down changes during tx
+	 * bursting */
+	num_of_slaves = dev_private->active_slave_count;
+	memcpy(slaves, dev_private->active_slaves,
+			sizeof(dev_private->active_slaves[0]) * num_of_slaves);
+
+	if (num_of_slaves < 1)
+		return num_tx_total;
+
+	/* Populate slaves mbuf with which packets are to be sent on it  */
+	for (i = 0; i < nb_pkts; i++) {
+		cs_idx = (slave_idx + i) % num_of_slaves;
+		slave_bufs[cs_idx][(slave_nb_pkts[cs_idx])++] = bufs[i];
+	}
+
+	/* increment current slave index so the next call to tx burst starts on the
+	 * next slave */
+	slave_idx = ++cs_idx;
+
+	/* Send packet burst on each slave device */
+	for (i = 0; i < num_of_slaves; i++)
+		if (slave_nb_pkts[i] > 0)
+			num_tx_total += rte_eth_tx_burst(slaves[i],
+					bd_tx_q->queue_id, slave_bufs[i], slave_nb_pkts[i]);
+
+	return num_tx_total;
+}
+
+static uint16_t
+bond_ethdev_tx_active_backup(void *queue,
+		struct rte_mbuf **bufs, uint16_t nb_pkts)
+{
+	struct bond_dev_private *internals;
+	struct bond_tx_queue *bd_tx_q;
+
+	bd_tx_q = (struct bond_tx_queue *)queue;
+	internals = bd_tx_q->dev_private;
+
+	if (internals->active_slave_count < 1)
+		return 0;
+
+	return rte_eth_tx_burst(internals->current_primary_port, bd_tx_q->queue_id,
+			bufs, nb_pkts);
+}
+
+static inline uint16_t
+ether_hash(struct ether_hdr *eth_hdr)
+{
+	uint16_t *word_src_addr = (uint16_t *)eth_hdr->s_addr.addr_bytes;
+	uint16_t *word_dst_addr = (uint16_t *)eth_hdr->d_addr.addr_bytes;
+
+	return (word_src_addr[0] ^ word_dst_addr[0]) ^
+			(word_src_addr[1] ^ word_dst_addr[1]) ^
+			(word_src_addr[2] ^ word_dst_addr[2]);
+}
+
+static inline uint32_t
+ipv4_hash(struct ipv4_hdr *ipv4_hdr)
+{
+	return (ipv4_hdr->src_addr ^ ipv4_hdr->dst_addr);
+}
+
+static inline uint32_t
+ipv6_hash(struct ipv6_hdr *ipv6_hdr)
+{
+	uint32_t *word_src_addr = (uint32_t *)&(ipv6_hdr->src_addr[0]);
+	uint32_t *word_dst_addr = (uint32_t *)&(ipv6_hdr->dst_addr[0]);
+
+	return (word_src_addr[0] ^ word_dst_addr[0]) ^
+			(word_src_addr[1] ^ word_dst_addr[1]) ^
+			(word_src_addr[2] ^ word_dst_addr[2]) ^
+			(word_src_addr[3] ^ word_dst_addr[3]);
+}
+
+static uint32_t
+udp_hash(struct udp_hdr *hdr)
+{
+	return hdr->src_port ^ hdr->dst_port;
+}
+
+static inline uint16_t
+xmit_slave_hash(const struct rte_mbuf *buf, uint8_t slave_count, uint8_t policy)
+{
+	struct ether_hdr *eth_hdr;
+	struct udp_hdr *udp_hdr;
+	size_t eth_offset = 0;
+	uint32_t hash = 0;
+
+	if (slave_count == 1)
+		return 0;
+
+	switch (policy) {
+	case BALANCE_XMIT_POLICY_LAYER2:
+		eth_hdr = (struct ether_hdr *)buf->pkt.data;
+
+		hash = ether_hash(eth_hdr);
+		hash ^= hash >> 8;
+		return hash % slave_count;
+
+	case BALANCE_XMIT_POLICY_LAYER23:
+		eth_hdr = (struct ether_hdr *)buf->pkt.data;
+
+		if (buf->ol_flags & PKT_RX_VLAN_PKT)
+			eth_offset = sizeof(struct ether_hdr) + sizeof(struct vlan_hdr);
+		else
+			eth_offset = sizeof(struct ether_hdr);
+
+		if (buf->ol_flags & PKT_RX_IPV4_HDR) {
+			struct ipv4_hdr *ipv4_hdr;
+			ipv4_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod(buf,
+					unsigned char *) + eth_offset);
+
+			hash = ether_hash(eth_hdr) ^ ipv4_hash(ipv4_hdr);
+
+		} else {
+			struct ipv6_hdr *ipv6_hdr;
+
+			ipv6_hdr = (struct ipv6_hdr *)(rte_pktmbuf_mtod(buf,
+					unsigned char *) + eth_offset);
+
+			hash = ether_hash(eth_hdr) ^ ipv6_hash(ipv6_hdr);
+		}
+		break;
+
+	case BALANCE_XMIT_POLICY_LAYER34:
+		if (buf->ol_flags & PKT_RX_VLAN_PKT)
+			eth_offset = sizeof(struct ether_hdr) + sizeof(struct vlan_hdr);
+		else
+			eth_offset = sizeof(struct ether_hdr);
+
+		if (buf->ol_flags & PKT_RX_IPV4_HDR) {
+			struct ipv4_hdr *ipv4_hdr = (struct ipv4_hdr *)
+					(rte_pktmbuf_mtod(buf, unsigned char *) + eth_offset);
+
+			if (ipv4_hdr->next_proto_id == IPPROTO_UDP) {
+				udp_hdr = (struct udp_hdr *)
+						(rte_pktmbuf_mtod(buf, unsigned char *) + eth_offset +
+								sizeof(struct ipv4_hdr));
+				hash = ipv4_hash(ipv4_hdr) ^ udp_hash(udp_hdr);
+			} else {
+				hash = ipv4_hash(ipv4_hdr);
+			}
+		} else {
+			struct ipv6_hdr *ipv6_hdr = (struct ipv6_hdr *)
+					(rte_pktmbuf_mtod(buf, unsigned char *) + eth_offset);
+
+			if (ipv6_hdr->proto == IPPROTO_UDP) {
+				udp_hdr = (struct udp_hdr *)
+						(rte_pktmbuf_mtod(buf, unsigned char *) + eth_offset +
+								sizeof(struct ipv6_hdr));
+				hash = ipv6_hash(ipv6_hdr) ^ udp_hash(udp_hdr);
+			} else {
+				hash = ipv6_hash(ipv6_hdr);
+			}
+		}
+		break;
+	}
+
+	hash ^= hash >> 16;
+	hash ^= hash >> 8;
+
+	return hash % slave_count;
+}
+
+static uint16_t
+bond_ethdev_tx_balance(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
+{
+	struct bond_dev_private *internals;
+	struct bond_tx_queue *bd_tx_q;
+
+	uint8_t num_of_slaves;
+	uint8_t slaves[RTE_MAX_ETHPORTS];
+
+	uint16_t num_tx_total = 0;
+
+	int i, op_slave_id;
+
+	struct rte_mbuf *slave_bufs[RTE_MAX_ETHPORTS][nb_pkts];
+	uint16_t slave_nb_pkts[RTE_MAX_ETHPORTS] = { 0 };
+
+	bd_tx_q = (struct bond_tx_queue *)queue;
+	internals = bd_tx_q->dev_private;
+
+	/* Copy slave list to protect against slave up/down changes during tx
+	 * bursting */
+	num_of_slaves = internals->active_slave_count;
+	memcpy(slaves, internals->active_slaves,
+			sizeof(internals->active_slaves[0]) * num_of_slaves);
+
+	if (num_of_slaves < 1)
+		return num_tx_total;
+
+	/* Populate slaves mbuf with the packets which are to be sent on it  */
+	for (i = 0; i < nb_pkts; i++) {
+		/* Select output slave using hash based on xmit policy */
+		op_slave_id = xmit_slave_hash(bufs[i], num_of_slaves,
+				internals->balance_xmit_policy);
+
+		/* Populate slave mbuf arrays with mbufs for that slave */
+		slave_bufs[op_slave_id][slave_nb_pkts[op_slave_id]++] = bufs[i];
+	}
+
+	/* Send packet burst on each slave device */
+	for (i = 0; i < num_of_slaves; i++) {
+		if (slave_nb_pkts[i] > 0) {
+			num_tx_total += rte_eth_tx_burst(slaves[i], bd_tx_q->queue_id,
+					slave_bufs[i], slave_nb_pkts[i]);
+		}
+	}
+
+	return num_tx_total;
+}
+
+static uint16_t
+bond_ethdev_tx_burst_broadcast(void *queue, struct rte_mbuf **bufs,
+		uint16_t nb_pkts)
+{
+	struct bond_dev_private *internals;
+	struct bond_tx_queue *bd_tx_q;
+
+	uint8_t num_of_slaves;
+	uint8_t slaves[RTE_MAX_ETHPORTS];
+
+	uint16_t num_tx_total = 0;
+
+	int i;
+
+	bd_tx_q = (struct bond_tx_queue *)queue;
+	internals = bd_tx_q->dev_private;
+
+	/* Copy slave list to protect against slave up/down changes during tx
+	 * bursting */
+	num_of_slaves = internals->active_slave_count;
+	memcpy(slaves, internals->active_slaves,
+			sizeof(internals->active_slaves[0]) * num_of_slaves);
+
+	if (num_of_slaves < 1)
+		return 0;
+
+	/* Increment reference count on mbufs */
+	for (i = 0; i < nb_pkts; i++)
+		rte_mbuf_refcnt_update(bufs[i], num_of_slaves - 1);
+
+	/* Transmit burst on each active slave */
+	for (i = 0; i < num_of_slaves; i++)
+		num_tx_total += rte_eth_tx_burst(slaves[i], bd_tx_q->queue_id,
+				bufs, nb_pkts);
+
+	return num_tx_total;
+}
+
+void
+link_properties_set(struct rte_eth_dev *bonded_eth_dev,
+		struct rte_eth_link *slave_dev_link)
+{
+	struct rte_eth_link *bonded_dev_link = &bonded_eth_dev->data->dev_link;
+	struct bond_dev_private *internals = bonded_eth_dev->data->dev_private;
+
+	if (slave_dev_link->link_status &&
+		bonded_eth_dev->data->dev_started) {
+		bonded_dev_link->link_duplex = slave_dev_link->link_duplex;
+		bonded_dev_link->link_speed = slave_dev_link->link_speed;
+
+		internals->link_props_set = 1;
+	}
+}
+
+void
+link_properties_reset(struct rte_eth_dev *bonded_eth_dev)
+{
+	struct bond_dev_private *internals = bonded_eth_dev->data->dev_private;
+
+	memset(&(bonded_eth_dev->data->dev_link), 0,
+			sizeof(bonded_eth_dev->data->dev_link));
+
+	internals->link_props_set = 0;
+}
+
+int
+link_properties_valid(struct rte_eth_link *bonded_dev_link,
+		struct rte_eth_link *slave_dev_link)
+{
+	if (bonded_dev_link->link_duplex != slave_dev_link->link_duplex ||
+		bonded_dev_link->link_speed !=  slave_dev_link->link_speed)
+		return -1;
+
+	return 0;
+}
+
+int
+mac_address_set(struct rte_eth_dev *eth_dev, struct ether_addr *new_mac_addr)
+{
+	struct ether_addr *mac_addr;
+
+	mac_addr = eth_dev->data->mac_addrs;
+
+	if (eth_dev == NULL) {
+		RTE_LOG(ERR, PMD, "%s: NULL pointer eth_dev specified\n", __func__);
+		return -1;
+	}
+
+	if (new_mac_addr == NULL) {
+		RTE_LOG(ERR, PMD, "%s: NULL pointer MAC specified\n", __func__);
+		return -1;
+	}
+
+	/* if new MAC is different to current MAC then update */
+	if (memcmp(mac_addr, new_mac_addr, sizeof(*mac_addr)) != 0)
+		memcpy(mac_addr, new_mac_addr, sizeof(*mac_addr));
+
+	return 0;
+}
+
+int
+mac_address_slaves_update(struct rte_eth_dev *bonded_eth_dev)
+{
+	struct bond_dev_private *internals = bonded_eth_dev->data->dev_private;
+	int i;
+
+	/* Update slave devices MAC addresses */
+	if (internals->slave_count < 1)
+		return -1;
+
+	switch (internals->mode) {
+	case BONDING_MODE_ROUND_ROBIN:
+	case BONDING_MODE_BALANCE:
+	case BONDING_MODE_BROADCAST:
+		for (i = 0; i < internals->slave_count; i++) {
+			if (mac_address_set(&rte_eth_devices[internals->slaves[i]],
+					bonded_eth_dev->data->mac_addrs)) {
+				RTE_LOG(ERR, PMD,
+						"%s: Failed to update port Id %d MAC address\n",
+						__func__, internals->slaves[i]);
+				return -1;
+			}
+		}
+		break;
+	case BONDING_MODE_ACTIVE_BACKUP:
+	default:
+		for (i = 0; i < internals->slave_count; i++) {
+			if (internals->slaves[i] == internals->current_primary_port) {
+				if (mac_address_set(&rte_eth_devices[internals->primary_port],
+						bonded_eth_dev->data->mac_addrs)) {
+					RTE_LOG(ERR, PMD,
+							"%s: Failed to update port Id %d MAC address\n",
+							__func__, internals->current_primary_port);
+				}
+			} else {
+				struct slave_conf *conf =
+						slave_config_get(internals, internals->slaves[i]);
+
+				if (mac_address_set(&rte_eth_devices[internals->slaves[i]],
+						&conf->mac_addr)) {
+					RTE_LOG(ERR, PMD,
+							"%s: Failed to update port Id %d MAC address\n",
+							__func__, internals->slaves[i]);
+
+					return -1;
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
+int
+bond_ethdev_mode_set(struct rte_eth_dev *eth_dev, int mode)
+{
+	struct bond_dev_private *internals;
+
+	internals = eth_dev->data->dev_private;
+
+	switch (mode) {
+	case BONDING_MODE_ROUND_ROBIN:
+		eth_dev->tx_pkt_burst = bond_ethdev_tx_round_robin;
+		break;
+	case BONDING_MODE_ACTIVE_BACKUP:
+		eth_dev->tx_pkt_burst = bond_ethdev_tx_active_backup;
+		break;
+	case BONDING_MODE_BALANCE:
+		eth_dev->tx_pkt_burst = bond_ethdev_tx_balance;
+		break;
+	case BONDING_MODE_BROADCAST:
+		eth_dev->tx_pkt_burst = bond_ethdev_tx_burst_broadcast;
+		break;
+	default:
+		return -1;
+	}
+
+	eth_dev->rx_pkt_burst = bond_ethdev_rx_burst;
+	internals->mode = mode;
+
+	return 0;
+}
+
+int
+slave_configure(struct rte_eth_dev *bonded_eth_dev,
+		struct rte_eth_dev *slave_eth_dev)
+{
+	struct bond_rx_queue *bd_rx_q;
+	struct bond_tx_queue *bd_tx_q;
+
+	int q_id;
+
+	/* Stop slave */
+	rte_eth_dev_stop(slave_eth_dev->data->port_id);
+
+	/* Enable interrupts on slave device */
+	slave_eth_dev->data->dev_conf.intr_conf.lsc = 1;
+
+	if (rte_eth_dev_configure(slave_eth_dev->data->port_id,
+			bonded_eth_dev->data->nb_rx_queues,
+			bonded_eth_dev->data->nb_tx_queues,
+			&(slave_eth_dev->data->dev_conf)) != 0) {
+		RTE_LOG(ERR, PMD, "Cannot configure slave device: port=%u\n",
+				slave_eth_dev->data->port_id);
+		return -1;
+	}
+
+	/* Setup Rx Queues */
+	for (q_id = 0; q_id < bonded_eth_dev->data->nb_rx_queues; q_id++) {
+		bd_rx_q = (struct bond_rx_queue *)bonded_eth_dev->data->rx_queues[q_id];
+
+		if (rte_eth_rx_queue_setup(slave_eth_dev->data->port_id, q_id,
+				bd_rx_q->nb_rx_desc,
+				rte_eth_dev_socket_id(slave_eth_dev->data->port_id),
+				&(bd_rx_q->rx_conf), bd_rx_q->mb_pool) != 0) {
+			RTE_LOG(ERR, PMD, "rte_eth_rx_queue_setup: port=%d queue_id %d\n",
+					slave_eth_dev->data->port_id, q_id);
+			return -1;
+		}
+	}
+
+	/* Setup Tx Queues */
+	for (q_id = 0; q_id < bonded_eth_dev->data->nb_tx_queues; q_id++) {
+		bd_tx_q = (struct bond_tx_queue *)bonded_eth_dev->data->tx_queues[q_id];
+
+		if (rte_eth_tx_queue_setup(slave_eth_dev->data->port_id, q_id,
+				bd_tx_q->nb_tx_desc,
+				rte_eth_dev_socket_id(slave_eth_dev->data->port_id),
+				&bd_tx_q->tx_conf) != 0) {
+			RTE_LOG(ERR, PMD, "rte_eth_tx_queue_setup: port=%d queue_id %d\n",
+					slave_eth_dev->data->port_id, q_id);
+			return -1;
+		}
+	}
+
+	/* Start device */
+	if (rte_eth_dev_start(slave_eth_dev->data->port_id) != 0) {
+		RTE_LOG(ERR, PMD, "rte_eth_dev_start: port=%u\n",
+				slave_eth_dev->data->port_id);
+		return -1;
+	}
+
+	return 0;
+}
+
+struct slave_conf *
+slave_config_get(struct bond_dev_private *internals, uint8_t slave_port_id)
+{
+	int i;
+
+	for (i = 0; i < internals->slave_count; i++) {
+		if (internals->presisted_slaves_conf[i].port_id == slave_port_id)
+			return &internals->presisted_slaves_conf[i];
+	}
+	return NULL;
+}
+
+void
+slave_config_clear(struct bond_dev_private *internals,
+		struct rte_eth_dev *slave_eth_dev)
+{
+	int i, found = 0;
+
+	for (i = 0; i < internals->slave_count; i++) {
+		if (internals->presisted_slaves_conf[i].port_id ==
+				slave_eth_dev->data->port_id) {
+			found = 1;
+			memset(&internals->presisted_slaves_conf[i], 0,
+					sizeof(internals->presisted_slaves_conf[i]));
+		}
+		if (found && i < (internals->slave_count - 1)) {
+			memcpy(&internals->presisted_slaves_conf[i],
+					&internals->presisted_slaves_conf[i+1],
+					sizeof(internals->presisted_slaves_conf[i]));
+		}
+	}
+}
+
+void
+slave_config_store(struct bond_dev_private *internals,
+		struct rte_eth_dev *slave_eth_dev)
+{
+	struct slave_conf *presisted_slave_conf =
+			&internals->presisted_slaves_conf[internals->slave_count];
+
+	presisted_slave_conf->port_id = slave_eth_dev->data->port_id;
+
+	memcpy(&(presisted_slave_conf->mac_addr), slave_eth_dev->data->mac_addrs,
+			sizeof(struct ether_addr));
+}
+
+void
+bond_ethdev_primary_set(struct bond_dev_private *internals,
+		uint8_t slave_port_id)
+{
+	int i;
+
+	if (internals->active_slave_count < 1)
+		internals->current_primary_port = slave_port_id;
+	else
+		/* Search bonded device slave ports for new proposed primary port */
+		for (i = 0; i < internals->active_slave_count; i++) {
+			if (internals->active_slaves[i] == slave_port_id)
+				internals->current_primary_port = slave_port_id;
+		}
+}
+
+static void
+bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev);
+
+static int
+bond_ethdev_start(struct rte_eth_dev *eth_dev)
+{
+	struct bond_dev_private *internals;
+	int i;
+
+	/* slave eth dev will be started by bonded device */
+	if (valid_bonded_ethdev(eth_dev)) {
+		RTE_LOG(ERR, PMD,
+				"%s: user tried to explicitly start a slave eth_dev (%d) of the bonded eth_dev\n",
+				__func__, eth_dev->data->port_id);
+		return -1;
+	}
+
+	eth_dev->data->dev_link.link_status = 1;
+	eth_dev->data->dev_started = 1;
+
+	internals = eth_dev->data->dev_private;
+
+	if (internals->slave_count == 0) {
+		RTE_LOG(ERR, PMD,
+				"%s: Cannot start port since there are no slave devices\n",
+				__func__);
+		return -1;
+	}
+
+	if (internals->user_defined_mac == 0) {
+		struct slave_conf *conf = slave_config_get(internals,
+				internals->primary_port);
+
+		if (mac_address_set(eth_dev, &(conf->mac_addr)) != 0) {
+			RTE_LOG(ERR, PMD,
+					"bonded port (%d) failed to update mac address",
+					eth_dev->data->port_id);
+			return -1;
+		}
+	}
+
+	/* Update all slave devices MACs*/
+	if (mac_address_slaves_update(eth_dev) != 0)
+		return -1;
+
+	/* If bonded device is configure in promiscuous mode then re-apply config */
+	if (internals->promiscuous_en)
+		bond_ethdev_promiscuous_enable(eth_dev);
+
+	/* Reconfigure each slave device if starting bonded device */
+	for (i = 0; i < internals->slave_count; i++) {
+		if (slave_configure(eth_dev, &(rte_eth_devices[internals->slaves[i]]))
+				!= 0) {
+			RTE_LOG(ERR, PMD,
+					"bonded port (%d) failed to reconfigure slave device %d)",
+					eth_dev->data->port_id, internals->slaves[i]);
+			return -1;
+		}
+	}
+
+	if (internals->user_defined_primary_port)
+		bond_ethdev_primary_set(internals, internals->primary_port);
+
+	return 0;
+}
+
+static void
+bond_ethdev_stop(struct rte_eth_dev *eth_dev)
+{
+	struct bond_dev_private *internals = eth_dev->data->dev_private;
+
+	internals->active_slave_count = 0;
+
+	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_started = 0;
+}
+
+static void
+bond_ethdev_close(struct rte_eth_dev *dev __rte_unused)
+{
+}
+
+static int
+bond_ethdev_configure(struct rte_eth_dev *dev __rte_unused)
+{
+	return 0;
+}
+
+static void
+bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
+{
+	dev_info->driver_name = driver_name;
+	dev_info->max_mac_addrs = 1;
+
+	dev_info->max_rx_pktlen = (uint32_t)2048;
+
+	dev_info->max_rx_queues = (uint16_t)128;
+	dev_info->max_tx_queues = (uint16_t)512;
+
+	dev_info->min_rx_bufsize = 0;
+	dev_info->pci_dev = dev->pci_dev;
+}
+
+static int
+bond_ethdev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
+		uint16_t nb_rx_desc, unsigned int socket_id __rte_unused,
+		const struct rte_eth_rxconf *rx_conf, struct rte_mempool *mb_pool)
+{
+	struct bond_rx_queue *bd_rx_q = (struct bond_rx_queue *)
+			rte_zmalloc_socket(NULL, sizeof(struct bond_rx_queue),
+					0, dev->pci_dev->numa_node);
+	if (bd_rx_q == NULL)
+		return -1;
+
+	bd_rx_q->queue_id = rx_queue_id;
+	bd_rx_q->dev_private = dev->data->dev_private;
+
+	bd_rx_q->nb_rx_desc = nb_rx_desc;
+
+	memcpy(&(bd_rx_q->rx_conf), rx_conf, sizeof(struct rte_eth_rxconf));
+	bd_rx_q->mb_pool = mb_pool;
+
+	dev->data->rx_queues[rx_queue_id] = bd_rx_q;
+
+	return 0;
+}
+
+static int
+bond_ethdev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
+		uint16_t nb_tx_desc, unsigned int socket_id __rte_unused,
+		const struct rte_eth_txconf *tx_conf)
+{
+	struct bond_tx_queue *bd_tx_q  = (struct bond_tx_queue *)
+			rte_zmalloc_socket(NULL, sizeof(struct bond_tx_queue),
+					0, dev->pci_dev->numa_node);
+
+	if (bd_tx_q == NULL)
+			return -1;
+
+	bd_tx_q->queue_id = tx_queue_id;
+	bd_tx_q->dev_private = dev->data->dev_private;
+
+	bd_tx_q->nb_tx_desc = nb_tx_desc;
+	memcpy(&(bd_tx_q->tx_conf), tx_conf, sizeof(bd_tx_q->tx_conf));
+
+	dev->data->tx_queues[tx_queue_id] = bd_tx_q;
+
+	return 0;
+}
+
+static void
+bond_ethdev_rx_queue_release(void *queue)
+{
+	if (queue == NULL)
+		return;
+
+	rte_free(queue);
+}
+
+static void
+bond_ethdev_tx_queue_release(void *queue)
+{
+	if (queue == NULL)
+		return;
+
+	rte_free(queue);
+}
+
+static int
+bond_ethdev_link_update(struct rte_eth_dev *bonded_eth_dev,
+		int wait_to_complete)
+{
+	struct bond_dev_private *internals = bonded_eth_dev->data->dev_private;
+
+	if (!bonded_eth_dev->data->dev_started ||
+		internals->active_slave_count == 0) {
+		bonded_eth_dev->data->dev_link.link_status = 0;
+		return 0;
+	} else {
+		struct rte_eth_dev *slave_eth_dev;
+		int i, link_up = 0;
+
+		for (i = 0; i < internals->active_slave_count; i++) {
+			slave_eth_dev = &rte_eth_devices[internals->active_slaves[i]];
+
+			(*slave_eth_dev->dev_ops->link_update)(slave_eth_dev,
+					wait_to_complete);
+			if (slave_eth_dev->data->dev_link.link_status == 1) {
+				link_up = 1;
+				break;
+			}
+		}
+
+		bonded_eth_dev->data->dev_link.link_status = link_up;
+	}
+
+	return 0;
+}
+
+static void
+bond_ethdev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	struct bond_dev_private *internals = dev->data->dev_private;
+	struct rte_eth_stats slave_stats;
+
+	int i;
+
+	/* clear bonded stats before populating from slaves */
+	memset(stats, 0, sizeof(*stats));
+
+	for (i = 0; i < internals->slave_count; i++) {
+		rte_eth_stats_get(internals->slaves[i], &slave_stats);
+
+		stats->ipackets += slave_stats.ipackets;
+		stats->opackets += slave_stats.opackets;
+		stats->ibytes += slave_stats.ibytes;
+		stats->obytes += slave_stats.obytes;
+		stats->ierrors += slave_stats.ierrors;
+		stats->oerrors += slave_stats.oerrors;
+		stats->imcasts += slave_stats.imcasts;
+		stats->rx_nombuf += slave_stats.rx_nombuf;
+		stats->fdirmatch += slave_stats.fdirmatch;
+		stats->fdirmiss += slave_stats.fdirmiss;
+		stats->tx_pause_xon += slave_stats.tx_pause_xon;
+		stats->rx_pause_xon += slave_stats.rx_pause_xon;
+		stats->tx_pause_xoff += slave_stats.tx_pause_xoff;
+		stats->rx_pause_xoff += slave_stats.rx_pause_xoff;
+	}
+}
+
+static void
+bond_ethdev_stats_reset(struct rte_eth_dev *dev)
+{
+	struct bond_dev_private *internals = dev->data->dev_private;
+	int i;
+
+	for (i = 0; i < internals->slave_count; i++)
+		rte_eth_stats_reset(internals->slaves[i]);
+}
+
+static void
+bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev)
+{
+	struct bond_dev_private *internals = eth_dev->data->dev_private;
+	int i;
+
+	internals->promiscuous_en = 1;
+
+	switch (internals->mode) {
+	/* Promiscuous mode is propagated to all slaves */
+	case BONDING_MODE_ROUND_ROBIN:
+	case BONDING_MODE_BALANCE:
+	case BONDING_MODE_BROADCAST:
+		for (i = 0; i < internals->slave_count; i++)
+			rte_eth_promiscuous_enable(internals->slaves[i]);
+		break;
+	/* Promiscuous mode is propagated only to primary slave */
+	case BONDING_MODE_ACTIVE_BACKUP:
+	default:
+		rte_eth_promiscuous_enable(internals->current_primary_port);
+
+	}
+}
+
+static void
+bond_ethdev_promiscuous_disable(struct rte_eth_dev *dev)
+{
+	struct bond_dev_private *internals = dev->data->dev_private;
+	int i;
+
+	internals->promiscuous_en = 0;
+
+	switch (internals->mode) {
+	/* Promiscuous mode is propagated to all slaves */
+	case BONDING_MODE_ROUND_ROBIN:
+	case BONDING_MODE_BALANCE:
+	case BONDING_MODE_BROADCAST:
+		for (i = 0; i < internals->slave_count; i++)
+			rte_eth_promiscuous_disable(internals->slaves[i]);
+		break;
+	/* Promiscuous mode is propagated only to primary slave */
+	case BONDING_MODE_ACTIVE_BACKUP:
+	default:
+		rte_eth_promiscuous_disable(internals->current_primary_port);
+	}
+}
+
+void
+bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
+		void *param)
+{
+	struct rte_eth_dev *bonded_eth_dev, *slave_eth_dev;
+	struct bond_dev_private *internals;
+	struct rte_eth_link link;
+
+	int i, bonded_port_id, valid_slave, active_pos = -1;
+
+	if (type != RTE_ETH_EVENT_INTR_LSC)
+		return;
+
+	if (param == NULL)
+		return;
+
+	bonded_port_id = *(uint8_t *)param;
+
+	bonded_eth_dev = &rte_eth_devices[bonded_port_id];
+	slave_eth_dev = &rte_eth_devices[port_id];
+
+	if (valid_bonded_ethdev(bonded_eth_dev))
+		return;
+
+	internals = bonded_eth_dev->data->dev_private;
+
+	/* If the device isn't started don't handle interrupts */
+	if (!bonded_eth_dev->data->dev_started)
+		return;
+
+	/* verify that port_id is a valid slave of bonded port */
+	for (i = 0; i < internals->slave_count; i++) {
+		if (internals->slaves[i] == port_id) {
+			valid_slave = 1;
+			break;
+		}
+	}
+
+	if (!valid_slave)
+		return;
+
+	/* Search for port in active port list */
+	for (i = 0; i < internals->active_slave_count; i++) {
+		if (port_id == internals->active_slaves[i]) {
+			active_pos = i;
+			break;
+		}
+	}
+
+	rte_eth_link_get_nowait(port_id, &link);
+	if (link.link_status) {
+		if (active_pos == -1) {
+			/* if no active slave ports then set this port to be primary port */
+			if (internals->active_slave_count == 0) {
+				/* If first active slave, then change link status */
+				bonded_eth_dev->data->dev_link.link_status = 1;
+				internals->current_primary_port = port_id;
+
+				/* Inherit eth dev link properties from first active slave */
+				link_properties_set(bonded_eth_dev,
+						&(slave_eth_dev->data->dev_link));
+
+			}
+			internals->active_slaves[internals->active_slave_count++] = port_id;
+
+			/* If user has defined the primary port then default to using it */
+			if (internals->user_defined_primary_port &&
+					internals->primary_port == port_id)
+				bond_ethdev_primary_set(internals, port_id);
+
+		}
+	} else {
+		if (active_pos != -1) {
+			/* Remove from active slave list */
+			for (i = active_pos; i < (internals->active_slave_count - 1); i++)
+				internals->active_slaves[i] = internals->active_slaves[i+1];
+
+			internals->active_slave_count--;
+
+			/* No active slaves, change link status to down and reset other
+			 * link properties */
+			if (internals->active_slave_count == 0)
+				link_properties_reset(bonded_eth_dev);
+
+			/* Update primary id, take first active slave from list or if none
+			 * available set to -1 */
+			if (port_id == internals->current_primary_port) {
+				if (internals->active_slave_count > 0)
+					bond_ethdev_primary_set(internals,
+							internals->active_slaves[0]);
+				else
+					internals->current_primary_port = internals->primary_port;
+			}
+		}
+	}
+}
+
+struct eth_dev_ops default_dev_ops = {
+		.dev_start = bond_ethdev_start,
+		.dev_stop = bond_ethdev_stop,
+		.dev_close = bond_ethdev_close,
+		.dev_configure = bond_ethdev_configure,
+		.dev_infos_get = bond_ethdev_info,
+		.rx_queue_setup = bond_ethdev_rx_queue_setup,
+		.tx_queue_setup = bond_ethdev_tx_queue_setup,
+		.rx_queue_release = bond_ethdev_rx_queue_release,
+		.tx_queue_release = bond_ethdev_tx_queue_release,
+		.link_update = bond_ethdev_link_update,
+		.stats_get = bond_ethdev_stats_get,
+		.stats_reset = bond_ethdev_stats_reset,
+		.promiscuous_enable = bond_ethdev_promiscuous_enable,
+		.promiscuous_disable = bond_ethdev_promiscuous_disable
+};
+
+static int
+bond_init(const char *name, const char *params)
+{
+	struct rte_kvargs *kvlist;
+	uint8_t bonding_mode, socket_id;
+	int  arg_count, port_id;
+
+	RTE_LOG(INFO, EAL, "Initializing pmd_bond for %s\n", name);
+
+	kvlist = rte_kvargs_parse(params, pmd_bond_init_valid_arguments);
+	if (kvlist == NULL)
+		return -1;
+
+	/* Parse link bonding mode */
+	if (rte_kvargs_count(kvlist, PMD_BOND_MODE_KVARG) == 1) {
+		if (rte_kvargs_process(kvlist, PMD_BOND_MODE_KVARG,
+				&bond_ethdev_parse_slave_mode_kvarg, &bonding_mode) != 0) {
+			RTE_LOG(ERR, EAL, "Invalid mode for bonded device %s\n", name);
+			return -1;
+		}
+	} else {
+		RTE_LOG(ERR, EAL,
+				"Mode must be specified only once for bonded device %s\n",
+				name);
+		return -1;
+	}
+
+	/* Parse socket id to create bonding device on */
+	arg_count = rte_kvargs_count(kvlist, PMD_BOND_SOCKET_ID_KVARG);
+	if (arg_count == 1) {
+		if (rte_kvargs_process(kvlist, PMD_BOND_SOCKET_ID_KVARG,
+				&bond_ethdev_parse_socket_id_kvarg, &socket_id) != 0) {
+			RTE_LOG(ERR, EAL,
+					"Invalid socket Id specified for bonded device %s\n",
+					name);
+			return -1;
+		}
+	} else if (arg_count > 1) {
+		RTE_LOG(ERR, EAL,
+				"Socket Id can be specified only once for bonded device %s\n",
+				name);
+		return -1;
+	} else {
+		socket_id = rte_socket_id();
+	}
+
+	/* Create link bonding eth device */
+	port_id = rte_eth_bond_create(name, bonding_mode, socket_id);
+	if (port_id < 0) {
+		RTE_LOG(ERR, EAL,
+				"Failed to create socket %s in mode %u on socket %u.\n",
+				name, bonding_mode, socket_id);
+		return -1;
+	}
+
+	RTE_LOG(INFO, EAL,
+			"Create bonded device %s on port %d in mode %u on socket %u.\n",
+			name, port_id, bonding_mode, socket_id);
+
+	/* Parse MAC address for bonded device */
+	arg_count = rte_kvargs_count(kvlist, PMD_BOND_MAC_ADDR_KVARG);
+	if (arg_count == 1) {
+		struct ether_addr bond_mac;
+
+		if (rte_kvargs_process(kvlist, PMD_BOND_MAC_ADDR_KVARG,
+				&bond_ethdev_parse_bond_mac_addr_kvarg, &bond_mac) < 0) {
+			RTE_LOG(INFO, EAL, "Invalid mac address for bonded device %s\n",
+					name);
+			return -1;
+		}
+
+		/* Set MAC address */
+		if (rte_eth_bond_mac_address_set(port_id, &bond_mac) != 0) {
+			RTE_LOG(ERR, EAL,
+					"Failed to set mac address on bonded device %s\n",
+					name);
+			return -1;
+		}
+	} else if (arg_count > 1) {
+		RTE_LOG(ERR, EAL,
+				"MAC address can be specified only once for bonded device %s\n",
+				name);
+		return -1;
+	}
+
+	/* Parse/set balance mode transmit policy */
+	arg_count = rte_kvargs_count(kvlist, PMD_BOND_XMIT_POLICY_KVARG);
+	if (arg_count == 1) {
+		uint8_t xmit_policy;
+
+		if (rte_kvargs_process(kvlist, PMD_BOND_XMIT_POLICY_KVARG,
+				&bond_ethdev_parse_balance_xmit_policy_kvarg, &xmit_policy) !=
+						0) {
+			RTE_LOG(INFO, EAL,
+					"Invalid xmit policy specified for bonded device %s\n",
+					name);
+			return -1;
+		}
+
+		/* Set balance mode transmit policy*/
+		if (rte_eth_bond_xmit_policy_set(port_id, xmit_policy) != 0) {
+			RTE_LOG(ERR, EAL,
+					"Failed to set balance xmit policy on bonded device %s\n",
+					name);
+			return -1;
+		}
+	} else if (arg_count > 1) {
+		RTE_LOG(ERR, EAL,
+				"Transmit policy can be specified only once for bonded device %s\n",
+				name);
+		return -1;
+	}
+
+	/* Parse/add slave ports to bonded device */
+	if (rte_kvargs_count(kvlist, PMD_BOND_SLAVE_PORT_KVARG) > 0) {
+		struct bond_ethdev_slave_ports slave_ports;
+		unsigned i;
+
+		memset(&slave_ports, 0, sizeof(slave_ports));
+
+		if (rte_kvargs_process(kvlist, PMD_BOND_SLAVE_PORT_KVARG,
+				&bond_ethdev_parse_slave_port_kvarg, &slave_ports) != 0) {
+			RTE_LOG(ERR, EAL,
+					"Failed to parse slave ports for bonded device %s\n",
+					name);
+			return -1;
+		}
+
+		for (i = 0; i < slave_ports.slave_count; i++) {
+			if (rte_eth_bond_slave_add(port_id, slave_ports.slaves[i]) != 0) {
+				RTE_LOG(ERR, EAL,
+						"Failed to add port %d as slave to bonded device %s\n",
+						slave_ports.slaves[i], name);
+			}
+		}
+
+	} else {
+		RTE_LOG(INFO, EAL, "No slaves specified for bonded device %s\n", name);
+		return -1;
+	}
+
+	/* Parse/set primary slave port id*/
+	arg_count = rte_kvargs_count(kvlist, PMD_BOND_PRIMARY_SLAVE_KVARG);
+	if (arg_count == 1) {
+		uint8_t primary_slave_port_id;
+
+		if (rte_kvargs_process(kvlist,
+				PMD_BOND_PRIMARY_SLAVE_KVARG,
+				&bond_ethdev_parse_primary_slave_port_id_kvarg,
+				&primary_slave_port_id) < 0) {
+			RTE_LOG(INFO, EAL,
+					"Invalid primary slave port id specified for bonded device %s\n",
+					name);
+			return -1;
+		}
+
+		/* Set balance mode transmit policy*/
+		if (rte_eth_bond_primary_set(port_id, (uint8_t)primary_slave_port_id)
+				!= 0) {
+			RTE_LOG(ERR, EAL,
+					"Failed to set primary slave port %d on bonded device %s\n",
+					primary_slave_port_id, name);
+			return -1;
+		}
+	} else if (arg_count > 1) {
+		RTE_LOG(INFO, EAL,
+				"Primary slave can be specified only once for bonded device %s\n",
+				name);
+		return -1;
+	}
+
+	return 0;
+}
+
+static struct rte_driver bond_drv = {
+	.name = PMD_BOND_NAME,
+	.type = PMD_BDEV,
+	.init = bond_init,
+};
+
+PMD_REGISTER_DRIVER(bond_drv);
diff --git a/lib/librte_pmd_bond/rte_eth_bond_private.h b/lib/librte_pmd_bond/rte_eth_bond_private.h
new file mode 100644
index 0000000..60f1e8d
--- /dev/null
+++ b/lib/librte_pmd_bond/rte_eth_bond_private.h
@@ -0,0 +1,215 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_ETH_BOND_PRIVATE_H_
+#define _RTE_ETH_BOND_PRIVATE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_ethdev.h>
+
+#include "rte_eth_bond.h"
+
+#define PMD_BOND_SLAVE_PORT_KVARG		("slave")
+#define PMD_BOND_PRIMARY_SLAVE_KVARG	("primary")
+#define PMD_BOND_MODE_KVARG				("mode")
+#define PMD_BOND_XMIT_POLICY_KVARG		("xmit_policy")
+#define PMD_BOND_SOCKET_ID_KVARG		("socket_id")
+#define PMD_BOND_MAC_ADDR_KVARG			("mac")
+
+#define PMD_BOND_XMIT_POLICY_LAYER2_KVARG	("l2")
+#define PMD_BOND_XMIT_POLICY_LAYER23_KVARG	("l23")
+#define PMD_BOND_XMIT_POLICY_LAYER34_KVARG	("l34")
+
+extern const char *pmd_bond_init_valid_arguments[];
+
+extern const char *driver_name;
+
+/** Port Queue Mapping Structure */
+struct bond_rx_queue {
+	int queue_id;
+	/**< Queue Id */
+	struct bond_dev_private *dev_private;
+	/**< Reference to eth_dev private structure */
+	uint16_t nb_rx_desc;
+	/**< Number of RX descriptors available for the queue */
+	struct rte_eth_rxconf rx_conf;
+	/**< Copy of RX configuration structure for queue */
+	struct rte_mempool *mb_pool;
+	/**< Reference to mbuf pool to use for RX queue */
+};
+
+struct bond_tx_queue {
+	int queue_id;
+	/**< Queue Id */
+	struct bond_dev_private *dev_private;
+	/**< Reference to dev private structure */
+	uint16_t nb_tx_desc;
+	/**< Number of TX descriptors available for the queue */
+	struct rte_eth_txconf tx_conf;
+	/**< Copy of TX configuration structure for queue */
+};
+
+/** Persisted Slave Configuration Structure */
+struct slave_conf {
+	uint8_t port_id;
+	/**< Port Id of slave eth_dev */
+	struct ether_addr mac_addr;
+	/**< Slave eth_dev original MAC address */
+};
+/** Bonded slave devices structure */
+struct bond_ethdev_slave_ports {
+	uint8_t slaves[RTE_MAX_ETHPORTS];	/**< Slave port id array */
+	uint8_t slave_count;				/**< Number of slaves */
+};
+
+/** Link Bonding PMD device private configuration Structure */
+struct bond_dev_private {
+	uint8_t mode;						/**< Link Bonding Mode */
+
+	uint8_t primary_port;				/**< Primary Slave Port */
+	uint8_t current_primary_port;		/**< Primary Slave Port */
+	uint8_t user_defined_primary_port;
+	/**< Flag for whether primary port is user defined or not */
+	uint8_t balance_xmit_policy;
+	/**< Transmit policy - l2 / l23 / l34 for operation in balance mode */
+	uint8_t user_defined_mac;
+	/**< Flag for whether MAC address is user defined or not */
+	uint8_t promiscuous_en;
+	/**< Enabled/disable promiscuous mode on slave devices */
+	uint8_t link_props_set;
+	/**< Bonded eth_dev link properties set */
+
+	uint16_t nb_rx_queues;			/**< Total number of rx queues */
+	uint16_t nb_tx_queues;			/**< Total number of tx queues*/
+
+	uint8_t slave_count;			/**< Number of active slaves */
+	uint8_t active_slave_count;		/**< Number of slaves */
+
+	uint8_t active_slaves[RTE_MAX_ETHPORTS];	/**< Active slave list */
+	uint8_t slaves[RTE_MAX_ETHPORTS];			/**< Slave list */
+
+	/** Persisted configuration of slaves */
+	struct slave_conf presisted_slaves_conf[RTE_MAX_ETHPORTS];
+};
+
+extern struct eth_dev_ops default_dev_ops;
+
+int
+valid_bonded_ethdev(struct rte_eth_dev *eth_dev);
+
+int
+valid_port_id(uint8_t port_id);
+
+int
+valid_bonded_port_id(uint8_t port_id);
+
+int
+valid_slave_port_id(uint8_t port_id);
+
+void
+link_properties_set(struct rte_eth_dev *bonded_eth_dev,
+		struct rte_eth_link *slave_dev_link);
+void
+link_properties_reset(struct rte_eth_dev *bonded_eth_dev);
+
+int
+link_properties_valid(struct rte_eth_link *bonded_dev_link,
+		struct rte_eth_link *slave_dev_link);
+
+int
+mac_address_set(struct rte_eth_dev *eth_dev, struct ether_addr *new_mac_addr);
+
+int
+mac_address_slaves_update(struct rte_eth_dev *bonded_eth_dev);
+
+uint8_t
+number_of_sockets(void);
+
+int
+bond_ethdev_mode_set(struct rte_eth_dev *eth_dev, int mode);
+
+int
+slave_configure(struct rte_eth_dev *bonded_eth_dev,
+		struct rte_eth_dev *slave_eth_dev);
+
+void
+slave_config_clear(struct bond_dev_private *internals,
+		struct rte_eth_dev *slave_eth_dev);
+
+void
+slave_config_store(struct bond_dev_private *internals,
+		struct rte_eth_dev *slave_eth_dev);
+
+struct slave_conf *
+slave_config_get(struct bond_dev_private *internals, uint8_t slave_port_id);
+
+void
+bond_ethdev_primary_set(struct bond_dev_private *internals,
+		uint8_t slave_port_id);
+
+void
+bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
+		void *param);
+
+int
+bond_ethdev_parse_slave_port_kvarg(const char *key __rte_unused,
+		const char *value, void *extra_args);
+
+int
+bond_ethdev_parse_slave_mode_kvarg(const char *key __rte_unused,
+		const char *value, void *extra_args);
+
+int
+bond_ethdev_parse_socket_id_kvarg(const char *key __rte_unused,
+		const char *value, void *extra_args);
+
+int
+bond_ethdev_parse_primary_slave_port_id_kvarg(const char *key __rte_unused,
+		const char *value, void *extra_args);
+
+int
+bond_ethdev_parse_balance_xmit_policy_kvarg(const char *key __rte_unused,
+		const char *value, void *extra_args);
+
+int
+bond_ethdev_parse_bond_mac_addr_kvarg(const char *key __rte_unused,
+		const char *value, void *extra_args);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 8db9cde..a4624e5 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -205,6 +205,10 @@ ifeq ($(CONFIG_RTE_LIBRTE_PMD_PCAP),y)
 LDLIBS += -lrte_pmd_pcap -lpcap
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_PMD_BOND),y)
+LDLIBS += -lrte_pmd_bond
+endif
+
 endif
 
 LDLIBS += $(EXECENV_LDLIBS)
-- 
1.7.0.7

  parent reply	other threads:[~2014-06-27 10:18 UTC|newest]

Thread overview: 127+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-28 15:32 [PATCH 0/4] Link Bonding Library declan.doherty-ral2JQCrhuEAvxtiuMwx3w
     [not found] ` <cover.1401287412.git.declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-05-28 15:32   ` [PATCH 1/4] " declan.doherty-ral2JQCrhuEAvxtiuMwx3w
     [not found]     ` <4d8e6bc2665fbaac641f0577714d7be9b0415d3c.1401287412.git.declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-05-28 16:54       ` Shaw, Jeffrey B
     [not found]         ` <4032A54B6BB5F04B8C08B6CFF08C59285543C357-AtyAts71sc9Qxe9IK+vIArfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2014-05-29 13:32           ` Doherty, Declan
2014-05-28 15:32   ` [PATCH 2/4] Link bonding unit tests declan.doherty-ral2JQCrhuEAvxtiuMwx3w
2014-05-28 15:32   ` [PATCH 3/4] Link bonding integration into testpmd declan.doherty-ral2JQCrhuEAvxtiuMwx3w
2014-05-28 15:32   ` [PATCH 4/4] Add Link Bonding Library to Doxygen declan.doherty-ral2JQCrhuEAvxtiuMwx3w
2014-05-28 17:49   ` [PATCH 0/4] Link Bonding Library Neil Horman
     [not found]     ` <20140528174908.GB2648-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2014-05-29 10:33       ` Doherty, Declan
     [not found]         ` <345C63BAECC1AD42A2EC8C63AFFC3ADC13D3327C-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2014-05-29 11:33           ` Neil Horman
2014-05-29  3:23   ` Cao, Waterman
     [not found]     ` <AA3F441F262C58498CD6D0C1801DE7EB0AA89A63-0J0gbvR4kTggGBtAFL8yw7fspsVTdybXVpNB7YpNyf8@public.gmane.org>
2014-05-29 10:35       ` Doherty, Declan
2014-06-04 15:18   ` [PATCH v2 " declan.doherty-ral2JQCrhuEAvxtiuMwx3w
2014-06-04 15:18   ` declan.doherty-ral2JQCrhuEAvxtiuMwx3w
     [not found]   ` <cover.1401891670.git.declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-06-04 15:18     ` [PATCH v2 1/4] " declan.doherty-ral2JQCrhuEAvxtiuMwx3w
     [not found]       ` <e6e8ecba5e2ba9d1a0e5299e042e7c54757e8644.1401891670.git.declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-06-05 15:15         ` Stephen Hemminger
     [not found]           ` <20140605081557.42a797e8-We1ePj4FEcvRI77zikRAJc56i+j3xesD0e7PPNI6Mm0@public.gmane.org>
2014-06-06  9:07             ` Doherty, Declan
     [not found]               ` <345C63BAECC1AD42A2EC8C63AFFC3ADC13D3737A-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2014-06-06 15:13                 ` Stephen Hemminger
2014-06-09 21:11         ` Eric Kinzie
     [not found]           ` <20140609211054.GA4853-5G/Vjf02Nsf/9pzu0YdTqQ@public.gmane.org>
2014-06-13 14:03             ` Doherty, Declan
2014-06-04 15:18     ` [PATCH v2 2/4] Link bonding unit tests, including: - code to generate packet bursts for testing rx and tx functionality of bonded device - virtual/stubbed out ethdev for use as slave ethdev in testing - checkpack fixes declan.doherty-ral2JQCrhuEAvxtiuMwx3w
2014-06-04 15:18     ` [PATCH v2 1/4] Link Bonding Library declan.doherty-ral2JQCrhuEAvxtiuMwx3w
2014-06-04 15:18     ` [PATCH v2 2/4] Link bonding unit tests, including: - code to generate packet bursts for testing rx and tx functionality of bonded device - virtual/stubbed out ethdev for use as slave ethdev in testing - checkpack fixes declan.doherty-ral2JQCrhuEAvxtiuMwx3w
2014-06-04 15:18     ` [PATCH v2 3/4] Adding link bonding support to testpmd. - Includes the ability to create new bonded devices. - Add /remove bonding slave devices. - Interogate bonded device stats/configuration - Change bonding modes and select balance transmit polices declan.doherty-ral2JQCrhuEAvxtiuMwx3w
2014-06-04 15:18     ` [PATCH v2 4/4] Add Link Bonding Library to Doxygen declan.doherty-ral2JQCrhuEAvxtiuMwx3w
2014-06-04 16:10     ` [PATCH v2 0/4] Link Bonding Library Doherty, Declan
2014-06-05  8:03     ` De Lara Guarch, Pablo
2014-06-05 11:03     ` Neil Horman
     [not found]       ` <20140605110340.GB20841-B26myB8xz7F8NnZeBjwnZQMhkBWG/bsMQH7oEaQurus@public.gmane.org>
2014-06-06  8:23         ` Doherty, Declan
     [not found]           ` <345C63BAECC1AD42A2EC8C63AFFC3ADC13D37331-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2014-06-06 14:54             ` Neil Horman
     [not found]               ` <20140606145426.GA2543-B26myB8xz7F8NnZeBjwnZQMhkBWG/bsMQH7oEaQurus@public.gmane.org>
2014-06-13 14:56                 ` Doherty, Declan
     [not found]                   ` <345C63BAECC1AD42A2EC8C63AFFC3ADC13D38DBF-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2014-06-13 15:11                     ` Neil Horman
2014-06-06  3:26     ` Cao, Waterman
2014-06-11 16:33     ` Thomas Monjalon
2014-06-13 14:08       ` Doherty, Declan
     [not found]         ` <345C63BAECC1AD42A2EC8C63AFFC3ADC13D38CDE-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2014-06-13 15:15           ` Thomas Monjalon
2014-06-13 14:41   ` [PATCH v3 0/5] Link Bonding PMD Library Declan Doherty
     [not found]   ` <cover.1402662300.git.declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-06-13 14:41     ` [PATCH v3 1/5] " Declan Doherty
2014-06-13 14:41     ` [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes) Declan Doherty
     [not found]       ` <258914f35917ae07dddc991ac9726542964dce44.1402662300.git.declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-06-13 16:08         ` Neil Horman
     [not found]           ` <20140613160807.GD22451-B26myB8xz7F8NnZeBjwnZQMhkBWG/bsMQH7oEaQurus@public.gmane.org>
2014-06-13 18:34             ` Doherty, Declan
     [not found]               ` <345C63BAECC1AD42A2EC8C63AFFC3ADC13D38EE9-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2014-06-13 19:38                 ` Neil Horman
     [not found]                   ` <20140613193815.GE22451-B26myB8xz7F8NnZeBjwnZQMhkBWG/bsMQH7oEaQurus@public.gmane.org>
2014-06-16  8:59                     ` Doherty, Declan
     [not found]                       ` <345C63BAECC1AD42A2EC8C63AFFC3ADC13D39383-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2014-06-16 11:07                         ` Neil Horman
     [not found]                           ` <20140616110758.GA15165-B26myB8xz7F8NnZeBjwnZQMhkBWG/bsMQH7oEaQurus@public.gmane.org>
2014-06-16 16:17                             ` Richardson, Bruce
     [not found]                               ` <59AF69C657FD0841A61C55336867B5B01AA368CE-kPTMFJFq+rELt2AQoY/u9bfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2014-06-16 17:47                                 ` Neil Horman
     [not found]                                   ` <20140616174746.GC15165-B26myB8xz7F8NnZeBjwnZQMhkBWG/bsMQH7oEaQurus@public.gmane.org>
2014-06-16 18:07                                     ` Richardson, Bruce
2014-06-16 18:09                                     ` Thomas Monjalon
2014-06-13 21:59         ` Stephen Hemminger
     [not found]           ` <20140613145918.5faebfde-We1ePj4FEcvRI77zikRAJc56i+j3xesD0e7PPNI6Mm0@public.gmane.org>
2014-06-16  7:59             ` Doherty, Declan
2014-06-13 14:42     ` [PATCH v3 3/5] Link Bonding PMD Library (Unit Test Suite) Declan Doherty
2014-06-13 14:42     ` [PATCH v3 4/5] Link Bonding PMD Library (testpmd link bonding API support) Declan Doherty
2014-06-13 14:42     ` [PATCH v3 5/5] Link Bonding PMD Library (Doxygen Additions) Declan Doherty
2014-06-13 15:20     ` [PATCH v3 0/5] Link Bonding PMD Library Neil Horman
2014-06-16 11:18     ` [PATCH v4 0/6] Link Bonding Library Declan Doherty
     [not found]       ` <1402917513-19495-1-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-06-18 16:14         ` [PATCH v5 " Declan Doherty
     [not found]           ` <1403108063-27169-1-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-06-18 16:18             ` Neil Horman
2014-06-24 14:52             ` [PATCH v6 " Declan Doherty
     [not found]               ` <1403621531-30487-1-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-06-24 16:03                 ` [PATCH v7 " Declan Doherty
     [not found]                   ` <1403625828-20956-1-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-06-25 20:07                     ` [PATCH v8 " Declan Doherty
     [not found]                       ` <1403726868-8161-1-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-06-26 16:02                         ` De Lara Guarch, Pablo
2014-06-26 23:57                         ` [PATCH v9 0/5] link bonding Thomas Monjalon
     [not found]                           ` <1403827075-9192-1-git-send-email-thomas.monjalon-pdR9zngts4EAvxtiuMwx3w@public.gmane.org>
2014-06-26 23:57                             ` [PATCH v9 1/5] bond: new link bonding library Thomas Monjalon
     [not found]                               ` <1403827075-9192-2-git-send-email-thomas.monjalon-pdR9zngts4EAvxtiuMwx3w@public.gmane.org>
2014-06-27  0:45                                 ` Thomas Monjalon
2014-06-26 23:57                             ` [PATCH v9 2/5] ethdev: add unique name to devices Thomas Monjalon
2014-06-26 23:57                             ` [PATCH v9 3/5] eal: support link bonding device initialization Thomas Monjalon
2014-06-26 23:57                             ` [PATCH v9 4/5] bond: unit tests Thomas Monjalon
2014-06-26 23:57                             ` [PATCH v9 5/5] bond: testpmd support Thomas Monjalon
2014-06-27 10:18                             ` [PATCH v10 0/5] link bonding Declan Doherty
     [not found]                               ` <1403864324-12022-1-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-06-27 20:58                                 ` Thomas Monjalon
2014-06-29 17:49                                 ` [PATCH v11 0/5] link bonding library Declan Doherty
     [not found]                                   ` <1404064161-26370-1-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-06-30  9:21                                     ` Thomas Monjalon
2014-06-30  9:28                                       ` Doherty, Declan
     [not found]                                         ` <345C63BAECC1AD42A2EC8C63AFFC3ADC2730631F-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2014-07-01 22:01                                           ` Thomas Monjalon
2014-06-29 17:49                                 ` [PATCH v11 1/5] bond: new " Declan Doherty
     [not found]                                   ` <1404064161-26370-2-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-06-30  9:13                                     ` Thomas Monjalon
2014-06-30 22:29                                     ` Robert Sanford
     [not found]                                       ` <CA+cr1cojs0sx5s1ohwVcdT6ojQ_7PEwEAqmtCca0LAz_jkvVdw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-07-01 14:16                                         ` Thomas Monjalon
2014-07-01 14:19                                         ` Doherty, Declan
     [not found]                                           ` <345C63BAECC1AD42A2EC8C63AFFC3ADC273077A5-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2014-07-01 14:26                                             ` Thomas Monjalon
2014-06-29 17:49                                 ` [PATCH v11 2/5] ethdev: add unique name to devices Declan Doherty
2014-06-29 17:49                                 ` [PATCH v11 3/5] eal: support link bonding device initialization Declan Doherty
2014-06-29 17:49                                 ` [PATCH v11 4/5] bond: unit tests Declan Doherty
     [not found]                                   ` <1404064161-26370-5-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-06-30  8:56                                     ` Thomas Monjalon
2014-06-29 17:49                                 ` [PATCH v11 5/5] bond: testpmd support Declan Doherty
2014-06-27 10:18                             ` Declan Doherty [this message]
2014-06-27 10:18                             ` [PATCH v10 2/5] ethdev: add unique name to devices Declan Doherty
2014-06-27 10:18                             ` [PATCH v10 3/5] eal: support link bonding device initialization Declan Doherty
2014-06-27 10:18                             ` [PATCH v10 4/5] bond: unit tests Declan Doherty
2014-06-27 10:18                             ` [PATCH v10 5/5] bond: testpmd support Declan Doherty
2014-06-25 20:07                     ` [PATCH v8 1/6] Link Bonding Library (lib/librte_pmd_bond) Declan Doherty
2014-06-25 20:07                     ` [PATCH v8 2/6] Support for unique interface naming of pmds Declan Doherty
2014-06-25 20:07                     ` [PATCH v8 3/6] EAL support for link bonding device initialization Declan Doherty
2014-06-25 20:07                     ` [PATCH v8 4/6] Link bonding Unit Tests Declan Doherty
2014-06-25 20:07                     ` [PATCH v8 5/6] testpmd link bonding additions Declan Doherty
2014-06-25 20:07                     ` [PATCH v8 6/6] Link Bonding Library doxygen additions Declan Doherty
2014-06-24 16:03                 ` [PATCH v7 1/6] Link Bonding Library (lib/librte_pmd_bond) Declan Doherty
2014-06-24 16:03                 ` [PATCH v7 2/6] Support for unique interface naming of pmds Declan Doherty
2014-06-24 16:03                 ` [PATCH v7 3/6] EAL support for link bonding device initialization Declan Doherty
     [not found]                   ` <1403625828-20956-4-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-06-25 13:54                     ` Thomas Monjalon
2014-06-25 14:41                       ` Doherty, Declan
     [not found]                         ` <345C63BAECC1AD42A2EC8C63AFFC3ADC272FB41C-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2014-06-25 16:00                           ` Thomas Monjalon
2014-06-25 16:15                             ` Richardson, Bruce
2014-06-24 16:03                 ` [PATCH v7 4/6] Link bonding Unit Tests Declan Doherty
2014-06-24 16:03                 ` [PATCH v7 5/6] testpmd link bonding additions Declan Doherty
2014-06-24 16:03                 ` [PATCH v7 6/6] Link Bonding Library doxygen additions Declan Doherty
     [not found]                   ` <1403625828-20956-7-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-06-25 13:43                     ` Thomas Monjalon
2014-06-25 14:19                       ` Doherty, Declan
     [not found]                         ` <345C63BAECC1AD42A2EC8C63AFFC3ADC272FA3EA-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2014-06-25 14:23                           ` Thomas Monjalon
2014-06-24 14:52             ` [PATCH v6 1/6] Link Bonding Library (lib/librte_pmd_bond) Declan Doherty
2014-06-24 14:52             ` [PATCH v6 2/6] Support for unique interface naming of pmds Declan Doherty
2014-06-24 14:52             ` [PATCH v6 3/6] EAL support for link bonding device initialization Declan Doherty
2014-06-24 14:52             ` [PATCH v6 4/6] Link bonding Unit Tests Declan Doherty
2014-06-24 14:52             ` [PATCH v6 5/6] testpmd link bonding additions Declan Doherty
2014-06-24 14:52             ` [PATCH v6 6/6] Link Bonding Library doxygen additions Declan Doherty
2014-06-18 16:14         ` [PATCH v5 1/6] Link Bonding Library (lib/librte_pmd_bond) Declan Doherty
2014-06-18 16:14         ` [PATCH v5 2/6] Support for unique interface naming of pmds Declan Doherty
2014-06-18 16:14         ` [PATCH v5 3/6] EAL support for link bonding device initialization Declan Doherty
2014-06-18 16:14         ` [PATCH v5 4/6] Link bonding Unit Tests Declan Doherty
2014-06-18 16:14         ` [PATCH v5 5/6] testpmd link bonding additions Declan Doherty
2014-06-18 16:14         ` [PATCH v5 6/6] Link Bonding Library doxygen additions Declan Doherty
2014-06-16 11:18     ` [PATCH v4 1/6] Link Bonding Library (lib/librte_pmd_bond) initial release with support for Mode 0 - Round Robin Mode 1 - Active Backup Mode 2 - Balance -> Supports 3 transmit polices (layer 2, layer 2+3, la Mode 3 - Broadcast Declan Doherty
2014-06-16 11:18     ` [PATCH v4 2/6] Support for unique interface naming of pmds Declan Doherty
2014-06-16 11:18     ` [PATCH v4 3/6] EAL support for link bonding device initialization Declan Doherty
2014-06-16 11:18     ` [PATCH v4 4/6] Link bonding Unit Tests Declan Doherty
2014-06-16 11:18     ` [PATCH v4 5/6] testpmd link bonding additions Declan Doherty
2014-06-16 11:18     ` [PATCH v4 6/6] Link Bonding Library doxygen additions Declan Doherty

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=1403864324-12022-2-git-send-email-declan.doherty@intel.com \
    --to=declan.doherty-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.