[dpdk-dev,2/2] ethtool: add new library to provide ethtool-alike APIs

Message ID 1432946276-9424-3-git-send-email-liang-min.wang@intel.com (mailing list archive)
State Superseded, archived
Headers

Commit Message

Liang-Min Larry Wang May 30, 2015, 12:37 a.m. UTC
  adding a new library based upon ethdev APIs to provide API's that bear
the same functionality as ethtool_ops (linux/ethtool.h) and net_device_ops
(linux/netdevice.h).

Signed-off-by: Liang-Min Larry Wang <liang-min.wang@intel.com>
---
 MAINTAINERS                                |   4 +
 config/common_linuxapp                     |   5 +
 lib/Makefile                               |   1 +
 lib/librte_ethtool/Makefile                |  56 +++++++
 lib/librte_ethtool/rte_ethtool.c           | 155 +++++++++++++++++
 lib/librte_ethtool/rte_ethtool.h           | 257 +++++++++++++++++++++++++++++
 lib/librte_ethtool/rte_ethtool_version.map |  18 ++
 mk/rte.app.mk                              |   1 +
 8 files changed, 497 insertions(+)
 create mode 100644 lib/librte_ethtool/Makefile
 create mode 100644 lib/librte_ethtool/rte_ethtool.c
 create mode 100644 lib/librte_ethtool/rte_ethtool.h
 create mode 100644 lib/librte_ethtool/rte_ethtool_version.map
  

Comments

Stephen Hemminger May 30, 2015, 3:48 p.m. UTC | #1
On Fri, 29 May 2015 20:37:56 -0400
Liang-Min Larry Wang <liang-min.wang@intel.com> wrote:

> adding a new library based upon ethdev APIs to provide API's that bear
> the same functionality as ethtool_ops (linux/ethtool.h) and net_device_ops
> (linux/netdevice.h).

The API's for ethtool like things are valuable, but please contain
it more.

I think you should contain this to only those things which are in
the original Linux ethtool. Adding yet another layer that calls DPDK
for open/close/start stop just adds more layers with out providing any
value.

The ones I would keep:
	get_driverinfo
	get_link

The ones I would add:
	cmd - for speed/duplex negotiation
	eeprom - for eeprom access
	eee - for energy awareness
	coalesce - for packet coalescing
	ringparam - to allow changing ring parameters
              (existing rx config model is limiting)
	pauseparam - existing flow control in DPDK is mess
	gstrings/stats - map to XSTATS
	test - for  offline tests
	dump - for register dump
	features - control offload features
	perm_addr - base mac address
  
Liang-Min Larry Wang May 30, 2015, 4:16 p.m. UTC | #2
>On Fri, 29 May 2015 20:37:56 -0400
>Liang-Min Larry Wang <liang-min.wang@intel.com> wrote:
>
>> adding a new library based upon ethdev APIs to provide API's that bear 
>> the same functionality as ethtool_ops (linux/ethtool.h) and 
> >net_device_ops (linux/netdevice.h).

>The API's for ethtool like things are valuable, but please contain it more.
>
>I think you should contain this to only those things which are in the original Linux ethtool. Adding yet another layer that calls DPDK for open/close/start stop just adds more layers with out providing any value.
>
>The ones I would keep:
>	get_driverinfo
>	get_link
>
>The ones I would add:
>	cmd - for speed/duplex negotiation
>	eeprom - for eeprom access
>	eee - for energy awareness
>	coalesce - for packet coalescing
>	ringparam - to allow changing ring parameters
>              (existing rx config model is limiting)
>	pauseparam - existing flow control in DPDK is mess
>	gstrings/stats - map to XSTATS
>	test - for  offline tests
>	dump - for register dump
>	features - control offload features
>	perm_addr - base mac address

The design decision is to keep ethdev as THE interface for all the external API, so ethtool APIs are designed based upon ethdev API. At the meantime, the ethtool APIs are designed to enable users to migrate designs based upon kernel-space ethtool. The open/close/start are put in place to enable quick migration.

As for the suggestion, eeprom/ringparam/pauseparam/register-dump are on their way for latter release. For other ops, I will take the feedback for future planning.
  
Stephen Hemminger May 30, 2015, 7:26 p.m. UTC | #3
On Sat, 30 May 2015 16:16:01 +0000
"Wang, Liang-min" <liang-min.wang@intel.com> wrote:

> The design decision is to keep ethdev as THE interface for all the external API, so ethtool APIs are designed based upon ethdev API. At the meantime, the ethtool APIs are designed to enable users to migrate designs based upon kernel-space ethtool. The open/close/start are put in place to enable quick migration.

But there is no open/close/start in ethtool in kernel.
Anyway ethtool is currently on the disfavored list from kernel developers.
What about netlink or something better?

Remember each new API creates more long term compatiablity and ABI issues.
So I am against introducing any new API that does the same thing as existing API's.
  
Liang-Min Larry Wang May 30, 2015, 7:40 p.m. UTC | #4
On Sat, 30 May 2015 16:16:01 +0000
"Wang, Liang-min" <liang-min.wang@intel.com> wrote:

> >The design decision is to keep ethdev as THE interface for all the external API, so ethtool APIs are designed based upon ethdev API. At the meantime, the ethtool APIs are designed to enable users to migrate designs based upon kernel-space ethtool. The open/close/start are put in place to enable quick migration.
>
>But there is no open/close/start in ethtool in kernel.
>Anyway ethtool is currently on the disfavored list from kernel developers.
>What about netlink or something better?
>
>Remember each new API creates more long term compatiablity and ABI issues.
>So I am against introducing any new API that does the same thing as existing API's.

Just to clarify APIs supported by this ethtool api: there are net_open and net_stop and no net_start. Both functions are put in place to support net_device_ops::ndo_open and net_device_ops::ndo_close as defined in linux/netdevice.h
  
Stephen Hemminger May 31, 2015, 4:48 p.m. UTC | #5
On Sat, 30 May 2015 19:40:46 +0000
"Wang, Liang-min" <liang-min.wang@intel.com> wrote:

> 
> On Sat, 30 May 2015 16:16:01 +0000
> "Wang, Liang-min" <liang-min.wang@intel.com> wrote:
> 
> > >The design decision is to keep ethdev as THE interface for all the external API, so ethtool APIs are designed based upon ethdev API. At the meantime, the ethtool APIs are designed to enable users to migrate designs based upon kernel-space ethtool. The open/close/start are put in place to enable quick migration.
> >
> >But there is no open/close/start in ethtool in kernel.
> >Anyway ethtool is currently on the disfavored list from kernel developers.
> >What about netlink or something better?
> >
> >Remember each new API creates more long term compatiablity and ABI issues.
> >So I am against introducing any new API that does the same thing as existing API's.
> 
> Just to clarify APIs supported by this ethtool api: there are net_open and net_stop and no net_start. Both functions are put in place to support net_device_ops::ndo_open and net_device_ops::ndo_close as defined in linux/netdevice.h


I get the feeling there is some use case you are not telling the list about.
What kind of application would use this api only. Why or how would DPDK application
be involved in net_device_ops. If you are planning on putting DPDK in the kernel
there are lots of other issues including kernel ABI stability and licensing
that need to be dealt with.
  
Liang-Min Larry Wang May 31, 2015, 5:30 p.m. UTC | #6
>On Sat, 30 May 2015 19:40:46 +0000
>"Wang, Liang-min" <liang-min.wang@intel.com> wrote:
>
>> 
> >On Sat, 30 May 2015 16:16:01 +0000
> >"Wang, Liang-min" <liang-min.wang@intel.com> wrote:
> >
> >> >The design decision is to keep ethdev as THE interface for all the external API, so ethtool APIs are designed based upon ethdev API. At the meantime, the ethtool APIs are designed to enable users to migrate designs based upon kernel-space ethtool. The open/close/start are put in place to enable quick migration.
> >>
> >>But there is no open/close/start in ethtool in kernel.
> >>Anyway ethtool is currently on the disfavored list from kernel developers.
> >>What about netlink or something better?
> >>
> >>Remember each new API creates more long term compatiablity and ABI issues.
> >>So I am against introducing any new API that does the same thing as existing API's.
> >
>> Just to clarify APIs supported by this ethtool api: there are net_open 
> >and net_stop and no net_start. Both functions are put in place to 
> >support net_device_ops::ndo_open and net_device_ops::ndo_close as 
> >defined in linux/netdevice.h
>
>
>I get the feeling there is some use case you are not telling the list about.
>What kind of application would use this api only. Why or how would DPDK application be involved in net_device_ops. If you are planning on putting DPDK in the kernel there are lots of other issues >including kernel ABI stability and licensing that need to be dealt with.

(I'm manually adding ">" through my email, outlook, to make my reply. I apology if I make any mistake on adding ">" in wrong place)
No, we don't plan to put DPDK into kernel space, and this patch has nothing to do with bifurcated driver that was announced for DPDK 2.0 then got scrubbed (or deferred). In contrary, the entire ethtool API (more support is coming) is designed to assist applications that were designed based upon kernel ethtool to migrate into user-space driver based DPDK libraries. Being said that, as you are aware the kernel version of ndo_open/ndo_close is more than just start and stop device. The initial implementation is to provide minimum functionality (strip off all the kernel related state management). In the future release (we need comments like yours), we will continue make improvement. So this new API can be another alternative for applications to run device management.
  
Liang-Min Larry Wang May 31, 2015, 6:31 p.m. UTC | #7
>>On Sat, 30 May 2015 19:40:46 +0000
>>"Wang, Liang-min" <liang-min.wang@intel.com> wrote:
>>
>>> 
> >>On Sat, 30 May 2015 16:16:01 +0000
> >>"Wang, Liang-min" <liang-min.wang@intel.com> wrote:
> >>
> >> >>The design decision is to keep ethdev as THE interface for all the external API, so ethtool APIs are designed based upon ethdev API. At the meantime, the ethtool APIs are designed to enable users to migrate designs based upon kernel-space ethtool. The open/close/start are put in place to enable quick migration.
> >>>
> >>>But there is no open/close/start in ethtool in kernel.
> >>>Anyway ethtool is currently on the disfavored list from kernel developers.
> >>>What about netlink or something better?
> >>>
> >>>Remember each new API creates more long term compatiablity and ABI issues.
> >>>So I am against introducing any new API that does the same thing as existing API's.
> >>
>>> Just to clarify APIs supported by this ethtool api: there are 
>>> net_open
> >>and net_stop and no net_start. Both functions are put in place to 
> >>support net_device_ops::ndo_open and net_device_ops::ndo_close as 
> >>defined in linux/netdevice.h
>>
>>
>>I get the feeling there is some use case you are not telling the list about.
>>What kind of application would use this api only. Why or how would DPDK application be involved in net_device_ops. If you are planning on putting DPDK in the kernel there are lots of other issues >>including kernel ABI stability and licensing that need to be dealt with.
>
>(I'm manually adding ">" through my email, outlook, to make my reply. I apology if I make any mistake on adding ">" in wrong place) No, we don't plan to put DPDK into kernel space, and this patch has >nothing to do with bifurcated driver that was announced for DPDK 2.0 then got scrubbed (or deferred). In contrary, the entire ethtool API (more support is coming) is designed to assist applications that >were designed based upon kernel ethtool to migrate into user-space driver based DPDK libraries. Being said that, as you are aware the kernel version of ndo_open/ndo_close is more than just start and >stop device. The initial implementation is to provide minimum functionality (strip off all the kernel related state management). In the future release (we need comments like yours), we will continue >make improvement. So this new API can be another alternative for applications to run device management.

Just to clarify my last reply: when I said "... based upon kernel ethtool to migrate ...", I was referring to both ethtool and net_device_op.
  
David Harton June 1, 2015, 12:42 p.m. UTC | #8
Acked-by: David Harton (dharton) <dharton@cisco.com>

> -----Original Message-----
> From: Liang-Min Larry Wang [mailto:liang-min.wang@intel.com]
> Sent: Friday, May 29, 2015 8:38 PM
> To: dev@dpdk.org
> Cc: bruce.richardson@intel.com; konstantin.ananyev@intel.com; David Harton
> (dharton); Andrew Harvey (agh); Liang-Min Larry Wang
> Subject: [PATCH 2/2] ethtool: add new library to provide ethtool-alike
> APIs
> 
> adding a new library based upon ethdev APIs to provide API's that bear
> the same functionality as ethtool_ops (linux/ethtool.h) and net_device_ops
> (linux/netdevice.h).
> 
> Signed-off-by: Liang-Min Larry Wang <liang-min.wang@intel.com>
> ---
>  MAINTAINERS                                |   4 +
>  config/common_linuxapp                     |   5 +
>  lib/Makefile                               |   1 +
>  lib/librte_ethtool/Makefile                |  56 +++++++
>  lib/librte_ethtool/rte_ethtool.c           | 155 +++++++++++++++++
>  lib/librte_ethtool/rte_ethtool.h           | 257
> +++++++++++++++++++++++++++++
>  lib/librte_ethtool/rte_ethtool_version.map |  18 ++
>  mk/rte.app.mk                              |   1 +
>  8 files changed, 497 insertions(+)
>  create mode 100644 lib/librte_ethtool/Makefile
>  create mode 100644 lib/librte_ethtool/rte_ethtool.c
>  create mode 100644 lib/librte_ethtool/rte_ethtool.h
>  create mode 100644 lib/librte_ethtool/rte_ethtool_version.map
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 9362c19..b8b481f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -186,6 +186,10 @@ M: Thomas Monjalon <thomas.monjalon@6wind.com>
>  F: lib/librte_ether/
>  F: scripts/test-null.sh
> 
> +Ethtool API
> +M: Liang-Min Larry Wang <liang-min.wang@intel.com>
> +F: lib/librte_ethtool/
> +
> 
>  Drivers
>  -------
> diff --git a/config/common_linuxapp b/config/common_linuxapp
> index 0078dc9..f5759fd 100644
> --- a/config/common_linuxapp
> +++ b/config/common_linuxapp
> @@ -129,6 +129,11 @@ CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
>  CONFIG_RTE_LIBRTE_KVARGS=y
> 
>  #
> +# Compile user-space ethtool library
> +#
> +CONFIG_RTE_LIBRTE_ETHTOOL=y
> +
> +#
>  # Compile generic ethernet library
>  #
>  CONFIG_RTE_LIBRTE_ETHER=y
> diff --git a/lib/Makefile b/lib/Makefile
> index 5f480f9..a6c7375 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -41,6 +41,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += librte_timer
>  DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
>  DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
>  DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
> +DIRS-$(CONFIG_RTE_LIBRTE_ETHTOOL) += librte_ethtool
>  DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += librte_vhost
>  DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash
>  DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm
> diff --git a/lib/librte_ethtool/Makefile b/lib/librte_ethtool/Makefile
> new file mode 100644
> index 0000000..1d981f6
> --- /dev/null
> +++ b/lib/librte_ethtool/Makefile
> @@ -0,0 +1,56 @@
> +#   BSD LICENSE
> +#
> +#   Copyright(c) 2010-2015 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_ethtool.a
> +
> +CFLAGS += -O3
> +CFLAGS += $(WERROR_FLAGS)
> +
> +EXPORT_MAP := rte_ethtool_version.map
> +
> +LIBABIVER := 1
> +
> +SRCS-y += rte_ethtool.c
> +
> +#
> +# Export include files
> +#
> +SYMLINK-y-include += rte_ethtool.h
> +
> +# this lib depends upon:
> +DEPDIRS-y += lib/librte_ether
> +
> +include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/lib/librte_ethtool/rte_ethtool.c
> b/lib/librte_ethtool/rte_ethtool.c
> new file mode 100644
> index 0000000..2ccf06f
> --- /dev/null
> +++ b/lib/librte_ethtool/rte_ethtool.c
> @@ -0,0 +1,155 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2010-2015 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 <stdio.h>
> +#include <string.h>
> +#include <stdint.h>
> +#include <rte_version.h>
> +#include <rte_ethdev.h>
> +#include "rte_ethtool.h"
> +
> +int
> +rte_ethtool_get_drvinfo(uint8_t port_id, struct ethtool_drvinfo *drvinfo)
> +{
> +	struct rte_eth_dev_info dev_info;
> +
> +	memset(&dev_info, 0, sizeof(dev_info));
> +	rte_eth_dev_info_get(port_id, &dev_info);
> +
> +	snprintf(drvinfo->driver, sizeof(drvinfo->driver), "%s",
> +		dev_info.driver_name);
> +	snprintf(drvinfo->version, sizeof(drvinfo->version), "%s",
> +		rte_version());
> +	snprintf(drvinfo->bus_info, sizeof(drvinfo->bus_info),
> +		"%04x:%02x:%02x.%x",
> +		dev_info.pci_dev->addr.domain, dev_info.pci_dev->addr.bus,
> +		dev_info.pci_dev->addr.devid, dev_info.pci_dev-
> >addr.function);
> +
> +	drvinfo->n_stats = sizeof(struct rte_eth_stats) / sizeof(uint64_t);
> +	drvinfo->testinfo_len = 0;
> +
> +	return 0;
> +}
> +
> +int
> +rte_ethtool_get_link(uint8_t port_id)
> +{
> +	struct rte_eth_link link;
> +
> +	rte_eth_link_get(port_id, &link);
> +	return link.link_status;
> +}
> +
> +int
> +rte_ethtool_net_open(uint8_t port_id)
> +{
> +	rte_eth_dev_stop(port_id);
> +
> +	return rte_eth_dev_start(port_id);
> +}
> +
> +int
> +rte_ethtool_net_stop(uint8_t port_id)
> +{
> +	rte_eth_dev_stop(port_id);
> +
> +	return 0;
> +}
> +
> +int
> +rte_ethtool_net_get_mac_addr(uint8_t port_id, struct ether_addr *addr)
> +{
> +	rte_eth_macaddr_get(port_id, addr);
> +
> +	return 0;
> +}
> +
> +int
> +rte_ethtool_net_set_mac_addr(uint8_t port_id, struct ether_addr *addr)
> +{
> +	return rte_eth_dev_default_mac_addr_set(port_id, addr);
> +}
> +
> +int
> +rte_ethtool_net_validate_addr(uint8_t port_id __rte_unused,
> +	struct ether_addr *addr)
> +{
> +	return is_valid_assigned_ether_addr(addr);
> +}
> +
> +int
> +rte_ethtool_net_set_config(uint8_t port_id, void *config __rte_unused)
> +{
> +	struct rte_eth_link link;
> +
> +	memset(&link, 0, sizeof(link));
> +	rte_eth_link_get(port_id, &link);
> +	if (link.link_status == 1)
> +		return -EINVAL;
> +	return 0;
> +}
> +
> +int
> +rte_ethtool_net_change_mtu(uint8_t port_id, int mtu)
> +{
> +	return rte_eth_dev_set_mtu(port_id, (uint16_t)mtu);
> +}
> +
> +int
> +rte_ethtool_net_get_stats64(uint8_t port_id, struct rte_eth_stats *stats)
> +{
> +	return rte_eth_stats_get(port_id, stats);
> +}
> +
> +int
> +rte_ethtool_net_vlan_rx_add_vid(uint8_t port_id, uint16_t vid)
> +{
> +	return rte_eth_dev_vlan_filter(port_id, vid, 1);
> +}
> +
> +int
> +rte_ethtool_net_vlan_rx_kill_vid(uint8_t port_id, uint16_t vid)
> +{
> +	return rte_eth_dev_vlan_filter(port_id, vid, 0);
> +}
> +
> +int
> +rte_ethtool_net_set_rx_mode(uint8_t port_id __rte_unused)
> +{
> +	/*
> +	 * The set_rx_mode op is part of pmd driver start operation, and
> +	 * the ethdev api maintains software configuration parameters and
> under-
> +	 * line hardware states consistent, so no operation is needed for
> +	 * rte_ethtool_net_set_rx_mode().
> +	 */
> +	return 0;
> +}
> diff --git a/lib/librte_ethtool/rte_ethtool.h
> b/lib/librte_ethtool/rte_ethtool.h
> new file mode 100644
> index 0000000..cb68d94
> --- /dev/null
> +++ b/lib/librte_ethtool/rte_ethtool.h
> @@ -0,0 +1,257 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2010-2015 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_ETHTOOL_H_
> +#define _RTE_ETHTOOL_H_
> +
> +/*
> + * This new interface is designed to provide a user-space shim layer for
> + * Ethtool and Netdevice op API.
> + *
> + * rte_ethtool_get_driver:          ethtool_ops::get_driverinfo
> + * rte_ethtool_get_link:            ethtool_ops::get_link
> + *
> + * rte_ethtool_net_open:            net_device_ops::ndo_open
> + * rte_ethtool_net_stop:            net_device_ops::ndo_stop
> + * rte_ethtool_net_set_mac_addr:    net_device_ops::ndo_set_mac_address
> + * rte_ethtool_net_validate_addr:   net_device_ops::ndo_validate_addr
> + * rte_ethtool_net_set_config:      net_device_ops::ndo_set_config
> + * rte_ethtool_net_change_mtu:      net_device_ops::ndo_net_change_mtu
> + * rte_ethtool_net_get_stats64:     net_device_ops::ndo_get_stats64
> + * rte_ethtool_net_vlan_rx_add_vid  net_device_ops::ndo_vlan_rx_add_vid
> + * rte_ethtool_net_vlan_rx_kill_vid net_device_ops::ndo_vlan_rx_kill_vid
> + * rte_ethtool_net_set_rx_mode      net_device_ops::ndo_set_rx_mode
> + *
> + */
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <stdint.h>
> +#include <rte_ethdev.h>
> +#include <linux/ethtool.h>
> +
> +/**
> + * Retrieve the Ethernet device driver information according to
> attributes described by
> + * ethtool data structure, ethtool_drvinfo
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param drvinfo
> + *   A pointer to get driver information
> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - others depends on the specific operations implementation.
> + */
> +int rte_ethtool_get_drvinfo(uint8_t port_id, struct ethtool_drvinfo
> *drvinfo);
> +
> +/**
> + * Retrieve the Ethernet device link status
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @return
> + *   - (1) if link up.
> + *   - (0) if link down.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - others depends on the specific operations implementation.
> + */
> +int rte_ethtool_get_link(uint8_t port_id);
> +
> +/**
> + * Start the Ethernet device.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - others depends on the specific operations implementation.
> + */
> +int rte_ethtool_net_open(uint8_t port_id);
> +
> +/**
> + * Stop the Ethernet device.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - others depends on the specific operations implementation.
> + */
> +int rte_ethtool_net_stop(uint8_t port_id);
> +
> +/**
> + * Get the Ethernet device MAC address.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param addr
> + *	 MAC address of the Ethernet device.
> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - others depends on the specific operations implementation.
> + */
> +int rte_ethtool_net_get_mac_addr(uint8_t port_id, struct ether_addr
> *addr);
> +
> +/**
> + * Setting the Ethernet device MAC address.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param addr
> + *	 The new MAC addr.
> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - others depends on the specific operations implementation.
> + */
> +int rte_ethtool_net_set_mac_addr(uint8_t port_id, struct ether_addr
> *addr);
> +
> +/**
> + * Validate if the provided MAC address is valid unicast address
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param addr
> + *	 A pointer to a buffer (6-byte, 48bit) for the target MAC address
> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - others depends on the specific operations implementation.
> + */
> +int rte_ethtool_net_validate_addr(uint8_t port_id, struct ether_addr
> *addr);
> +
> +/**
> + * Setting the Ethernet device configuration.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param config
> + *	 A opintr to a configuration parameter.
> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - others depends on the specific operations implementation.
> + */
> +int rte_ethtool_net_set_config(uint8_t port_id, void *config);
> +
> +/**
> + * Setting the Ethernet device maximum Tx unit.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param mtu
> + *	 New MTU
> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - others depends on the specific operations implementation.
> + */
> +int rte_ethtool_net_change_mtu(uint8_t port_id, int mtu);
> +
> +/**
> + * Retrieve the Ethernet device traffic statistics
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param stats
> + *	 A pointer to struct rte_eth_stats for statistics parameters
> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - others depends on the specific operations implementation.
> + */
> +int rte_ethtool_net_get_stats64(uint8_t port_id, struct rte_eth_stats
> *stats);
> +
> +/**
> + * Update the Ethernet device VLAN filter with new vid
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param vid
> + *	 A new VLAN id
> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - others depends on the specific operations implementation.
> + */
> +int rte_ethtool_net_vlan_rx_add_vid(uint8_t port_id, uint16_t vid);
> +
> +/**
> + * Remove VLAN id from Ethernet device.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param vid
> + *	 A new VLAN id
> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - others depends on the specific operations implementation.
> + */
> +int rte_ethtool_net_vlan_rx_kill_vid(uint8_t port_id, uint16_t vid);
> +
> +/**
> + * Setting the Ethernet device rx mode.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - others depends on the specific operations implementation.
> + */
> +int rte_ethtool_net_set_rx_mode(uint8_t port_id);
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_ETHTOOL_H_ */
> diff --git a/lib/librte_ethtool/rte_ethtool_version.map
> b/lib/librte_ethtool/rte_ethtool_version.map
> new file mode 100644
> index 0000000..82fc0d3
> --- /dev/null
> +++ b/lib/librte_ethtool/rte_ethtool_version.map
> @@ -0,0 +1,18 @@
> +DPDK_2.0 {
> +	global:
> +
> +	rte_ethtool_net_open;
> +	rte_ethtool_net_stop;
> +	rte_ethtool_net_get_mac_addr;
> +	rte_ethtool_net_get_mac_addr;
> +	rte_ethtool_net_validate_addr;
> +	rte_ethtool_net_set_config;
> +	rte_ethtool_net_change_mtu;
> +	rte_ethtool_net_get_stats64;
> +	rte_ethtool_net_vlan_rx_add_vid;
> +	rte_ethtool_net_vlan_rx_kill_vid;
> +	rte_ethtool_get_drvinfo;
> +	rte_ethtool_get_link;
> +
> +	local: *;
> +};
> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
> index 1a2043a..86867a6 100644
> --- a/mk/rte.app.mk
> +++ b/mk/rte.app.mk
> @@ -105,6 +105,7 @@ ifeq ($(CONFIG_RTE_BUILD_COMBINE_LIBS),n)
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_KVARGS)         += -lrte_kvargs
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF)           += -lrte_mbuf
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_IP_FRAG)        += -lrte_ip_frag
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_ETHTOOL)        += -lrte_ethtool
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHER)          += -lethdev
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_MALLOC)         += -lrte_malloc
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
> --
> 2.1.4
  

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index 9362c19..b8b481f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -186,6 +186,10 @@  M: Thomas Monjalon <thomas.monjalon@6wind.com>
 F: lib/librte_ether/
 F: scripts/test-null.sh
 
+Ethtool API
+M: Liang-Min Larry Wang <liang-min.wang@intel.com>
+F: lib/librte_ethtool/
+
 
 Drivers
 -------
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 0078dc9..f5759fd 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -129,6 +129,11 @@  CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
 CONFIG_RTE_LIBRTE_KVARGS=y
 
 #
+# Compile user-space ethtool library
+#
+CONFIG_RTE_LIBRTE_ETHTOOL=y
+
+#
 # Compile generic ethernet library
 #
 CONFIG_RTE_LIBRTE_ETHER=y
diff --git a/lib/Makefile b/lib/Makefile
index 5f480f9..a6c7375 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -41,6 +41,7 @@  DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += librte_timer
 DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
 DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
+DIRS-$(CONFIG_RTE_LIBRTE_ETHTOOL) += librte_ethtool
 DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += librte_vhost
 DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash
 DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm
diff --git a/lib/librte_ethtool/Makefile b/lib/librte_ethtool/Makefile
new file mode 100644
index 0000000..1d981f6
--- /dev/null
+++ b/lib/librte_ethtool/Makefile
@@ -0,0 +1,56 @@ 
+#   BSD LICENSE
+#
+#   Copyright(c) 2010-2015 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_ethtool.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+EXPORT_MAP := rte_ethtool_version.map
+
+LIBABIVER := 1
+
+SRCS-y += rte_ethtool.c
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_ethtool.h
+
+# this lib depends upon:
+DEPDIRS-y += lib/librte_ether
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_ethtool/rte_ethtool.c b/lib/librte_ethtool/rte_ethtool.c
new file mode 100644
index 0000000..2ccf06f
--- /dev/null
+++ b/lib/librte_ethtool/rte_ethtool.c
@@ -0,0 +1,155 @@ 
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 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 <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <rte_version.h>
+#include <rte_ethdev.h>
+#include "rte_ethtool.h"
+
+int
+rte_ethtool_get_drvinfo(uint8_t port_id, struct ethtool_drvinfo *drvinfo)
+{
+	struct rte_eth_dev_info dev_info;
+
+	memset(&dev_info, 0, sizeof(dev_info));
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	snprintf(drvinfo->driver, sizeof(drvinfo->driver), "%s",
+		dev_info.driver_name);
+	snprintf(drvinfo->version, sizeof(drvinfo->version), "%s",
+		rte_version());
+	snprintf(drvinfo->bus_info, sizeof(drvinfo->bus_info),
+		"%04x:%02x:%02x.%x",
+		dev_info.pci_dev->addr.domain, dev_info.pci_dev->addr.bus,
+		dev_info.pci_dev->addr.devid, dev_info.pci_dev->addr.function);
+
+	drvinfo->n_stats = sizeof(struct rte_eth_stats) / sizeof(uint64_t);
+	drvinfo->testinfo_len = 0;
+
+	return 0;
+}
+
+int
+rte_ethtool_get_link(uint8_t port_id)
+{
+	struct rte_eth_link link;
+
+	rte_eth_link_get(port_id, &link);
+	return link.link_status;
+}
+
+int
+rte_ethtool_net_open(uint8_t port_id)
+{
+	rte_eth_dev_stop(port_id);
+
+	return rte_eth_dev_start(port_id);
+}
+
+int
+rte_ethtool_net_stop(uint8_t port_id)
+{
+	rte_eth_dev_stop(port_id);
+
+	return 0;
+}
+
+int
+rte_ethtool_net_get_mac_addr(uint8_t port_id, struct ether_addr *addr)
+{
+	rte_eth_macaddr_get(port_id, addr);
+
+	return 0;
+}
+
+int
+rte_ethtool_net_set_mac_addr(uint8_t port_id, struct ether_addr *addr)
+{
+	return rte_eth_dev_default_mac_addr_set(port_id, addr);
+}
+
+int
+rte_ethtool_net_validate_addr(uint8_t port_id __rte_unused,
+	struct ether_addr *addr)
+{
+	return is_valid_assigned_ether_addr(addr);
+}
+
+int
+rte_ethtool_net_set_config(uint8_t port_id, void *config __rte_unused)
+{
+	struct rte_eth_link link;
+
+	memset(&link, 0, sizeof(link));
+	rte_eth_link_get(port_id, &link);
+	if (link.link_status == 1)
+		return -EINVAL;
+	return 0;
+}
+
+int
+rte_ethtool_net_change_mtu(uint8_t port_id, int mtu)
+{
+	return rte_eth_dev_set_mtu(port_id, (uint16_t)mtu);
+}
+
+int
+rte_ethtool_net_get_stats64(uint8_t port_id, struct rte_eth_stats *stats)
+{
+	return rte_eth_stats_get(port_id, stats);
+}
+
+int
+rte_ethtool_net_vlan_rx_add_vid(uint8_t port_id, uint16_t vid)
+{
+	return rte_eth_dev_vlan_filter(port_id, vid, 1);
+}
+
+int
+rte_ethtool_net_vlan_rx_kill_vid(uint8_t port_id, uint16_t vid)
+{
+	return rte_eth_dev_vlan_filter(port_id, vid, 0);
+}
+
+int
+rte_ethtool_net_set_rx_mode(uint8_t port_id __rte_unused)
+{
+	/*
+	 * The set_rx_mode op is part of pmd driver start operation, and
+	 * the ethdev api maintains software configuration parameters and under-
+	 * line hardware states consistent, so no operation is needed for
+	 * rte_ethtool_net_set_rx_mode().
+	 */
+	return 0;
+}
diff --git a/lib/librte_ethtool/rte_ethtool.h b/lib/librte_ethtool/rte_ethtool.h
new file mode 100644
index 0000000..cb68d94
--- /dev/null
+++ b/lib/librte_ethtool/rte_ethtool.h
@@ -0,0 +1,257 @@ 
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 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_ETHTOOL_H_
+#define _RTE_ETHTOOL_H_
+
+/*
+ * This new interface is designed to provide a user-space shim layer for
+ * Ethtool and Netdevice op API.
+ *
+ * rte_ethtool_get_driver:          ethtool_ops::get_driverinfo
+ * rte_ethtool_get_link:            ethtool_ops::get_link
+ *
+ * rte_ethtool_net_open:            net_device_ops::ndo_open
+ * rte_ethtool_net_stop:            net_device_ops::ndo_stop
+ * rte_ethtool_net_set_mac_addr:    net_device_ops::ndo_set_mac_address
+ * rte_ethtool_net_validate_addr:   net_device_ops::ndo_validate_addr
+ * rte_ethtool_net_set_config:      net_device_ops::ndo_set_config
+ * rte_ethtool_net_change_mtu:      net_device_ops::ndo_net_change_mtu
+ * rte_ethtool_net_get_stats64:     net_device_ops::ndo_get_stats64
+ * rte_ethtool_net_vlan_rx_add_vid  net_device_ops::ndo_vlan_rx_add_vid
+ * rte_ethtool_net_vlan_rx_kill_vid net_device_ops::ndo_vlan_rx_kill_vid
+ * rte_ethtool_net_set_rx_mode      net_device_ops::ndo_set_rx_mode
+ *
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <rte_ethdev.h>
+#include <linux/ethtool.h>
+
+/**
+ * Retrieve the Ethernet device driver information according to attributes described by
+ * ethtool data structure, ethtool_drvinfo
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param drvinfo
+ *   A pointer to get driver information
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_get_drvinfo(uint8_t port_id, struct ethtool_drvinfo *drvinfo);
+
+/**
+ * Retrieve the Ethernet device link status
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @return
+ *   - (1) if link up.
+ *   - (0) if link down.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_get_link(uint8_t port_id);
+
+/**
+ * Start the Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_open(uint8_t port_id);
+
+/**
+ * Stop the Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_stop(uint8_t port_id);
+
+/**
+ * Get the Ethernet device MAC address.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param addr
+ *	 MAC address of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_get_mac_addr(uint8_t port_id, struct ether_addr *addr);
+
+/**
+ * Setting the Ethernet device MAC address.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param addr
+ *	 The new MAC addr.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_set_mac_addr(uint8_t port_id, struct ether_addr *addr);
+
+/**
+ * Validate if the provided MAC address is valid unicast address
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param addr
+ *	 A pointer to a buffer (6-byte, 48bit) for the target MAC address
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_validate_addr(uint8_t port_id, struct ether_addr *addr);
+
+/**
+ * Setting the Ethernet device configuration.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param config
+ *	 A opintr to a configuration parameter.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_set_config(uint8_t port_id, void *config);
+
+/**
+ * Setting the Ethernet device maximum Tx unit.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param mtu
+ *	 New MTU
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_change_mtu(uint8_t port_id, int mtu);
+
+/**
+ * Retrieve the Ethernet device traffic statistics
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param stats
+ *	 A pointer to struct rte_eth_stats for statistics parameters
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_get_stats64(uint8_t port_id, struct rte_eth_stats *stats);
+
+/**
+ * Update the Ethernet device VLAN filter with new vid
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param vid
+ *	 A new VLAN id
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_vlan_rx_add_vid(uint8_t port_id, uint16_t vid);
+
+/**
+ * Remove VLAN id from Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param vid
+ *	 A new VLAN id
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_vlan_rx_kill_vid(uint8_t port_id, uint16_t vid);
+
+/**
+ * Setting the Ethernet device rx mode.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_ethtool_net_set_rx_mode(uint8_t port_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_ETHTOOL_H_ */
diff --git a/lib/librte_ethtool/rte_ethtool_version.map b/lib/librte_ethtool/rte_ethtool_version.map
new file mode 100644
index 0000000..82fc0d3
--- /dev/null
+++ b/lib/librte_ethtool/rte_ethtool_version.map
@@ -0,0 +1,18 @@ 
+DPDK_2.0 {
+	global:
+
+	rte_ethtool_net_open;
+	rte_ethtool_net_stop;
+	rte_ethtool_net_get_mac_addr;
+	rte_ethtool_net_get_mac_addr;
+	rte_ethtool_net_validate_addr;
+	rte_ethtool_net_set_config;
+	rte_ethtool_net_change_mtu;
+	rte_ethtool_net_get_stats64;
+	rte_ethtool_net_vlan_rx_add_vid;
+	rte_ethtool_net_vlan_rx_kill_vid;
+	rte_ethtool_get_drvinfo;
+	rte_ethtool_get_link;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 1a2043a..86867a6 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -105,6 +105,7 @@  ifeq ($(CONFIG_RTE_BUILD_COMBINE_LIBS),n)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_KVARGS)         += -lrte_kvargs
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF)           += -lrte_mbuf
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IP_FRAG)        += -lrte_ip_frag
+_LDLIBS-$(CONFIG_RTE_LIBRTE_ETHTOOL)        += -lrte_ethtool
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHER)          += -lethdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MALLOC)         += -lrte_malloc
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool