All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] Kernel Control Path (KCP)
@ 2017-05-26 16:52 Ferruh Yigit
  2017-05-28 16:55 ` Wiles, Keith
                   ` (2 more replies)
  0 siblings, 3 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-05-26 16:52 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit

We are looking for re-sending [1] the Kernel Control Path (KCP)
with some updates [2].

Mainly this is an usability improvement for DPDK.

And a quick reminder about what KCP is:

"KCP is Linux virtual network interface that can control DPDK ports".

So DPDK interfaces, somehow will be visible and it will be possible to
use common Linux tools on DPDK interfaces.

This work can be done in multiple steps:

- At first step virtual interfaces can be read-only, and can be used
  to get stats / information from DPDK ports.

- Second step can be controlling the DPDK interfaces in a common way
  like Linux interfaces.

It is good to remind that KCP is only for control path, and no data
traffic will be available on those interfaces, meaning not able to use
tcpdump or similar tools on those interfaces.

I would like to hear about comments, requirements and objection about
the idea?

Also the name "Kernel Control Path" can be too broad, I am open to a
name change, any comments on naming is welcome.


[1]
http://dpdk.org/ml/archives/dev/2016-March/035139.html

[2]
Updates planned to the latest version sent:
- Create control interfaces without requiring an API call from user
  application, this will let DPDK applications have this support
  without any modification.
- Default enabled interfaces will be read-only.
- Possible rename.


Thanks,
ferruh


Ferruh Yigit (4):
  ethtool: move from sample folder to lib folder
  kcp: add kernel control path kernel module
  rte_ctrl_if: add control interface library
  ethdev: add control interface support

-- 
2.9.3

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [RFC] Kernel Control Path (KCP)
  2017-05-26 16:52 [RFC] Kernel Control Path (KCP) Ferruh Yigit
@ 2017-05-28 16:55 ` Wiles, Keith
  2017-05-29  9:26   ` Bruce Richardson
  2017-06-16 15:54   ` Ferruh Yigit
  2017-05-30 10:55 ` Thomas Monjalon
  2017-06-21 11:06 ` [PATCH v8 0/4] Userspace Network Control Interface (UNCI) Ferruh Yigit
  2 siblings, 2 replies; 91+ messages in thread
From: Wiles, Keith @ 2017-05-28 16:55 UTC (permalink / raw)
  To: Yigit, Ferruh; +Cc: DPDK, Walker, Benjamin


> On May 26, 2017, at 11:52 AM, Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> 
> We are looking for re-sending [1] the Kernel Control Path (KCP)
> with some updates [2].
> 
> Mainly this is an usability improvement for DPDK.
> 
> And a quick reminder about what KCP is:
> 
> "KCP is Linux virtual network interface that can control DPDK ports".
> 
> So DPDK interfaces, somehow will be visible and it will be possible to
> use common Linux tools on DPDK interfaces.
> 
> This work can be done in multiple steps:
> 
> - At first step virtual interfaces can be read-only, and can be used
>  to get stats / information from DPDK ports.
> 
> - Second step can be controlling the DPDK interfaces in a common way
>  like Linux interfaces.
> 
> It is good to remind that KCP is only for control path, and no data
> traffic will be available on those interfaces, meaning not able to use
> tcpdump or similar tools on those interfaces.
> 
> I would like to hear about comments, requirements and objection about
> the idea?
> 
> Also the name "Kernel Control Path" can be too broad, I am open to a
> name change, any comments on naming is welcome.

Using kernel in the name is not very useful, but netlink is the real part that makes sense.

How about one of these:
- DNI = DPDK Netlink Interface
- DNC = DPDK Netlink Control
- NCI = Netlink Control Interface

Being able to control DPDK interfaces via Netlink is one of the customer needs I have heard of late.

> 
> 
> [1]
> http://dpdk.org/ml/archives/dev/2016-March/035139.html
> 
> [2]
> Updates planned to the latest version sent:
> - Create control interfaces without requiring an API call from user
>  application, this will let DPDK applications have this support
>  without any modification.
> - Default enabled interfaces will be read-only.
> - Possible rename.
> 
> 
> Thanks,
> ferruh
> 
> 
> Ferruh Yigit (4):
>  ethtool: move from sample folder to lib folder
>  kcp: add kernel control path kernel module
>  rte_ctrl_if: add control interface library
>  ethdev: add control interface support
> 
> -- 
> 2.9.3
> 

Regards,
Keith

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [RFC] Kernel Control Path (KCP)
  2017-05-28 16:55 ` Wiles, Keith
@ 2017-05-29  9:26   ` Bruce Richardson
  2017-05-29 17:29     ` Wiles, Keith
  2017-06-16 15:54   ` Ferruh Yigit
  1 sibling, 1 reply; 91+ messages in thread
From: Bruce Richardson @ 2017-05-29  9:26 UTC (permalink / raw)
  To: Wiles, Keith; +Cc: Yigit, Ferruh, DPDK, Walker, Benjamin

On Sun, May 28, 2017 at 04:55:11PM +0000, Wiles, Keith wrote:
> 
> > On May 26, 2017, at 11:52 AM, Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> > 
> > We are looking for re-sending [1] the Kernel Control Path (KCP)
> > with some updates [2].
> > 
> > Mainly this is an usability improvement for DPDK.
> > 
> > And a quick reminder about what KCP is:
> > 
> > "KCP is Linux virtual network interface that can control DPDK ports".
> > 
> > So DPDK interfaces, somehow will be visible and it will be possible to
> > use common Linux tools on DPDK interfaces.
> > 
> > This work can be done in multiple steps:
> > 
> > - At first step virtual interfaces can be read-only, and can be used
> >  to get stats / information from DPDK ports.
> > 
> > - Second step can be controlling the DPDK interfaces in a common way
> >  like Linux interfaces.
> > 
> > It is good to remind that KCP is only for control path, and no data
> > traffic will be available on those interfaces, meaning not able to use
> > tcpdump or similar tools on those interfaces.
> > 
> > I would like to hear about comments, requirements and objection about
> > the idea?
> > 
> > Also the name "Kernel Control Path" can be too broad, I am open to a
> > name change, any comments on naming is welcome.
> 
> Using kernel in the name is not very useful, but netlink is the real part that makes sense.
> 
> How about one of these:
> - DNI = DPDK Netlink Interface
> - DNC = DPDK Netlink Control
> - NCI = Netlink Control Interface
> 
I like that last one, NCI. [It's also pronouncable as "nicky", too]

/Bruce

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [RFC] Kernel Control Path (KCP)
  2017-05-29  9:26   ` Bruce Richardson
@ 2017-05-29 17:29     ` Wiles, Keith
  0 siblings, 0 replies; 91+ messages in thread
From: Wiles, Keith @ 2017-05-29 17:29 UTC (permalink / raw)
  To: Richardson, Bruce; +Cc: Yigit, Ferruh, DPDK, Walker, Benjamin


On May 29, 2017, at 4:26 AM, Richardson, Bruce <bruce.richardson@intel.com<mailto:bruce.richardson@intel.com>> wrote:

On Sun, May 28, 2017 at 04:55:11PM +0000, Wiles, Keith wrote:

On May 26, 2017, at 11:52 AM, Ferruh Yigit <ferruh.yigit@intel.com<mailto:ferruh.yigit@intel.com>> wrote:

We are looking for re-sending [1] the Kernel Control Path (KCP)
with some updates [2].

Mainly this is an usability improvement for DPDK.

And a quick reminder about what KCP is:

"KCP is Linux virtual network interface that can control DPDK ports".

So DPDK interfaces, somehow will be visible and it will be possible to
use common Linux tools on DPDK interfaces.

This work can be done in multiple steps:

- At first step virtual interfaces can be read-only, and can be used
to get stats / information from DPDK ports.

- Second step can be controlling the DPDK interfaces in a common way
like Linux interfaces.

It is good to remind that KCP is only for control path, and no data
traffic will be available on those interfaces, meaning not able to use
tcpdump or similar tools on those interfaces.

I would like to hear about comments, requirements and objection about
the idea?

Also the name "Kernel Control Path" can be too broad, I am open to a
name change, any comments on naming is welcome.

Using kernel in the name is not very useful, but netlink is the real part that makes sense.

How about one of these:
- DNI = DPDK Netlink Interface
- DNC = DPDK Netlink Control
- NCI = Netlink Control Interface

I like that last one, NCI. [It's also pronouncable as "nicky", too]

Nice, one did not notice the name could be “nicky” :-)


/Bruce

Regards,
Keith


^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [RFC] Kernel Control Path (KCP)
  2017-05-26 16:52 [RFC] Kernel Control Path (KCP) Ferruh Yigit
  2017-05-28 16:55 ` Wiles, Keith
@ 2017-05-30 10:55 ` Thomas Monjalon
  2017-06-13 17:21   ` Ferruh Yigit
  2017-06-21 11:06 ` [PATCH v8 0/4] Userspace Network Control Interface (UNCI) Ferruh Yigit
  2 siblings, 1 reply; 91+ messages in thread
From: Thomas Monjalon @ 2017-05-30 10:55 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev

26/05/2017 18:52, Ferruh Yigit:
> We are looking for re-sending [1] the Kernel Control Path (KCP)
> with some updates [2].
> 
> Mainly this is an usability improvement for DPDK.
> 
> And a quick reminder about what KCP is:
> 
> "KCP is Linux virtual network interface that can control DPDK ports".
> 
> So DPDK interfaces, somehow will be visible and it will be possible to
> use common Linux tools on DPDK interfaces.

Reminder: the Mellanox PMDs live with their upstream kernel modules,
allowing such features.

The best model would be to have control path in kernel for every PMDs.

Anyway, do you think KCP (or NCI) could be upstreamed in any way?

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [RFC] Kernel Control Path (KCP)
  2017-05-30 10:55 ` Thomas Monjalon
@ 2017-06-13 17:21   ` Ferruh Yigit
  2017-06-13 18:00     ` Jay Rolette
  0 siblings, 1 reply; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-13 17:21 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

On 5/30/2017 11:55 AM, Thomas Monjalon wrote:
> 26/05/2017 18:52, Ferruh Yigit:
>> We are looking for re-sending [1] the Kernel Control Path (KCP)
>> with some updates [2].
>>
>> Mainly this is an usability improvement for DPDK.
>>
>> And a quick reminder about what KCP is:
>>
>> "KCP is Linux virtual network interface that can control DPDK ports".
>>
>> So DPDK interfaces, somehow will be visible and it will be possible to
>> use common Linux tools on DPDK interfaces.
> 
> Reminder: the Mellanox PMDs live with their upstream kernel modules,
> allowing such features.
> 
> The best model would be to have control path in kernel for every PMDs.

That is the intention with this feature.

> 
> Anyway, do you think KCP (or NCI) could be upstreamed in any way?

Unfortunately I believe the answer is same, it may not be possible to
upsteam this kernel module. Should this fact block the feature?

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [RFC] Kernel Control Path (KCP)
  2017-06-13 17:21   ` Ferruh Yigit
@ 2017-06-13 18:00     ` Jay Rolette
  2017-06-13 18:04       ` Dumitrescu, Cristian
  2017-06-13 18:17       ` Wiles, Keith
  0 siblings, 2 replies; 91+ messages in thread
From: Jay Rolette @ 2017-06-13 18:00 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: Thomas Monjalon, DPDK

On Tue, Jun 13, 2017 at 12:21 PM, Ferruh Yigit <ferruh.yigit@intel.com>
wrote:

> On 5/30/2017 11:55 AM, Thomas Monjalon wrote:
> > 26/05/2017 18:52, Ferruh Yigit:
> >> We are looking for re-sending [1] the Kernel Control Path (KCP)
> >> with some updates [2].
> >>
> >> Mainly this is an usability improvement for DPDK.
> >>
> >> And a quick reminder about what KCP is:
> >>
> >> "KCP is Linux virtual network interface that can control DPDK ports".
> >>
> >> So DPDK interfaces, somehow will be visible and it will be possible to
> >> use common Linux tools on DPDK interfaces.
> >
> > Reminder: the Mellanox PMDs live with their upstream kernel modules,
> > allowing such features.
> >
> > The best model would be to have control path in kernel for every PMDs.
>
> That is the intention with this feature.
>
> >
> > Anyway, do you think KCP (or NCI) could be upstreamed in any way?
>
> Unfortunately I believe the answer is same, it may not be possible to
> upsteam this kernel module. Should this fact block the feature?
>

Upstream is better, but KCP is a nice quality-of-life feature that I'd like
to see go in regardless. Anything that helps make DPDK less "foreign" to
normal port configuration and status tools is goodness.

Jay

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [RFC] Kernel Control Path (KCP)
  2017-06-13 18:00     ` Jay Rolette
@ 2017-06-13 18:04       ` Dumitrescu, Cristian
  2017-06-13 18:18         ` Wiles, Keith
  2017-06-13 18:17       ` Wiles, Keith
  1 sibling, 1 reply; 91+ messages in thread
From: Dumitrescu, Cristian @ 2017-06-13 18:04 UTC (permalink / raw)
  To: Jay Rolette, Yigit, Ferruh; +Cc: Thomas Monjalon, DPDK



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Jay Rolette
> Sent: Tuesday, June 13, 2017 7:00 PM
> To: Yigit, Ferruh <ferruh.yigit@intel.com>
> Cc: Thomas Monjalon <thomas@monjalon.net>; DPDK <dev@dpdk.org>
> Subject: Re: [dpdk-dev] [RFC] Kernel Control Path (KCP)
> 
> On Tue, Jun 13, 2017 at 12:21 PM, Ferruh Yigit <ferruh.yigit@intel.com>
> wrote:
> 
> > On 5/30/2017 11:55 AM, Thomas Monjalon wrote:
> > > 26/05/2017 18:52, Ferruh Yigit:
> > >> We are looking for re-sending [1] the Kernel Control Path (KCP)
> > >> with some updates [2].
> > >>
> > >> Mainly this is an usability improvement for DPDK.
> > >>
> > >> And a quick reminder about what KCP is:
> > >>
> > >> "KCP is Linux virtual network interface that can control DPDK ports".
> > >>
> > >> So DPDK interfaces, somehow will be visible and it will be possible to
> > >> use common Linux tools on DPDK interfaces.
> > >
> > > Reminder: the Mellanox PMDs live with their upstream kernel modules,
> > > allowing such features.
> > >
> > > The best model would be to have control path in kernel for every PMDs.
> >
> > That is the intention with this feature.
> >
> > >
> > > Anyway, do you think KCP (or NCI) could be upstreamed in any way?
> >
> > Unfortunately I believe the answer is same, it may not be possible to
> > upsteam this kernel module. Should this fact block the feature?
> >
> 
> Upstream is better, but KCP is a nice quality-of-life feature that I'd like
> to see go in regardless. Anything that helps make DPDK less "foreign" to
> normal port configuration and status tools is goodness.
> 
> Jay

+1

Let's not block this feature based on Linux kernel upstream reasons.

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [RFC] Kernel Control Path (KCP)
  2017-06-13 18:00     ` Jay Rolette
  2017-06-13 18:04       ` Dumitrescu, Cristian
@ 2017-06-13 18:17       ` Wiles, Keith
  1 sibling, 0 replies; 91+ messages in thread
From: Wiles, Keith @ 2017-06-13 18:17 UTC (permalink / raw)
  To: Jay Rolette; +Cc: Yigit, Ferruh, Thomas Monjalon, DPDK


> On Jun 13, 2017, at 1:00 PM, Jay Rolette <rolette@infinite.io> wrote:
> 
> On Tue, Jun 13, 2017 at 12:21 PM, Ferruh Yigit <ferruh.yigit@intel.com>
> wrote:
> 
>> On 5/30/2017 11:55 AM, Thomas Monjalon wrote:
>>> 26/05/2017 18:52, Ferruh Yigit:
>>>> We are looking for re-sending [1] the Kernel Control Path (KCP)
>>>> with some updates [2].
>>>> 
>>>> Mainly this is an usability improvement for DPDK.
>>>> 
>>>> And a quick reminder about what KCP is:
>>>> 
>>>> "KCP is Linux virtual network interface that can control DPDK ports".
>>>> 
>>>> So DPDK interfaces, somehow will be visible and it will be possible to
>>>> use common Linux tools on DPDK interfaces.
>>> 
>>> Reminder: the Mellanox PMDs live with their upstream kernel modules,
>>> allowing such features.
>>> 
>>> The best model would be to have control path in kernel for every PMDs.
>> 
>> That is the intention with this feature.
>> 
>>> 
>>> Anyway, do you think KCP (or NCI) could be upstreamed in any way?
>> 
>> Unfortunately I believe the answer is same, it may not be possible to
>> upsteam this kernel module. Should this fact block the feature?
>> 
> 
> Upstream is better, but KCP is a nice quality-of-life feature that I'd like
> to see go in regardless. Anything that helps make DPDK less "foreign" to
> normal port configuration and status tools is goodness.

+1

> 
> Jay

Regards,
Keith

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [RFC] Kernel Control Path (KCP)
  2017-06-13 18:04       ` Dumitrescu, Cristian
@ 2017-06-13 18:18         ` Wiles, Keith
  2017-06-15 12:07           ` Alex Rosenbaum
  0 siblings, 1 reply; 91+ messages in thread
From: Wiles, Keith @ 2017-06-13 18:18 UTC (permalink / raw)
  To: Dumitrescu, Cristian; +Cc: Jay Rolette, Yigit, Ferruh, Thomas Monjalon, DPDK


> On Jun 13, 2017, at 1:04 PM, Dumitrescu, Cristian <cristian.dumitrescu@intel.com> wrote:
> 
> 
> 
>> -----Original Message-----
>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Jay Rolette
>> Sent: Tuesday, June 13, 2017 7:00 PM
>> To: Yigit, Ferruh <ferruh.yigit@intel.com>
>> Cc: Thomas Monjalon <thomas@monjalon.net>; DPDK <dev@dpdk.org>
>> Subject: Re: [dpdk-dev] [RFC] Kernel Control Path (KCP)
>> 
>> On Tue, Jun 13, 2017 at 12:21 PM, Ferruh Yigit <ferruh.yigit@intel.com>
>> wrote:
>> 
>>> On 5/30/2017 11:55 AM, Thomas Monjalon wrote:
>>>> 26/05/2017 18:52, Ferruh Yigit:
>>>>> We are looking for re-sending [1] the Kernel Control Path (KCP)
>>>>> with some updates [2].
>>>>> 
>>>>> Mainly this is an usability improvement for DPDK.
>>>>> 
>>>>> And a quick reminder about what KCP is:
>>>>> 
>>>>> "KCP is Linux virtual network interface that can control DPDK ports".
>>>>> 
>>>>> So DPDK interfaces, somehow will be visible and it will be possible to
>>>>> use common Linux tools on DPDK interfaces.
>>>> 
>>>> Reminder: the Mellanox PMDs live with their upstream kernel modules,
>>>> allowing such features.
>>>> 
>>>> The best model would be to have control path in kernel for every PMDs.
>>> 
>>> That is the intention with this feature.
>>> 
>>>> 
>>>> Anyway, do you think KCP (or NCI) could be upstreamed in any way?
>>> 
>>> Unfortunately I believe the answer is same, it may not be possible to
>>> upsteam this kernel module. Should this fact block the feature?
>>> 
>> 
>> Upstream is better, but KCP is a nice quality-of-life feature that I'd like
>> to see go in regardless. Anything that helps make DPDK less "foreign" to
>> normal port configuration and status tools is goodness.
>> 
>> Jay
> 
> +1

+1

> 
> Let's not block this feature based on Linux kernel upstream reasons.

Regards,
Keith

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [RFC] Kernel Control Path (KCP)
  2017-06-13 18:18         ` Wiles, Keith
@ 2017-06-15 12:07           ` Alex Rosenbaum
  2017-06-16 15:27             ` Ferruh Yigit
  0 siblings, 1 reply; 91+ messages in thread
From: Alex Rosenbaum @ 2017-06-15 12:07 UTC (permalink / raw)
  To: Wiles, Keith
  Cc: Dumitrescu, Cristian, Jay Rolette, Yigit, Ferruh, Thomas Monjalon, DPDK

please excuse me if I missed out of the previous conversation and
asking these questions again...

Why create a new driver instead of improving the existing KNI driver?
Can you share a table of the differences between the two driver /
approaches [KNI vs KCP]?

Why do you want to remove features like data path that is provided by KNI today?

thanks,
Alex

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [RFC] Kernel Control Path (KCP)
  2017-06-15 12:07           ` Alex Rosenbaum
@ 2017-06-16 15:27             ` Ferruh Yigit
  2017-06-16 16:48               ` Stephen Hemminger
  0 siblings, 1 reply; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-16 15:27 UTC (permalink / raw)
  To: Alex Rosenbaum, Wiles, Keith
  Cc: Dumitrescu, Cristian, Jay Rolette, Thomas Monjalon, DPDK

Hi Alex,

On 6/15/2017 1:07 PM, Alex Rosenbaum wrote:
> please excuse me if I missed out of the previous conversation and
> asking these questions again...
> 
> Why create a new driver instead of improving the existing KNI driver?

For control path, KNI uses Linux kernel driver within KNI kernel module.
This method works, but may not be best option, and technically not
extendable for some drivers. KNI control path currently supports only
two drivers, proposed KCP works for all PMDs by default.

Overall, KCP is outcome of the effort of improving KNI control path.

Initial proposal was (a year ago I guess) introducing two new modules,
one for control path and one for data path, and replace KNI completely.
But current target is have KCP to have better control path support.

Also, KNI handles both data and control path. But both are different
functionalities and not need to be in some module. For example an
application may not need exception data path to kernel, but may be
interested in controlling DPDK interfaces via common Linux tools.

> Can you share a table of the differences between the two driver /
> approaches [KNI vs KCP]?

KCP differences against KNI:

- KCP is only for control path
- Linux virtual interfaces created automatically, without DPDK
application modification.
- To create/destroy interfaces KCP uses rtnl, KNI uses ioctl. So
technically it is possible to use "ip" tool to create / destroy
interfaces supported by KCP.
- KCP kernel module and userspace counterpart communicates via netlink,
KNI uses ioctl.
- KCP works for all PMDs without update on PMDs.

> 
> Why do you want to remove features like data path that is provided by KNI today?

There is not intention to remove exception data path, the focus is to
improve KNI.

> 
> thanks,
> Alex
> 

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [RFC] Kernel Control Path (KCP)
  2017-05-28 16:55 ` Wiles, Keith
  2017-05-29  9:26   ` Bruce Richardson
@ 2017-06-16 15:54   ` Ferruh Yigit
  2017-06-20 12:33     ` Ferruh Yigit
  1 sibling, 1 reply; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-16 15:54 UTC (permalink / raw)
  To: Wiles, Keith; +Cc: DPDK, Walker, Benjamin

On 5/28/2017 5:55 PM, Wiles, Keith wrote:
> 
>> On May 26, 2017, at 11:52 AM, Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>>
>> We are looking for re-sending [1] the Kernel Control Path (KCP)
>> with some updates [2].
>>
>> Mainly this is an usability improvement for DPDK.
>>
>> And a quick reminder about what KCP is:
>>
>> "KCP is Linux virtual network interface that can control DPDK ports".
>>
>> So DPDK interfaces, somehow will be visible and it will be possible to
>> use common Linux tools on DPDK interfaces.
>>
>> This work can be done in multiple steps:
>>
>> - At first step virtual interfaces can be read-only, and can be used
>>  to get stats / information from DPDK ports.
>>
>> - Second step can be controlling the DPDK interfaces in a common way
>>  like Linux interfaces.
>>
>> It is good to remind that KCP is only for control path, and no data
>> traffic will be available on those interfaces, meaning not able to use
>> tcpdump or similar tools on those interfaces.
>>
>> I would like to hear about comments, requirements and objection about
>> the idea?
>>
>> Also the name "Kernel Control Path" can be too broad, I am open to a
>> name change, any comments on naming is welcome.
> 
> Using kernel in the name is not very useful, but netlink is the real part that makes sense.
> 
> How about one of these:
> - DNI = DPDK Netlink Interface
> - DNC = DPDK Netlink Control
> - NCI = Netlink Control Interface
> 
> Being able to control DPDK interfaces via Netlink is one of the customer needs I have heard of late.

My concern is this name my create a miss understanding that DPDK is
providing a netlink interface for other applications that they can use
to control DPDK application / interfaces.

Here although netlink sockets used to communicate between kernel and
userspace, DPDK application connects to the netlink socket provided by
kernel module, and DPDK interfaces controlled using virtual Linux
network interfaces, independent from what kind of communication method
used between kernel and userspace.

> 
>>
>>
>> [1]
>> http://dpdk.org/ml/archives/dev/2016-March/035139.html
>>
>> [2]
>> Updates planned to the latest version sent:
>> - Create control interfaces without requiring an API call from user
>>  application, this will let DPDK applications have this support
>>  without any modification.
>> - Default enabled interfaces will be read-only.
>> - Possible rename.
>>
>>
>> Thanks,
>> ferruh
>>
>>
>> Ferruh Yigit (4):
>>  ethtool: move from sample folder to lib folder
>>  kcp: add kernel control path kernel module
>>  rte_ctrl_if: add control interface library
>>  ethdev: add control interface support
>>
>> -- 
>> 2.9.3
>>
> 
> Regards,
> Keith
> 

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [RFC] Kernel Control Path (KCP)
  2017-06-16 15:27             ` Ferruh Yigit
@ 2017-06-16 16:48               ` Stephen Hemminger
  0 siblings, 0 replies; 91+ messages in thread
From: Stephen Hemminger @ 2017-06-16 16:48 UTC (permalink / raw)
  To: Ferruh Yigit
  Cc: Alex Rosenbaum, Wiles, Keith, Dumitrescu, Cristian, Jay Rolette,
	Thomas Monjalon, DPDK

On Fri, 16 Jun 2017 16:27:47 +0100
Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> Hi Alex,
> 
> On 6/15/2017 1:07 PM, Alex Rosenbaum wrote:
> > please excuse me if I missed out of the previous conversation and
> > asking these questions again...
> > 
> > Why create a new driver instead of improving the existing KNI driver?  
> 
> For control path, KNI uses Linux kernel driver within KNI kernel module.
> This method works, but may not be best option, and technically not
> extendable for some drivers. KNI control path currently supports only
> two drivers, proposed KCP works for all PMDs by default.
> 
> Overall, KCP is outcome of the effort of improving KNI control path.
> 
> Initial proposal was (a year ago I guess) introducing two new modules,
> one for control path and one for data path, and replace KNI completely.
> But current target is have KCP to have better control path support.
> 
> Also, KNI handles both data and control path. But both are different
> functionalities and not need to be in some module. For example an
> application may not need exception data path to kernel, but may be
> interested in controlling DPDK interfaces via common Linux tools.
> 
> > Can you share a table of the differences between the two driver /
> > approaches [KNI vs KCP]?  
> 
> KCP differences against KNI:
> 
> - KCP is only for control path
> - Linux virtual interfaces created automatically, without DPDK
> application modification.
> - To create/destroy interfaces KCP uses rtnl, KNI uses ioctl. So
> technically it is possible to use "ip" tool to create / destroy
> interfaces supported by KCP.
> - KCP kernel module and userspace counterpart communicates via netlink,
> KNI uses ioctl.
> - KCP works for all PMDs without update on PMDs.
> 
> > 
> > Why do you want to remove features like data path that is provided by KNI today?  
> 
> There is not intention to remove exception data path, the focus is to
> improve KNI.
> 
> > 
> > thanks,
> > Alex
> >   
> 

Hopefully KCP can be submitted for upstream kernel, and therefore be supportable over
the long term. KNI in its current form is not acceptable upstream for a number
of reasons: style, use of ioctl, races with control operations, etc.

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [RFC] Kernel Control Path (KCP)
  2017-06-16 15:54   ` Ferruh Yigit
@ 2017-06-20 12:33     ` Ferruh Yigit
  0 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-20 12:33 UTC (permalink / raw)
  To: Wiles, Keith; +Cc: DPDK, Walker, Benjamin

On 6/16/2017 4:54 PM, Ferruh Yigit wrote:
> On 5/28/2017 5:55 PM, Wiles, Keith wrote:
>>
>>> On May 26, 2017, at 11:52 AM, Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>>>
>>> We are looking for re-sending [1] the Kernel Control Path (KCP)
>>> with some updates [2].
>>>
>>> Mainly this is an usability improvement for DPDK.
>>>
>>> And a quick reminder about what KCP is:
>>>
>>> "KCP is Linux virtual network interface that can control DPDK ports".
>>>
>>> So DPDK interfaces, somehow will be visible and it will be possible to
>>> use common Linux tools on DPDK interfaces.
>>>
>>> This work can be done in multiple steps:
>>>
>>> - At first step virtual interfaces can be read-only, and can be used
>>>  to get stats / information from DPDK ports.
>>>
>>> - Second step can be controlling the DPDK interfaces in a common way
>>>  like Linux interfaces.
>>>
>>> It is good to remind that KCP is only for control path, and no data
>>> traffic will be available on those interfaces, meaning not able to use
>>> tcpdump or similar tools on those interfaces.
>>>
>>> I would like to hear about comments, requirements and objection about
>>> the idea?
>>>
>>> Also the name "Kernel Control Path" can be too broad, I am open to a
>>> name change, any comments on naming is welcome.
>>
>> Using kernel in the name is not very useful, but netlink is the real part that makes sense.
>>
>> How about one of these:
>> - DNI = DPDK Netlink Interface
>> - DNC = DPDK Netlink Control
>> - NCI = Netlink Control Interface
>>
>> Being able to control DPDK interfaces via Netlink is one of the customer needs I have heard of late.
> 
> My concern is this name my create a miss understanding that DPDK is
> providing a netlink interface for other applications that they can use
> to control DPDK application / interfaces.
> 
> Here although netlink sockets used to communicate between kernel and
> userspace, DPDK application connects to the netlink socket provided by
> kernel module, and DPDK interfaces controlled using virtual Linux
> network interfaces, independent from what kind of communication method
> used between kernel and userspace.

what do you thinks about "Userspace Network Control Interface (UNCI)" ? [*]

I am for this one, if there is no objection.


[*]
Suggested by Tim O'Driscoll

> 
>>
>>>
>>>
>>> [1]
>>> http://dpdk.org/ml/archives/dev/2016-March/035139.html
>>>
>>> [2]
>>> Updates planned to the latest version sent:
>>> - Create control interfaces without requiring an API call from user
>>>  application, this will let DPDK applications have this support
>>>  without any modification.
>>> - Default enabled interfaces will be read-only.
>>> - Possible rename.
>>>
>>>
>>> Thanks,
>>> ferruh
>>>
>>>
>>> Ferruh Yigit (4):
>>>  ethtool: move from sample folder to lib folder
>>>  kcp: add kernel control path kernel module
>>>  rte_ctrl_if: add control interface library
>>>  ethdev: add control interface support
>>>
>>> -- 
>>> 2.9.3
>>>
>>
>> Regards,
>> Keith
>>
> 

^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCH v8 0/4] Userspace Network Control Interface (UNCI)
  2017-05-26 16:52 [RFC] Kernel Control Path (KCP) Ferruh Yigit
  2017-05-28 16:55 ` Wiles, Keith
  2017-05-30 10:55 ` Thomas Monjalon
@ 2017-06-21 11:06 ` Ferruh Yigit
  2017-06-21 11:06   ` [PATCH v8 1/4] ethtool: move from sample folder to lib folder Ferruh Yigit
                     ` (5 more replies)
  2 siblings, 6 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-21 11:06 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, anatoly.burakov, Bruce Richardson

Userspace Network Control Interface (UNCI), (formerly KCP).

When a NIC bound to the DPDK, it can't be controlled by Linux tools.

This patch creates a virtual network interface for each DPDK port,
initial target is to get some data from those interfaces, in next
step target is to control DPDK ports using virtual interfaces.

KNI control path already provides this capability and this work is
based on KNI, but current KNI only supports some devices and requires
application changes. UNCI is improved KNI control related part.

Control messages to the virtual interface moved to the underlying
PMD and response moved back to Linux:

  +-------+
  | dpdk0 |
  +---^---+
      |
      | netlink
      v
+-------------------+
| control interface |
+--------------+    |
+------------+ |    |
| ethtool lib| |    |
+------------+ +----+
+-------------------+
|      ethdev       |
+-------------------+
       |
  +---------+
  | Any PMD |
  +---------+


First patch in the set is moving DPDK ethtool library from sample
application folder to the lib. This library provides ethtool commands
on top of ethdev library.

Second patch introduces a control library, which gets some commands
via netlink and converts these into ethtool or ethdev APIs.
A background thread created to listen commands.

Third patch implements a kernel module, similar to KNI, which is a
simple virtual network driver with netlink communication capability.
This driver pass through all control commands to userspace via netlink.

Forth patch adds control interface create and destroy APIs for ethdev.
This will create Linux interfaces automatically if rte_unci  kernel
module is inserted. Will work as it is if module is not inserted.

The intension is to upstream the Linux kernel module, please provide
comments to make it ready for upstream.


Samples:

Run testpmd with no extra arguments: "testpmd -- -i"
If the rte_unci module inserted two new interfaces will show up:

$ ifconfig dpdk0 && ifconfig dpdk1
dpdk0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 90:e2:ba:0e:49:b8  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

dpdk1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 00:1b:21:76:fa:20  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

The MAC address information already get from actual HW.

(Interfaces are shown down by default)

When data transfer start in testpmd, stats updated accordingly:

$ ifconfig dpdk0 && ifconfig dpdk1
dpdk0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 90:e2:ba:0e:49:b8  txqueuelen 1000  (Ethernet)
        RX packets 9662125409  bytes 553368167417 (515.3 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 9605125821  bytes 518893560100 (483.2 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

dpdk1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 00:1b:21:76:fa:20  txqueuelen 1000  (Ethernet)
        RX packets 9605137856  bytes 552991297017 (515.0 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 9662138670  bytes 518732030928 (483.1 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Or able to get same data via ethtool:

$ ethtool -i dpdk0
driver: net_ixgbe
version: DPDK 17.08.0-rc0
firmware-version: 0x61bf0001
expansion-rom-version:
bus-info: 0000:08:00.0
supports-statistics: no
supports-test: no
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: no

$ ethtool -g dpdk0
Ring parameters for dpdk0:
Pre-set maximums:
RX:             4096
RX Mini:        0
RX Jumbo:       0
TX:             4096
Current hardware settings:
RX:             128
RX Mini:        0
RX Jumbo:       0
TX:             512


Ferruh Yigit (4):
  ethtool: move from sample folder to lib folder
  unci: add kernel control path kernel module
  rte_ctrl_if: add control interface library
  ethdev: add control interface support

 MAINTAINERS                                        |   5 +
 config/common_base                                 |  16 +
 config/common_linuxapp                             |   3 +
 doc/api/doxy-api-index.md                          |   4 +-
 doc/api/doxy-api.conf                              |   2 +
 doc/guides/prog_guide/ctrl_if_lib.rst              |  52 +++
 doc/guides/prog_guide/ethtool_lib.rst              |  62 ++++
 doc/guides/prog_guide/index.rst                    |   2 +
 doc/guides/rel_notes/release_17_08.rst             |  10 +
 doc/guides/sample_app_ug/ethtool.rst               |  36 +-
 examples/ethtool/Makefile                          |  24 +-
 examples/ethtool/{ethtool-app => }/ethapp.c        |   2 +-
 examples/ethtool/{ethtool-app => }/ethapp.h        |   2 +-
 examples/ethtool/{ethtool-app => }/main.c          |   0
 lib/Makefile                                       |   4 +
 lib/librte_ctrl_if/Makefile                        |  56 +++
 lib/librte_ctrl_if/rte_ctrl_ethtool.c              | 390 +++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_ethtool.h              |  54 +++
 lib/librte_ctrl_if/rte_ctrl_if.c                   | 347 ++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_if.h                   |  88 +++++
 lib/librte_ctrl_if/rte_ctrl_if_version.map         |  10 +
 lib/librte_ctrl_if/rte_nl.c                        | 291 +++++++++++++++
 lib/librte_ctrl_if/rte_nl.h                        |  48 +++
 lib/librte_eal/common/include/rte_log.h            |   1 +
 lib/librte_eal/linuxapp/Makefile                   |   4 +-
 lib/librte_eal/linuxapp/eal/Makefile               |   1 +
 .../eal/include/exec-env/rte_unci_common.h         | 109 ++++++
 lib/librte_eal/linuxapp/unci/Makefile              |  54 +++
 lib/librte_eal/linuxapp/unci/unci_dev.h            |  56 +++
 lib/librte_eal/linuxapp/unci/unci_ethtool.c        | 293 ++++++++++++++++
 lib/librte_eal/linuxapp/unci/unci_net.c            | 217 ++++++++++++
 lib/librte_eal/linuxapp/unci/unci_nl.c             | 220 ++++++++++++
 lib/librte_ether/rte_ethdev_pci.h                  |  15 +-
 .../ethtool/lib => lib/librte_ethtool}/Makefile    |  35 +-
 .../lib => lib/librte_ethtool}/rte_ethtool.c       |  12 -
 .../lib => lib/librte_ethtool}/rte_ethtool.h       |  59 ++--
 lib/librte_ethtool/rte_ethtool_version.map         |  28 ++
 mk/rte.app.mk                                      |   2 +
 38 files changed, 2504 insertions(+), 110 deletions(-)
 create mode 100644 doc/guides/prog_guide/ctrl_if_lib.rst
 create mode 100644 doc/guides/prog_guide/ethtool_lib.rst
 rename examples/ethtool/{ethtool-app => }/ethapp.c (99%)
 rename examples/ethtool/{ethtool-app => }/ethapp.h (96%)
 rename examples/ethtool/{ethtool-app => }/main.c (100%)
 create mode 100644 lib/librte_ctrl_if/Makefile
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_ethtool.c
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_ethtool.h
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.c
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.h
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if_version.map
 create mode 100644 lib/librte_ctrl_if/rte_nl.c
 create mode 100644 lib/librte_ctrl_if/rte_nl.h
 create mode 100644 lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h
 create mode 100644 lib/librte_eal/linuxapp/unci/Makefile
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_dev.h
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_ethtool.c
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_net.c
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_nl.c
 rename {examples/ethtool/lib => lib/librte_ethtool}/Makefile (74%)
 rename {examples/ethtool/lib => lib/librte_ethtool}/rte_ethtool.c (97%)
 rename {examples/ethtool/lib => lib/librte_ethtool}/rte_ethtool.h (91%)
 create mode 100644 lib/librte_ethtool/rte_ethtool_version.map

-- 
2.13.0

^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCH v8 1/4] ethtool: move from sample folder to lib folder
  2017-06-21 11:06 ` [PATCH v8 0/4] Userspace Network Control Interface (UNCI) Ferruh Yigit
@ 2017-06-21 11:06   ` Ferruh Yigit
  2017-06-26 11:02     ` Bruce Richardson
  2017-06-21 11:06   ` [PATCH v8 2/4] unci: add kernel control path kernel module Ferruh Yigit
                     ` (4 subsequent siblings)
  5 siblings, 1 reply; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-21 11:06 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, anatoly.burakov, Bruce Richardson

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
v7:
* rebase v17.08
---
 config/common_base                                 |  5 ++
 config/common_linuxapp                             |  1 +
 doc/api/doxy-api-index.md                          |  3 +-
 doc/api/doxy-api.conf                              |  1 +
 doc/guides/prog_guide/ethtool_lib.rst              | 62 ++++++++++++++++++++++
 doc/guides/prog_guide/index.rst                    |  1 +
 doc/guides/rel_notes/release_17_08.rst             |  1 +
 doc/guides/sample_app_ug/ethtool.rst               | 36 ++-----------
 examples/ethtool/Makefile                          | 24 +++++----
 examples/ethtool/{ethtool-app => }/ethapp.c        |  2 +-
 examples/ethtool/{ethtool-app => }/ethapp.h        |  2 +-
 examples/ethtool/{ethtool-app => }/main.c          |  0
 lib/Makefile                                       |  2 +
 .../ethtool/lib => lib/librte_ethtool}/Makefile    | 35 +++++-------
 .../lib => lib/librte_ethtool}/rte_ethtool.c       | 12 -----
 .../lib => lib/librte_ethtool}/rte_ethtool.h       | 59 ++++++++++----------
 lib/librte_ethtool/rte_ethtool_version.map         | 28 ++++++++++
 mk/rte.app.mk                                      |  1 +
 18 files changed, 167 insertions(+), 108 deletions(-)
 create mode 100644 doc/guides/prog_guide/ethtool_lib.rst
 rename examples/ethtool/{ethtool-app => }/ethapp.c (99%)
 rename examples/ethtool/{ethtool-app => }/ethapp.h (96%)
 rename examples/ethtool/{ethtool-app => }/main.c (100%)
 rename {examples/ethtool/lib => lib/librte_ethtool}/Makefile (74%)
 rename {examples/ethtool/lib => lib/librte_ethtool}/rte_ethtool.c (97%)
 rename {examples/ethtool/lib => lib/librte_ethtool}/rte_ethtool.h (91%)
 create mode 100644 lib/librte_ethtool/rte_ethtool_version.map

diff --git a/config/common_base b/config/common_base
index f6aafd17d..c767b1090 100644
--- a/config/common_base
+++ b/config/common_base
@@ -699,6 +699,11 @@ CONFIG_RTE_KNI_PREEMPT_DEFAULT=y
 CONFIG_RTE_LIBRTE_PDUMP=y
 
 #
+# Compile librte_ethtool
+#
+CONFIG_RTE_LIBRTE_ETHTOOL=n
+
+#
 # Compile vhost user library
 #
 CONFIG_RTE_LIBRTE_VHOST=n
diff --git a/config/common_linuxapp b/config/common_linuxapp
index b3cf41b01..33ed11b37 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -40,6 +40,7 @@ CONFIG_RTE_EAL_VFIO=y
 CONFIG_RTE_KNI_KMOD=y
 CONFIG_RTE_LIBRTE_KNI=y
 CONFIG_RTE_LIBRTE_PMD_KNI=y
+CONFIG_RTE_LIBRTE_ETHTOOL=y
 CONFIG_RTE_LIBRTE_VHOST=y
 CONFIG_RTE_LIBRTE_PMD_VHOST=y
 CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index f5f1f199f..71350849f 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -161,4 +161,5 @@ There are many libraries, so their headers may be grouped by topics:
   [device metrics]     (@ref rte_metrics.h),
   [bitrate statistics] (@ref rte_bitrate.h),
   [latency statistics] (@ref rte_latencystats.h),
-  [version]            (@ref rte_version.h)
+  [version]            (@ref rte_version.h),
+  [ethtool]            (@ref rte_ethtool.h)
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index ca9194fe0..b66e86541 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -45,6 +45,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           lib/librte_distributor \
                           lib/librte_efd \
                           lib/librte_ether \
+                          lib/librte_ethtool \
                           lib/librte_eventdev \
                           lib/librte_hash \
                           lib/librte_ip_frag \
diff --git a/doc/guides/prog_guide/ethtool_lib.rst b/doc/guides/prog_guide/ethtool_lib.rst
new file mode 100644
index 000000000..a667bcfe3
--- /dev/null
+++ b/doc/guides/prog_guide/ethtool_lib.rst
@@ -0,0 +1,62 @@
+..  BSD LICENSE
+    Copyright(c) 2017 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.
+
+.. _Ethtool_Library:
+
+Ethtool Library
+===============
+
+Ethtool interface
+-----------------
+
+The Ethtool interface is built as a separate library, and implements
+the following functions:
+
+- ``rte_ethtool_get_drvinfo()``
+- ``rte_ethtool_get_regs_len()``
+- ``rte_ethtool_get_regs()``
+- ``rte_ethtool_get_link()``
+- ``rte_ethtool_get_eeprom_len()``
+- ``rte_ethtool_get_eeprom()``
+- ``rte_ethtool_set_eeprom()``
+- ``rte_ethtool_get_pauseparam()``
+- ``rte_ethtool_set_pauseparam()``
+- ``rte_ethtool_net_open()``
+- ``rte_ethtool_net_stop()``
+- ``rte_ethtool_net_get_mac_addr()``
+- ``rte_ethtool_net_set_mac_addr()``
+- ``rte_ethtool_net_validate_addr()``
+- ``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_net_set_rx_mode()``
+- ``rte_ethtool_get_ringparam()``
+- ``rte_ethtool_set_ringparam()``
diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index ef5a02ad5..54f9538ea 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -54,6 +54,7 @@ Programmer's Guide
     reorder_lib
     ip_fragment_reassembly_lib
     pdump_lib
+    ethtool_lib
     multi_proc_support
     kernel_nic_interface
     thread_safety_dpdk_functions
diff --git a/doc/guides/rel_notes/release_17_08.rst b/doc/guides/rel_notes/release_17_08.rst
index 842f46f75..dbe1ee906 100644
--- a/doc/guides/rel_notes/release_17_08.rst
+++ b/doc/guides/rel_notes/release_17_08.rst
@@ -186,6 +186,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_distributor.so.1
      librte_eal.so.4
      librte_ethdev.so.6
+   + librte_ethtool.so.1
      librte_hash.so.2
      librte_ip_frag.so.1
      librte_jobstats.so.1
diff --git a/doc/guides/sample_app_ug/ethtool.rst b/doc/guides/sample_app_ug/ethtool.rst
index 67797954d..def48985d 100644
--- a/doc/guides/sample_app_ug/ethtool.rst
+++ b/doc/guides/sample_app_ug/ethtool.rst
@@ -1,6 +1,6 @@
 
 ..  BSD LICENSE
-    Copyright(c) 2015 Intel Corporation. All rights reserved.
+    Copyright(c) 2015-2017 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -71,7 +71,7 @@ The only available options are the standard ones for the EAL:
 
 .. code-block:: console
 
-    ./ethtool-app/ethtool-app/${RTE_TARGET}/ethtool [EAL options]
+    ./${RTE_TARGET}/ethtool [EAL options]
 
 Refer to the *DPDK Getting Started Guide* for general information on
 running applications and the Environment Abstraction Layer (EAL)
@@ -128,33 +128,5 @@ Ethtool Shell
 The foreground part of the Ethtool sample is a console-based
 interface that accepts commands as described in `using the
 application`_. Individual call-back functions handle the detail
-associated with each command, which make use of the functions
-defined in the `Ethtool interface`_ to the DPDK functions.
-
-Ethtool interface
------------------
-
-The Ethtool interface is built as a separate library, and implements
-the following functions:
-
-- ``rte_ethtool_get_drvinfo()``
-- ``rte_ethtool_get_regs_len()``
-- ``rte_ethtool_get_regs()``
-- ``rte_ethtool_get_link()``
-- ``rte_ethtool_get_eeprom_len()``
-- ``rte_ethtool_get_eeprom()``
-- ``rte_ethtool_set_eeprom()``
-- ``rte_ethtool_get_pauseparam()``
-- ``rte_ethtool_set_pauseparam()``
-- ``rte_ethtool_net_open()``
-- ``rte_ethtool_net_stop()``
-- ``rte_ethtool_net_get_mac_addr()``
-- ``rte_ethtool_net_set_mac_addr()``
-- ``rte_ethtool_net_validate_addr()``
-- ``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_net_set_rx_mode()``
-- ``rte_ethtool_get_ringparam()``
-- ``rte_ethtool_set_ringparam()``
+associated with each command, which make use of librte_ethtool
+library.
diff --git a/examples/ethtool/Makefile b/examples/ethtool/Makefile
index 30b42b70e..a774eace0 100644
--- a/examples/ethtool/Makefile
+++ b/examples/ethtool/Makefile
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2015 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -33,20 +33,22 @@ ifeq ($(RTE_SDK),)
 $(error "Please define RTE_SDK environment variable")
 endif
 
-# Default target, can be overwritten by command line or environment
+# Default target, can be overridden by command line or environment
 RTE_TARGET ?= x86_64-native-linuxapp-gcc
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
-$(info This application can only operate in a linuxapp environment, \
-please change the definition of the RTE_TARGET environment variable)
-else
+# binary name
+APP = ethtool
 
-DIRS-y += lib ethtool-app
-endif
+# all source are stored in SRCS-y
+SRCS-y := main.c ethapp.c
+
+#CFLAGS += -O3 -D_GNU_SOURCE -pthread -I$(SRCDIR)/../lib
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
 
-DEPDIRS-ethtool-app := lib
-DEPDIRS-lib := librte_eal librte_ether
+#LDLIBS += -L$(subst ethtool-app,lib,$(RTE_OUTPUT))/lib
+#LDLIBS += -lrte_ethtool
 
-include $(RTE_SDK)/mk/rte.extsubdir.mk
+include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/ethtool/ethtool-app/ethapp.c b/examples/ethtool/ethapp.c
similarity index 99%
rename from examples/ethtool/ethtool-app/ethapp.c
rename to examples/ethtool/ethapp.c
index 35269ea24..6eb593d94 100644
--- a/examples/ethtool/ethtool-app/ethapp.c
+++ b/examples/ethtool/ethapp.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2015 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2015-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
diff --git a/examples/ethtool/ethtool-app/ethapp.h b/examples/ethtool/ethapp.h
similarity index 96%
rename from examples/ethtool/ethtool-app/ethapp.h
rename to examples/ethtool/ethapp.h
index ba438eea8..667aae7fd 100644
--- a/examples/ethtool/ethtool-app/ethapp.h
+++ b/examples/ethtool/ethapp.h
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2015 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2015-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
diff --git a/examples/ethtool/ethtool-app/main.c b/examples/ethtool/main.c
similarity index 100%
rename from examples/ethtool/ethtool-app/main.c
rename to examples/ethtool/main.c
diff --git a/lib/Makefile b/lib/Makefile
index 07e1fd0c5..434237d6e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -106,6 +106,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += librte_reorder
 DEPDIRS-librte_reorder := librte_eal librte_mempool librte_mbuf
 DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += librte_pdump
 DEPDIRS-librte_pdump := librte_eal librte_mempool librte_mbuf librte_ether
+DIRS-$(CONFIG_RTE_LIBRTE_ETHTOOL) += librte_ethtool
+DEPDIRS-librte_ethtool := librte_eal librte_ether
 
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
diff --git a/examples/ethtool/lib/Makefile b/lib/librte_ethtool/Makefile
similarity index 74%
rename from examples/ethtool/lib/Makefile
rename to lib/librte_ethtool/Makefile
index 266babade..6d677f973 100644
--- a/examples/ethtool/lib/Makefile
+++ b/lib/librte_ethtool/Makefile
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2015 Intel Corporation. All rights reserved.
+#   Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -29,35 +29,26 @@
 #   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 #   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-ifeq ($(RTE_SDK),)
-$(error "Please define RTE_SDK environment variable")
-endif
-
-# Default target, can be overwritten by command line or environment
-RTE_TARGET ?= x86_64-native-linuxapp-gcc
-
 include $(RTE_SDK)/mk/rte.vars.mk
 
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
-$(error This application can only operate in a linuxapp environment, \
-please change the definition of the RTE_TARGET environment variable)
-endif
-
+#
 # library name
+#
 LIB = librte_ethtool.a
 
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+EXPORT_MAP := rte_ethtool_version.map
+
 LIBABIVER := 1
 
 # all source are stored in SRC-Y
 SRCS-y := rte_ethtool.c
 
-CFLAGS += -O3
-CFLAGS += $(WERROR_FLAGS)
-
-ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
-ifeq ($(CONFIG_RTE_LIBRTE_IXGBE_PMD),y)
-LDLIBS += -lrte_pmd_ixgbe
-endif
-endif
+#
+# Export include files
+#
+SYMLINK-y-include += rte_ethtool.h
 
-include $(RTE_SDK)/mk/rte.extlib.mk
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/examples/ethtool/lib/rte_ethtool.c b/lib/librte_ethtool/rte_ethtool.c
similarity index 97%
rename from examples/ethtool/lib/rte_ethtool.c
rename to lib/librte_ethtool/rte_ethtool.c
index fabfcb2ba..80121fe7a 100644
--- a/examples/ethtool/lib/rte_ethtool.c
+++ b/lib/librte_ethtool/rte_ethtool.c
@@ -36,9 +36,6 @@
 #include <rte_version.h>
 #include <rte_ethdev.h>
 #include <rte_ether.h>
-#ifdef RTE_LIBRTE_IXGBE_PMD
-#include <rte_pmd_ixgbe.h>
-#endif
 #include "rte_ethtool.h"
 
 #define PKTPOOL_SIZE 512
@@ -363,20 +360,11 @@ rte_ethtool_net_set_rx_mode(uint8_t port_id)
 {
 	uint16_t num_vfs;
 	struct rte_eth_dev_info dev_info;
-	uint16_t vf;
 
 	memset(&dev_info, 0, sizeof(dev_info));
 	rte_eth_dev_info_get(port_id, &dev_info);
 	num_vfs = dev_info.max_vfs;
 
-	/* Set VF vf_rx_mode, VF unsupport status is discard */
-	for (vf = 0; vf < num_vfs; vf++) {
-#ifdef RTE_LIBRTE_IXGBE_PMD
-		rte_pmd_ixgbe_set_vf_rxmode(port_id, vf,
-			ETH_VMDQ_ACCEPT_UNTAG, 0);
-#endif
-	}
-
 	/* Enable Rx vlan filter, VF unspport status is discard */
 	rte_eth_dev_set_vlan_offload(port_id, ETH_VLAN_FILTER_MASK);
 
diff --git a/examples/ethtool/lib/rte_ethtool.h b/lib/librte_ethtool/rte_ethtool.h
similarity index 91%
rename from examples/ethtool/lib/rte_ethtool.h
rename to lib/librte_ethtool/rte_ethtool.h
index 18f44404b..9f4d069b6 100644
--- a/examples/ethtool/lib/rte_ethtool.h
+++ b/lib/librte_ethtool/rte_ethtool.h
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -34,11 +34,13 @@
 #ifndef _RTE_ETHTOOL_H_
 #define _RTE_ETHTOOL_H_
 
-/*
+/**
+ * @file
+ *
  * 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_drvinfo:         ethtool_ops::get_driverinfo
  * rte_ethtool_get_link:            ethtool_ops::get_link
  * rte_ethtool_get_regs_len:        ethtool_ops::get_regs_len
  * rte_ethtool_get_regs:            ethtool_ops::get_regs
@@ -47,6 +49,8 @@
  * rte_ethtool_set_eeprom:          ethtool_ops::set_eeprom
  * rte_ethtool_get_pauseparam:      ethtool_ops::get_pauseparam
  * rte_ethtool_set_pauseparam:      ethtool_ops::set_pauseparam
+ * rte_ethtool_get_ringparam:       ethtool_ops::set_ringparam
+ * rte_ethtool_set_ringparam:       ethtool_ops::set_ringparam
  *
  * rte_ethtool_net_open:            net_device_ops::ndo_open
  * rte_ethtool_net_stop:            net_device_ops::ndo_stop
@@ -101,7 +105,7 @@ int rte_ethtool_get_regs_len(uint8_t port_id);
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
- * @param reg
+ * @param regs
  *   A pointer to ethtool_regs that has register information
  * @param data
  *   A pointer to a buffer that is used to retrieve device register content
@@ -112,7 +116,7 @@ int rte_ethtool_get_regs_len(uint8_t port_id);
  *   - others depends on the specific operations implementation.
  */
 int rte_ethtool_get_regs(uint8_t port_id, struct ethtool_regs *regs,
-			    void *data);
+		void *data);
 
 /**
  * Retrieve the Ethernet device link status
@@ -135,7 +139,7 @@ int rte_ethtool_get_link(uint8_t port_id);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @return
- *	 - (> 0) device EEPROM size in bytes
+ *   - (> 0) device EEPROM size in bytes
  *   - (0) device has NO EEPROM
  *   - (-ENOTSUP) if hardware doesn't support.
  *   - (-ENODEV) if *port_id* invalid.
@@ -150,9 +154,9 @@ int rte_ethtool_get_eeprom_len(uint8_t port_id);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param eeprom
- *	 The pointer of ethtool_eeprom that provides eeprom range
+ *   The pointer of ethtool_eeprom that provides eeprom range
  * @param words
- *	 A buffer that holds data read from eeprom
+ *   A buffer that holds data read from eeprom
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -160,7 +164,7 @@ int rte_ethtool_get_eeprom_len(uint8_t port_id);
  *   - others depends on the specific operations implementation.
  */
 int rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
-			      void *words);
+		void *words);
 
 /**
  * Setting EEPROM content based upon eeprom range described in ethtool
@@ -169,9 +173,9 @@ int rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param eeprom
- *	 The pointer of ethtool_eeprom that provides eeprom range
+ *   The pointer of ethtool_eeprom that provides eeprom range
  * @param words
- *	 A buffer that holds data to be written into eeprom
+ *   A buffer that holds data to be written into eeprom
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -180,7 +184,7 @@ int rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
  *   - others depends on the specific operations implementation.
  */
 int rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
-			      void *words);
+		void *words);
 
 /**
  * Retrieve the Ethernet device pause frame configuration according to
@@ -190,8 +194,8 @@ int rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param pause_param
- *	 The pointer of ethtool_coalesce that gets pause frame
- *	 configuration parameters
+ *   The pointer of ethtool_coalesce that gets pause frame
+ *   configuration parameters
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -200,7 +204,7 @@ int rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
  *   - others depends on the specific operations implementation.
  */
 int rte_ethtool_get_pauseparam(uint8_t port_id,
-				   struct ethtool_pauseparam *pause_param);
+		struct ethtool_pauseparam *pause_param);
 
 /**
  * Setting the Ethernet device pause frame configuration according to
@@ -208,8 +212,8 @@ int rte_ethtool_get_pauseparam(uint8_t port_id,
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
- * @param pause_param
- *	 The pointer of ethtool_coalesce that gets ring configuration parameters
+ * @param param
+ *   The pointer of ethtool_coalesce that gets ring configuration parameters
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -218,7 +222,7 @@ int rte_ethtool_get_pauseparam(uint8_t port_id,
  *   - others depends on the specific operations implementation.
  */
 int rte_ethtool_set_pauseparam(uint8_t port_id,
-				   struct ethtool_pauseparam *param);
+		struct ethtool_pauseparam *param);
 
 /**
  * Start the Ethernet device.
@@ -250,7 +254,7 @@ int rte_ethtool_net_stop(uint8_t port_id);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param addr
- *	 MAC address of the Ethernet device.
+ *   MAC address of the Ethernet device.
  * @return
  *   - (0) if successful.
  *   - (-ENODEV) if *port_id* invalid.
@@ -263,7 +267,7 @@ int rte_ethtool_net_get_mac_addr(uint8_t port_id, struct ether_addr *addr);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param addr
- *	 The new MAC addr.
+ *   The new MAC addr.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -279,7 +283,7 @@ int rte_ethtool_net_set_mac_addr(uint8_t port_id, struct ether_addr *addr);
  * @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
+ *   A pointer to a buffer (6-byte, 48bit) for the target MAC address
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -295,7 +299,7 @@ int rte_ethtool_net_validate_addr(uint8_t port_id, struct ether_addr *addr);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param mtu
- *	 New MTU
+ *   New MTU
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -311,7 +315,7 @@ int rte_ethtool_net_change_mtu(uint8_t port_id, int mtu);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param stats
- *	 A pointer to struct rte_eth_stats for statistics parameters
+ *   A pointer to struct rte_eth_stats for statistics parameters
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -327,7 +331,7 @@ int rte_ethtool_net_get_stats64(uint8_t port_id, struct rte_eth_stats *stats);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param vid
- *	 A new VLAN id
+ *   A new VLAN id
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -342,7 +346,7 @@ int rte_ethtool_net_vlan_rx_add_vid(uint8_t port_id, uint16_t vid);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param vid
- *	 A new VLAN id
+ *   A new VLAN id
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -381,7 +385,7 @@ int rte_ethtool_net_set_rx_mode(uint8_t port_id);
  *   are used, and the function only gets parameters for queue 0.
  */
 int rte_ethtool_get_ringparam(uint8_t port_id,
-	struct ethtool_ringparam *ring_param);
+		struct ethtool_ringparam *ring_param);
 
 /**
  * Setting ring parameters for Ethernet device.
@@ -400,8 +404,7 @@ int rte_ethtool_get_ringparam(uint8_t port_id,
  *   are used, and the function only sets parameters for queue 0.
  */
 int rte_ethtool_set_ringparam(uint8_t port_id,
-	struct ethtool_ringparam *ring_param);
-
+		struct ethtool_ringparam *ring_param);
 
 #ifdef __cplusplus
 }
diff --git a/lib/librte_ethtool/rte_ethtool_version.map b/lib/librte_ethtool/rte_ethtool_version.map
new file mode 100644
index 000000000..a6e756c50
--- /dev/null
+++ b/lib/librte_ethtool/rte_ethtool_version.map
@@ -0,0 +1,28 @@
+DPDK_17.08 {
+	global:
+
+	rte_ethtool_get_drvinfo;
+	rte_ethtool_get_link;
+	rte_ethtool_get_regs_len;
+	rte_ethtool_get_regs;
+	rte_ethtool_get_eeprom_len;
+	rte_ethtool_get_eeprom;
+	rte_ethtool_set_eeprom;
+	rte_ethtool_get_pauseparam;
+	rte_ethtool_set_pauseparam;
+	rte_ethtool_get_ringparam;
+	rte_ethtool_set_ringparam;
+
+	rte_ethtool_net_open;
+	rte_ethtool_net_stop;
+	rte_ethtool_net_get_mac_addr;
+	rte_ethtool_net_set_mac_addr;
+	rte_ethtool_net_validate_addr;
+	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_net_set_rx_mode;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index bcaf1b382..449bd2f61 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -90,6 +90,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_KVARGS)         += -lrte_kvargs
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF)           += -lrte_mbuf
 _LDLIBS-$(CONFIG_RTE_LIBRTE_NET)            += -lrte_net
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHER)          += -lrte_ethdev
+_LDLIBS-$(CONFIG_RTE_LIBRTE_ETHTOOL)        += -lrte_ethtool
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CRYPTODEV)      += -lrte_cryptodev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV)       += -lrte_eventdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v8 2/4] unci: add kernel control path kernel module
  2017-06-21 11:06 ` [PATCH v8 0/4] Userspace Network Control Interface (UNCI) Ferruh Yigit
  2017-06-21 11:06   ` [PATCH v8 1/4] ethtool: move from sample folder to lib folder Ferruh Yigit
@ 2017-06-21 11:06   ` Ferruh Yigit
  2017-06-21 15:23     ` Stephen Hemminger
  2017-06-21 11:06   ` [PATCH v8 3/4] rte_ctrl_if: add control interface library Ferruh Yigit
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-21 11:06 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, anatoly.burakov, Bruce Richardson

This kernel module is based on KNI module, but this one is stripped
version of it and only for control messages, no data transfer
functionality provided.

This Linux kernel module helps userspace application create virtual
interfaces and when a control command issued into that virtual
interface, module pushes the command to the userspace and gets the
response back for the caller application.

The Linux tools like ethtool/ifconfig/ip can be used on virtual
interfaces but not ones for related data, like tcpdump.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---

v8:
* rename to usci

v7:
* rebase v17.08

v6:
* rebase v17.05

v5:
* Use unsigned primitive types as possible

v4:
* Remove logging helper macros, use pr_fmt
* Seperate log msg for timeout and error

v3:
* Devices are not up by default
* Add enable/disable promisc, allmulti support
* Increase timeout to 500ms and print log when a command timedout

v2:
* Use rtnetlink to create interfaces
* Fix ethtool get/set eeprom
* Remove commented out code
---
 MAINTAINERS                                        |   4 +
 config/common_base                                 |   6 +
 config/common_linuxapp                             |   1 +
 lib/librte_eal/linuxapp/Makefile                   |   4 +-
 lib/librte_eal/linuxapp/eal/Makefile               |   1 +
 .../eal/include/exec-env/rte_unci_common.h         | 109 ++++++++
 lib/librte_eal/linuxapp/unci/Makefile              |  54 ++++
 lib/librte_eal/linuxapp/unci/unci_dev.h            |  56 ++++
 lib/librte_eal/linuxapp/unci/unci_ethtool.c        | 293 +++++++++++++++++++++
 lib/librte_eal/linuxapp/unci/unci_net.c            | 217 +++++++++++++++
 lib/librte_eal/linuxapp/unci/unci_nl.c             | 220 ++++++++++++++++
 11 files changed, 964 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h
 create mode 100644 lib/librte_eal/linuxapp/unci/Makefile
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_dev.h
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_ethtool.c
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_net.c
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_nl.c

diff --git a/MAINTAINERS b/MAINTAINERS
index f6095efff..8d1fb0431 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -277,6 +277,10 @@ F: test/test/test_kni.c
 F: examples/kni/
 F: doc/guides/sample_app_ug/kernel_nic_interface.rst
 
+Linux Userspace Network Control Interface (UNCI)
+M: Ferruh Yigit <ferruh.yigit@intel.com>
+F: lib/librte_eal/linuxapp/unci/
+
 Linux AF_PACKET
 M: John W. Linville <linville@tuxdriver.com>
 F: drivers/net/af_packet/
diff --git a/config/common_base b/config/common_base
index c767b1090..f50ccc193 100644
--- a/config/common_base
+++ b/config/common_base
@@ -704,6 +704,12 @@ CONFIG_RTE_LIBRTE_PDUMP=y
 CONFIG_RTE_LIBRTE_ETHTOOL=n
 
 #
+# Compile Userspace Network Control Interface (UNCI) kernel module
+#
+CONFIG_RTE_UNCI_KMOD=n
+CONFIG_RTE_UNCI_KO_DEBUG=n
+
+#
 # Compile vhost user library
 #
 CONFIG_RTE_LIBRTE_VHOST=n
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 33ed11b37..4deab42c3 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -41,6 +41,7 @@ CONFIG_RTE_KNI_KMOD=y
 CONFIG_RTE_LIBRTE_KNI=y
 CONFIG_RTE_LIBRTE_PMD_KNI=y
 CONFIG_RTE_LIBRTE_ETHTOOL=y
+CONFIG_RTE_UNCI_KMOD=y
 CONFIG_RTE_LIBRTE_VHOST=y
 CONFIG_RTE_LIBRTE_PMD_VHOST=y
 CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
diff --git a/lib/librte_eal/linuxapp/Makefile b/lib/librte_eal/linuxapp/Makefile
index 4794696b6..2d293f1a6 100644
--- a/lib/librte_eal/linuxapp/Makefile
+++ b/lib/librte_eal/linuxapp/Makefile
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,8 @@ DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal
 DIRS-$(CONFIG_RTE_EAL_IGB_UIO) += igb_uio
 DIRS-$(CONFIG_RTE_KNI_KMOD) += kni
 DEPDIRS-kni := eal
+DIRS-$(CONFIG_RTE_UNCI_KMOD) += unci
+DEPDIRS-unci := eal
 DIRS-$(CONFIG_RTE_LIBRTE_XEN_DOM0) += xen_dom0
 DEPDIRS-xen_dom0 := eal
 
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 640afd088..401160bc9 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -127,6 +127,7 @@ CFLAGS_eal_thread.o += -Wno-return-type
 endif
 
 INC := rte_interrupts.h rte_kni_common.h rte_dom0_common.h
+INC += rte_unci_common.h
 
 SYMLINK-$(CONFIG_RTE_EXEC_ENV_LINUXAPP)-include/exec-env := \
 	$(addprefix include/exec-env/,$(INC))
diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h
new file mode 100644
index 000000000..a29805734
--- /dev/null
+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h
@@ -0,0 +1,109 @@
+/*-
+ *   This file is provided under a dual BSD/LGPLv2 license.  When using or
+ *   redistributing this file, you may do so under either license.
+ *
+ *   GNU LESSER GENERAL PUBLIC LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2.1 of the GNU Lesser General Public License
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this program;
+ *
+ *   Contact Information:
+ *   Intel Corporation
+ *
+ *
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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_UNCI_COMMON_H_
+#define _RTE_UNCI_COMMON_H_
+
+#define UNCI_DEVICE "unci"
+
+#define UNCI_NL_GRP 31
+
+#define UNCI_ETHTOOL_MSG_LEN 500
+struct unci_ethtool_msg {
+	uint32_t cmd_id;
+	uint8_t port_id;
+	uint32_t flag;
+	uint8_t input_buffer[UNCI_ETHTOOL_MSG_LEN];
+	uint8_t output_buffer[UNCI_ETHTOOL_MSG_LEN];
+	size_t input_buffer_len;
+	size_t output_buffer_len;
+	int err;
+};
+
+enum unci_ethtool_msg_flag {
+	UNCI_MSG_FLAG_NONE,
+	UNCI_MSG_FLAG_REQUEST,
+	UNCI_MSG_FLAG_RESPONSE,
+};
+
+enum {
+	IFLA_UNCI_UNSPEC,
+	IFLA_UNCI_PORTID,
+	IFLA_UNCI_PID,
+	__IFLA_UNCI_MAX,
+};
+
+#define IFLA_UNCI_MAX (__IFLA_UNCI_MAX - 1)
+
+/*
+ * Request id.
+ */
+enum rte_unci_req_id {
+	RTE_UNCI_REQ_UNKNOWN = (1 << 16),
+	RTE_UNCI_REQ_CHANGE_MTU,
+	RTE_UNCI_REQ_CFG_NETWORK_IF,
+	RTE_UNCI_REQ_GET_STATS,
+	RTE_UNCI_REQ_GET_MAC,
+	RTE_UNCI_REQ_SET_MAC,
+	RTE_UNCI_REQ_START_PORT,
+	RTE_UNCI_REQ_STOP_PORT,
+	RTE_UNCI_REQ_SET_PROMISC,
+	RTE_UNCI_REQ_SET_ALLMULTI,
+	RTE_UNCI_REQ_MAX,
+};
+
+#endif /* _RTE_UNCI_COMMON_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/Makefile b/lib/librte_eal/linuxapp/unci/Makefile
new file mode 100644
index 000000000..64f64b41f
--- /dev/null
+++ b/lib/librte_eal/linuxapp/unci/Makefile
@@ -0,0 +1,54 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2016 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
+
+#
+# module name and path
+#
+MODULE = rte_unci
+
+#
+# CFLAGS
+#
+MODULE_CFLAGS += -I$(SRCDIR)
+MODULE_CFLAGS += -I$(RTE_OUTPUT)/include
+MODULE_CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
+MODULE_CFLAGS += -Wall -Werror
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-y += unci_net.c
+SRCS-y += unci_ethtool.c
+SRCS-y += unci_nl.c
+
+include $(RTE_SDK)/mk/rte.module.mk
diff --git a/lib/librte_eal/linuxapp/unci/unci_dev.h b/lib/librte_eal/linuxapp/unci/unci_dev.h
new file mode 100644
index 000000000..d699f12d2
--- /dev/null
+++ b/lib/librte_eal/linuxapp/unci/unci_dev.h
@@ -0,0 +1,56 @@
+/*-
+ * GPL LICENSE SUMMARY
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;
+ *
+ *   The full GNU General Public License is included in this distribution
+ *   in the file called LICENSE.GPL.
+ *
+ *   Contact Information:
+ *   Intel Corporation
+ */
+
+#ifndef _UNCI_DEV_H_
+#define _UNCI_DEV_H_
+
+#include <linux/netdevice.h>
+#include <exec-env/rte_unci_common.h>
+
+#ifdef pr_fmt
+#undef pr_fmt
+#endif
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+struct unci_dev {
+	u8 port_id;
+	u32 pid;
+	struct completion msg_received;
+	u32 nb_timedout_msg;
+};
+
+void unci_nl_init(void);
+void unci_nl_release(void);
+int unci_nl_exec(u32 cmd, struct net_device *dev, void *in_data,
+		size_t in_len, void *out_data, size_t out_len);
+
+void unci_set_ethtool_ops(struct net_device *netdev);
+
+#ifdef RTE_UNCI_KO_DEBUG
+#define UNCI_DBG(args...) pr_debug(args)
+#else
+#define UNCI_DBG(args...)
+#endif
+
+#endif /* _UNCI_DEV_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/unci_ethtool.c b/lib/librte_eal/linuxapp/unci/unci_ethtool.c
new file mode 100644
index 000000000..035344559
--- /dev/null
+++ b/lib/librte_eal/linuxapp/unci/unci_ethtool.c
@@ -0,0 +1,293 @@
+/*-
+ * GPL LICENSE SUMMARY
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;
+ *
+ *   The full GNU General Public License is included in this distribution
+ *   in the file called LICENSE.GPL.
+ *
+ *   Contact Information:
+ *   Intel Corporation
+ */
+
+#include "unci_dev.h"
+
+#define ETHTOOL_GEEPROM_LEN 99
+#define ETHTOOL_GREGS_LEN 98
+#define ETHTOOL_GSSET_COUNT 97
+
+static int unci_check_if_running(struct net_device *dev)
+{
+	return 0;
+}
+
+static void unci_get_drvinfo(struct net_device *dev,
+		struct ethtool_drvinfo *info)
+{
+	int ret;
+
+	ret = unci_nl_exec(info->cmd, dev, NULL, 0,
+			info, sizeof(struct ethtool_drvinfo));
+	if (ret < 0)
+		memset(info, 0, sizeof(struct ethtool_drvinfo));
+}
+
+static int unci_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	return unci_nl_exec(ecmd->cmd, dev, NULL, 0,
+			ecmd, sizeof(struct ethtool_cmd));
+}
+
+static int unci_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	return unci_nl_exec(ecmd->cmd, dev, ecmd, sizeof(struct ethtool_cmd),
+			NULL, 0);
+}
+
+static void unci_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	int ret;
+
+	ret = unci_nl_exec(wol->cmd, dev, NULL, 0,
+			wol, sizeof(struct ethtool_wolinfo));
+	if (ret < 0)
+		memset(wol, 0, sizeof(struct ethtool_wolinfo));
+}
+
+static int unci_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	return unci_nl_exec(wol->cmd, dev, wol, sizeof(struct ethtool_wolinfo),
+			NULL, 0);
+}
+
+static int unci_nway_reset(struct net_device *dev)
+{
+	return unci_nl_exec(ETHTOOL_NWAY_RST, dev, NULL, 0, NULL, 0);
+}
+
+static u32 unci_get_link(struct net_device *dev)
+{
+	u32 data;
+	int ret;
+
+	ret = unci_nl_exec(ETHTOOL_GLINK, dev, NULL, 0, &data, sizeof(u32));
+	if (ret < 0)
+		return 0;
+
+	return data;
+}
+
+static int unci_get_eeprom_len(struct net_device *dev)
+{
+	int data;
+	int ret;
+
+	ret = unci_nl_exec(ETHTOOL_GEEPROM_LEN, dev, NULL, 0,
+			&data, sizeof(int));
+	if (ret < 0)
+		return 0;
+
+	return data;
+}
+
+static int unci_get_eeprom(struct net_device *dev,
+		struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct ethtool_eeprom eeprom_tmp;
+	int ret = 0;
+	int remaining;
+	u32 offset = 0;
+
+	eeprom_tmp = *eeprom;
+
+	remaining = eeprom_tmp.len;
+	while (remaining > 0 && ret == 0) {
+		eeprom_tmp.len = min(remaining, UNCI_ETHTOOL_MSG_LEN);
+
+		ret = unci_nl_exec(eeprom_tmp.cmd, dev,
+				&eeprom_tmp, sizeof(struct ethtool_eeprom),
+				data + offset, eeprom_tmp.len);
+		eeprom_tmp.offset += eeprom_tmp.len;
+		offset += eeprom_tmp.len;
+		remaining -= eeprom_tmp.len;
+	}
+
+	return ret;
+}
+
+static int unci_set_eeprom(struct net_device *dev,
+		struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct ethtool_eeprom *eeprom_tmp;
+	int ret = 0;
+	u32 remaining;
+	u32 offset = 0;
+	u32 payload;
+
+	if (sizeof(struct ethtool_eeprom) > UNCI_ETHTOOL_MSG_LEN)
+		return -1;
+
+	eeprom_tmp = kmalloc(UNCI_ETHTOOL_MSG_LEN, GFP_KERNEL);
+	payload = UNCI_ETHTOOL_MSG_LEN - sizeof(struct ethtool_eeprom);
+
+	*eeprom_tmp = *eeprom;
+	remaining = eeprom->len;
+
+	while (remaining > 0 && ret == 0) {
+		eeprom_tmp->len = min(remaining, payload);
+
+		memcpy(eeprom_tmp->data, data + offset, payload);
+
+		ret = unci_nl_exec(eeprom->cmd, dev, eeprom,
+				UNCI_ETHTOOL_MSG_LEN, NULL, 0);
+
+		eeprom_tmp->offset += eeprom_tmp->len;
+		offset += eeprom_tmp->len;
+		remaining -= eeprom_tmp->len;
+	}
+
+	kfree(eeprom_tmp);
+
+	return ret;
+}
+
+static void unci_get_ringparam(struct net_device *dev,
+		struct ethtool_ringparam *ring)
+{
+	unci_nl_exec(ring->cmd, dev, NULL, 0,
+			ring, sizeof(struct ethtool_ringparam));
+}
+
+static int unci_set_ringparam(struct net_device *dev,
+		struct ethtool_ringparam *ring)
+{
+	return unci_nl_exec(ring->cmd, dev, ring,
+			sizeof(struct ethtool_ringparam), NULL, 0);
+}
+
+static void unci_get_pauseparam(struct net_device *dev,
+		struct ethtool_pauseparam *pause)
+{
+	unci_nl_exec(pause->cmd, dev, NULL, 0,
+			pause, sizeof(struct ethtool_pauseparam));
+}
+
+static int unci_set_pauseparam(struct net_device *dev,
+		struct ethtool_pauseparam *pause)
+{
+	return unci_nl_exec(pause->cmd, dev, pause,
+			sizeof(struct ethtool_pauseparam), NULL, 0);
+}
+
+static u32 unci_get_msglevel(struct net_device *dev)
+{
+	u32 data;
+	int ret;
+
+	ret = unci_nl_exec(ETHTOOL_GMSGLVL, dev, NULL, 0, &data, sizeof(u32));
+	if (ret < 0)
+		return 0;
+
+	return data;
+}
+
+static void unci_set_msglevel(struct net_device *dev, u32 data)
+{
+	unci_nl_exec(ETHTOOL_SMSGLVL, dev, &data, sizeof(u32), NULL, 0);
+}
+
+static int unci_get_regs_len(struct net_device *dev)
+{
+	int data;
+	int ret;
+
+	ret = unci_nl_exec(ETHTOOL_GREGS_LEN, dev, NULL, 0, &data, sizeof(int));
+	if (ret < 0)
+		return 0;
+
+	return data;
+}
+
+static void unci_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+		void *p)
+{
+	struct ethtool_regs regs_tmp;
+	u32 len = regs->len;
+
+	regs_tmp = *regs;
+
+	if (len > UNCI_ETHTOOL_MSG_LEN) {
+		len = UNCI_ETHTOOL_MSG_LEN;
+		regs_tmp.len = len;
+	}
+
+	unci_nl_exec(regs->cmd, dev, &regs_tmp, sizeof(struct ethtool_regs),
+			p, len);
+}
+
+static void unci_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+	unci_nl_exec(ETHTOOL_GSTRINGS, dev, &stringset, sizeof(u32), data, 0);
+}
+
+static int unci_get_sset_count(struct net_device *dev, int sset)
+{
+	int data;
+	int ret;
+
+	ret = unci_nl_exec(ETHTOOL_GSSET_COUNT, dev, &sset, sizeof(int),
+			&data, sizeof(int));
+	if (ret < 0)
+		return 0;
+
+	return data;
+}
+
+static void unci_get_ethtool_stats(struct net_device *dev,
+		struct ethtool_stats *stats, u64 *data)
+{
+	unci_nl_exec(stats->cmd, dev, stats, sizeof(struct ethtool_stats),
+			data, stats->n_stats);
+}
+
+static const struct ethtool_ops unci_ethtool_ops = {
+	.begin			= unci_check_if_running,
+	.get_drvinfo		= unci_get_drvinfo,
+	.get_settings		= unci_get_settings,
+	.set_settings		= unci_set_settings,
+	.get_regs_len		= unci_get_regs_len,
+	.get_regs		= unci_get_regs,
+	.get_wol		= unci_get_wol,
+	.set_wol		= unci_set_wol,
+	.nway_reset		= unci_nway_reset,
+	.get_link		= unci_get_link,
+	.get_eeprom_len		= unci_get_eeprom_len,
+	.get_eeprom		= unci_get_eeprom,
+	.set_eeprom		= unci_set_eeprom,
+	.get_ringparam		= unci_get_ringparam,
+	.set_ringparam		= unci_set_ringparam,
+	.get_pauseparam		= unci_get_pauseparam,
+	.set_pauseparam		= unci_set_pauseparam,
+	.get_msglevel		= unci_get_msglevel,
+	.set_msglevel		= unci_set_msglevel,
+	.get_strings		= unci_get_strings,
+	.get_sset_count		= unci_get_sset_count,
+	.get_ethtool_stats	= unci_get_ethtool_stats,
+};
+
+void unci_set_ethtool_ops(struct net_device *netdev)
+{
+	netdev->ethtool_ops = &unci_ethtool_ops;
+}
diff --git a/lib/librte_eal/linuxapp/unci/unci_net.c b/lib/librte_eal/linuxapp/unci/unci_net.c
new file mode 100644
index 000000000..59dfd99f1
--- /dev/null
+++ b/lib/librte_eal/linuxapp/unci/unci_net.c
@@ -0,0 +1,217 @@
+/*-
+ * GPL LICENSE SUMMARY
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;
+ *
+ *   The full GNU General Public License is included in this distribution
+ *   in the file called LICENSE.GPL.
+ *
+ *   Contact Information:
+ *   Intel Corporation
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <net/rtnetlink.h>
+
+#include "unci_dev.h"
+
+static int unci_net_init(struct net_device *dev)
+{
+	u8 mac[ETH_ALEN] = {0};
+
+	unci_nl_exec(RTE_UNCI_REQ_GET_MAC, dev, NULL, 0, mac, ETH_ALEN);
+	memcpy(dev->dev_addr, mac, dev->addr_len);
+	return 0;
+}
+
+static int unci_net_open(struct net_device *dev)
+{
+	/* DPDK port already started, stop it first */
+	unci_nl_exec(RTE_UNCI_REQ_STOP_PORT, dev, NULL, 0, NULL, 0);
+	unci_nl_exec(RTE_UNCI_REQ_START_PORT, dev, NULL, 0, NULL, 0);
+	netif_start_queue(dev);
+	return 0;
+}
+
+static int unci_net_close(struct net_device *dev)
+{
+	unci_nl_exec(RTE_UNCI_REQ_STOP_PORT, dev, NULL, 0, NULL, 0);
+	netif_stop_queue(dev);
+	return 0;
+}
+
+static int unci_net_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
+}
+
+static void unci_net_change_rx_flags(struct net_device *dev, int flags)
+{
+	u32 on = 1;
+	u32 off = 0;
+
+	if (flags & IFF_PROMISC)
+		unci_nl_exec(RTE_UNCI_REQ_SET_PROMISC, dev,
+				dev->flags & IFF_PROMISC ?  &on : &off,
+				sizeof(u32), NULL, 0);
+
+	if (flags & IFF_ALLMULTI)
+		unci_nl_exec(RTE_UNCI_REQ_SET_ALLMULTI, dev,
+				dev->flags & IFF_ALLMULTI ?  &on : &off,
+				sizeof(u32), NULL, 0);
+}
+
+static int unci_net_set_mac(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr = p;
+	int err;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	err = unci_nl_exec(RTE_UNCI_REQ_SET_MAC, dev, addr->sa_data,
+			dev->addr_len, NULL, 0);
+	if (err < 0)
+		return -EADDRNOTAVAIL;
+
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	return 0;
+}
+
+static int unci_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	return -EOPNOTSUPP;
+}
+
+/*
+ * Configuration changes (passed on by ifconfig)
+ */
+static int unci_net_config(struct net_device *dev, struct ifmap *map)
+{
+	if (dev->flags & IFF_UP)
+		return -EBUSY;
+
+	return -EOPNOTSUPP;
+}
+
+static int unci_net_change_mtu(struct net_device *dev, int new_mtu)
+{
+	int err = 0;
+
+	err = unci_nl_exec(RTE_UNCI_REQ_CHANGE_MTU, dev, &new_mtu, sizeof(int),
+			NULL, 0);
+
+	if (err == 0)
+		dev->mtu = new_mtu;
+
+	return err;
+}
+
+static void unci_net_stats64(struct net_device *dev,
+		struct rtnl_link_stats64 *stats)
+{
+	int err;
+
+	err = unci_nl_exec(RTE_UNCI_REQ_GET_STATS, dev, NULL, 0,
+			stats, sizeof(struct rtnl_link_stats64));
+}
+
+#if (KERNEL_VERSION(3, 9, 0) <= LINUX_VERSION_CODE)
+static int unci_net_change_carrier(struct net_device *dev, bool new_carrier)
+{
+	if (new_carrier)
+		netif_carrier_on(dev);
+	else
+		netif_carrier_off(dev);
+	return 0;
+}
+#endif
+
+static const struct net_device_ops unci_net_netdev_ops = {
+	.ndo_init = unci_net_init,
+	.ndo_open = unci_net_open,
+	.ndo_stop = unci_net_close,
+	.ndo_start_xmit = unci_net_xmit,
+	.ndo_change_rx_flags = unci_net_change_rx_flags,
+	.ndo_set_mac_address = unci_net_set_mac,
+	.ndo_do_ioctl = unci_net_ioctl,
+	.ndo_set_config = unci_net_config,
+	.ndo_change_mtu = unci_net_change_mtu,
+	.ndo_get_stats64 = unci_net_stats64,
+#if (KERNEL_VERSION(3, 9, 0) <= LINUX_VERSION_CODE)
+	.ndo_change_carrier = unci_net_change_carrier,
+#endif
+};
+
+static void unci_net_setup(struct net_device *dev)
+{
+	struct unci_dev *unci;
+
+	ether_setup(dev);
+	dev->netdev_ops = &unci_net_netdev_ops;
+
+	unci = netdev_priv(dev);
+	init_completion(&unci->msg_received);
+
+	unci_set_ethtool_ops(dev);
+}
+
+static int unci_net_newlink(struct net *net, struct net_device *dev,
+		struct nlattr *tb[], struct nlattr *data[])
+{
+	struct unci_dev *unci = netdev_priv(dev);
+
+	if (data && data[IFLA_UNCI_PORTID])
+		unci->port_id = nla_get_u8(data[IFLA_UNCI_PORTID]);
+	else
+		unci->port_id = 0;
+
+	if (data && data[IFLA_UNCI_PID])
+		unci->pid = nla_get_u32(data[IFLA_UNCI_PID]);
+	else
+		unci->pid = 0;
+
+	return register_netdevice(dev);
+}
+
+static struct rtnl_link_ops unci_link_ops __read_mostly = {
+	.kind = UNCI_DEVICE,
+	.priv_size = sizeof(struct unci_dev),
+	.setup = unci_net_setup,
+	.maxtype = IFLA_UNCI_MAX,
+	.newlink = unci_net_newlink,
+};
+
+static int __init unci_init(void)
+{
+	unci_nl_init();
+	return rtnl_link_register(&unci_link_ops);
+}
+module_init(unci_init);
+
+static void __exit unci_exit(void)
+{
+	rtnl_link_unregister(&unci_link_ops);
+	unci_nl_release();
+}
+module_exit(unci_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Kernel Module for managing unci devices");
diff --git a/lib/librte_eal/linuxapp/unci/unci_nl.c b/lib/librte_eal/linuxapp/unci/unci_nl.c
new file mode 100644
index 000000000..68a7da5fc
--- /dev/null
+++ b/lib/librte_eal/linuxapp/unci/unci_nl.c
@@ -0,0 +1,220 @@
+/*-
+ * GPL LICENSE SUMMARY
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;
+ *   The full GNU General Public License is included in this distribution
+ *   in the file called LICENSE.GPL.
+ *
+ *   Contact Information:
+ *   Intel Corporation
+ */
+
+#include <net/sock.h>
+
+#include "unci_dev.h"
+
+#define UNCI_CMD_TIMEOUT 500 /* ms */
+
+static struct ethtool_input_buffer {
+	int magic;
+	void *buffer;
+	size_t length;
+	struct completion *msg_received;
+	int *err;
+	u32 in_use;
+} ethtool_input_buffer;
+
+static struct sock *nl_sock;
+static struct mutex sync_lock;
+
+static int unci_input_buffer_register(int magic, void *buffer, size_t length,
+		struct completion *msg_received, int *err)
+{
+	if (!ethtool_input_buffer.in_use) {
+		ethtool_input_buffer.magic = magic;
+		ethtool_input_buffer.buffer = buffer;
+		ethtool_input_buffer.length = length;
+		ethtool_input_buffer.msg_received = msg_received;
+		ethtool_input_buffer.err = err;
+		ethtool_input_buffer.in_use = 1;
+		return 0;
+	}
+
+	return 1;
+}
+
+static void unci_input_buffer_unregister(int magic)
+{
+	if (ethtool_input_buffer.in_use) {
+		if (magic == ethtool_input_buffer.magic) {
+			ethtool_input_buffer.magic = -1;
+			ethtool_input_buffer.buffer = NULL;
+			ethtool_input_buffer.length = 0;
+			ethtool_input_buffer.msg_received = NULL;
+			ethtool_input_buffer.err = NULL;
+			ethtool_input_buffer.in_use = 0;
+		} else {
+			pr_err("Unregister magic mismatch\n");
+		}
+	}
+}
+
+static void nl_recv_user_request(struct unci_ethtool_msg *ethtool_msg)
+{
+	UNCI_DBG("Request from userspace received\n");
+}
+
+static void nl_recv_user_response(struct unci_ethtool_msg *ethtool_msg)
+{
+	struct completion *msg_received;
+	size_t recv_len;
+	size_t expected_len;
+
+	if (ethtool_input_buffer.in_use) {
+		if (ethtool_input_buffer.buffer != NULL) {
+			recv_len = ethtool_msg->output_buffer_len;
+			expected_len = ethtool_input_buffer.length;
+
+			memcpy(ethtool_input_buffer.buffer,
+					ethtool_msg->output_buffer,
+					ethtool_input_buffer.length);
+
+			if (ethtool_msg->err == 0 && recv_len != expected_len)
+				pr_info("Expected and received len not match "
+					"%zu - %zu\n", recv_len, expected_len);
+		}
+
+		*ethtool_input_buffer.err = ethtool_msg->err;
+		msg_received = ethtool_input_buffer.msg_received;
+		unci_input_buffer_unregister(ethtool_input_buffer.magic);
+		complete(msg_received);
+	}
+}
+
+static void nl_recv(struct sk_buff *skb)
+{
+	struct nlmsghdr *nlh;
+	struct unci_ethtool_msg ethtool_msg;
+
+	nlh = (struct nlmsghdr *)skb->data;
+
+	memcpy(&ethtool_msg, NLMSG_DATA(nlh), sizeof(struct unci_ethtool_msg));
+	UNCI_DBG("CMD: %u\n", ethtool_msg.cmd_id);
+
+	if (ethtool_msg.flag & UNCI_MSG_FLAG_REQUEST) {
+		nl_recv_user_request(&ethtool_msg);
+		return;
+	}
+
+	nl_recv_user_response(&ethtool_msg);
+}
+
+static int unci_nl_send(u32 cmd_id, u8 port_id, u32 pid, void *in_data,
+		size_t in_data_len)
+{
+	struct sk_buff *skb;
+	struct nlmsghdr *nlh;
+	struct unci_ethtool_msg ethtool_msg;
+
+	if (pid == 0)
+		return -1;
+
+	memset(&ethtool_msg, 0, sizeof(struct unci_ethtool_msg));
+	ethtool_msg.cmd_id = cmd_id;
+	ethtool_msg.port_id = port_id;
+
+	if (in_data) {
+		if (in_data_len == 0 || in_data_len > UNCI_ETHTOOL_MSG_LEN)
+			return -EINVAL;
+		ethtool_msg.input_buffer_len = in_data_len;
+		memcpy(ethtool_msg.input_buffer, in_data, in_data_len);
+	}
+
+	skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct unci_ethtool_msg)),
+			GFP_ATOMIC);
+	nlh = nlmsg_put(skb, 0, 0, NLMSG_DONE, sizeof(struct unci_ethtool_msg),
+			0);
+
+	NETLINK_CB(skb).dst_group = 0;
+
+	memcpy(nlmsg_data(nlh), &ethtool_msg, sizeof(struct unci_ethtool_msg));
+
+	nlmsg_unicast(nl_sock, skb, pid);
+	UNCI_DBG("Sent cmd:%u port:%u pid:%u\n", cmd_id, port_id, pid);
+
+	return 0;
+}
+
+int unci_nl_exec(u32 cmd, struct net_device *dev, void *in_data,
+		size_t in_data_len, void *out_data, size_t out_data_len)
+{
+	struct unci_dev *unci = netdev_priv(dev);
+	int err = -EINVAL;
+	int ret;
+
+	if (out_data_len > UNCI_ETHTOOL_MSG_LEN) {
+		pr_err("Message is too big to receive:%zu\n", out_data_len);
+		return err;
+	}
+
+	mutex_lock(&sync_lock);
+	ret = unci_input_buffer_register(cmd, out_data, out_data_len,
+			&unci->msg_received, &err);
+	if (ret) {
+		mutex_unlock(&sync_lock);
+		return -EINVAL;
+	}
+
+	ret = unci_nl_send(cmd, unci->port_id, unci->pid, in_data, in_data_len);
+	if (ret) {
+		unci_input_buffer_unregister(ethtool_input_buffer.magic);
+		mutex_unlock(&sync_lock);
+		return ret;
+	}
+
+	ret = wait_for_completion_interruptible_timeout(&unci->msg_received,
+			 msecs_to_jiffies(UNCI_CMD_TIMEOUT));
+	if (ret == 0 || err < 0) {
+		unci_input_buffer_unregister(ethtool_input_buffer.magic);
+		mutex_unlock(&sync_lock);
+		if (ret == 0) { /* timeout */
+			unci->nb_timedout_msg++;
+			pr_info("Command timed-out for port:%u cmd:%u (%u)\n",
+				unci->port_id, cmd, unci->nb_timedout_msg);
+			return -EINVAL;
+		}
+		UNCI_DBG("Command return error for port:%d cmd:%d err:%d\n",
+				unci->port_id, cmd, err);
+		return err;
+	}
+	mutex_unlock(&sync_lock);
+
+	return 0;
+}
+
+static struct netlink_kernel_cfg cfg = {
+	.input = nl_recv,
+};
+
+void unci_nl_init(void)
+{
+	nl_sock = netlink_kernel_create(&init_net, UNCI_NL_GRP, &cfg);
+	mutex_init(&sync_lock);
+}
+
+void unci_nl_release(void)
+{
+	netlink_kernel_release(nl_sock);
+}
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v8 3/4] rte_ctrl_if: add control interface library
  2017-06-21 11:06 ` [PATCH v8 0/4] Userspace Network Control Interface (UNCI) Ferruh Yigit
  2017-06-21 11:06   ` [PATCH v8 1/4] ethtool: move from sample folder to lib folder Ferruh Yigit
  2017-06-21 11:06   ` [PATCH v8 2/4] unci: add kernel control path kernel module Ferruh Yigit
@ 2017-06-21 11:06   ` Ferruh Yigit
  2017-06-26 11:09     ` Bruce Richardson
  2017-06-26 11:30     ` Bruce Richardson
  2017-06-21 11:06   ` [PATCH v8 4/4] ethdev: add control interface support Ferruh Yigit
                     ` (2 subsequent siblings)
  5 siblings, 2 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-21 11:06 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, anatoly.burakov, Bruce Richardson

This library gets control messages form kernelspace and forwards them to
librte_ether and returns response back to the kernelspace.

Library does:
1) Trigger Linux virtual interface creation
2) Initialize the netlink socket communication
3) Provides process() API to the application that does processing the
received messages

This library requires corresponding kernel module to be inserted.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---

v8:
* rename kernel module to unci

v7:
* rebase v17.08

v6:
* rebase v17.05

v5:
* Use unsigned primitive types as possible

v4:
* Add ethtool_get_settings as dummy

v3:
* Use librte_ethtool
* Don't create interfaces for virtual PMDs
* Add a new API ...msg_exist() to support port based locking
* Add enable/disable promisc, allmulti support

v2:
* User rtnetlink to create interfaces.
* Add more ethtool support: get/set ringparam, set pauseparam.
* return defined error instead of hardcoded value
---
 MAINTAINERS                                |   1 +
 config/common_base                         |   5 +
 config/common_linuxapp                     |   1 +
 doc/api/doxy-api-index.md                  |   3 +-
 doc/api/doxy-api.conf                      |   1 +
 doc/guides/prog_guide/ctrl_if_lib.rst      |  52 ++++
 doc/guides/prog_guide/index.rst            |   1 +
 doc/guides/rel_notes/release_17_08.rst     |   9 +
 lib/Makefile                               |   2 +
 lib/librte_ctrl_if/Makefile                |  56 +++++
 lib/librte_ctrl_if/rte_ctrl_ethtool.c      | 390 +++++++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_ethtool.h      |  54 ++++
 lib/librte_ctrl_if/rte_ctrl_if.c           | 347 +++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_if.h           |  88 +++++++
 lib/librte_ctrl_if/rte_ctrl_if_version.map |  10 +
 lib/librte_ctrl_if/rte_nl.c                | 291 +++++++++++++++++++++
 lib/librte_ctrl_if/rte_nl.h                |  48 ++++
 lib/librte_eal/common/include/rte_log.h    |   1 +
 mk/rte.app.mk                              |   1 +
 19 files changed, 1360 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/prog_guide/ctrl_if_lib.rst
 create mode 100644 lib/librte_ctrl_if/Makefile
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_ethtool.c
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_ethtool.h
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.c
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.h
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if_version.map
 create mode 100644 lib/librte_ctrl_if/rte_nl.c
 create mode 100644 lib/librte_ctrl_if/rte_nl.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 8d1fb0431..2fb18ab79 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -280,6 +280,7 @@ F: doc/guides/sample_app_ug/kernel_nic_interface.rst
 Linux Userspace Network Control Interface (UNCI)
 M: Ferruh Yigit <ferruh.yigit@intel.com>
 F: lib/librte_eal/linuxapp/unci/
+F: lib/librte_ctrl_if/
 
 Linux AF_PACKET
 M: John W. Linville <linville@tuxdriver.com>
diff --git a/config/common_base b/config/common_base
index f50ccc193..98652b556 100644
--- a/config/common_base
+++ b/config/common_base
@@ -710,6 +710,11 @@ CONFIG_RTE_UNCI_KMOD=n
 CONFIG_RTE_UNCI_KO_DEBUG=n
 
 #
+# Compile librte_ctrl_if
+#
+CONFIG_RTE_LIBRTE_CTRL_IF=n
+
+#
 # Compile vhost user library
 #
 CONFIG_RTE_LIBRTE_VHOST=n
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 4deab42c3..209a6d3d1 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -42,6 +42,7 @@ CONFIG_RTE_LIBRTE_KNI=y
 CONFIG_RTE_LIBRTE_PMD_KNI=y
 CONFIG_RTE_LIBRTE_ETHTOOL=y
 CONFIG_RTE_UNCI_KMOD=y
+CONFIG_RTE_LIBRTE_CTRL_IF=y
 CONFIG_RTE_LIBRTE_VHOST=y
 CONFIG_RTE_LIBRTE_PMD_VHOST=y
 CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 71350849f..ba45ff69a 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -162,4 +162,5 @@ There are many libraries, so their headers may be grouped by topics:
   [bitrate statistics] (@ref rte_bitrate.h),
   [latency statistics] (@ref rte_latencystats.h),
   [version]            (@ref rte_version.h),
-  [ethtool]            (@ref rte_ethtool.h)
+  [ethtool]            (@ref rte_ethtool.h),
+  [control interface]  (@ref rte_ctrl_if.h)
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index b66e86541..896c2b247 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -42,6 +42,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           lib/librte_cmdline \
                           lib/librte_compat \
                           lib/librte_cryptodev \
+                          lib/librte_ctrl_if \
                           lib/librte_distributor \
                           lib/librte_efd \
                           lib/librte_ether \
diff --git a/doc/guides/prog_guide/ctrl_if_lib.rst b/doc/guides/prog_guide/ctrl_if_lib.rst
new file mode 100644
index 000000000..407cf0dca
--- /dev/null
+++ b/doc/guides/prog_guide/ctrl_if_lib.rst
@@ -0,0 +1,52 @@
+..  BSD LICENSE
+    Copyright(c) 2016 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.
+
+.. _Ctrl_If_Library:
+
+Control Interface Library
+=========================
+
+This Library is to create/destroy control interfaces and process messages
+received by control interface.
+
+Control Interface is Linux network interface and it is possible to call
+various Linux commands to this interface and commands will be forwarded
+to the matching DPDK PMD, and response will be generated by PMD.
+
+Control interface required UNCI kernel module to be inserted to function.
+
+Control Interface APIS
+----------------------
+
+
+- ``rte_eth_control_interface_create()``
+- ``rte_eth_control_interface_destroy()``
+- ``rte_eth_control_interface_msg_exist()``
+- ``rte_eth_control_interface_msg_process()``
diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index 54f9538ea..c7cb4b0f8 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -55,6 +55,7 @@ Programmer's Guide
     ip_fragment_reassembly_lib
     pdump_lib
     ethtool_lib
+    ctrl_if_lib
     multi_proc_support
     kernel_nic_interface
     thread_safety_dpdk_functions
diff --git a/doc/guides/rel_notes/release_17_08.rst b/doc/guides/rel_notes/release_17_08.rst
index dbe1ee906..af7ddace0 100644
--- a/doc/guides/rel_notes/release_17_08.rst
+++ b/doc/guides/rel_notes/release_17_08.rst
@@ -75,6 +75,14 @@ New Features
 
   Added support for firmwares with multiple Ethernet ports per physical port.
 
+* **Control interface support added.**
+
+  To enable controlling DPDK ports by common Linux tools.
+  Following modules added to DPDK:
+
+  * librte_ctrl_if library
+  * librte_eal/linuxapp/unci kernel module
+
 
 Resolved Issues
 ---------------
@@ -183,6 +191,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_cfgfile.so.2
      librte_cmdline.so.2
      librte_cryptodev.so.2
+   + librte_ctrl_if.so.1
      librte_distributor.so.1
      librte_eal.so.4
      librte_ethdev.so.6
diff --git a/lib/Makefile b/lib/Makefile
index 434237d6e..45c3168e3 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -108,6 +108,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += librte_pdump
 DEPDIRS-librte_pdump := librte_eal librte_mempool librte_mbuf librte_ether
 DIRS-$(CONFIG_RTE_LIBRTE_ETHTOOL) += librte_ethtool
 DEPDIRS-librte_ethtool := librte_eal librte_ether
+DIRS-$(CONFIG_RTE_LIBRTE_CTRL_IF) += librte_ctrl_if
+DEPDIRS-librte_ctrl_if := librte_ether
 
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
diff --git a/lib/librte_ctrl_if/Makefile b/lib/librte_ctrl_if/Makefile
new file mode 100644
index 000000000..686eb25d2
--- /dev/null
+++ b/lib/librte_ctrl_if/Makefile
@@ -0,0 +1,56 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2016 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_ctrl_if.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lpthread
+
+EXPORT_MAP := rte_ctrl_if_version.map
+
+LIBABIVER := 1
+
+SRCS-y += rte_ctrl_if.c
+SRCS-y += rte_nl.c
+SRCS-y += rte_ctrl_ethtool.c
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_ctrl_if.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_ctrl_if/rte_ctrl_ethtool.c b/lib/librte_ctrl_if/rte_ctrl_ethtool.c
new file mode 100644
index 000000000..70c60197b
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_ethtool.c
@@ -0,0 +1,390 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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 <error.h>
+
+#include <linux/if_link.h>
+
+#include <rte_version.h>
+#include <rte_ethdev.h>
+#include <rte_ethtool.h>
+#include "rte_ctrl_ethtool.h"
+
+#define ETHTOOL_GEEPROM_LEN 99
+#define ETHTOOL_GREGS_LEN 98
+#define ETHTOOL_GSSET_COUNT 97
+
+static int
+get_settings(uint8_t port_id __rte_unused, void *data, size_t *data_len)
+{
+	struct ethtool_cmd *ecmd = data;
+
+	/* No PMD equivalent, added to make get pauseparam work */
+	memset(ecmd, 0, sizeof(struct ethtool_cmd));
+
+	*data_len = sizeof(struct ethtool_cmd);
+	return 0;
+}
+
+static int
+get_drvinfo(uint8_t port_id, void *data, size_t *data_len)
+{
+	struct ethtool_drvinfo *info = data;
+	int ret;
+
+	ret = rte_ethtool_get_drvinfo(port_id, info);
+	if (ret < 0)
+		return ret;
+
+	*data_len = sizeof(struct ethtool_drvinfo);
+
+	return 0;
+}
+
+static int
+get_reg_len(uint8_t port_id, void *data, size_t *data_len)
+{
+	int reg_length = 0;
+
+	reg_length = rte_ethtool_get_regs_len(port_id);
+	if (reg_length < 0)
+		return reg_length;
+
+	*(int *)data = reg_length;
+	*data_len = sizeof(int);
+
+	return 0;
+}
+
+static int
+get_reg_len_internal(uint8_t port_id, size_t *reg_length)
+{
+	size_t reg_length_out_len;
+
+	return get_reg_len(port_id, reg_length, &reg_length_out_len);
+}
+
+static int
+get_reg(uint8_t port_id, void *in_data, void *out_data, size_t *out_data_len)
+{
+	size_t reg_length;
+	struct ethtool_regs *ethtool_regs = in_data;
+	int ret;
+
+	ret = get_reg_len_internal(port_id, &reg_length);
+	/* not enough space in out data buffer */
+	if (ret < 0 || reg_length > ethtool_regs->len)
+		return -1;
+
+	ret = rte_ethtool_get_regs(port_id, ethtool_regs, out_data);
+	if (ret < 0)
+		return ret;
+
+	*out_data_len = reg_length;
+
+	return 0;
+}
+
+static int
+get_link(uint8_t port_id, void *data, size_t *data_len)
+{
+	int ret;
+
+	ret = rte_ethtool_get_link(port_id);
+
+	*(int *)data = ret;
+	*data_len = sizeof(size_t);
+
+	return 0;
+}
+
+static int
+get_eeprom_length(uint8_t port_id, void *data, size_t *data_len)
+{
+	int eeprom_length = 0;
+
+	eeprom_length = rte_ethtool_get_eeprom_len(port_id);
+	if (eeprom_length < 0)
+		return eeprom_length;
+
+	*(int *)data = eeprom_length;
+	*data_len = sizeof(int);
+
+	return 0;
+}
+
+static int
+get_eeprom(uint8_t port_id, void *in_data, void *out_data,
+		size_t *out_data_len)
+{
+	struct ethtool_eeprom *eeprom = in_data;
+	int ret;
+
+	ret = rte_ethtool_get_eeprom(port_id, eeprom, out_data);
+	if (ret < 0)
+		return ret;
+
+	*out_data_len = eeprom->len;
+
+	return 0;
+}
+
+static int
+set_eeprom(uint8_t port_id, void *in_data)
+{
+	struct ethtool_eeprom *eeprom = in_data;
+	int ret;
+
+	ret = rte_ethtool_set_eeprom(port_id, eeprom, eeprom->data);
+	if (ret != 0)
+		return -1;
+
+	return 0;
+}
+
+static int
+get_ringparam(uint8_t port_id, void *data, size_t *data_len)
+{
+	struct ethtool_ringparam *ringparam = data;
+	int ret;
+
+	ret = rte_ethtool_get_ringparam(port_id, ringparam);
+	if (ret < 0)
+		return ret;
+
+	*data_len = sizeof(struct ethtool_ringparam);
+
+	return 0;
+}
+
+static int
+set_ringparam(uint8_t port_id, void *data)
+{
+	struct ethtool_ringparam *ringparam = data;
+	int ret;
+
+	ret = rte_ethtool_set_ringparam(port_id, ringparam);
+	if (ret != 0)
+		return -1;
+
+	return 0;
+}
+
+static int
+get_pauseparam(uint8_t port_id, void *data, size_t *data_len)
+{
+	struct ethtool_pauseparam *pauseparam = data;
+	int ret;
+
+	ret = rte_ethtool_get_pauseparam(port_id, pauseparam);
+	if (ret < 0)
+		return ret;
+
+	*data_len = sizeof(struct ethtool_pauseparam);
+
+	return 0;
+}
+
+static int
+set_pauseparam(uint8_t port_id, void *data)
+{
+	struct ethtool_pauseparam *pauseparam = data;
+
+	return rte_ethtool_set_pauseparam(port_id, pauseparam);
+}
+
+int
+rte_eth_dev_ethtool_process(uint32_t cmd_id, uint8_t port_id, void *in_data,
+		void *out_data, size_t *out_data_len)
+{
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return -ENODEV;
+
+	switch (cmd_id) {
+	case ETHTOOL_GSET:
+		return get_settings(port_id, out_data, out_data_len);
+	case ETHTOOL_GDRVINFO:
+		return get_drvinfo(port_id, out_data, out_data_len);
+	case ETHTOOL_GREGS_LEN:
+		return get_reg_len(port_id, out_data, out_data_len);
+	case ETHTOOL_GREGS:
+		return get_reg(port_id, in_data, out_data, out_data_len);
+	case ETHTOOL_GLINK:
+		return get_link(port_id, out_data, out_data_len);
+	case ETHTOOL_GEEPROM_LEN:
+		return get_eeprom_length(port_id, out_data, out_data_len);
+	case ETHTOOL_GEEPROM:
+		return get_eeprom(port_id, in_data, out_data, out_data_len);
+	case ETHTOOL_SEEPROM:
+		return set_eeprom(port_id, in_data);
+	case ETHTOOL_GRINGPARAM:
+		return get_ringparam(port_id, out_data, out_data_len);
+	case ETHTOOL_SRINGPARAM:
+		return set_ringparam(port_id, in_data);
+	case ETHTOOL_GPAUSEPARAM:
+		return get_pauseparam(port_id, out_data, out_data_len);
+	case ETHTOOL_SPAUSEPARAM:
+		return set_pauseparam(port_id, in_data);
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int
+set_mtu(uint8_t port_id, void *in_data)
+{
+	int *mtu = in_data;
+
+	return rte_eth_dev_set_mtu(port_id, *mtu);
+}
+
+static int
+get_stats(uint8_t port_id, void *data, size_t *data_len)
+{
+	struct rte_eth_stats stats;
+	struct rtnl_link_stats64 *if_stats = data;
+	int ret;
+
+	ret = rte_eth_stats_get(port_id, &stats);
+	if (ret < 0)
+		return -EOPNOTSUPP;
+
+	if_stats->rx_packets = stats.ipackets;
+	if_stats->tx_packets = stats.opackets;
+	if_stats->rx_bytes = stats.ibytes;
+	if_stats->tx_bytes = stats.obytes;
+	if_stats->rx_errors = stats.ierrors;
+	if_stats->tx_errors = stats.oerrors;
+	if_stats->rx_dropped = stats.imissed;
+
+	*data_len = sizeof(struct rtnl_link_stats64);
+
+	return 0;
+}
+
+static int
+get_mac(uint8_t port_id, void *data, size_t *data_len)
+{
+	struct ether_addr addr;
+
+	rte_eth_macaddr_get(port_id, &addr);
+	memcpy(data, &addr, sizeof(struct ether_addr));
+
+	*data_len = sizeof(struct ether_addr);
+
+	return 0;
+}
+
+static int
+set_mac(uint8_t port_id, void *in_data)
+{
+	struct ether_addr addr;
+
+	memcpy(&addr, in_data, ETHER_ADDR_LEN);
+
+	return rte_eth_dev_default_mac_addr_set(port_id, &addr);
+}
+
+static int
+start_port(uint8_t port_id)
+{
+	rte_eth_dev_stop(port_id);
+	return rte_eth_dev_start(port_id);
+}
+
+static int
+stop_port(uint8_t port_id)
+{
+	rte_eth_dev_stop(port_id);
+	return 0;
+}
+
+static int
+set_promisc(uint8_t port_id, void *in_data)
+{
+	int *promisc = in_data;
+
+	if (*promisc)
+		rte_eth_promiscuous_enable(port_id);
+	else
+		rte_eth_promiscuous_disable(port_id);
+
+	return 0;
+}
+
+static int
+set_allmulti(uint8_t port_id, void *in_data)
+{
+	int *allmulti = in_data;
+
+	if (*allmulti)
+		rte_eth_allmulticast_enable(port_id);
+	else
+		rte_eth_allmulticast_disable(port_id);
+
+	return 0;
+}
+
+int
+rte_eth_dev_control_process(uint32_t cmd_id, uint8_t port_id, void *in_data,
+		void *out_data, size_t *out_data_len)
+{
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return -ENODEV;
+
+	switch (cmd_id) {
+	case RTE_UNCI_REQ_CHANGE_MTU:
+		return set_mtu(port_id, in_data);
+	case RTE_UNCI_REQ_GET_STATS:
+		return get_stats(port_id, out_data, out_data_len);
+	case RTE_UNCI_REQ_GET_MAC:
+		return get_mac(port_id, out_data, out_data_len);
+	case RTE_UNCI_REQ_SET_MAC:
+		return set_mac(port_id, in_data);
+	case RTE_UNCI_REQ_START_PORT:
+		return start_port(port_id);
+	case RTE_UNCI_REQ_STOP_PORT:
+		return stop_port(port_id);
+	case RTE_UNCI_REQ_SET_PROMISC:
+		return set_promisc(port_id, in_data);
+	case RTE_UNCI_REQ_SET_ALLMULTI:
+		return set_allmulti(port_id, in_data);
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
diff --git a/lib/librte_ctrl_if/rte_ctrl_ethtool.h b/lib/librte_ctrl_if/rte_ctrl_ethtool.h
new file mode 100644
index 000000000..caa4f15f3
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_ethtool.h
@@ -0,0 +1,54 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 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_CTRL_ETHTOOL_H_
+#define _RTE_CTRL_ETHTOOL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <linux/ethtool.h>
+
+#include <exec-env/rte_unci_common.h>
+
+int rte_eth_dev_ethtool_process(uint32_t cmd_id, uint8_t port_id, void *in_data,
+		void *out_data, size_t *out_data_len);
+int rte_eth_dev_control_process(uint32_t cmd_id, uint8_t port_id, void *in_data,
+		void *out_data, size_t *out_data_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_CTRL_ETHTOOL_H_ */
diff --git a/lib/librte_ctrl_if/rte_ctrl_if.c b/lib/librte_ctrl_if/rte_ctrl_if.c
new file mode 100644
index 000000000..6255a2a1a
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_if.c
@@ -0,0 +1,347 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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 <fcntl.h>
+#include <stdint.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <rte_log.h>
+#include "rte_ctrl_if.h"
+#include "rte_nl.h"
+
+#define NAMESZ 32
+#define IFNAME "dpdk"
+#define BUFSZ 1024
+
+static int unci_rtnl_fd = -1;
+static uint32_t unci_fd_ref;
+
+struct unci_request {
+	struct nlmsghdr nlmsg;
+	uint8_t buf[BUFSZ];
+};
+
+static int
+conrol_interface_rtnl_init(void)
+{
+	struct sockaddr_nl src;
+	int ret;
+
+	unci_rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+	if (unci_rtnl_fd < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Socket for create failed\n");
+		return -1;
+	}
+
+	memset(&src, 0, sizeof(struct sockaddr_nl));
+
+	src.nl_family = AF_NETLINK;
+	src.nl_pid = getpid();
+
+	ret = bind(unci_rtnl_fd, (struct sockaddr *)&src,
+			sizeof(struct sockaddr_nl));
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Bind for create failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+control_interface_init(void)
+{
+	int ret;
+
+	ret = conrol_interface_rtnl_init();
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Failed to initialize rtnetlink\n");
+		return -1;
+	}
+
+	ret = control_interface_nl_init();
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Failed to initialize netlink\n");
+		close(unci_rtnl_fd);
+		unci_rtnl_fd = -1;
+	}
+
+	return ret;
+}
+
+static int
+control_interface_ref_get(void)
+{
+	int ret = 0;
+
+	if (unci_fd_ref == 0)
+		ret = control_interface_init();
+
+	if (ret == 0)
+		unci_fd_ref++;
+	else
+		RTE_LOG(ERR, CTRL_IF,
+				"Failed to initialize control interface\n");
+
+	return unci_fd_ref;
+}
+
+static void
+control_interface_release(void)
+{
+	close(unci_rtnl_fd);
+	control_interface_nl_release();
+}
+
+static int
+control_interface_ref_put(void)
+{
+	if (unci_fd_ref == 0)
+		return 0;
+
+	unci_fd_ref--;
+
+	if (unci_fd_ref == 0)
+		control_interface_release();
+
+	return unci_fd_ref;
+}
+
+static int
+add_attr(struct unci_request *req, uint16_t type, void *buf, size_t len)
+{
+	struct rtattr *rta;
+	int nlmsg_len;
+
+	nlmsg_len = NLMSG_ALIGN(req->nlmsg.nlmsg_len);
+	rta = (struct rtattr *)((char *)&req->nlmsg + nlmsg_len);
+	if (nlmsg_len + RTA_LENGTH(len) > sizeof(struct unci_request))
+		return -1;
+	rta->rta_type = type;
+	rta->rta_len = RTA_LENGTH(len);
+	memcpy(RTA_DATA(rta), buf, len);
+	req->nlmsg.nlmsg_len = nlmsg_len + RTA_LENGTH(len);
+
+	return 0;
+}
+
+static struct
+rtattr *add_attr_nested(struct unci_request *req, unsigned short type)
+{
+	struct rtattr *rta;
+	uint32_t nlmsg_len;
+
+	nlmsg_len = NLMSG_ALIGN(req->nlmsg.nlmsg_len);
+	rta = (struct rtattr *)((uint8_t *)&req->nlmsg + nlmsg_len);
+	if (nlmsg_len + RTA_LENGTH(0) > sizeof(struct unci_request))
+		return NULL;
+	rta->rta_type = type;
+	rta->rta_len = nlmsg_len;
+	req->nlmsg.nlmsg_len = nlmsg_len + RTA_LENGTH(0);
+
+	return rta;
+}
+
+static void
+end_attr_nested(struct unci_request *req, struct rtattr *rta)
+{
+	rta->rta_len = req->nlmsg.nlmsg_len - rta->rta_len;
+}
+
+static int
+rte_eth_rtnl_create(uint8_t port_id)
+{
+	struct unci_request req;
+	struct ifinfomsg *info;
+	struct rtattr *rta1;
+	struct rtattr *rta2;
+	uint32_t pid = getpid();
+	char name[NAMESZ];
+	char type[NAMESZ];
+	struct iovec iov;
+	struct msghdr msg;
+	struct sockaddr_nl nladdr;
+	int ret;
+	uint8_t buf[BUFSZ];
+
+	memset(&req, 0, sizeof(struct unci_request));
+
+	req.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+	req.nlmsg.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
+	req.nlmsg.nlmsg_flags |= NLM_F_ACK;
+	req.nlmsg.nlmsg_type = RTM_NEWLINK;
+
+	info = NLMSG_DATA(&req.nlmsg);
+
+	info->ifi_family = AF_UNSPEC;
+	info->ifi_index = 0;
+
+	snprintf(name, NAMESZ, IFNAME"%u", port_id);
+	ret = add_attr(&req, IFLA_IFNAME, name, strlen(name) + 1);
+	if (ret < 0)
+		return -1;
+
+	rta1 = add_attr_nested(&req, IFLA_LINKINFO);
+	if (rta1 == NULL)
+		return -1;
+
+	snprintf(type, NAMESZ, UNCI_DEVICE);
+	ret = add_attr(&req, IFLA_INFO_KIND, type, strlen(type) + 1);
+	if (ret < 0)
+		return -1;
+
+	rta2 = add_attr_nested(&req, IFLA_INFO_DATA);
+	if (rta2 == NULL)
+		return -1;
+
+	ret = add_attr(&req, IFLA_UNCI_PORTID, &port_id, sizeof(uint8_t));
+	if (ret < 0)
+		return -1;
+
+	ret = add_attr(&req, IFLA_UNCI_PID, &pid, sizeof(uint32_t));
+	if (ret < 0)
+		return -1;
+
+	end_attr_nested(&req, rta2);
+	end_attr_nested(&req, rta1);
+
+	memset(&nladdr, 0, sizeof(nladdr));
+	nladdr.nl_family = AF_NETLINK;
+
+	iov.iov_base = (void *)&req.nlmsg;
+	iov.iov_len = req.nlmsg.nlmsg_len;
+
+	memset(&msg, 0, sizeof(struct msghdr));
+	msg.msg_name = &nladdr;
+	msg.msg_namelen = sizeof(nladdr);
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+
+	ret = sendmsg(unci_rtnl_fd, &msg, 0);
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Send for create failed %d.\n", errno);
+		return -1;
+	}
+
+	memset(buf, 0, sizeof(buf));
+	iov.iov_base = buf;
+	iov.iov_len = sizeof(buf);
+
+	ret = recvmsg(unci_rtnl_fd, &msg, 0);
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Recv for create failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+int
+rte_eth_control_interface_create_one(uint8_t port_id)
+{
+	int ret;
+
+	if (control_interface_ref_get() != 0) {
+		ret = rte_eth_rtnl_create(port_id);
+		RTE_LOG(DEBUG, CTRL_IF,
+			"Control interface %s for port:%u\n",
+			ret < 0 ? "failed" : "created", port_id);
+	}
+
+	return 0;
+}
+
+static int
+rte_eth_rtnl_destroy(uint8_t port_id)
+{
+	struct unci_request req;
+	struct ifinfomsg *info;
+	char name[NAMESZ];
+	struct iovec iov;
+	struct msghdr msg;
+	struct sockaddr_nl nladdr;
+	int ret;
+
+	memset(&req, 0, sizeof(struct unci_request));
+
+	req.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+	req.nlmsg.nlmsg_flags = NLM_F_REQUEST;
+	req.nlmsg.nlmsg_type = RTM_DELLINK;
+
+	info = NLMSG_DATA(&req.nlmsg);
+
+	info->ifi_family = AF_UNSPEC;
+	info->ifi_index = 0;
+
+	snprintf(name, NAMESZ, IFNAME"%u", port_id);
+	ret = add_attr(&req, IFLA_IFNAME, name, strlen(name) + 1);
+	if (ret < 0)
+		return -1;
+
+	memset(&nladdr, 0, sizeof(nladdr));
+	nladdr.nl_family = AF_NETLINK;
+
+	iov.iov_base = (void *)&req.nlmsg;
+	iov.iov_len = req.nlmsg.nlmsg_len;
+
+	memset(&msg, 0, sizeof(struct msghdr));
+	msg.msg_name = &nladdr;
+	msg.msg_namelen = sizeof(nladdr);
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+
+	ret = sendmsg(unci_rtnl_fd, &msg, 0);
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Send for destroy failed\n");
+		return -1;
+	}
+	return 0;
+}
+
+int
+rte_eth_control_interface_destroy_one(uint8_t port_id)
+{
+	rte_eth_rtnl_destroy(port_id);
+	control_interface_ref_put();
+	RTE_LOG(DEBUG, CTRL_IF, "Control interface destroyed for port:%u\n",
+			port_id);
+
+	return 0;
+}
diff --git a/lib/librte_ctrl_if/rte_ctrl_if.h b/lib/librte_ctrl_if/rte_ctrl_if.h
new file mode 100644
index 000000000..54696bd93
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_if.h
@@ -0,0 +1,88 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 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_CTRL_IF_H_
+#define _RTE_CTRL_IF_H_
+
+/**
+ * @file
+ *
+ * Control Interface Library for RTE
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <exec-env/rte_unci_common.h>
+
+/**
+ * Creates control interfaces (Linux virtual network interface)for
+ * given ethdev port.
+ *
+ * This API opens device created by supportive kernel module and initializes
+ * kernel communication interface.
+ *
+ * With first interface created, a pthread created to receive the control
+ * messages.
+ *
+ * If supportive kernel module is not inserted this API will return
+ * an error.
+ *
+ * @param port_id
+ *  port id to create virtual interface
+ * @return
+ *  0 on success.
+ *  Negative value on error.
+ */
+int rte_eth_control_interface_create_one(uint8_t port_id);
+
+/**
+ * Destroys control interfaces.
+ *
+ * This API close device created by supportive kernel module and release
+ * underlying communication interface.
+ *
+ * @return
+ * @param port_id
+ *  port id to destroy virtual interface
+ *  0 on success.
+ *  Negative value on error.
+ */
+int rte_eth_control_interface_destroy_one(uint8_t port_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_CTRL_IF_H_ */
diff --git a/lib/librte_ctrl_if/rte_ctrl_if_version.map b/lib/librte_ctrl_if/rte_ctrl_if_version.map
new file mode 100644
index 000000000..3a86ab1a8
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_if_version.map
@@ -0,0 +1,10 @@
+DPDK_17.02 {
+	global:
+
+	rte_eth_control_interface_create;
+	rte_eth_control_interface_destroy;
+	rte_eth_control_interface_msg_exist;
+	rte_eth_control_interface_msg_process;
+
+	local: *;
+};
diff --git a/lib/librte_ctrl_if/rte_nl.c b/lib/librte_ctrl_if/rte_nl.c
new file mode 100644
index 000000000..011f5207b
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_nl.c
@@ -0,0 +1,291 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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 <string.h>
+#include <unistd.h>
+
+#include <sys/socket.h>
+#include <linux/netlink.h>
+
+#include <rte_spinlock.h>
+#include <rte_log.h>
+#include "rte_ctrl_ethtool.h"
+#include "rte_nl.h"
+#include "rte_ctrl_if.h"
+
+#define MAX_PAYLOAD sizeof(struct unci_ethtool_msg)
+
+struct ctrl_if_nl {
+	union {
+		struct nlmsghdr nlh;
+		uint8_t nlmsg[NLMSG_SPACE(MAX_PAYLOAD)];
+	};
+	struct msghdr msg;
+	struct iovec iov;
+	struct sockaddr_nl dest_addr;
+};
+
+struct ctrl_if_msg_sync {
+	struct unci_ethtool_msg msg_storage;
+	pthread_mutex_t msg_lock;
+	uint32_t pending_process;
+};
+
+
+/**
+ * Flags values for rte_eth_control_interface_process_msg() API
+ */
+enum control_interface_process_flag {
+	/**< Process if msg available. */
+	RTE_ETHTOOL_CTRL_IF_PROCESS_MSG,
+
+	/**< Discard msg if available, respond with a error value. */
+	RTE_ETHTOOL_CTRL_IF_DISCARD_MSG,
+};
+
+static int sock_fd = -1;
+static pthread_t thread_id;
+
+static struct ctrl_if_nl nl_s;
+static struct ctrl_if_nl nl_r;
+
+static struct ctrl_if_msg_sync ctrl_if_sync = {
+	.msg_lock = PTHREAD_MUTEX_INITIALIZER,
+};
+
+static int
+nl_send(void *buf, size_t len)
+{
+	int ret;
+
+	if (nl_s.nlh.nlmsg_len < len) {
+		RTE_LOG(ERR, CTRL_IF, "Message is too big, len:%zu\n", len);
+		return -1;
+	}
+
+	if (!NLMSG_OK(&nl_s.nlh, NLMSG_SPACE(MAX_PAYLOAD))) {
+		RTE_LOG(ERR, CTRL_IF, "Message is not OK\n");
+		return -1;
+	}
+
+	/* Fill in the netlink message payload */
+	memcpy(NLMSG_DATA(nl_s.nlmsg), buf, len);
+
+	ret = sendmsg(sock_fd, &nl_s.msg, 0);
+
+	if (ret < 0)
+		RTE_LOG(ERR, CTRL_IF, "Failed nl msg send. ret:%d, err:%d\n",
+				ret, errno);
+	return ret;
+}
+
+static int
+nl_ethtool_msg_send(struct unci_ethtool_msg *msg)
+{
+	return nl_send((void *)msg, sizeof(struct unci_ethtool_msg));
+}
+
+static void
+process_msg(struct unci_ethtool_msg *msg)
+{
+	if (msg->cmd_id > RTE_UNCI_REQ_UNKNOWN) {
+		msg->err = rte_eth_dev_control_process(msg->cmd_id,
+				msg->port_id, msg->input_buffer,
+				msg->output_buffer, &msg->output_buffer_len);
+	} else {
+		msg->err = rte_eth_dev_ethtool_process(msg->cmd_id,
+				msg->port_id, msg->input_buffer,
+				msg->output_buffer, &msg->output_buffer_len);
+	}
+
+	if (msg->err)
+		memset(msg->output_buffer, 0, msg->output_buffer_len);
+
+	nl_ethtool_msg_send(msg);
+}
+
+static int
+control_interface_msg_process(uint32_t flag)
+{
+	struct unci_ethtool_msg msg_storage;
+	int ret = 0;
+
+	pthread_mutex_lock(&ctrl_if_sync.msg_lock);
+	if (ctrl_if_sync.pending_process == 0) {
+		pthread_mutex_unlock(&ctrl_if_sync.msg_lock);
+		return 0;
+	}
+
+	memcpy(&msg_storage, &ctrl_if_sync.msg_storage,
+			sizeof(struct unci_ethtool_msg));
+	ctrl_if_sync.pending_process = 0;
+	pthread_mutex_unlock(&ctrl_if_sync.msg_lock);
+
+	switch (flag) {
+	case RTE_ETHTOOL_CTRL_IF_PROCESS_MSG:
+		process_msg(&msg_storage);
+		break;
+
+	case RTE_ETHTOOL_CTRL_IF_DISCARD_MSG:
+		msg_storage.err = -1;
+		nl_ethtool_msg_send(&msg_storage);
+		break;
+
+	default:
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
+
+static int
+msg_add_and_process(struct nlmsghdr *nlh)
+{
+	pthread_mutex_lock(&ctrl_if_sync.msg_lock);
+
+	if (ctrl_if_sync.pending_process) {
+		pthread_mutex_unlock(&ctrl_if_sync.msg_lock);
+		return -1;
+	}
+
+	memcpy(&ctrl_if_sync.msg_storage, NLMSG_DATA(nlh),
+			sizeof(struct unci_ethtool_msg));
+	ctrl_if_sync.msg_storage.flag = UNCI_MSG_FLAG_RESPONSE;
+	ctrl_if_sync.pending_process = 1;
+
+	pthread_mutex_unlock(&ctrl_if_sync.msg_lock);
+
+	control_interface_msg_process(RTE_ETHTOOL_CTRL_IF_PROCESS_MSG);
+
+	return 0;
+}
+
+static void *
+nl_recv(void *arg)
+{
+	int ret;
+
+	for (;;) {
+		ret = recvmsg(sock_fd, &nl_r.msg, 0);
+		if (ret < 0)
+			continue;
+
+		if ((unsigned int)ret < sizeof(struct unci_ethtool_msg)) {
+			RTE_LOG(WARNING, CTRL_IF,
+					"Received %d bytes, payload %zu\n",
+					ret, sizeof(struct unci_ethtool_msg));
+			continue;
+		}
+
+		msg_add_and_process(&nl_r.nlh);
+	}
+
+	return arg;
+}
+
+static void
+nl_setup_header(struct ctrl_if_nl *nl)
+{
+	nl->dest_addr.nl_family = AF_NETLINK;
+	nl->dest_addr.nl_pid = 0;   /*  For Linux Kernel */
+	nl->dest_addr.nl_groups = 0;
+
+	memset(nl->nlmsg, 0, NLMSG_SPACE(MAX_PAYLOAD));
+
+	/* Fill the netlink message header */
+	nl->nlh.nlmsg_len = NLMSG_LENGTH(MAX_PAYLOAD);
+	nl->nlh.nlmsg_pid = getpid();  /* self pid */
+	nl->nlh.nlmsg_flags = 0;
+
+	nl->iov.iov_base = (void *)nl->nlmsg;
+	nl->iov.iov_len = nl->nlh.nlmsg_len;
+	memset(&nl->msg, 0, sizeof(struct msghdr));
+	nl->msg.msg_name = (void *)&nl->dest_addr;
+	nl->msg.msg_namelen = sizeof(struct sockaddr_nl);
+	nl->msg.msg_iov = &nl->iov;
+	nl->msg.msg_iovlen = 1;
+}
+
+static int
+nl_socket_init(void)
+{
+	struct sockaddr_nl src_addr;
+	int fd;
+	int ret;
+
+	fd = socket(PF_NETLINK, SOCK_RAW, UNCI_NL_GRP);
+	if (fd < 0)
+		return -1;
+
+	src_addr.nl_family = AF_NETLINK;
+	src_addr.nl_pid = getpid();
+	ret = bind(fd, (struct sockaddr *)&src_addr, sizeof(src_addr));
+	if (ret) {
+		close(fd);
+		return -1;
+	}
+
+	nl_setup_header(&nl_s);
+	nl_setup_header(&nl_r);
+
+	return fd;
+}
+
+int
+control_interface_nl_init(void)
+{
+	int ret;
+
+	sock_fd = nl_socket_init();
+	if (sock_fd < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Failed to initialize netlink socket\n");
+		return -1;
+	}
+
+	ret = pthread_create(&thread_id, NULL, nl_recv, NULL);
+	if (ret != 0) {
+		RTE_LOG(ERR, CTRL_IF, "Failed to create receive thread\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+void
+control_interface_nl_release(void)
+{
+	pthread_cancel(thread_id);
+	pthread_join(thread_id, NULL);
+	close(sock_fd);
+}
diff --git a/lib/librte_ctrl_if/rte_nl.h b/lib/librte_ctrl_if/rte_nl.h
new file mode 100644
index 000000000..889be87e8
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_nl.h
@@ -0,0 +1,48 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 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_NL_H_
+#define _RTE_NL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int control_interface_nl_init(void);
+void control_interface_nl_release(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_NL_H_ */
diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
index 341913851..1dbf6b1a3 100644
--- a/lib/librte_eal/common/include/rte_log.h
+++ b/lib/librte_eal/common/include/rte_log.h
@@ -87,6 +87,7 @@ extern struct rte_logs rte_logs;
 #define RTE_LOGTYPE_CRYPTODEV 17 /**< Log related to cryptodev. */
 #define RTE_LOGTYPE_EFD       18 /**< Log related to EFD. */
 #define RTE_LOGTYPE_EVENTDEV  19 /**< Log related to eventdev. */
+#define RTE_LOGTYPE_CTRL_IF   20 /**< Log related to control interface. */
 
 /* these log types can be used in an application */
 #define RTE_LOGTYPE_USER1     24 /**< User-defined log type 1. */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 449bd2f61..866bd41c5 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -91,6 +91,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF)           += -lrte_mbuf
 _LDLIBS-$(CONFIG_RTE_LIBRTE_NET)            += -lrte_net
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHER)          += -lrte_ethdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHTOOL)        += -lrte_ethtool
+_LDLIBS-$(CONFIG_RTE_LIBRTE_CTRL_IF)        += -lrte_ctrl_if
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CRYPTODEV)      += -lrte_cryptodev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV)       += -lrte_eventdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v8 4/4] ethdev: add control interface support
  2017-06-21 11:06 ` [PATCH v8 0/4] Userspace Network Control Interface (UNCI) Ferruh Yigit
                     ` (2 preceding siblings ...)
  2017-06-21 11:06   ` [PATCH v8 3/4] rte_ctrl_if: add control interface library Ferruh Yigit
@ 2017-06-21 11:06   ` Ferruh Yigit
  2017-06-21 15:24     ` Stephen Hemminger
  2017-06-26 11:39   ` [PATCH v8 0/4] Userspace Network Control Interface (UNCI) Bruce Richardson
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
  5 siblings, 1 reply; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-21 11:06 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, anatoly.burakov, Bruce Richardson

To have the support corresponding kernel module (UNCI) needs to be
inserted.  If kernel module is not there, application will run as
it is without kernel control path support.

When UNCI module inserted, running application creates a virtual Linux
network interface (dpdk$) per DPDK port. This interface can be used by
traditional Linux tools.

If Userspace Network Control Interface (UNCI) kernel module
(rte_unci.ko) inserted, virtual interfaces created for each DPDK port
for control purposes.

Created interfaces are named as dpdk#, like:

    $ ifconfig dpdk0; ifconfig dpdk1
    dpdk0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
            ether 90:e2:ba:0e:49:b9  txqueuelen 1000  (Ethernet)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

    dpdk1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
            ether 00:1b:21:76:fa:21  txqueuelen 1000  (Ethernet)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Regular Linux commands can be issued on interfaces:

	$ ethtool -i dpdk0
	driver: net_ixgbe
	version: DPDK 17.08.0-rc0
	firmware-version: 0x61bf0001
	expansion-rom-version:
	bus-info: 0000:08:00.1
	supports-statistics: no
	supports-test: no
	supports-eeprom-access: yes
	supports-register-dump: yes
	supports-priv-flags: no

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ether/rte_ethdev_pci.h | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev_pci.h b/lib/librte_ether/rte_ethdev_pci.h
index 69aab03fb..a32a617d7 100644
--- a/lib/librte_ether/rte_ethdev_pci.h
+++ b/lib/librte_ether/rte_ethdev_pci.h
@@ -38,6 +38,13 @@
 #include <rte_pci.h>
 #include <rte_ethdev.h>
 
+#ifdef RTE_LIBRTE_CTRL_IF
+#include <rte_ctrl_if.h>
+#else
+#define rte_eth_control_interface_create_one(port_id) do { } while(0)
+#define rte_eth_control_interface_destroy_one(port_id) do { } while(0)
+#endif
+
 /**
  * Copy pci device info to the Ethernet device data.
  *
@@ -157,8 +164,12 @@ rte_eth_dev_pci_generic_probe(struct rte_pci_device *pci_dev,
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
 	ret = dev_init(eth_dev);
-	if (ret)
+	if (ret) {
 		rte_eth_dev_pci_release(eth_dev);
+		return ret;
+	}
+
+	rte_eth_control_interface_create_one(eth_dev->data->port_id);
 
 	return ret;
 }
@@ -179,6 +190,8 @@ rte_eth_dev_pci_generic_remove(struct rte_pci_device *pci_dev,
 	if (!eth_dev)
 		return -ENODEV;
 
+	rte_eth_control_interface_destroy_one(eth_dev->data->port_id);
+
 	if (dev_uninit) {
 		ret = dev_uninit(eth_dev);
 		if (ret)
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* Re: [PATCH v8 2/4] unci: add kernel control path kernel module
  2017-06-21 11:06   ` [PATCH v8 2/4] unci: add kernel control path kernel module Ferruh Yigit
@ 2017-06-21 15:23     ` Stephen Hemminger
  2017-06-30 17:02       ` Ferruh Yigit
  0 siblings, 1 reply; 91+ messages in thread
From: Stephen Hemminger @ 2017-06-21 15:23 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, anatoly.burakov, Bruce Richardson

On Wed, 21 Jun 2017 12:06:49 +0100
Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> +static struct ethtool_input_buffer {
> +	int magic;
> +	void *buffer;
> +	size_t length;
> +	struct completion *msg_received;
> +	int *err;
> +	u32 in_use;
> +} ethtool_input_buffer

Naming in kernel is important. This isn't kernel ethtool, so  it shouldn't be named that.

Having a single instance per system for a control interface means it won't work
if multiple apps have control channel open or in containers.

You should also do policy validation on the netlink message.

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v8 4/4] ethdev: add control interface support
  2017-06-21 11:06   ` [PATCH v8 4/4] ethdev: add control interface support Ferruh Yigit
@ 2017-06-21 15:24     ` Stephen Hemminger
  2017-06-30 17:06       ` Ferruh Yigit
  0 siblings, 1 reply; 91+ messages in thread
From: Stephen Hemminger @ 2017-06-21 15:24 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, anatoly.burakov, Bruce Richardson

On Wed, 21 Jun 2017 12:06:51 +0100
Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> To have the support corresponding kernel module (UNCI) needs to be
> inserted.  If kernel module is not there, application will run as
> it is without kernel control path support.
> 
> When UNCI module inserted, running application creates a virtual Linux
> network interface (dpdk$) per DPDK port. This interface can be used by
> traditional Linux tools.
> 
> If Userspace Network Control Interface (UNCI) kernel module
> (rte_unci.ko) inserted, virtual interfaces created for each DPDK port
> for control purposes.
> 
> Created interfaces are named as dpdk#, like:
> 
>     $ ifconfig dpdk0; ifconfig dpdk1
>     dpdk0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
>             ether 90:e2:ba:0e:49:b9  txqueuelen 1000  (Ethernet)
>             RX packets 0  bytes 0 (0.0 B)
>             RX errors 0  dropped 0  overruns 0  frame 0
>             TX packets 0  bytes 0 (0.0 B)
>             TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
> 
>     dpdk1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
>             ether 00:1b:21:76:fa:21  txqueuelen 1000  (Ethernet)
>             RX packets 0  bytes 0 (0.0 B)
>             RX errors 0  dropped 0  overruns 0  frame 0
>             TX packets 0  bytes 0 (0.0 B)
>             TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


If you get the sysfs network links correct, then udev should be able to
generate peristent network names.

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v8 1/4] ethtool: move from sample folder to lib folder
  2017-06-21 11:06   ` [PATCH v8 1/4] ethtool: move from sample folder to lib folder Ferruh Yigit
@ 2017-06-26 11:02     ` Bruce Richardson
  0 siblings, 0 replies; 91+ messages in thread
From: Bruce Richardson @ 2017-06-26 11:02 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, anatoly.burakov

On Wed, Jun 21, 2017 at 12:06:48PM +0100, Ferruh Yigit wrote:
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>

This patch fails to compile with gcc 7.1
Comment at error site below.

/Bruce

> ---
> v7:
> * rebase v17.08
> ---
>  config/common_base                                 |  5 ++
>  config/common_linuxapp                             |  1 +
>  doc/api/doxy-api-index.md                          |  3 +-
>  doc/api/doxy-api.conf                              |  1 +
>  doc/guides/prog_guide/ethtool_lib.rst              | 62 ++++++++++++++++++++++
>  doc/guides/prog_guide/index.rst                    |  1 +
>  doc/guides/rel_notes/release_17_08.rst             |  1 +
>  doc/guides/sample_app_ug/ethtool.rst               | 36 ++-----------
>  examples/ethtool/Makefile                          | 24 +++++----
>  examples/ethtool/{ethtool-app => }/ethapp.c        |  2 +-
>  examples/ethtool/{ethtool-app => }/ethapp.h        |  2 +-
>  examples/ethtool/{ethtool-app => }/main.c          |  0
>  lib/Makefile                                       |  2 +
>  .../ethtool/lib => lib/librte_ethtool}/Makefile    | 35 +++++-------
>  .../lib => lib/librte_ethtool}/rte_ethtool.c       | 12 -----
>  .../lib => lib/librte_ethtool}/rte_ethtool.h       | 59 ++++++++++----------
>  lib/librte_ethtool/rte_ethtool_version.map         | 28 ++++++++++
>  mk/rte.app.mk                                      |  1 +
>  18 files changed, 167 insertions(+), 108 deletions(-)

<snip>

>  #include "rte_ethtool.h"
>  
>  #define PKTPOOL_SIZE 512
> @@ -363,20 +360,11 @@ rte_ethtool_net_set_rx_mode(uint8_t port_id)
>  {
>  	uint16_t num_vfs;
>  	struct rte_eth_dev_info dev_info;
> -	uint16_t vf;
>  
>  	memset(&dev_info, 0, sizeof(dev_info));
>  	rte_eth_dev_info_get(port_id, &dev_info);
>  	num_vfs = dev_info.max_vfs;
>  
> -	/* Set VF vf_rx_mode, VF unsupport status is discard */
> -	for (vf = 0; vf < num_vfs; vf++) {
> -#ifdef RTE_LIBRTE_IXGBE_PMD
> -		rte_pmd_ixgbe_set_vf_rxmode(port_id, vf,
> -			ETH_VMDQ_ACCEPT_UNTAG, 0);
> -#endif
> -	}
> -
>  	/* Enable Rx vlan filter, VF unspport status is discard */
>  	rte_eth_dev_set_vlan_offload(port_id, ETH_VLAN_FILTER_MASK);
>  

Compiler gives error about num_vfs being unused. Looking at the code
now, with the removal of the ifdef, it looks like this can be collapsed
down to a 1-line function.

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v8 3/4] rte_ctrl_if: add control interface library
  2017-06-21 11:06   ` [PATCH v8 3/4] rte_ctrl_if: add control interface library Ferruh Yigit
@ 2017-06-26 11:09     ` Bruce Richardson
  2017-06-26 11:30     ` Bruce Richardson
  1 sibling, 0 replies; 91+ messages in thread
From: Bruce Richardson @ 2017-06-26 11:09 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, anatoly.burakov

On Wed, Jun 21, 2017 at 12:06:50PM +0100, Ferruh Yigit wrote:
> This library gets control messages form kernelspace and forwards them to
> librte_ether and returns response back to the kernelspace.
> 
> Library does:
> 1) Trigger Linux virtual interface creation
> 2) Initialize the netlink socket communication
> 3) Provides process() API to the application that does processing the
> received messages
> 
> This library requires corresponding kernel module to be inserted.
> 
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> ---
<snip>
> +static int
> +conrol_interface_rtnl_init(void)

Minor nit, typo in patch code to fix in next version: s/conrol/control/

/Bruce

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v8 3/4] rte_ctrl_if: add control interface library
  2017-06-21 11:06   ` [PATCH v8 3/4] rte_ctrl_if: add control interface library Ferruh Yigit
  2017-06-26 11:09     ` Bruce Richardson
@ 2017-06-26 11:30     ` Bruce Richardson
  1 sibling, 0 replies; 91+ messages in thread
From: Bruce Richardson @ 2017-06-26 11:30 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, anatoly.burakov

On Wed, Jun 21, 2017 at 12:06:50PM +0100, Ferruh Yigit wrote:
> This library gets control messages form kernelspace and forwards them to
> librte_ether and returns response back to the kernelspace.
> 
> Library does:
> 1) Trigger Linux virtual interface creation
> 2) Initialize the netlink socket communication
> 3) Provides process() API to the application that does processing the
> received messages
> 
> This library requires corresponding kernel module to be inserted.
> 
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> ---
> 
I'm getting errors compiling for shared libs after this patch is
applied.

/Bruce

rte_ctrl_if.o: In function `rte_eth_rtnl_destroy':
/home/bruce/dpdk.org/lib/librte_ctrl_if/rte_ctrl_if.c:332: undefined reference to `rte_log'
rte_ctrl_if.o: In function `rte_eth_control_interface_create_one':
rte_ctrl_if.c:(.text+0x2e9): undefined reference to `rte_log'
rte_ctrl_if.c:(.text+0x306): undefined reference to `rte_log'
rte_ctrl_if.c:(.text+0x31e): undefined reference to `rte_log'
rte_ctrl_if.c:(.text+0x336): undefined reference to `rte_log'
rte_ctrl_if.o:rte_ctrl_if.c:(.text+0x359): more undefined references to `rte_log' follow
rte_ctrl_ethtool.o: In function `get_eeprom_length':
/home/bruce/dpdk.org/lib/librte_ctrl_if/rte_ctrl_ethtool.c:137: undefined reference to `rte_ethtool_get_eeprom_len'
rte_ctrl_ethtool.o: In function `rte_eth_dev_ethtool_process':
rte_ctrl_ethtool.c:(.text+0x14e): undefined reference to `rte_ethtool_get_drvinfo'
rte_ctrl_ethtool.c:(.text+0x16b): undefined reference to `rte_ethtool_get_regs_len'
rte_ctrl_ethtool.c:(.text+0x196): undefined reference to `rte_ethtool_get_regs'
rte_ctrl_ethtool.c:(.text+0x1ab): undefined reference to `rte_ethtool_get_link'
rte_ctrl_ethtool.c:(.text+0x1d1): undefined reference to `rte_ethtool_get_eeprom'
rte_ctrl_ethtool.c:(.text+0x1fa): undefined reference to `rte_ethtool_set_eeprom'
rte_ctrl_ethtool.c:(.text+0x216): undefined reference to `rte_ethtool_get_ringparam'
rte_ctrl_ethtool.c:(.text+0x236): undefined reference to `rte_ethtool_set_ringparam'
rte_ctrl_ethtool.c:(.text+0x256): undefined reference to `rte_ethtool_get_pauseparam'
rte_ctrl_ethtool.o: In function `get_reg_len':
/home/bruce/dpdk.org/lib/librte_ctrl_if/rte_ctrl_ethtool.c:80: undefined reference to `rte_ethtool_get_regs_len'
rte_ctrl_ethtool.o: In function `rte_eth_dev_ethtool_process':
rte_ctrl_ethtool.c:(.text+0x282): undefined reference to `rte_ethtool_set_pauseparam'
collect2: error: ld returned 1 exit status

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v8 0/4] Userspace Network Control Interface (UNCI)
  2017-06-21 11:06 ` [PATCH v8 0/4] Userspace Network Control Interface (UNCI) Ferruh Yigit
                     ` (3 preceding siblings ...)
  2017-06-21 11:06   ` [PATCH v8 4/4] ethdev: add control interface support Ferruh Yigit
@ 2017-06-26 11:39   ` Bruce Richardson
  2017-06-29 16:13     ` Ferruh Yigit
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
  5 siblings, 1 reply; 91+ messages in thread
From: Bruce Richardson @ 2017-06-26 11:39 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, anatoly.burakov

On Wed, Jun 21, 2017 at 12:06:47PM +0100, Ferruh Yigit wrote:
> Userspace Network Control Interface (UNCI), (formerly KCP).
> 
> When a NIC bound to the DPDK, it can't be controlled by Linux tools.
> 
> This patch creates a virtual network interface for each DPDK port,
> initial target is to get some data from those interfaces, in next
> step target is to control DPDK ports using virtual interfaces.
> 

I've tried out this set to see how it goes, and apart from a few
compile/link errors with individual patches which I've flagged, I think
the result is great. Running testpmd and seeing the dpdk interfaces
listed in "ifconfig" for example, is a great improvement for usability.
Let's hope we can get this into DPDK as soon as possible.

Some thoughts about the patchset:

1. Do we really need to use a whole new library for the ethtool
functions? Can the UNCI userspace code not just call into ethdev
directly without going through another library?

2. Right now the interfaces are only created on application start, but
are not removed on app close. My first thought is that we should correct
his imbalance, but perhaps it might be better to always have the
interfaces displayed even before/after an app has run. We obviously need
some way of detecting if a process is controlling the ports or not, but
I'm hopeful that should be doable without too much work.

3. From a patchset split point of view, could this set be split up to be
a bit more granular. There are a lot of functions to be performed on
NICs called out in the code, e.g. start/stop, get stats, etc. etc. To
make review easier, should we initially add the kernel module and
userspace parts with just one function supported, and then add in each
additional function in a new patchset, so that we can clearly see the
code for each function isolated from the rest. This is the approach -
adding feature by feature - that is recommended for NIC drivers, and it
might make sense here too.

Otherwise, great work. I think this is a huge improvement in usability
for DPDK, especially if we add in future support for controlling DPDK
interfaces in a (not interfering with the app) safe manner too.

/Bruce

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v8 0/4] Userspace Network Control Interface (UNCI)
  2017-06-26 11:39   ` [PATCH v8 0/4] Userspace Network Control Interface (UNCI) Bruce Richardson
@ 2017-06-29 16:13     ` Ferruh Yigit
  2017-06-30 16:56       ` Ferruh Yigit
  0 siblings, 1 reply; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-29 16:13 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: dev, anatoly.burakov

On 6/26/2017 12:39 PM, Bruce Richardson wrote:
> On Wed, Jun 21, 2017 at 12:06:47PM +0100, Ferruh Yigit wrote:
>> Userspace Network Control Interface (UNCI), (formerly KCP).
>>
>> When a NIC bound to the DPDK, it can't be controlled by Linux tools.
>>
>> This patch creates a virtual network interface for each DPDK port,
>> initial target is to get some data from those interfaces, in next
>> step target is to control DPDK ports using virtual interfaces.
>>
> 
> I've tried out this set to see how it goes, and apart from a few
> compile/link errors with individual patches which I've flagged, I think
> the result is great. Running testpmd and seeing the dpdk interfaces
> listed in "ifconfig" for example, is a great improvement for usability.
> Let's hope we can get this into DPDK as soon as possible.

Thanks for trying this and reviews.

> 
> Some thoughts about the patchset:
> 
> 1. Do we really need to use a whole new library for the ethtool
> functions? Can the UNCI userspace code not just call into ethdev
> directly without going through another library?

We don't have to, but ethtool library in sample folder is wrapper around
ethdev APIs for ethtool functions, that fits well here, and we can
re-use that code.

> 
> 2. Right now the interfaces are only created on application start, but
> are not removed on app close. My first thought is that we should correct
> his imbalance, but perhaps it might be better to always have the
> interfaces displayed even before/after an app has run. We obviously need
> some way of detecting if a process is controlling the ports or not, but
> I'm hopeful that should be doable without too much work.

Yes, currently interfaces should be removed manually via "ip", but this
is because PMD destroy code paths not called during app exit. I am not
sure keeping virtual interfaces always, it looks me better if they
disappear when app exits.

> 
> 3. From a patchset split point of view, could this set be split up to be
> a bit more granular. There are a lot of functions to be performed on
> NICs called out in the code, e.g. start/stop, get stats, etc. etc. To
> make review easier, should we initially add the kernel module and
> userspace parts with just one function supported, and then add in each
> additional function in a new patchset, so that we can clearly see the
> code for each function isolated from the rest. This is the approach -
> adding feature by feature - that is recommended for NIC drivers, and it
> might make sense here too.

Let me try to split patches more.

> 
> Otherwise, great work. I think this is a huge improvement in usability
> for DPDK, especially if we add in future support for controlling DPDK
> interfaces in a (not interfering with the app) safe manner too.
> 
> /Bruce
> 

^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCH v9 00/20] Userspace Network Control Interface (UNCI)
  2017-06-21 11:06 ` [PATCH v8 0/4] Userspace Network Control Interface (UNCI) Ferruh Yigit
                     ` (4 preceding siblings ...)
  2017-06-26 11:39   ` [PATCH v8 0/4] Userspace Network Control Interface (UNCI) Bruce Richardson
@ 2017-06-30 16:51   ` Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 01/20] ethtool: add library skeleton Ferruh Yigit
                       ` (20 more replies)
  5 siblings, 21 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Userspace Network Control Interface (UNCI), (formerly KCP).

When a NIC bound to the DPDK, it can't be controlled by Linux tools.

This patch creates a virtual network interface for each DPDK port,
initial target is to get some data from those interfaces, in next
step target is to control DPDK ports using virtual interfaces.

KNI control path already provides this capability and this work is
based on KNI, but current KNI only supports some devices and requires
application changes. UNCI is improved KNI control related part.

Control messages to the virtual interface moved to the underlying
PMD and response moved back to Linux:

  +-------+
  | dpdk0 |
  +---^---+
      |
      | netlink
      v
+-------------------+
| control interface |
+--------------+    |
+------------+ |    |
| ethtool lib| |    |
+------------+ +----+
+-------------------+
|      ethdev       |
+-------------------+
       |
  +---------+
  | Any PMD |
  +---------+


First patch in the set is moving DPDK ethtool library from sample
application folder to the lib. This library provides ethtool commands
on top of ethdev library.

Second patch introduces a control library, which gets some commands
via netlink and converts these into ethtool or ethdev APIs.
A background thread created to listen commands.

Third patch implements a kernel module, similar to KNI, which is a
simple virtual network driver with netlink communication capability.
This driver pass through all control commands to userspace via netlink.

Forth patch adds control interface create and destroy APIs for ethdev.
This will create Linux interfaces automatically if rte_unci  kernel
module is inserted. Will work as it is if module is not inserted.

The intension is to upstream the Linux kernel module, please provide
comments to make it ready for upstream.


Samples:

Run testpmd with no extra arguments: "testpmd -- -i"
If the rte_unci module inserted two new interfaces will show up:

$ ifconfig dpdk0 && ifconfig dpdk1
dpdk0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 90:e2:ba:0e:49:b8  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

dpdk1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 00:1b:21:76:fa:20  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

The MAC address information already get from actual HW.

(Interfaces are shown down by default)

When data transfer start in testpmd, stats updated accordingly:

$ ifconfig dpdk0 && ifconfig dpdk1
dpdk0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 90:e2:ba:0e:49:b8  txqueuelen 1000  (Ethernet)
        RX packets 9662125409  bytes 553368167417 (515.3 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 9605125821  bytes 518893560100 (483.2 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

dpdk1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 00:1b:21:76:fa:20  txqueuelen 1000  (Ethernet)
        RX packets 9605137856  bytes 552991297017 (515.0 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 9662138670  bytes 518732030928 (483.1 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Or able to get same data via ethtool:

$ ethtool -i dpdk0
driver: net_ixgbe
version: DPDK 17.08.0-rc0
firmware-version: 0x61bf0001
expansion-rom-version:
bus-info: 0000:08:00.0
supports-statistics: no
supports-test: no
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: no

$ ethtool -g dpdk0
Ring parameters for dpdk0:
Pre-set maximums:
RX:             4096
RX Mini:        0
RX Jumbo:       0
TX:             4096
Current hardware settings:
RX:             128
RX Mini:        0
RX Jumbo:       0
TX:             512

---

v9:
* patchset split into more patches
* renamed some structs / variables

---
Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: Bruce Richardson <bruce.richardson@intel.com>
Cc: Anatoly Burakov <anatoly.burakov@intel.com>
---


Ferruh Yigit (20):
  ethtool: add library skeleton
  ethtool: move from sample folder into lib folder
  ethtool: remove PMD specific API call
  ethtool: update header doxygen syntax
  ethtool: enable library
  doc: add ethtool library documentation
  doc: update ethtool sample app doc
  unci: add module skeleton
  unci: add rtnl newlink
  unci: init netlink
  unci: add netlink exec
  unci: add netdevice ops
  unci: add ethtool support
  ctrl_if: add library skeleton
  ctrl_if: add create destroy interface APIs
  ctrl_if: initialize netlink interface
  ctrl_if: process control messages
  ctrl_if: process ethtool messages
  doc: add control interface library documentation
  ethdev: add control interface support

 MAINTAINERS                                        |   8 +
 config/common_base                                 |  15 +
 config/common_linuxapp                             |   3 +
 doc/api/doxy-api-index.md                          |   4 +-
 doc/api/doxy-api.conf                              |   2 +
 doc/guides/prog_guide/ctrl_if_lib.rst              |  50 +++
 doc/guides/prog_guide/ethtool_lib.rst              |  62 ++++
 doc/guides/prog_guide/index.rst                    |   2 +
 doc/guides/rel_notes/release_17_08.rst             |  15 +
 doc/guides/sample_app_ug/ethtool.rst               |  36 +-
 drivers/net/Makefile                               |   4 +
 examples/ethtool/Makefile                          |  24 +-
 examples/ethtool/{ethtool-app => }/ethapp.c        |   0
 examples/ethtool/{ethtool-app => }/ethapp.h        |   0
 examples/ethtool/{ethtool-app => }/main.c          |   0
 lib/Makefile                                       |   4 +
 lib/librte_ctrl_if/Makefile                        |  56 +++
 lib/librte_ctrl_if/rte_ctrl_if.c                   | 347 ++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_if.h                   |  91 +++++
 lib/librte_ctrl_if/rte_ctrl_if_version.map         |   8 +
 lib/librte_ctrl_if/rte_ctrl_process.c              | 390 +++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_process.h              |  54 +++
 lib/librte_ctrl_if/rte_nl.c                        | 292 +++++++++++++++
 lib/librte_ctrl_if/rte_nl.h                        |  48 +++
 lib/librte_eal/common/include/rte_log.h            |   2 +
 lib/librte_eal/linuxapp/Makefile                   |   4 +-
 lib/librte_eal/linuxapp/eal/Makefile               |   1 +
 .../eal/include/exec-env/rte_unci_common.h         | 109 ++++++
 lib/librte_eal/linuxapp/unci/Makefile              |  54 +++
 lib/librte_eal/linuxapp/unci/unci_dev.h            |  50 +++
 lib/librte_eal/linuxapp/unci/unci_ethtool.c        | 293 ++++++++++++++++
 lib/librte_eal/linuxapp/unci/unci_net.c            | 217 ++++++++++++
 lib/librte_eal/linuxapp/unci/unci_nl.c             | 219 ++++++++++++
 lib/librte_ether/rte_ethdev_pci.h                  |  15 +-
 .../ethtool/lib => lib/librte_ethtool}/Makefile    |  35 +-
 .../lib => lib/librte_ethtool}/rte_ethtool.c       |  23 +-
 .../lib => lib/librte_ethtool}/rte_ethtool.h       |  57 +--
 lib/librte_ethtool/rte_ethtool_version.map         |  28 ++
 mk/rte.app.mk                                      |   2 +
 39 files changed, 2507 insertions(+), 117 deletions(-)
 create mode 100644 doc/guides/prog_guide/ctrl_if_lib.rst
 create mode 100644 doc/guides/prog_guide/ethtool_lib.rst
 rename examples/ethtool/{ethtool-app => }/ethapp.c (100%)
 rename examples/ethtool/{ethtool-app => }/ethapp.h (100%)
 rename examples/ethtool/{ethtool-app => }/main.c (100%)
 create mode 100644 lib/librte_ctrl_if/Makefile
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.c
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.h
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if_version.map
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_process.c
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_process.h
 create mode 100644 lib/librte_ctrl_if/rte_nl.c
 create mode 100644 lib/librte_ctrl_if/rte_nl.h
 create mode 100644 lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h
 create mode 100644 lib/librte_eal/linuxapp/unci/Makefile
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_dev.h
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_ethtool.c
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_net.c
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_nl.c
 rename {examples/ethtool/lib => lib/librte_ethtool}/Makefile (76%)
 rename {examples/ethtool/lib => lib/librte_ethtool}/rte_ethtool.c (95%)
 rename {examples/ethtool/lib => lib/librte_ethtool}/rte_ethtool.h (91%)
 create mode 100644 lib/librte_ethtool/rte_ethtool_version.map

-- 
2.13.0

^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCH v9 01/20] ethtool: add library skeleton
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 02/20] ethtool: move from sample folder into lib folder Ferruh Yigit
                       ` (19 subsequent siblings)
  20 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Library is disabled by default.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 MAINTAINERS                                | 3 +++
 config/common_base                         | 5 +++++
 doc/guides/rel_notes/release_17_08.rst     | 1 +
 lib/Makefile                               | 2 ++
 lib/librte_eal/common/include/rte_log.h    | 1 +
 lib/librte_ethtool/rte_ethtool_version.map | 4 ++++
 mk/rte.app.mk                              | 1 +
 7 files changed, 17 insertions(+)
 create mode 100644 lib/librte_ethtool/rte_ethtool_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index f6095efff..b2cf83c8e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -754,6 +754,9 @@ Latency statistics
 M: Reshma Pattan <reshma.pattan@intel.com>
 F: lib/librte_latencystats/
 
+Ethtool
+M: Remy Horton <remy.horton@intel.com>
+F: lib/librte_ethtool/
 
 Test Applications
 -----------------
diff --git a/config/common_base b/config/common_base
index f6aafd17d..c767b1090 100644
--- a/config/common_base
+++ b/config/common_base
@@ -699,6 +699,11 @@ CONFIG_RTE_KNI_PREEMPT_DEFAULT=y
 CONFIG_RTE_LIBRTE_PDUMP=y
 
 #
+# Compile librte_ethtool
+#
+CONFIG_RTE_LIBRTE_ETHTOOL=n
+
+#
 # Compile vhost user library
 #
 CONFIG_RTE_LIBRTE_VHOST=n
diff --git a/doc/guides/rel_notes/release_17_08.rst b/doc/guides/rel_notes/release_17_08.rst
index 842f46f75..dbe1ee906 100644
--- a/doc/guides/rel_notes/release_17_08.rst
+++ b/doc/guides/rel_notes/release_17_08.rst
@@ -186,6 +186,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_distributor.so.1
      librte_eal.so.4
      librte_ethdev.so.6
+   + librte_ethtool.so.1
      librte_hash.so.2
      librte_ip_frag.so.1
      librte_jobstats.so.1
diff --git a/lib/Makefile b/lib/Makefile
index 07e1fd0c5..434237d6e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -106,6 +106,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += librte_reorder
 DEPDIRS-librte_reorder := librte_eal librte_mempool librte_mbuf
 DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += librte_pdump
 DEPDIRS-librte_pdump := librte_eal librte_mempool librte_mbuf librte_ether
+DIRS-$(CONFIG_RTE_LIBRTE_ETHTOOL) += librte_ethtool
+DEPDIRS-librte_ethtool := librte_eal librte_ether
 
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
index 341913851..5b240e8b1 100644
--- a/lib/librte_eal/common/include/rte_log.h
+++ b/lib/librte_eal/common/include/rte_log.h
@@ -87,6 +87,7 @@ extern struct rte_logs rte_logs;
 #define RTE_LOGTYPE_CRYPTODEV 17 /**< Log related to cryptodev. */
 #define RTE_LOGTYPE_EFD       18 /**< Log related to EFD. */
 #define RTE_LOGTYPE_EVENTDEV  19 /**< Log related to eventdev. */
+#define RTE_LOGTYPE_ETHTOOL   20 /**< Log related to ethtool. */
 
 /* these log types can be used in an application */
 #define RTE_LOGTYPE_USER1     24 /**< User-defined log type 1. */
diff --git a/lib/librte_ethtool/rte_ethtool_version.map b/lib/librte_ethtool/rte_ethtool_version.map
new file mode 100644
index 000000000..b6d2840be
--- /dev/null
+++ b/lib/librte_ethtool/rte_ethtool_version.map
@@ -0,0 +1,4 @@
+DPDK_17.08 {
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index bcaf1b382..449bd2f61 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -90,6 +90,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_KVARGS)         += -lrte_kvargs
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF)           += -lrte_mbuf
 _LDLIBS-$(CONFIG_RTE_LIBRTE_NET)            += -lrte_net
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHER)          += -lrte_ethdev
+_LDLIBS-$(CONFIG_RTE_LIBRTE_ETHTOOL)        += -lrte_ethtool
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CRYPTODEV)      += -lrte_cryptodev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV)       += -lrte_eventdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 02/20] ethtool: move from sample folder into lib folder
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 01/20] ethtool: add library skeleton Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 03/20] ethtool: remove PMD specific API call Ferruh Yigit
                       ` (18 subsequent siblings)
  20 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

ethtool library initially developed for ethtool sample application,
moving it to library folder to reuse it.

Sample application will continue to use ethtool library.

Sample application disabled for now, it will be enabled again when
modifications to the ethtool library finished.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 examples/Makefile                                  |  2 +-
 examples/ethtool/Makefile                          | 24 ++++++++-------
 examples/ethtool/{ethtool-app => }/ethapp.c        |  0
 examples/ethtool/{ethtool-app => }/ethapp.h        |  0
 examples/ethtool/{ethtool-app => }/main.c          |  0
 .../ethtool/lib => lib/librte_ethtool}/Makefile    | 35 ++++++++--------------
 .../lib => lib/librte_ethtool}/rte_ethtool.c       |  0
 .../lib => lib/librte_ethtool}/rte_ethtool.h       |  0
 lib/librte_ethtool/rte_ethtool_version.map         | 24 +++++++++++++++
 9 files changed, 51 insertions(+), 34 deletions(-)
 rename examples/ethtool/{ethtool-app => }/ethapp.c (100%)
 rename examples/ethtool/{ethtool-app => }/ethapp.h (100%)
 rename examples/ethtool/{ethtool-app => }/main.c (100%)
 rename {examples/ethtool/lib => lib/librte_ethtool}/Makefile (76%)
 rename {examples/ethtool/lib => lib/librte_ethtool}/rte_ethtool.c (100%)
 rename {examples/ethtool/lib => lib/librte_ethtool}/rte_ethtool.h (100%)

diff --git a/examples/Makefile b/examples/Makefile
index c0e9c3be6..aa1696158 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -40,7 +40,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += bond
 DIRS-y += cmdline
 DIRS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += distributor
-DIRS-y += ethtool
+DIRS-n += ethtool
 DIRS-y += exception_path
 DIRS-$(CONFIG_RTE_LIBRTE_EFD) += server_node_efd
 DIRS-y += helloworld
diff --git a/examples/ethtool/Makefile b/examples/ethtool/Makefile
index 30b42b70e..a774eace0 100644
--- a/examples/ethtool/Makefile
+++ b/examples/ethtool/Makefile
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2015 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -33,20 +33,22 @@ ifeq ($(RTE_SDK),)
 $(error "Please define RTE_SDK environment variable")
 endif
 
-# Default target, can be overwritten by command line or environment
+# Default target, can be overridden by command line or environment
 RTE_TARGET ?= x86_64-native-linuxapp-gcc
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
-$(info This application can only operate in a linuxapp environment, \
-please change the definition of the RTE_TARGET environment variable)
-else
+# binary name
+APP = ethtool
 
-DIRS-y += lib ethtool-app
-endif
+# all source are stored in SRCS-y
+SRCS-y := main.c ethapp.c
+
+#CFLAGS += -O3 -D_GNU_SOURCE -pthread -I$(SRCDIR)/../lib
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
 
-DEPDIRS-ethtool-app := lib
-DEPDIRS-lib := librte_eal librte_ether
+#LDLIBS += -L$(subst ethtool-app,lib,$(RTE_OUTPUT))/lib
+#LDLIBS += -lrte_ethtool
 
-include $(RTE_SDK)/mk/rte.extsubdir.mk
+include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/ethtool/ethtool-app/ethapp.c b/examples/ethtool/ethapp.c
similarity index 100%
rename from examples/ethtool/ethtool-app/ethapp.c
rename to examples/ethtool/ethapp.c
diff --git a/examples/ethtool/ethtool-app/ethapp.h b/examples/ethtool/ethapp.h
similarity index 100%
rename from examples/ethtool/ethtool-app/ethapp.h
rename to examples/ethtool/ethapp.h
diff --git a/examples/ethtool/ethtool-app/main.c b/examples/ethtool/main.c
similarity index 100%
rename from examples/ethtool/ethtool-app/main.c
rename to examples/ethtool/main.c
diff --git a/examples/ethtool/lib/Makefile b/lib/librte_ethtool/Makefile
similarity index 76%
rename from examples/ethtool/lib/Makefile
rename to lib/librte_ethtool/Makefile
index 266babade..f41cad3da 100644
--- a/examples/ethtool/lib/Makefile
+++ b/lib/librte_ethtool/Makefile
@@ -29,35 +29,26 @@
 #   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 #   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-ifeq ($(RTE_SDK),)
-$(error "Please define RTE_SDK environment variable")
-endif
-
-# Default target, can be overwritten by command line or environment
-RTE_TARGET ?= x86_64-native-linuxapp-gcc
-
 include $(RTE_SDK)/mk/rte.vars.mk
 
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
-$(error This application can only operate in a linuxapp environment, \
-please change the definition of the RTE_TARGET environment variable)
-endif
-
+#
 # library name
+#
 LIB = librte_ethtool.a
 
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+EXPORT_MAP := rte_ethtool_version.map
+
 LIBABIVER := 1
 
 # all source are stored in SRC-Y
-SRCS-y := rte_ethtool.c
+SRCS-$(CONFIG_RTE_LIBRTE_ETHTOOL) := rte_ethtool.c
 
-CFLAGS += -O3
-CFLAGS += $(WERROR_FLAGS)
-
-ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
-ifeq ($(CONFIG_RTE_LIBRTE_IXGBE_PMD),y)
-LDLIBS += -lrte_pmd_ixgbe
-endif
-endif
+#
+# Export include files
+#
+SYMLINK-$(CONFIG_RTE_LIBRTE_ETHTOOL)-include += rte_ethtool.h
 
-include $(RTE_SDK)/mk/rte.extlib.mk
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/examples/ethtool/lib/rte_ethtool.c b/lib/librte_ethtool/rte_ethtool.c
similarity index 100%
rename from examples/ethtool/lib/rte_ethtool.c
rename to lib/librte_ethtool/rte_ethtool.c
diff --git a/examples/ethtool/lib/rte_ethtool.h b/lib/librte_ethtool/rte_ethtool.h
similarity index 100%
rename from examples/ethtool/lib/rte_ethtool.h
rename to lib/librte_ethtool/rte_ethtool.h
diff --git a/lib/librte_ethtool/rte_ethtool_version.map b/lib/librte_ethtool/rte_ethtool_version.map
index b6d2840be..a6e756c50 100644
--- a/lib/librte_ethtool/rte_ethtool_version.map
+++ b/lib/librte_ethtool/rte_ethtool_version.map
@@ -1,4 +1,28 @@
 DPDK_17.08 {
+	global:
+
+	rte_ethtool_get_drvinfo;
+	rte_ethtool_get_link;
+	rte_ethtool_get_regs_len;
+	rte_ethtool_get_regs;
+	rte_ethtool_get_eeprom_len;
+	rte_ethtool_get_eeprom;
+	rte_ethtool_set_eeprom;
+	rte_ethtool_get_pauseparam;
+	rte_ethtool_set_pauseparam;
+	rte_ethtool_get_ringparam;
+	rte_ethtool_set_ringparam;
+
+	rte_ethtool_net_open;
+	rte_ethtool_net_stop;
+	rte_ethtool_net_get_mac_addr;
+	rte_ethtool_net_set_mac_addr;
+	rte_ethtool_net_validate_addr;
+	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_net_set_rx_mode;
 
 	local: *;
 };
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 03/20] ethtool: remove PMD specific API call
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 01/20] ethtool: add library skeleton Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 02/20] ethtool: move from sample folder into lib folder Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 04/20] ethtool: update header doxygen syntax Ferruh Yigit
                       ` (17 subsequent siblings)
  20 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

ethtool library has ixgbe specific API call, this needs to be removed
when moved into lib folder, libraries shouldn't have PMD dependencies.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ethtool/rte_ethtool.c | 23 +----------------------
 1 file changed, 1 insertion(+), 22 deletions(-)

diff --git a/lib/librte_ethtool/rte_ethtool.c b/lib/librte_ethtool/rte_ethtool.c
index fabfcb2ba..2807a53ff 100644
--- a/lib/librte_ethtool/rte_ethtool.c
+++ b/lib/librte_ethtool/rte_ethtool.c
@@ -36,9 +36,6 @@
 #include <rte_version.h>
 #include <rte_ethdev.h>
 #include <rte_ether.h>
-#ifdef RTE_LIBRTE_IXGBE_PMD
-#include <rte_pmd_ixgbe.h>
-#endif
 #include "rte_ethtool.h"
 
 #define PKTPOOL_SIZE 512
@@ -361,26 +358,8 @@ rte_ethtool_net_vlan_rx_kill_vid(uint8_t port_id, uint16_t vid)
 int
 rte_ethtool_net_set_rx_mode(uint8_t port_id)
 {
-	uint16_t num_vfs;
-	struct rte_eth_dev_info dev_info;
-	uint16_t vf;
-
-	memset(&dev_info, 0, sizeof(dev_info));
-	rte_eth_dev_info_get(port_id, &dev_info);
-	num_vfs = dev_info.max_vfs;
-
-	/* Set VF vf_rx_mode, VF unsupport status is discard */
-	for (vf = 0; vf < num_vfs; vf++) {
-#ifdef RTE_LIBRTE_IXGBE_PMD
-		rte_pmd_ixgbe_set_vf_rxmode(port_id, vf,
-			ETH_VMDQ_ACCEPT_UNTAG, 0);
-#endif
-	}
-
 	/* Enable Rx vlan filter, VF unspport status is discard */
-	rte_eth_dev_set_vlan_offload(port_id, ETH_VLAN_FILTER_MASK);
-
-	return 0;
+	return rte_eth_dev_set_vlan_offload(port_id, ETH_VLAN_FILTER_MASK);
 }
 
 
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 04/20] ethtool: update header doxygen syntax
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (2 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 03/20] ethtool: remove PMD specific API call Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 05/20] ethtool: enable library Ferruh Yigit
                       ` (16 subsequent siblings)
  20 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Minor corrections and doxygen syntax fixes on library header file.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ethtool/rte_ethtool.h | 57 +++++++++++++++++++++-------------------
 1 file changed, 30 insertions(+), 27 deletions(-)

diff --git a/lib/librte_ethtool/rte_ethtool.h b/lib/librte_ethtool/rte_ethtool.h
index 18f44404b..bcf20870c 100644
--- a/lib/librte_ethtool/rte_ethtool.h
+++ b/lib/librte_ethtool/rte_ethtool.h
@@ -34,11 +34,13 @@
 #ifndef _RTE_ETHTOOL_H_
 #define _RTE_ETHTOOL_H_
 
-/*
+/**
+ * @file
+ *
  * 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_drvinfo:         ethtool_ops::get_driverinfo
  * rte_ethtool_get_link:            ethtool_ops::get_link
  * rte_ethtool_get_regs_len:        ethtool_ops::get_regs_len
  * rte_ethtool_get_regs:            ethtool_ops::get_regs
@@ -47,6 +49,8 @@
  * rte_ethtool_set_eeprom:          ethtool_ops::set_eeprom
  * rte_ethtool_get_pauseparam:      ethtool_ops::get_pauseparam
  * rte_ethtool_set_pauseparam:      ethtool_ops::set_pauseparam
+ * rte_ethtool_get_ringparam:       ethtool_ops::set_ringparam
+ * rte_ethtool_set_ringparam:       ethtool_ops::set_ringparam
  *
  * rte_ethtool_net_open:            net_device_ops::ndo_open
  * rte_ethtool_net_stop:            net_device_ops::ndo_stop
@@ -101,7 +105,7 @@ int rte_ethtool_get_regs_len(uint8_t port_id);
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
- * @param reg
+ * @param regs
  *   A pointer to ethtool_regs that has register information
  * @param data
  *   A pointer to a buffer that is used to retrieve device register content
@@ -112,7 +116,7 @@ int rte_ethtool_get_regs_len(uint8_t port_id);
  *   - others depends on the specific operations implementation.
  */
 int rte_ethtool_get_regs(uint8_t port_id, struct ethtool_regs *regs,
-			    void *data);
+		void *data);
 
 /**
  * Retrieve the Ethernet device link status
@@ -135,7 +139,7 @@ int rte_ethtool_get_link(uint8_t port_id);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @return
- *	 - (> 0) device EEPROM size in bytes
+ *   - (> 0) device EEPROM size in bytes
  *   - (0) device has NO EEPROM
  *   - (-ENOTSUP) if hardware doesn't support.
  *   - (-ENODEV) if *port_id* invalid.
@@ -150,9 +154,9 @@ int rte_ethtool_get_eeprom_len(uint8_t port_id);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param eeprom
- *	 The pointer of ethtool_eeprom that provides eeprom range
+ *   The pointer of ethtool_eeprom that provides eeprom range
  * @param words
- *	 A buffer that holds data read from eeprom
+ *   A buffer that holds data read from eeprom
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -160,7 +164,7 @@ int rte_ethtool_get_eeprom_len(uint8_t port_id);
  *   - others depends on the specific operations implementation.
  */
 int rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
-			      void *words);
+		void *words);
 
 /**
  * Setting EEPROM content based upon eeprom range described in ethtool
@@ -169,9 +173,9 @@ int rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param eeprom
- *	 The pointer of ethtool_eeprom that provides eeprom range
+ *   The pointer of ethtool_eeprom that provides eeprom range
  * @param words
- *	 A buffer that holds data to be written into eeprom
+ *   A buffer that holds data to be written into eeprom
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -180,7 +184,7 @@ int rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
  *   - others depends on the specific operations implementation.
  */
 int rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
-			      void *words);
+		void *words);
 
 /**
  * Retrieve the Ethernet device pause frame configuration according to
@@ -190,8 +194,8 @@ int rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param pause_param
- *	 The pointer of ethtool_coalesce that gets pause frame
- *	 configuration parameters
+ *   The pointer of ethtool_coalesce that gets pause frame
+ *   configuration parameters
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -200,7 +204,7 @@ int rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
  *   - others depends on the specific operations implementation.
  */
 int rte_ethtool_get_pauseparam(uint8_t port_id,
-				   struct ethtool_pauseparam *pause_param);
+		struct ethtool_pauseparam *pause_param);
 
 /**
  * Setting the Ethernet device pause frame configuration according to
@@ -208,8 +212,8 @@ int rte_ethtool_get_pauseparam(uint8_t port_id,
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
- * @param pause_param
- *	 The pointer of ethtool_coalesce that gets ring configuration parameters
+ * @param param
+ *   The pointer of ethtool_coalesce that gets ring configuration parameters
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -218,7 +222,7 @@ int rte_ethtool_get_pauseparam(uint8_t port_id,
  *   - others depends on the specific operations implementation.
  */
 int rte_ethtool_set_pauseparam(uint8_t port_id,
-				   struct ethtool_pauseparam *param);
+		struct ethtool_pauseparam *param);
 
 /**
  * Start the Ethernet device.
@@ -250,7 +254,7 @@ int rte_ethtool_net_stop(uint8_t port_id);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param addr
- *	 MAC address of the Ethernet device.
+ *   MAC address of the Ethernet device.
  * @return
  *   - (0) if successful.
  *   - (-ENODEV) if *port_id* invalid.
@@ -263,7 +267,7 @@ int rte_ethtool_net_get_mac_addr(uint8_t port_id, struct ether_addr *addr);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param addr
- *	 The new MAC addr.
+ *   The new MAC addr.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -279,7 +283,7 @@ int rte_ethtool_net_set_mac_addr(uint8_t port_id, struct ether_addr *addr);
  * @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
+ *   A pointer to a buffer (6-byte, 48bit) for the target MAC address
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -295,7 +299,7 @@ int rte_ethtool_net_validate_addr(uint8_t port_id, struct ether_addr *addr);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param mtu
- *	 New MTU
+ *   New MTU
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -311,7 +315,7 @@ int rte_ethtool_net_change_mtu(uint8_t port_id, int mtu);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param stats
- *	 A pointer to struct rte_eth_stats for statistics parameters
+ *   A pointer to struct rte_eth_stats for statistics parameters
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -327,7 +331,7 @@ int rte_ethtool_net_get_stats64(uint8_t port_id, struct rte_eth_stats *stats);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param vid
- *	 A new VLAN id
+ *   A new VLAN id
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -342,7 +346,7 @@ int rte_ethtool_net_vlan_rx_add_vid(uint8_t port_id, uint16_t vid);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param vid
- *	 A new VLAN id
+ *   A new VLAN id
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -381,7 +385,7 @@ int rte_ethtool_net_set_rx_mode(uint8_t port_id);
  *   are used, and the function only gets parameters for queue 0.
  */
 int rte_ethtool_get_ringparam(uint8_t port_id,
-	struct ethtool_ringparam *ring_param);
+		struct ethtool_ringparam *ring_param);
 
 /**
  * Setting ring parameters for Ethernet device.
@@ -400,8 +404,7 @@ int rte_ethtool_get_ringparam(uint8_t port_id,
  *   are used, and the function only sets parameters for queue 0.
  */
 int rte_ethtool_set_ringparam(uint8_t port_id,
-	struct ethtool_ringparam *ring_param);
-
+		struct ethtool_ringparam *ring_param);
 
 #ifdef __cplusplus
 }
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 05/20] ethtool: enable library
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (3 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 04/20] ethtool: update header doxygen syntax Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 06/20] doc: add ethtool library documentation Ferruh Yigit
                       ` (15 subsequent siblings)
  20 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Enable ethtool library for Linux by default.

Enable ethtool sample application that uses ethtool library.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 config/common_linuxapp | 1 +
 examples/Makefile      | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/config/common_linuxapp b/config/common_linuxapp
index b3cf41b01..33ed11b37 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -40,6 +40,7 @@ CONFIG_RTE_EAL_VFIO=y
 CONFIG_RTE_KNI_KMOD=y
 CONFIG_RTE_LIBRTE_KNI=y
 CONFIG_RTE_LIBRTE_PMD_KNI=y
+CONFIG_RTE_LIBRTE_ETHTOOL=y
 CONFIG_RTE_LIBRTE_VHOST=y
 CONFIG_RTE_LIBRTE_PMD_VHOST=y
 CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
diff --git a/examples/Makefile b/examples/Makefile
index aa1696158..c0e9c3be6 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -40,7 +40,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += bond
 DIRS-y += cmdline
 DIRS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += distributor
-DIRS-n += ethtool
+DIRS-y += ethtool
 DIRS-y += exception_path
 DIRS-$(CONFIG_RTE_LIBRTE_EFD) += server_node_efd
 DIRS-y += helloworld
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 06/20] doc: add ethtool library documentation
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (4 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 05/20] ethtool: enable library Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-07-02 20:18       ` Mcnamara, John
  2017-06-30 16:51     ` [PATCH v9 07/20] doc: update ethtool sample app doc Ferruh Yigit
                       ` (14 subsequent siblings)
  20 siblings, 1 reply; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 doc/api/doxy-api-index.md              |  3 +-
 doc/api/doxy-api.conf                  |  1 +
 doc/guides/prog_guide/ethtool_lib.rst  | 62 ++++++++++++++++++++++++++++++++++
 doc/guides/prog_guide/index.rst        |  1 +
 doc/guides/rel_notes/release_17_08.rst |  5 +++
 5 files changed, 71 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/prog_guide/ethtool_lib.rst

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index f5f1f199f..71350849f 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -161,4 +161,5 @@ There are many libraries, so their headers may be grouped by topics:
   [device metrics]     (@ref rte_metrics.h),
   [bitrate statistics] (@ref rte_bitrate.h),
   [latency statistics] (@ref rte_latencystats.h),
-  [version]            (@ref rte_version.h)
+  [version]            (@ref rte_version.h),
+  [ethtool]            (@ref rte_ethtool.h)
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index ca9194fe0..b66e86541 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -45,6 +45,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           lib/librte_distributor \
                           lib/librte_efd \
                           lib/librte_ether \
+                          lib/librte_ethtool \
                           lib/librte_eventdev \
                           lib/librte_hash \
                           lib/librte_ip_frag \
diff --git a/doc/guides/prog_guide/ethtool_lib.rst b/doc/guides/prog_guide/ethtool_lib.rst
new file mode 100644
index 000000000..a667bcfe3
--- /dev/null
+++ b/doc/guides/prog_guide/ethtool_lib.rst
@@ -0,0 +1,62 @@
+..  BSD LICENSE
+    Copyright(c) 2017 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.
+
+.. _Ethtool_Library:
+
+Ethtool Library
+===============
+
+Ethtool interface
+-----------------
+
+The Ethtool interface is built as a separate library, and implements
+the following functions:
+
+- ``rte_ethtool_get_drvinfo()``
+- ``rte_ethtool_get_regs_len()``
+- ``rte_ethtool_get_regs()``
+- ``rte_ethtool_get_link()``
+- ``rte_ethtool_get_eeprom_len()``
+- ``rte_ethtool_get_eeprom()``
+- ``rte_ethtool_set_eeprom()``
+- ``rte_ethtool_get_pauseparam()``
+- ``rte_ethtool_set_pauseparam()``
+- ``rte_ethtool_net_open()``
+- ``rte_ethtool_net_stop()``
+- ``rte_ethtool_net_get_mac_addr()``
+- ``rte_ethtool_net_set_mac_addr()``
+- ``rte_ethtool_net_validate_addr()``
+- ``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_net_set_rx_mode()``
+- ``rte_ethtool_get_ringparam()``
+- ``rte_ethtool_set_ringparam()``
diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index ef5a02ad5..54f9538ea 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -54,6 +54,7 @@ Programmer's Guide
     reorder_lib
     ip_fragment_reassembly_lib
     pdump_lib
+    ethtool_lib
     multi_proc_support
     kernel_nic_interface
     thread_safety_dpdk_functions
diff --git a/doc/guides/rel_notes/release_17_08.rst b/doc/guides/rel_notes/release_17_08.rst
index dbe1ee906..423877f49 100644
--- a/doc/guides/rel_notes/release_17_08.rst
+++ b/doc/guides/rel_notes/release_17_08.rst
@@ -75,6 +75,11 @@ New Features
 
   Added support for firmwares with multiple Ethernet ports per physical port.
 
+* **Added ethtool library.**
+
+  Ethtool library is wrapper for ethdev library and provides APIs to get data
+  similar to Linux ethtool provides.
+
 
 Resolved Issues
 ---------------
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 07/20] doc: update ethtool sample app doc
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (5 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 06/20] doc: add ethtool library documentation Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-07-02 20:17       ` Mcnamara, John
  2017-06-30 16:51     ` [PATCH v9 08/20] unci: add module skeleton Ferruh Yigit
                       ` (13 subsequent siblings)
  20 siblings, 1 reply; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 doc/guides/sample_app_ug/ethtool.rst | 36 ++++--------------------------------
 1 file changed, 4 insertions(+), 32 deletions(-)

diff --git a/doc/guides/sample_app_ug/ethtool.rst b/doc/guides/sample_app_ug/ethtool.rst
index 67797954d..def48985d 100644
--- a/doc/guides/sample_app_ug/ethtool.rst
+++ b/doc/guides/sample_app_ug/ethtool.rst
@@ -1,6 +1,6 @@
 
 ..  BSD LICENSE
-    Copyright(c) 2015 Intel Corporation. All rights reserved.
+    Copyright(c) 2015-2017 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -71,7 +71,7 @@ The only available options are the standard ones for the EAL:
 
 .. code-block:: console
 
-    ./ethtool-app/ethtool-app/${RTE_TARGET}/ethtool [EAL options]
+    ./${RTE_TARGET}/ethtool [EAL options]
 
 Refer to the *DPDK Getting Started Guide* for general information on
 running applications and the Environment Abstraction Layer (EAL)
@@ -128,33 +128,5 @@ Ethtool Shell
 The foreground part of the Ethtool sample is a console-based
 interface that accepts commands as described in `using the
 application`_. Individual call-back functions handle the detail
-associated with each command, which make use of the functions
-defined in the `Ethtool interface`_ to the DPDK functions.
-
-Ethtool interface
------------------
-
-The Ethtool interface is built as a separate library, and implements
-the following functions:
-
-- ``rte_ethtool_get_drvinfo()``
-- ``rte_ethtool_get_regs_len()``
-- ``rte_ethtool_get_regs()``
-- ``rte_ethtool_get_link()``
-- ``rte_ethtool_get_eeprom_len()``
-- ``rte_ethtool_get_eeprom()``
-- ``rte_ethtool_set_eeprom()``
-- ``rte_ethtool_get_pauseparam()``
-- ``rte_ethtool_set_pauseparam()``
-- ``rte_ethtool_net_open()``
-- ``rte_ethtool_net_stop()``
-- ``rte_ethtool_net_get_mac_addr()``
-- ``rte_ethtool_net_set_mac_addr()``
-- ``rte_ethtool_net_validate_addr()``
-- ``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_net_set_rx_mode()``
-- ``rte_ethtool_get_ringparam()``
-- ``rte_ethtool_set_ringparam()``
+associated with each command, which make use of librte_ethtool
+library.
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 08/20] unci: add module skeleton
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (6 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 07/20] doc: update ethtool sample app doc Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 09/20] unci: add rtnl newlink Ferruh Yigit
                       ` (12 subsequent siblings)
  20 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Base files to have a new kernel module, without actual source code.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 MAINTAINERS                             |  4 +++
 config/common_base                      |  5 ++++
 config/common_linuxapp                  |  1 +
 lib/librte_eal/linuxapp/Makefile        |  4 ++-
 lib/librte_eal/linuxapp/unci/Makefile   | 52 +++++++++++++++++++++++++++++++++
 lib/librte_eal/linuxapp/unci/unci_dev.h | 36 +++++++++++++++++++++++
 lib/librte_eal/linuxapp/unci/unci_net.c | 42 ++++++++++++++++++++++++++
 7 files changed, 143 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_eal/linuxapp/unci/Makefile
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_dev.h
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_net.c

diff --git a/MAINTAINERS b/MAINTAINERS
index b2cf83c8e..9adca546a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -758,6 +758,10 @@ Ethtool
 M: Remy Horton <remy.horton@intel.com>
 F: lib/librte_ethtool/
 
+Linux Userspace Network Control Interface (UNCI)
+M: Ferruh Yigit <ferruh.yigit@intel.com>
+F: lib/librte_eal/linuxapp/unci/
+
 Test Applications
 -----------------
 
diff --git a/config/common_base b/config/common_base
index c767b1090..af92d1932 100644
--- a/config/common_base
+++ b/config/common_base
@@ -704,6 +704,11 @@ CONFIG_RTE_LIBRTE_PDUMP=y
 CONFIG_RTE_LIBRTE_ETHTOOL=n
 
 #
+# Compile Userspace Network Control Interface (UNCI) kernel module
+#
+CONFIG_RTE_UNCI_KMOD=n
+
+#
 # Compile vhost user library
 #
 CONFIG_RTE_LIBRTE_VHOST=n
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 33ed11b37..4deab42c3 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -41,6 +41,7 @@ CONFIG_RTE_KNI_KMOD=y
 CONFIG_RTE_LIBRTE_KNI=y
 CONFIG_RTE_LIBRTE_PMD_KNI=y
 CONFIG_RTE_LIBRTE_ETHTOOL=y
+CONFIG_RTE_UNCI_KMOD=y
 CONFIG_RTE_LIBRTE_VHOST=y
 CONFIG_RTE_LIBRTE_PMD_VHOST=y
 CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
diff --git a/lib/librte_eal/linuxapp/Makefile b/lib/librte_eal/linuxapp/Makefile
index 4794696b6..2d293f1a6 100644
--- a/lib/librte_eal/linuxapp/Makefile
+++ b/lib/librte_eal/linuxapp/Makefile
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,8 @@ DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal
 DIRS-$(CONFIG_RTE_EAL_IGB_UIO) += igb_uio
 DIRS-$(CONFIG_RTE_KNI_KMOD) += kni
 DEPDIRS-kni := eal
+DIRS-$(CONFIG_RTE_UNCI_KMOD) += unci
+DEPDIRS-unci := eal
 DIRS-$(CONFIG_RTE_LIBRTE_XEN_DOM0) += xen_dom0
 DEPDIRS-xen_dom0 := eal
 
diff --git a/lib/librte_eal/linuxapp/unci/Makefile b/lib/librte_eal/linuxapp/unci/Makefile
new file mode 100644
index 000000000..02e354814
--- /dev/null
+++ b/lib/librte_eal/linuxapp/unci/Makefile
@@ -0,0 +1,52 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 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
+
+#
+# module name and path
+#
+MODULE = rte_unci
+
+#
+# CFLAGS
+#
+MODULE_CFLAGS += -I$(SRCDIR)
+MODULE_CFLAGS += -I$(RTE_OUTPUT)/include
+MODULE_CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
+MODULE_CFLAGS += -Wall -Werror
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_UNCI_KMOD) := unci_net.c
+
+include $(RTE_SDK)/mk/rte.module.mk
diff --git a/lib/librte_eal/linuxapp/unci/unci_dev.h b/lib/librte_eal/linuxapp/unci/unci_dev.h
new file mode 100644
index 000000000..0337fa82b
--- /dev/null
+++ b/lib/librte_eal/linuxapp/unci/unci_dev.h
@@ -0,0 +1,36 @@
+/*-
+ * GPL LICENSE SUMMARY
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;
+ *
+ *   The full GNU General Public License is included in this distribution
+ *   in the file called LICENSE.GPL.
+ *
+ *   Contact Information:
+ *   Intel Corporation
+ */
+
+#ifndef _UNCI_DEV_H_
+#define _UNCI_DEV_H_
+
+#include <linux/netdevice.h>
+
+#ifdef pr_fmt
+#undef pr_fmt
+#endif
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+
+#endif /* _UNCI_DEV_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/unci_net.c b/lib/librte_eal/linuxapp/unci/unci_net.c
new file mode 100644
index 000000000..b8ef409d3
--- /dev/null
+++ b/lib/librte_eal/linuxapp/unci/unci_net.c
@@ -0,0 +1,42 @@
+/*-
+ * GPL LICENSE SUMMARY
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;
+ *
+ *   The full GNU General Public License is included in this distribution
+ *   in the file called LICENSE.GPL.
+ *
+ *   Contact Information:
+ *   Intel Corporation
+ */
+
+#include <linux/module.h>
+
+#include "unci_dev.h"
+
+static int __init unci_init(void)
+{
+	return 0;
+}
+module_init(unci_init);
+
+static void __exit unci_exit(void)
+{
+}
+module_exit(unci_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Kernel Module for managing unci devices");
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 09/20] unci: add rtnl newlink
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (7 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 08/20] unci: add module skeleton Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-06-30 17:27       ` Stephen Hemminger
  2017-06-30 16:51     ` [PATCH v9 10/20] unci: init netlink Ferruh Yigit
                       ` (11 subsequent siblings)
  20 siblings, 1 reply; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Use rtnl to create a new interface. Interface is not setup yet.

Pid and port_id should be provided by userspace application that does
the call for interface creation.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_eal/linuxapp/eal/Makefile               |  1 +
 .../eal/include/exec-env/rte_unci_common.h         | 72 ++++++++++++++++++++++
 lib/librte_eal/linuxapp/unci/unci_dev.h            |  5 ++
 lib/librte_eal/linuxapp/unci/unci_net.c            | 38 +++++++++++-
 4 files changed, 115 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h

diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 640afd088..401160bc9 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -127,6 +127,7 @@ CFLAGS_eal_thread.o += -Wno-return-type
 endif
 
 INC := rte_interrupts.h rte_kni_common.h rte_dom0_common.h
+INC += rte_unci_common.h
 
 SYMLINK-$(CONFIG_RTE_EXEC_ENV_LINUXAPP)-include/exec-env := \
 	$(addprefix include/exec-env/,$(INC))
diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h
new file mode 100644
index 000000000..d90423a07
--- /dev/null
+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h
@@ -0,0 +1,72 @@
+/*-
+ *   This file is provided under a dual BSD/LGPLv2 license.  When using or
+ *   redistributing this file, you may do so under either license.
+ *
+ *   GNU LESSER GENERAL PUBLIC LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2.1 of the GNU Lesser General Public License
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this program;
+ *
+ *   Contact Information:
+ *   Intel Corporation
+ *
+ *
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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_UNCI_COMMON_H_
+#define _RTE_UNCI_COMMON_H_
+
+#define UNCI_DEVICE "unci"
+
+enum {
+	IFLA_UNCI_UNSPEC,
+	IFLA_UNCI_PORTID,
+	IFLA_UNCI_PID,
+	__IFLA_UNCI_MAX,
+};
+
+#define IFLA_UNCI_MAX (__IFLA_UNCI_MAX - 1)
+
+#endif /* _RTE_UNCI_COMMON_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/unci_dev.h b/lib/librte_eal/linuxapp/unci/unci_dev.h
index 0337fa82b..b0a215f1b 100644
--- a/lib/librte_eal/linuxapp/unci/unci_dev.h
+++ b/lib/librte_eal/linuxapp/unci/unci_dev.h
@@ -26,11 +26,16 @@
 #define _UNCI_DEV_H_
 
 #include <linux/netdevice.h>
+#include <exec-env/rte_unci_common.h>
 
 #ifdef pr_fmt
 #undef pr_fmt
 #endif
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+struct unci_dev {
+	u8 port_id;
+	u32 pid;
+};
 
 #endif /* _UNCI_DEV_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/unci_net.c b/lib/librte_eal/linuxapp/unci/unci_net.c
index b8ef409d3..ee23b0e4d 100644
--- a/lib/librte_eal/linuxapp/unci/unci_net.c
+++ b/lib/librte_eal/linuxapp/unci/unci_net.c
@@ -23,17 +23,53 @@
  */
 
 #include <linux/module.h>
+#include <net/rtnetlink.h>
 
 #include "unci_dev.h"
 
+static const struct net_device_ops unci_net_netdev_ops = { 0 };
+
+static void unci_net_setup(struct net_device *dev)
+{
+	ether_setup(dev);
+	dev->netdev_ops = &unci_net_netdev_ops;
+}
+
+static int unci_net_newlink(struct net *net, struct net_device *dev,
+		struct nlattr *tb[], struct nlattr *data[])
+{
+	struct unci_dev *unci = netdev_priv(dev);
+
+	if (data && data[IFLA_UNCI_PORTID])
+		unci->port_id = nla_get_u8(data[IFLA_UNCI_PORTID]);
+	else
+		unci->port_id = 0;
+
+	if (data && data[IFLA_UNCI_PID])
+		unci->pid = nla_get_u32(data[IFLA_UNCI_PID]);
+	else
+		unci->pid = 0;
+
+	return register_netdevice(dev);
+}
+
+static struct rtnl_link_ops unci_link_ops __read_mostly = {
+	.kind = UNCI_DEVICE,
+	.priv_size = sizeof(struct unci_dev),
+	.setup = unci_net_setup,
+	.maxtype = IFLA_UNCI_MAX,
+	.newlink = unci_net_newlink,
+};
+
 static int __init unci_init(void)
 {
-	return 0;
+	return rtnl_link_register(&unci_link_ops);
 }
 module_init(unci_init);
 
 static void __exit unci_exit(void)
 {
+	rtnl_link_unregister(&unci_link_ops);
 }
 module_exit(unci_exit);
 
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 10/20] unci: init netlink
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (8 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 09/20] unci: add rtnl newlink Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-06-30 17:28       ` Stephen Hemminger
  2017-06-30 17:29       ` Stephen Hemminger
  2017-06-30 16:51     ` [PATCH v9 11/20] unci: add netlink exec Ferruh Yigit
                       ` (10 subsequent siblings)
  20 siblings, 2 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Initialize netlink socket.

Userspace application will connect to the socket for data transfer.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 .../eal/include/exec-env/rte_unci_common.h         | 14 ++++++
 lib/librte_eal/linuxapp/unci/Makefile              |  1 +
 lib/librte_eal/linuxapp/unci/unci_dev.h            |  3 ++
 lib/librte_eal/linuxapp/unci/unci_net.c            |  2 +
 lib/librte_eal/linuxapp/unci/unci_nl.c             | 55 ++++++++++++++++++++++
 5 files changed, 75 insertions(+)
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_nl.c

diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h
index d90423a07..a14c463a0 100644
--- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h
+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h
@@ -60,6 +60,20 @@
 
 #define UNCI_DEVICE "unci"
 
+#define UNCI_NL_GRP 31
+
+#define UNCI_NL_MSG_LEN 500
+struct unci_nl_msg {
+	uint32_t cmd_id;
+	uint8_t port_id;
+	uint32_t flag;
+	uint8_t input_buffer[UNCI_NL_MSG_LEN];
+	uint8_t output_buffer[UNCI_NL_MSG_LEN];
+	size_t input_buffer_len;
+	size_t output_buffer_len;
+	int err;
+};
+
 enum {
 	IFLA_UNCI_UNSPEC,
 	IFLA_UNCI_PORTID,
diff --git a/lib/librte_eal/linuxapp/unci/Makefile b/lib/librte_eal/linuxapp/unci/Makefile
index 02e354814..c2a81be7d 100644
--- a/lib/librte_eal/linuxapp/unci/Makefile
+++ b/lib/librte_eal/linuxapp/unci/Makefile
@@ -48,5 +48,6 @@ MODULE_CFLAGS += -Wall -Werror
 # all source are stored in SRCS-y
 #
 SRCS-$(CONFIG_RTE_UNCI_KMOD) := unci_net.c
+SRCS-$(CONFIG_RTE_UNCI_KMOD) += unci_nl.c
 
 include $(RTE_SDK)/mk/rte.module.mk
diff --git a/lib/librte_eal/linuxapp/unci/unci_dev.h b/lib/librte_eal/linuxapp/unci/unci_dev.h
index b0a215f1b..668574167 100644
--- a/lib/librte_eal/linuxapp/unci/unci_dev.h
+++ b/lib/librte_eal/linuxapp/unci/unci_dev.h
@@ -38,4 +38,7 @@ struct unci_dev {
 	u32 pid;
 };
 
+void unci_nl_init(void);
+void unci_nl_release(void);
+
 #endif /* _UNCI_DEV_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/unci_net.c b/lib/librte_eal/linuxapp/unci/unci_net.c
index ee23b0e4d..131769c37 100644
--- a/lib/librte_eal/linuxapp/unci/unci_net.c
+++ b/lib/librte_eal/linuxapp/unci/unci_net.c
@@ -63,6 +63,7 @@ static struct rtnl_link_ops unci_link_ops __read_mostly = {
 
 static int __init unci_init(void)
 {
+	unci_nl_init();
 	return rtnl_link_register(&unci_link_ops);
 }
 module_init(unci_init);
@@ -70,6 +71,7 @@ module_init(unci_init);
 static void __exit unci_exit(void)
 {
 	rtnl_link_unregister(&unci_link_ops);
+	unci_nl_release();
 }
 module_exit(unci_exit);
 
diff --git a/lib/librte_eal/linuxapp/unci/unci_nl.c b/lib/librte_eal/linuxapp/unci/unci_nl.c
new file mode 100644
index 000000000..9d07e9822
--- /dev/null
+++ b/lib/librte_eal/linuxapp/unci/unci_nl.c
@@ -0,0 +1,55 @@
+/*-
+ * GPL LICENSE SUMMARY
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;
+ *   The full GNU General Public License is included in this distribution
+ *   in the file called LICENSE.GPL.
+ *
+ *   Contact Information:
+ *   Intel Corporation
+ */
+
+#include <net/sock.h>
+
+#include "unci_dev.h"
+
+static struct sock *nl_sock;
+static struct mutex sync_lock;
+
+static void nl_recv(struct sk_buff *skb)
+{
+	struct nlmsghdr *nlh;
+	struct unci_nl_msg nl_msg;
+
+	nlh = (struct nlmsghdr *)skb->data;
+
+	memcpy(&nl_msg, NLMSG_DATA(nlh), sizeof(struct unci_nl_msg));
+	pr_debug("CMD: %u\n", nl_msg.cmd_id);
+}
+
+static struct netlink_kernel_cfg cfg = {
+	.input = nl_recv,
+};
+
+void unci_nl_init(void)
+{
+	nl_sock = netlink_kernel_create(&init_net, UNCI_NL_GRP, &cfg);
+	mutex_init(&sync_lock);
+}
+
+void unci_nl_release(void)
+{
+	netlink_kernel_release(nl_sock);
+}
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 11/20] unci: add netlink exec
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (9 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 10/20] unci: init netlink Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 12/20] unci: add netdevice ops Ferruh Yigit
                       ` (9 subsequent siblings)
  20 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Add netlink exec function, which sends a message to userspace and waits
and receives the response from userspace.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 .../eal/include/exec-env/rte_unci_common.h         |   6 +
 lib/librte_eal/linuxapp/unci/unci_dev.h            |   4 +
 lib/librte_eal/linuxapp/unci/unci_net.c            |   5 +
 lib/librte_eal/linuxapp/unci/unci_nl.c             | 164 +++++++++++++++++++++
 4 files changed, 179 insertions(+)

diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h
index a14c463a0..474f62606 100644
--- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h
+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h
@@ -74,6 +74,12 @@ struct unci_nl_msg {
 	int err;
 };
 
+enum unci_ethtool_msg_flag {
+	UNCI_MSG_FLAG_NONE,
+	UNCI_MSG_FLAG_REQUEST,
+	UNCI_MSG_FLAG_RESPONSE,
+};
+
 enum {
 	IFLA_UNCI_UNSPEC,
 	IFLA_UNCI_PORTID,
diff --git a/lib/librte_eal/linuxapp/unci/unci_dev.h b/lib/librte_eal/linuxapp/unci/unci_dev.h
index 668574167..75a4098bd 100644
--- a/lib/librte_eal/linuxapp/unci/unci_dev.h
+++ b/lib/librte_eal/linuxapp/unci/unci_dev.h
@@ -36,9 +36,13 @@
 struct unci_dev {
 	u8 port_id;
 	u32 pid;
+	struct completion msg_received;
+	u32 nb_timedout_msg;
 };
 
 void unci_nl_init(void);
 void unci_nl_release(void);
+int unci_nl_exec(u32 cmd, struct net_device *dev, void *in_data,
+		size_t in_len, void *out_data, size_t out_len);
 
 #endif /* _UNCI_DEV_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/unci_net.c b/lib/librte_eal/linuxapp/unci/unci_net.c
index 131769c37..72099e596 100644
--- a/lib/librte_eal/linuxapp/unci/unci_net.c
+++ b/lib/librte_eal/linuxapp/unci/unci_net.c
@@ -31,8 +31,13 @@ static const struct net_device_ops unci_net_netdev_ops = { 0 };
 
 static void unci_net_setup(struct net_device *dev)
 {
+	struct unci_dev *unci;
+
 	ether_setup(dev);
 	dev->netdev_ops = &unci_net_netdev_ops;
+
+	unci = netdev_priv(dev);
+	init_completion(&unci->msg_received);
 }
 
 static int unci_net_newlink(struct net *net, struct net_device *dev,
diff --git a/lib/librte_eal/linuxapp/unci/unci_nl.c b/lib/librte_eal/linuxapp/unci/unci_nl.c
index 9d07e9822..a0a317cca 100644
--- a/lib/librte_eal/linuxapp/unci/unci_nl.c
+++ b/lib/librte_eal/linuxapp/unci/unci_nl.c
@@ -25,9 +25,85 @@
 
 #include "unci_dev.h"
 
+#define UNCI_CMD_TIMEOUT 500 /* ms */
+
+static struct response_buffer {
+	int magic; /* for sanity check */
+	void *buffer;
+	size_t length;
+	struct completion *msg_received;
+	int *err;
+	u32 in_use;
+} response_buffer;
+
 static struct sock *nl_sock;
 static struct mutex sync_lock;
 
+static int unci_response_buffer_register(int magic, void *buffer, size_t length,
+		struct completion *msg_received, int *err)
+{
+	if (!response_buffer.in_use) {
+		response_buffer.magic = magic;
+		response_buffer.buffer = buffer;
+		response_buffer.length = length;
+		response_buffer.msg_received = msg_received;
+		response_buffer.err = err;
+		response_buffer.in_use = 1;
+		return 0;
+	}
+
+	return 1;
+}
+
+static void unci_response_buffer_unregister(int magic)
+{
+	if (response_buffer.in_use) {
+		if (magic == response_buffer.magic) {
+			response_buffer.magic = -1;
+			response_buffer.buffer = NULL;
+			response_buffer.length = 0;
+			response_buffer.msg_received = NULL;
+			response_buffer.err = NULL;
+			response_buffer.in_use = 0;
+		} else {
+			pr_err("Unregister magic mismatch\n");
+		}
+	}
+}
+
+static void nl_recv_user_request(struct unci_nl_msg *nl_msg)
+{
+	/* Userspace requests not supported yet */
+	pr_debug("Request from userspace received\n");
+}
+
+static void nl_recv_user_response(struct unci_nl_msg *nl_msg)
+{
+	struct completion *msg_received;
+	size_t recv_len;
+	size_t expected_len;
+
+	if (response_buffer.in_use) {
+		if (response_buffer.buffer != NULL) {
+			recv_len = nl_msg->output_buffer_len;
+			expected_len = response_buffer.length;
+
+			memcpy(response_buffer.buffer,
+					nl_msg->output_buffer,
+					response_buffer.length);
+
+			if (nl_msg->err == 0 && recv_len != expected_len)
+				pr_info("Expected and received len not match "
+					"%zu - %zu\n", recv_len, expected_len);
+		}
+
+		*response_buffer.err = nl_msg->err;
+		msg_received = response_buffer.msg_received;
+		unci_response_buffer_unregister(response_buffer.magic);
+		complete(msg_received);
+	}
+}
+
 static void nl_recv(struct sk_buff *skb)
 {
 	struct nlmsghdr *nlh;
@@ -37,6 +113,94 @@ static void nl_recv(struct sk_buff *skb)
 
 	memcpy(&nl_msg, NLMSG_DATA(nlh), sizeof(struct unci_nl_msg));
 	pr_debug("CMD: %u\n", nl_msg.cmd_id);
+
+	if (nl_msg.flag & UNCI_MSG_FLAG_REQUEST) {
+		nl_recv_user_request(&nl_msg);
+		return;
+	}
+
+	nl_recv_user_response(&nl_msg);
+}
+
+static int unci_nl_send(u32 cmd_id, u8 port_id, u32 pid, void *in_data,
+		size_t in_data_len)
+{
+	struct sk_buff *skb;
+	struct nlmsghdr *nlh;
+	struct unci_nl_msg nl_msg;
+
+	if (pid == 0)
+		return -1;
+
+	memset(&nl_msg, 0, sizeof(struct unci_nl_msg));
+	nl_msg.cmd_id = cmd_id;
+	nl_msg.port_id = port_id;
+
+	if (in_data) {
+		if (in_data_len == 0 || in_data_len > UNCI_NL_MSG_LEN)
+			return -EINVAL;
+		nl_msg.input_buffer_len = in_data_len;
+		memcpy(nl_msg.input_buffer, in_data, in_data_len);
+	}
+
+	skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct unci_nl_msg)), GFP_ATOMIC);
+	nlh = nlmsg_put(skb, 0, 0, NLMSG_DONE, sizeof(struct unci_nl_msg), 0);
+
+	NETLINK_CB(skb).dst_group = 0;
+
+	memcpy(nlmsg_data(nlh), &nl_msg, sizeof(struct unci_nl_msg));
+
+	nlmsg_unicast(nl_sock, skb, pid);
+	pr_debug("Sent cmd:%u port:%u pid:%u\n", cmd_id, port_id, pid);
+
+	return 0;
+}
+
+int unci_nl_exec(u32 cmd, struct net_device *dev, void *in_data,
+		size_t in_data_len, void *out_data, size_t out_data_len)
+{
+	struct unci_dev *unci = netdev_priv(dev);
+	int err = -EINVAL;
+	int ret;
+
+	if (out_data_len > UNCI_NL_MSG_LEN) {
+		pr_err("Message is too big to receive:%zu\n", out_data_len);
+		return err;
+	}
+
+	mutex_lock(&sync_lock);
+	ret = unci_response_buffer_register(cmd, out_data, out_data_len,
+			&unci->msg_received, &err);
+	if (ret) {
+		mutex_unlock(&sync_lock);
+		return -EINVAL;
+	}
+
+	ret = unci_nl_send(cmd, unci->port_id, unci->pid, in_data, in_data_len);
+	if (ret) {
+		unci_response_buffer_unregister(response_buffer.magic);
+		mutex_unlock(&sync_lock);
+		return ret;
+	}
+
+	ret = wait_for_completion_interruptible_timeout(&unci->msg_received,
+			 msecs_to_jiffies(UNCI_CMD_TIMEOUT));
+	if (ret == 0 || err < 0) {
+		unci_response_buffer_unregister(response_buffer.magic);
+		mutex_unlock(&sync_lock);
+		if (ret == 0) { /* timeout */
+			unci->nb_timedout_msg++;
+			pr_info("Command timed-out for port:%u cmd:%u (%u)\n",
+				unci->port_id, cmd, unci->nb_timedout_msg);
+			return -EINVAL;
+		}
+		pr_debug("Command return error for port:%d cmd:%d err:%d\n",
+				unci->port_id, cmd, err);
+		return err;
+	}
+	mutex_unlock(&sync_lock);
+
+	return 0;
 }
 
 static struct netlink_kernel_cfg cfg = {
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 12/20] unci: add netdevice ops
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (10 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 11/20] unci: add netlink exec Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 13/20] unci: add ethtool support Ferruh Yigit
                       ` (8 subsequent siblings)
  20 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Add ndos for virtual interface. Almost all ndos use netlink exec
to pass command to userspace and read response.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 .../eal/include/exec-env/rte_unci_common.h         |  17 +++
 lib/librte_eal/linuxapp/unci/unci_net.c            | 132 ++++++++++++++++++++-
 2 files changed, 148 insertions(+), 1 deletion(-)

diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h
index 474f62606..3daa8a6ec 100644
--- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h
+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h
@@ -89,4 +89,21 @@ enum {
 
 #define IFLA_UNCI_MAX (__IFLA_UNCI_MAX - 1)
 
+/*
+ * Request id.
+ */
+enum unci_req_id {
+	UNCI_REQ_UNKNOWN = (1 << 16),
+	UNCI_REQ_CHANGE_MTU,
+	UNCI_REQ_CFG_NETWORK_IF,
+	UNCI_REQ_GET_STATS,
+	UNCI_REQ_GET_MAC,
+	UNCI_REQ_SET_MAC,
+	UNCI_REQ_START_PORT,
+	UNCI_REQ_STOP_PORT,
+	UNCI_REQ_SET_PROMISC,
+	UNCI_REQ_SET_ALLMULTI,
+	UNCI_REQ_MAX,
+};
+
 #endif /* _RTE_UNCI_COMMON_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/unci_net.c b/lib/librte_eal/linuxapp/unci/unci_net.c
index 72099e596..2ce337a48 100644
--- a/lib/librte_eal/linuxapp/unci/unci_net.c
+++ b/lib/librte_eal/linuxapp/unci/unci_net.c
@@ -22,12 +22,142 @@
  *   Intel Corporation
  */
 
+#include <linux/version.h>
 #include <linux/module.h>
+#include <linux/etherdevice.h>
 #include <net/rtnetlink.h>
 
 #include "unci_dev.h"
 
-static const struct net_device_ops unci_net_netdev_ops = { 0 };
+static int unci_net_init(struct net_device *dev)
+{
+	u8 mac[ETH_ALEN] = {0};
+
+	unci_nl_exec(UNCI_REQ_GET_MAC, dev, NULL, 0, mac, ETH_ALEN);
+	memcpy(dev->dev_addr, mac, dev->addr_len);
+	return 0;
+}
+
+static int unci_net_open(struct net_device *dev)
+{
+	/* DPDK port already started, stop it first */
+	unci_nl_exec(UNCI_REQ_STOP_PORT, dev, NULL, 0, NULL, 0);
+	unci_nl_exec(UNCI_REQ_START_PORT, dev, NULL, 0, NULL, 0);
+	netif_start_queue(dev);
+	return 0;
+}
+
+static int unci_net_close(struct net_device *dev)
+{
+	unci_nl_exec(UNCI_REQ_STOP_PORT, dev, NULL, 0, NULL, 0);
+	netif_stop_queue(dev);
+	return 0;
+}
+
+static int unci_net_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
+}
+
+static void unci_net_change_rx_flags(struct net_device *dev, int flags)
+{
+	u32 on = 1;
+	u32 off = 0;
+
+	if (flags & IFF_PROMISC)
+		unci_nl_exec(UNCI_REQ_SET_PROMISC, dev,
+				dev->flags & IFF_PROMISC ?  &on : &off,
+				sizeof(u32), NULL, 0);
+
+	if (flags & IFF_ALLMULTI)
+		unci_nl_exec(UNCI_REQ_SET_ALLMULTI, dev,
+				dev->flags & IFF_ALLMULTI ?  &on : &off,
+				sizeof(u32), NULL, 0);
+}
+
+static int unci_net_set_mac(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr = p;
+	int err;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	err = unci_nl_exec(UNCI_REQ_SET_MAC, dev, addr->sa_data,
+			dev->addr_len, NULL, 0);
+	if (err < 0)
+		return -EADDRNOTAVAIL;
+
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	return 0;
+}
+
+static int unci_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	return -EOPNOTSUPP;
+}
+
+/*
+ * Configuration changes (passed on by ifconfig)
+ */
+static int unci_net_config(struct net_device *dev, struct ifmap *map)
+{
+	if (dev->flags & IFF_UP)
+		return -EBUSY;
+
+	return -EOPNOTSUPP;
+}
+
+static int unci_net_change_mtu(struct net_device *dev, int new_mtu)
+{
+	int err = 0;
+
+	err = unci_nl_exec(UNCI_REQ_CHANGE_MTU, dev, &new_mtu, sizeof(int),
+			NULL, 0);
+
+	if (err == 0)
+		dev->mtu = new_mtu;
+
+	return err;
+}
+
+static void unci_net_stats64(struct net_device *dev,
+		struct rtnl_link_stats64 *stats)
+{
+	int err;
+
+	err = unci_nl_exec(UNCI_REQ_GET_STATS, dev, NULL, 0,
+			stats, sizeof(struct rtnl_link_stats64));
+}
+
+#if (KERNEL_VERSION(3, 9, 0) <= LINUX_VERSION_CODE)
+static int unci_net_change_carrier(struct net_device *dev, bool new_carrier)
+{
+	if (new_carrier)
+		netif_carrier_on(dev);
+	else
+		netif_carrier_off(dev);
+	return 0;
+}
+#endif
+
+static const struct net_device_ops unci_net_netdev_ops = {
+	.ndo_init = unci_net_init,
+	.ndo_open = unci_net_open,
+	.ndo_stop = unci_net_close,
+	.ndo_start_xmit = unci_net_xmit,
+	.ndo_change_rx_flags = unci_net_change_rx_flags,
+	.ndo_set_mac_address = unci_net_set_mac,
+	.ndo_do_ioctl = unci_net_ioctl,
+	.ndo_set_config = unci_net_config,
+	.ndo_change_mtu = unci_net_change_mtu,
+	.ndo_get_stats64 = unci_net_stats64,
+#if (KERNEL_VERSION(3, 9, 0) <= LINUX_VERSION_CODE)
+	.ndo_change_carrier = unci_net_change_carrier,
+#endif
+};
 
 static void unci_net_setup(struct net_device *dev)
 {
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 13/20] unci: add ethtool support
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (11 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 12/20] unci: add netdevice ops Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 14/20] ctrl_if: add library skeleton Ferruh Yigit
                       ` (7 subsequent siblings)
  20 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Add ethtool support to the virtual interface. Ethtool functions also use
netlink exec to get data from userspace.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_eal/linuxapp/unci/Makefile       |   1 +
 lib/librte_eal/linuxapp/unci/unci_dev.h     |   2 +
 lib/librte_eal/linuxapp/unci/unci_ethtool.c | 293 ++++++++++++++++++++++++++++
 lib/librte_eal/linuxapp/unci/unci_net.c     |   2 +
 4 files changed, 298 insertions(+)
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_ethtool.c

diff --git a/lib/librte_eal/linuxapp/unci/Makefile b/lib/librte_eal/linuxapp/unci/Makefile
index c2a81be7d..25d20d94d 100644
--- a/lib/librte_eal/linuxapp/unci/Makefile
+++ b/lib/librte_eal/linuxapp/unci/Makefile
@@ -49,5 +49,6 @@ MODULE_CFLAGS += -Wall -Werror
 #
 SRCS-$(CONFIG_RTE_UNCI_KMOD) := unci_net.c
 SRCS-$(CONFIG_RTE_UNCI_KMOD) += unci_nl.c
+SRCS-$(CONFIG_RTE_UNCI_KMOD) += unci_ethtool.c
 
 include $(RTE_SDK)/mk/rte.module.mk
diff --git a/lib/librte_eal/linuxapp/unci/unci_dev.h b/lib/librte_eal/linuxapp/unci/unci_dev.h
index 75a4098bd..01a759de6 100644
--- a/lib/librte_eal/linuxapp/unci/unci_dev.h
+++ b/lib/librte_eal/linuxapp/unci/unci_dev.h
@@ -45,4 +45,6 @@ void unci_nl_release(void);
 int unci_nl_exec(u32 cmd, struct net_device *dev, void *in_data,
 		size_t in_len, void *out_data, size_t out_len);
 
+void unci_set_ethtool_ops(struct net_device *netdev);
+
 #endif /* _UNCI_DEV_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/unci_ethtool.c b/lib/librte_eal/linuxapp/unci/unci_ethtool.c
new file mode 100644
index 000000000..13106fab3
--- /dev/null
+++ b/lib/librte_eal/linuxapp/unci/unci_ethtool.c
@@ -0,0 +1,293 @@
+/*-
+ * GPL LICENSE SUMMARY
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;
+ *
+ *   The full GNU General Public License is included in this distribution
+ *   in the file called LICENSE.GPL.
+ *
+ *   Contact Information:
+ *   Intel Corporation
+ */
+
+#include "unci_dev.h"
+
+#define ETHTOOL_GEEPROM_LEN 99
+#define ETHTOOL_GREGS_LEN 98
+#define ETHTOOL_GSSET_COUNT 97
+
+static int unci_check_if_running(struct net_device *dev)
+{
+	return 0;
+}
+
+static void unci_get_drvinfo(struct net_device *dev,
+		struct ethtool_drvinfo *info)
+{
+	int ret;
+
+	ret = unci_nl_exec(info->cmd, dev, NULL, 0,
+			info, sizeof(struct ethtool_drvinfo));
+	if (ret < 0)
+		memset(info, 0, sizeof(struct ethtool_drvinfo));
+}
+
+static int unci_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	return unci_nl_exec(ecmd->cmd, dev, NULL, 0,
+			ecmd, sizeof(struct ethtool_cmd));
+}
+
+static int unci_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	return unci_nl_exec(ecmd->cmd, dev, ecmd, sizeof(struct ethtool_cmd),
+			NULL, 0);
+}
+
+static void unci_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	int ret;
+
+	ret = unci_nl_exec(wol->cmd, dev, NULL, 0,
+			wol, sizeof(struct ethtool_wolinfo));
+	if (ret < 0)
+		memset(wol, 0, sizeof(struct ethtool_wolinfo));
+}
+
+static int unci_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	return unci_nl_exec(wol->cmd, dev, wol, sizeof(struct ethtool_wolinfo),
+			NULL, 0);
+}
+
+static int unci_nway_reset(struct net_device *dev)
+{
+	return unci_nl_exec(ETHTOOL_NWAY_RST, dev, NULL, 0, NULL, 0);
+}
+
+static u32 unci_get_link(struct net_device *dev)
+{
+	u32 data;
+	int ret;
+
+	ret = unci_nl_exec(ETHTOOL_GLINK, dev, NULL, 0, &data, sizeof(u32));
+	if (ret < 0)
+		return 0;
+
+	return data;
+}
+
+static int unci_get_eeprom_len(struct net_device *dev)
+{
+	int data;
+	int ret;
+
+	ret = unci_nl_exec(ETHTOOL_GEEPROM_LEN, dev, NULL, 0,
+			&data, sizeof(int));
+	if (ret < 0)
+		return 0;
+
+	return data;
+}
+
+static int unci_get_eeprom(struct net_device *dev,
+		struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct ethtool_eeprom eeprom_tmp;
+	int ret = 0;
+	int remaining;
+	u32 offset = 0;
+
+	eeprom_tmp = *eeprom;
+
+	remaining = eeprom_tmp.len;
+	while (remaining > 0 && ret == 0) {
+		eeprom_tmp.len = min(remaining, UNCI_NL_MSG_LEN);
+
+		ret = unci_nl_exec(eeprom_tmp.cmd, dev,
+				&eeprom_tmp, sizeof(struct ethtool_eeprom),
+				data + offset, eeprom_tmp.len);
+		eeprom_tmp.offset += eeprom_tmp.len;
+		offset += eeprom_tmp.len;
+		remaining -= eeprom_tmp.len;
+	}
+
+	return ret;
+}
+
+static int unci_set_eeprom(struct net_device *dev,
+		struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct ethtool_eeprom *eeprom_tmp;
+	int ret = 0;
+	u32 remaining;
+	u32 offset = 0;
+	u32 payload;
+
+	if (sizeof(struct ethtool_eeprom) > UNCI_NL_MSG_LEN)
+		return -1;
+
+	eeprom_tmp = kmalloc(UNCI_NL_MSG_LEN, GFP_KERNEL);
+	payload = UNCI_NL_MSG_LEN - sizeof(struct ethtool_eeprom);
+
+	*eeprom_tmp = *eeprom;
+	remaining = eeprom->len;
+
+	while (remaining > 0 && ret == 0) {
+		eeprom_tmp->len = min(remaining, payload);
+
+		memcpy(eeprom_tmp->data, data + offset, payload);
+
+		ret = unci_nl_exec(eeprom->cmd, dev, eeprom,
+				UNCI_NL_MSG_LEN, NULL, 0);
+
+		eeprom_tmp->offset += eeprom_tmp->len;
+		offset += eeprom_tmp->len;
+		remaining -= eeprom_tmp->len;
+	}
+
+	kfree(eeprom_tmp);
+
+	return ret;
+}
+
+static void unci_get_ringparam(struct net_device *dev,
+		struct ethtool_ringparam *ring)
+{
+	unci_nl_exec(ring->cmd, dev, NULL, 0,
+			ring, sizeof(struct ethtool_ringparam));
+}
+
+static int unci_set_ringparam(struct net_device *dev,
+		struct ethtool_ringparam *ring)
+{
+	return unci_nl_exec(ring->cmd, dev, ring,
+			sizeof(struct ethtool_ringparam), NULL, 0);
+}
+
+static void unci_get_pauseparam(struct net_device *dev,
+		struct ethtool_pauseparam *pause)
+{
+	unci_nl_exec(pause->cmd, dev, NULL, 0,
+			pause, sizeof(struct ethtool_pauseparam));
+}
+
+static int unci_set_pauseparam(struct net_device *dev,
+		struct ethtool_pauseparam *pause)
+{
+	return unci_nl_exec(pause->cmd, dev, pause,
+			sizeof(struct ethtool_pauseparam), NULL, 0);
+}
+
+static u32 unci_get_msglevel(struct net_device *dev)
+{
+	u32 data;
+	int ret;
+
+	ret = unci_nl_exec(ETHTOOL_GMSGLVL, dev, NULL, 0, &data, sizeof(u32));
+	if (ret < 0)
+		return 0;
+
+	return data;
+}
+
+static void unci_set_msglevel(struct net_device *dev, u32 data)
+{
+	unci_nl_exec(ETHTOOL_SMSGLVL, dev, &data, sizeof(u32), NULL, 0);
+}
+
+static int unci_get_regs_len(struct net_device *dev)
+{
+	int data;
+	int ret;
+
+	ret = unci_nl_exec(ETHTOOL_GREGS_LEN, dev, NULL, 0, &data, sizeof(int));
+	if (ret < 0)
+		return 0;
+
+	return data;
+}
+
+static void unci_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+		void *p)
+{
+	struct ethtool_regs regs_tmp;
+	u32 len = regs->len;
+
+	regs_tmp = *regs;
+
+	if (len > UNCI_NL_MSG_LEN) {
+		len = UNCI_NL_MSG_LEN;
+		regs_tmp.len = len;
+	}
+
+	unci_nl_exec(regs->cmd, dev, &regs_tmp, sizeof(struct ethtool_regs),
+			p, len);
+}
+
+static void unci_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+	unci_nl_exec(ETHTOOL_GSTRINGS, dev, &stringset, sizeof(u32), data, 0);
+}
+
+static int unci_get_sset_count(struct net_device *dev, int sset)
+{
+	int data;
+	int ret;
+
+	ret = unci_nl_exec(ETHTOOL_GSSET_COUNT, dev, &sset, sizeof(int),
+			&data, sizeof(int));
+	if (ret < 0)
+		return 0;
+
+	return data;
+}
+
+static void unci_get_ethtool_stats(struct net_device *dev,
+		struct ethtool_stats *stats, u64 *data)
+{
+	unci_nl_exec(stats->cmd, dev, stats, sizeof(struct ethtool_stats),
+			data, stats->n_stats);
+}
+
+static const struct ethtool_ops unci_ethtool_ops = {
+	.begin			= unci_check_if_running,
+	.get_drvinfo		= unci_get_drvinfo,
+	.get_settings		= unci_get_settings,
+	.set_settings		= unci_set_settings,
+	.get_regs_len		= unci_get_regs_len,
+	.get_regs		= unci_get_regs,
+	.get_wol		= unci_get_wol,
+	.set_wol		= unci_set_wol,
+	.nway_reset		= unci_nway_reset,
+	.get_link		= unci_get_link,
+	.get_eeprom_len		= unci_get_eeprom_len,
+	.get_eeprom		= unci_get_eeprom,
+	.set_eeprom		= unci_set_eeprom,
+	.get_ringparam		= unci_get_ringparam,
+	.set_ringparam		= unci_set_ringparam,
+	.get_pauseparam		= unci_get_pauseparam,
+	.set_pauseparam		= unci_set_pauseparam,
+	.get_msglevel		= unci_get_msglevel,
+	.set_msglevel		= unci_set_msglevel,
+	.get_strings		= unci_get_strings,
+	.get_sset_count		= unci_get_sset_count,
+	.get_ethtool_stats	= unci_get_ethtool_stats,
+};
+
+void unci_set_ethtool_ops(struct net_device *netdev)
+{
+	netdev->ethtool_ops = &unci_ethtool_ops;
+}
diff --git a/lib/librte_eal/linuxapp/unci/unci_net.c b/lib/librte_eal/linuxapp/unci/unci_net.c
index 2ce337a48..e83136382 100644
--- a/lib/librte_eal/linuxapp/unci/unci_net.c
+++ b/lib/librte_eal/linuxapp/unci/unci_net.c
@@ -168,6 +168,8 @@ static void unci_net_setup(struct net_device *dev)
 
 	unci = netdev_priv(dev);
 	init_completion(&unci->msg_received);
+
+	unci_set_ethtool_ops(dev);
 }
 
 static int unci_net_newlink(struct net *net, struct net_device *dev,
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 14/20] ctrl_if: add library skeleton
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (12 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 13/20] unci: add ethtool support Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 15/20] ctrl_if: add create destroy interface APIs Ferruh Yigit
                       ` (6 subsequent siblings)
  20 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Add base files for new control interface library.

Control interface is on top of ethtool and ethdev libraries.

Control interface connects to the netlink socket provided by Linux
kernel and passes commands received via netlink interface to the
network drivers.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 MAINTAINERS                                |  1 +
 config/common_base                         |  5 +++
 config/common_linuxapp                     |  1 +
 doc/guides/rel_notes/release_17_08.rst     |  1 +
 lib/Makefile                               |  2 ++
 lib/librte_ctrl_if/Makefile                | 53 +++++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_if.c           | 34 ++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_if.h           | 57 ++++++++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_if_version.map |  4 +++
 lib/librte_eal/common/include/rte_log.h    |  1 +
 mk/rte.app.mk                              |  1 +
 11 files changed, 160 insertions(+)
 create mode 100644 lib/librte_ctrl_if/Makefile
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.c
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.h
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index 9adca546a..0c23dff8a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -761,6 +761,7 @@ F: lib/librte_ethtool/
 Linux Userspace Network Control Interface (UNCI)
 M: Ferruh Yigit <ferruh.yigit@intel.com>
 F: lib/librte_eal/linuxapp/unci/
+F: lib/librte_ctrl_if/
 
 Test Applications
 -----------------
diff --git a/config/common_base b/config/common_base
index af92d1932..4bb6b6bda 100644
--- a/config/common_base
+++ b/config/common_base
@@ -709,6 +709,11 @@ CONFIG_RTE_LIBRTE_ETHTOOL=n
 CONFIG_RTE_UNCI_KMOD=n
 
 #
+# Compile librte_ctrl_if
+#
+CONFIG_RTE_LIBRTE_CTRL_IF=n
+
+#
 # Compile vhost user library
 #
 CONFIG_RTE_LIBRTE_VHOST=n
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 4deab42c3..209a6d3d1 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -42,6 +42,7 @@ CONFIG_RTE_LIBRTE_KNI=y
 CONFIG_RTE_LIBRTE_PMD_KNI=y
 CONFIG_RTE_LIBRTE_ETHTOOL=y
 CONFIG_RTE_UNCI_KMOD=y
+CONFIG_RTE_LIBRTE_CTRL_IF=y
 CONFIG_RTE_LIBRTE_VHOST=y
 CONFIG_RTE_LIBRTE_PMD_VHOST=y
 CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
diff --git a/doc/guides/rel_notes/release_17_08.rst b/doc/guides/rel_notes/release_17_08.rst
index 423877f49..e21d4e17c 100644
--- a/doc/guides/rel_notes/release_17_08.rst
+++ b/doc/guides/rel_notes/release_17_08.rst
@@ -188,6 +188,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_cfgfile.so.2
      librte_cmdline.so.2
      librte_cryptodev.so.2
+   + librte_ctrl_if.so.1
      librte_distributor.so.1
      librte_eal.so.4
      librte_ethdev.so.6
diff --git a/lib/Makefile b/lib/Makefile
index 434237d6e..99ee7e224 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -108,6 +108,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += librte_pdump
 DEPDIRS-librte_pdump := librte_eal librte_mempool librte_mbuf librte_ether
 DIRS-$(CONFIG_RTE_LIBRTE_ETHTOOL) += librte_ethtool
 DEPDIRS-librte_ethtool := librte_eal librte_ether
+DIRS-$(CONFIG_RTE_LIBRTE_CTRL_IF) += librte_ctrl_if
+DEPDIRS-librte_ctrl_if := librte_eal librte_ether librte_ethtool
 
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
diff --git a/lib/librte_ctrl_if/Makefile b/lib/librte_ctrl_if/Makefile
new file mode 100644
index 000000000..c682af4c4
--- /dev/null
+++ b/lib/librte_ctrl_if/Makefile
@@ -0,0 +1,53 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 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_ctrl_if.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+EXPORT_MAP := rte_ctrl_if_version.map
+
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) := rte_ctrl_if.c
+
+#
+# Export include files
+#
+SYMLINK-$(CONFIG_RTE_LIBRTE_CTRL_IF)-include += rte_ctrl_if.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_ctrl_if/rte_ctrl_if.c b/lib/librte_ctrl_if/rte_ctrl_if.c
new file mode 100644
index 000000000..45a3a07cf
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_if.c
@@ -0,0 +1,34 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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_ctrl_if.h"
diff --git a/lib/librte_ctrl_if/rte_ctrl_if.h b/lib/librte_ctrl_if/rte_ctrl_if.h
new file mode 100644
index 000000000..04a6983bb
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_if.h
@@ -0,0 +1,57 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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_CTRL_IF_H_
+#define _RTE_CTRL_IF_H_
+
+/**
+ * @file
+ *
+ * Control Interface Library for RTE
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <exec-env/rte_unci_common.h>
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_CTRL_IF_H_ */
diff --git a/lib/librte_ctrl_if/rte_ctrl_if_version.map b/lib/librte_ctrl_if/rte_ctrl_if_version.map
new file mode 100644
index 000000000..b6d2840be
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_if_version.map
@@ -0,0 +1,4 @@
+DPDK_17.08 {
+
+	local: *;
+};
diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
index 5b240e8b1..3727fc5f1 100644
--- a/lib/librte_eal/common/include/rte_log.h
+++ b/lib/librte_eal/common/include/rte_log.h
@@ -88,6 +88,7 @@ extern struct rte_logs rte_logs;
 #define RTE_LOGTYPE_EFD       18 /**< Log related to EFD. */
 #define RTE_LOGTYPE_EVENTDEV  19 /**< Log related to eventdev. */
 #define RTE_LOGTYPE_ETHTOOL   20 /**< Log related to ethtool. */
+#define RTE_LOGTYPE_CTRL_IF   21 /**< Log related to control interface. */
 
 /* these log types can be used in an application */
 #define RTE_LOGTYPE_USER1     24 /**< User-defined log type 1. */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 449bd2f61..866bd41c5 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -91,6 +91,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF)           += -lrte_mbuf
 _LDLIBS-$(CONFIG_RTE_LIBRTE_NET)            += -lrte_net
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHER)          += -lrte_ethdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHTOOL)        += -lrte_ethtool
+_LDLIBS-$(CONFIG_RTE_LIBRTE_CTRL_IF)        += -lrte_ctrl_if
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CRYPTODEV)      += -lrte_cryptodev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV)       += -lrte_eventdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 15/20] ctrl_if: add create destroy interface APIs
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (13 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 14/20] ctrl_if: add library skeleton Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 16/20] ctrl_if: initialize netlink interface Ferruh Yigit
                       ` (5 subsequent siblings)
  20 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Library provides two APIs to create and destroy interfaces.

rtnl used to create or destroy interfaces.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ctrl_if/rte_ctrl_if.c           | 304 +++++++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_if.h           |  34 ++++
 lib/librte_ctrl_if/rte_ctrl_if_version.map |   4 +
 3 files changed, 342 insertions(+)

diff --git a/lib/librte_ctrl_if/rte_ctrl_if.c b/lib/librte_ctrl_if/rte_ctrl_if.c
index 45a3a07cf..8b0718969 100644
--- a/lib/librte_ctrl_if/rte_ctrl_if.c
+++ b/lib/librte_ctrl_if/rte_ctrl_if.c
@@ -31,4 +31,308 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <fcntl.h>
+#include <stdint.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <rte_log.h>
 #include "rte_ctrl_if.h"
+
+#define NAMESZ 32
+#define IFNAME "dpdk"
+#define BUFSZ 1024
+
+static int unci_rtnl_fd = -1;
+static uint32_t unci_fd_ref;
+
+struct unci_request {
+	struct nlmsghdr nlmsg;
+	uint8_t buf[BUFSZ];
+};
+
+static int
+control_interface_rtnl_init(void)
+{
+	struct sockaddr_nl src;
+	int ret;
+
+	unci_rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+	if (unci_rtnl_fd < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Socket for create failed\n");
+		return -1;
+	}
+
+	memset(&src, 0, sizeof(struct sockaddr_nl));
+
+	src.nl_family = AF_NETLINK;
+	src.nl_pid = getpid();
+
+	ret = bind(unci_rtnl_fd, (struct sockaddr *)&src,
+			sizeof(struct sockaddr_nl));
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Bind for create failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+control_interface_init(void)
+{
+	int ret;
+
+	ret = control_interface_rtnl_init();
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Failed to initialize rtnetlink\n");
+		return -1;
+	}
+
+	return ret;
+}
+
+static int
+control_interface_ref_get(void)
+{
+	int ret = 0;
+
+	if (unci_fd_ref == 0)
+		ret = control_interface_init();
+
+	if (ret == 0)
+		unci_fd_ref++;
+	else
+		RTE_LOG(ERR, CTRL_IF,
+				"Failed to initialize control interface\n");
+
+	return unci_fd_ref;
+}
+
+static void
+control_interface_release(void)
+{
+	close(unci_rtnl_fd);
+}
+
+static int
+control_interface_ref_put(void)
+{
+	if (unci_fd_ref == 0)
+		return 0;
+
+	unci_fd_ref--;
+
+	if (unci_fd_ref == 0)
+		control_interface_release();
+
+	return unci_fd_ref;
+}
+
+static int
+add_attr(struct unci_request *req, uint16_t type, void *buf, size_t len)
+{
+	struct rtattr *rta;
+	int nlmsg_len;
+
+	nlmsg_len = NLMSG_ALIGN(req->nlmsg.nlmsg_len);
+	rta = (struct rtattr *)((char *)&req->nlmsg + nlmsg_len);
+	if (nlmsg_len + RTA_LENGTH(len) > sizeof(struct unci_request))
+		return -1;
+	rta->rta_type = type;
+	rta->rta_len = RTA_LENGTH(len);
+	memcpy(RTA_DATA(rta), buf, len);
+	req->nlmsg.nlmsg_len = nlmsg_len + RTA_LENGTH(len);
+
+	return 0;
+}
+
+static struct
+rtattr *add_attr_nested(struct unci_request *req, unsigned short type)
+{
+	struct rtattr *rta;
+	uint32_t nlmsg_len;
+
+	nlmsg_len = NLMSG_ALIGN(req->nlmsg.nlmsg_len);
+	rta = (struct rtattr *)((uint8_t *)&req->nlmsg + nlmsg_len);
+	if (nlmsg_len + RTA_LENGTH(0) > sizeof(struct unci_request))
+		return NULL;
+	rta->rta_type = type;
+	rta->rta_len = nlmsg_len;
+	req->nlmsg.nlmsg_len = nlmsg_len + RTA_LENGTH(0);
+
+	return rta;
+}
+
+static void
+end_attr_nested(struct unci_request *req, struct rtattr *rta)
+{
+	rta->rta_len = req->nlmsg.nlmsg_len - rta->rta_len;
+}
+
+static int
+rte_eth_rtnl_create(uint8_t port_id)
+{
+	struct unci_request req;
+	struct ifinfomsg *info;
+	struct rtattr *rta1;
+	struct rtattr *rta2;
+	uint32_t pid = getpid();
+	char name[NAMESZ];
+	char type[NAMESZ];
+	struct iovec iov;
+	struct msghdr msg;
+	struct sockaddr_nl nladdr;
+	int ret;
+	uint8_t buf[BUFSZ];
+
+	memset(&req, 0, sizeof(struct unci_request));
+
+	req.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+	req.nlmsg.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
+	req.nlmsg.nlmsg_flags |= NLM_F_ACK;
+	req.nlmsg.nlmsg_type = RTM_NEWLINK;
+
+	info = NLMSG_DATA(&req.nlmsg);
+
+	info->ifi_family = AF_UNSPEC;
+	info->ifi_index = 0;
+
+	snprintf(name, NAMESZ, IFNAME"%u", port_id);
+	ret = add_attr(&req, IFLA_IFNAME, name, strlen(name) + 1);
+	if (ret < 0)
+		return -1;
+
+	rta1 = add_attr_nested(&req, IFLA_LINKINFO);
+	if (rta1 == NULL)
+		return -1;
+
+	snprintf(type, NAMESZ, UNCI_DEVICE);
+	ret = add_attr(&req, IFLA_INFO_KIND, type, strlen(type) + 1);
+	if (ret < 0)
+		return -1;
+
+	rta2 = add_attr_nested(&req, IFLA_INFO_DATA);
+	if (rta2 == NULL)
+		return -1;
+
+	ret = add_attr(&req, IFLA_UNCI_PORTID, &port_id, sizeof(uint8_t));
+	if (ret < 0)
+		return -1;
+
+	ret = add_attr(&req, IFLA_UNCI_PID, &pid, sizeof(uint32_t));
+	if (ret < 0)
+		return -1;
+
+	end_attr_nested(&req, rta2);
+	end_attr_nested(&req, rta1);
+
+	memset(&nladdr, 0, sizeof(nladdr));
+	nladdr.nl_family = AF_NETLINK;
+
+	iov.iov_base = (void *)&req.nlmsg;
+	iov.iov_len = req.nlmsg.nlmsg_len;
+
+	memset(&msg, 0, sizeof(struct msghdr));
+	msg.msg_name = &nladdr;
+	msg.msg_namelen = sizeof(nladdr);
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+
+	ret = sendmsg(unci_rtnl_fd, &msg, 0);
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Send for create failed %d.\n", errno);
+		return -1;
+	}
+
+	memset(buf, 0, sizeof(buf));
+	iov.iov_base = buf;
+	iov.iov_len = sizeof(buf);
+
+	ret = recvmsg(unci_rtnl_fd, &msg, 0);
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Recv for create failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+int
+rte_eth_control_interface_create_one(uint8_t port_id)
+{
+	int ret;
+
+	if (control_interface_ref_get() != 0) {
+		ret = rte_eth_rtnl_create(port_id);
+		RTE_LOG(DEBUG, CTRL_IF,
+			"Control interface %s for port:%u\n",
+			ret < 0 ? "failed" : "created", port_id);
+	}
+
+	return 0;
+}
+
+static int
+rte_eth_rtnl_destroy(uint8_t port_id)
+{
+	struct unci_request req;
+	struct ifinfomsg *info;
+	char name[NAMESZ];
+	struct iovec iov;
+	struct msghdr msg;
+	struct sockaddr_nl nladdr;
+	int ret;
+
+	memset(&req, 0, sizeof(struct unci_request));
+
+	req.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+	req.nlmsg.nlmsg_flags = NLM_F_REQUEST;
+	req.nlmsg.nlmsg_type = RTM_DELLINK;
+
+	info = NLMSG_DATA(&req.nlmsg);
+
+	info->ifi_family = AF_UNSPEC;
+	info->ifi_index = 0;
+
+	snprintf(name, NAMESZ, IFNAME"%u", port_id);
+	ret = add_attr(&req, IFLA_IFNAME, name, strlen(name) + 1);
+	if (ret < 0)
+		return -1;
+
+	memset(&nladdr, 0, sizeof(nladdr));
+	nladdr.nl_family = AF_NETLINK;
+
+	iov.iov_base = (void *)&req.nlmsg;
+	iov.iov_len = req.nlmsg.nlmsg_len;
+
+	memset(&msg, 0, sizeof(struct msghdr));
+	msg.msg_name = &nladdr;
+	msg.msg_namelen = sizeof(nladdr);
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+
+	ret = sendmsg(unci_rtnl_fd, &msg, 0);
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Send for destroy failed\n");
+		return -1;
+	}
+	return 0;
+}
+
+int
+rte_eth_control_interface_destroy_one(uint8_t port_id)
+{
+	rte_eth_rtnl_destroy(port_id);
+	control_interface_ref_put();
+	RTE_LOG(DEBUG, CTRL_IF, "Control interface destroyed for port:%u\n",
+			port_id);
+
+	return 0;
+}
diff --git a/lib/librte_ctrl_if/rte_ctrl_if.h b/lib/librte_ctrl_if/rte_ctrl_if.h
index 04a6983bb..13ede38a8 100644
--- a/lib/librte_ctrl_if/rte_ctrl_if.h
+++ b/lib/librte_ctrl_if/rte_ctrl_if.h
@@ -49,6 +49,40 @@ extern "C" {
 
 #include <exec-env/rte_unci_common.h>
 
+/**
+ * Creates control interfaces (Linux virtual network interface)for
+ * given ethdev port.
+ *
+ * This API opens device created by supportive kernel module and initializes
+ * kernel communication interface.
+ *
+ * With first interface created, a pthread created to receive the control
+ * messages.
+ *
+ * If supportive kernel module is not inserted this API will return
+ * an error.
+ *
+ * @param port_id
+ *  port id to create virtual interface
+ * @return
+ *  0 on success.
+ *  Negative value on error.
+ */
+int rte_eth_control_interface_create_one(uint8_t port_id);
+
+/**
+ * Destroys control interfaces.
+ *
+ * This API close device created by supportive kernel module and release
+ * underlying communication interface.
+ *
+ * @return
+ * @param port_id
+ *  port id to destroy virtual interface
+ *  0 on success.
+ *  Negative value on error.
+ */
+int rte_eth_control_interface_destroy_one(uint8_t port_id);
 
 #ifdef __cplusplus
 }
diff --git a/lib/librte_ctrl_if/rte_ctrl_if_version.map b/lib/librte_ctrl_if/rte_ctrl_if_version.map
index b6d2840be..b658a0ee0 100644
--- a/lib/librte_ctrl_if/rte_ctrl_if_version.map
+++ b/lib/librte_ctrl_if/rte_ctrl_if_version.map
@@ -1,4 +1,8 @@
 DPDK_17.08 {
+	global:
+
+	rte_eth_control_interface_create_one;
+	rte_eth_control_interface_destroy_one;
 
 	local: *;
 };
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 16/20] ctrl_if: initialize netlink interface
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (14 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 15/20] ctrl_if: add create destroy interface APIs Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 17/20] ctrl_if: process control messages Ferruh Yigit
                       ` (4 subsequent siblings)
  20 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Initialize netlink sockets to exchange data between kernelspace.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ctrl_if/Makefile      |   2 +
 lib/librte_ctrl_if/rte_ctrl_if.c |   9 +++
 lib/librte_ctrl_if/rte_nl.c      | 158 +++++++++++++++++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_nl.h      |  48 ++++++++++++
 4 files changed, 217 insertions(+)
 create mode 100644 lib/librte_ctrl_if/rte_nl.c
 create mode 100644 lib/librte_ctrl_if/rte_nl.h

diff --git a/lib/librte_ctrl_if/Makefile b/lib/librte_ctrl_if/Makefile
index c682af4c4..0da04f7d0 100644
--- a/lib/librte_ctrl_if/Makefile
+++ b/lib/librte_ctrl_if/Makefile
@@ -38,12 +38,14 @@ LIB = librte_ctrl_if.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lpthread
 
 EXPORT_MAP := rte_ctrl_if_version.map
 
 LIBABIVER := 1
 
 SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) := rte_ctrl_if.c
+SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) += rte_nl.c
 
 #
 # Export include files
diff --git a/lib/librte_ctrl_if/rte_ctrl_if.c b/lib/librte_ctrl_if/rte_ctrl_if.c
index 8b0718969..a26699be7 100644
--- a/lib/librte_ctrl_if/rte_ctrl_if.c
+++ b/lib/librte_ctrl_if/rte_ctrl_if.c
@@ -44,6 +44,7 @@
 
 #include <rte_log.h>
 #include "rte_ctrl_if.h"
+#include "rte_nl.h"
 
 #define NAMESZ 32
 #define IFNAME "dpdk"
@@ -95,6 +96,13 @@ control_interface_init(void)
 		return -1;
 	}
 
+	ret = control_interface_nl_init();
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Failed to initialize netlink\n");
+		close(unci_rtnl_fd);
+		unci_rtnl_fd = -1;
+	}
+
 	return ret;
 }
 
@@ -119,6 +127,7 @@ static void
 control_interface_release(void)
 {
 	close(unci_rtnl_fd);
+	control_interface_nl_release();
 }
 
 static int
diff --git a/lib/librte_ctrl_if/rte_nl.c b/lib/librte_ctrl_if/rte_nl.c
new file mode 100644
index 000000000..e88b3fc91
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_nl.c
@@ -0,0 +1,158 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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 <string.h>
+#include <unistd.h>
+
+#include <sys/socket.h>
+#include <linux/netlink.h>
+
+#include <rte_spinlock.h>
+#include <rte_log.h>
+#include "rte_nl.h"
+#include "rte_ctrl_if.h"
+
+#define MAX_PAYLOAD sizeof(struct unci_nl_msg)
+
+struct ctrl_if_nl {
+	union {
+		struct nlmsghdr nlh;
+		uint8_t nlmsg[NLMSG_SPACE(MAX_PAYLOAD)];
+	};
+	struct msghdr msg;
+	struct iovec iov;
+	struct sockaddr_nl dest_addr;
+};
+
+static int sock_fd = -1;
+static pthread_t thread_id;
+
+static struct ctrl_if_nl nl_s;
+static struct ctrl_if_nl nl_r;
+
+static void *
+nl_recv(void *arg)
+{
+	int ret;
+
+	for (;;) {
+		ret = recvmsg(sock_fd, &nl_r.msg, 0);
+		if (ret < 0)
+			continue;
+
+		if ((unsigned int)ret < sizeof(struct unci_nl_msg)) {
+			RTE_LOG(WARNING, CTRL_IF,
+					"Received %d bytes, payload %zu\n",
+					ret, sizeof(struct unci_nl_msg));
+			continue;
+		}
+	}
+
+	return arg;
+}
+
+static void
+nl_setup_header(struct ctrl_if_nl *nl)
+{
+	nl->dest_addr.nl_family = AF_NETLINK;
+	nl->dest_addr.nl_pid = 0;   /*  For Linux Kernel */
+	nl->dest_addr.nl_groups = 0;
+
+	memset(nl->nlmsg, 0, NLMSG_SPACE(MAX_PAYLOAD));
+
+	/* Fill the netlink message header */
+	nl->nlh.nlmsg_len = NLMSG_LENGTH(MAX_PAYLOAD);
+	nl->nlh.nlmsg_pid = getpid();  /* self pid */
+	nl->nlh.nlmsg_flags = 0;
+
+	nl->iov.iov_base = (void *)nl->nlmsg;
+	nl->iov.iov_len = nl->nlh.nlmsg_len;
+	memset(&nl->msg, 0, sizeof(struct msghdr));
+	nl->msg.msg_name = (void *)&nl->dest_addr;
+	nl->msg.msg_namelen = sizeof(struct sockaddr_nl);
+	nl->msg.msg_iov = &nl->iov;
+	nl->msg.msg_iovlen = 1;
+}
+
+static int
+nl_socket_init(void)
+{
+	struct sockaddr_nl src_addr;
+	int fd;
+	int ret;
+
+	fd = socket(PF_NETLINK, SOCK_RAW, UNCI_NL_GRP);
+	if (fd < 0)
+		return -1;
+
+	src_addr.nl_family = AF_NETLINK;
+	src_addr.nl_pid = getpid();
+	ret = bind(fd, (struct sockaddr *)&src_addr, sizeof(src_addr));
+	if (ret) {
+		close(fd);
+		return -1;
+	}
+
+	nl_setup_header(&nl_s);
+	nl_setup_header(&nl_r);
+
+	return fd;
+}
+
+int
+control_interface_nl_init(void)
+{
+	int ret;
+
+	sock_fd = nl_socket_init();
+	if (sock_fd < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Failed to initialize netlink socket\n");
+		return -1;
+	}
+
+	ret = pthread_create(&thread_id, NULL, nl_recv, NULL);
+	if (ret != 0) {
+		RTE_LOG(ERR, CTRL_IF, "Failed to create receive thread\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+void
+control_interface_nl_release(void)
+{
+	pthread_cancel(thread_id);
+	pthread_join(thread_id, NULL);
+	close(sock_fd);
+}
diff --git a/lib/librte_ctrl_if/rte_nl.h b/lib/librte_ctrl_if/rte_nl.h
new file mode 100644
index 000000000..05a61e193
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_nl.h
@@ -0,0 +1,48 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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_NL_H_
+#define _RTE_NL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int control_interface_nl_init(void);
+void control_interface_nl_release(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_NL_H_ */
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 17/20] ctrl_if: process control messages
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (15 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 16/20] ctrl_if: initialize netlink interface Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 18/20] ctrl_if: process ethtool messages Ferruh Yigit
                       ` (3 subsequent siblings)
  20 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Receive the requests from virtual interface and process control
messages.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ctrl_if/Makefile           |   1 +
 lib/librte_ctrl_if/rte_ctrl_process.c | 167 ++++++++++++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_process.h |  50 ++++++++++
 lib/librte_ctrl_if/rte_nl.c           | 130 ++++++++++++++++++++++++++
 4 files changed, 348 insertions(+)
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_process.c
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_process.h

diff --git a/lib/librte_ctrl_if/Makefile b/lib/librte_ctrl_if/Makefile
index 0da04f7d0..67b9967b4 100644
--- a/lib/librte_ctrl_if/Makefile
+++ b/lib/librte_ctrl_if/Makefile
@@ -46,6 +46,7 @@ LIBABIVER := 1
 
 SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) := rte_ctrl_if.c
 SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) += rte_nl.c
+SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) += rte_ctrl_process.c
 
 #
 # Export include files
diff --git a/lib/librte_ctrl_if/rte_ctrl_process.c b/lib/librte_ctrl_if/rte_ctrl_process.c
new file mode 100644
index 000000000..cfb243f64
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_process.c
@@ -0,0 +1,167 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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 <error.h>
+
+#include <linux/if_link.h>
+
+#include <rte_version.h>
+#include <rte_ethdev.h>
+#include "rte_ctrl_process.h"
+
+static int
+set_mtu(uint8_t port_id, void *in_data)
+{
+	int *mtu = in_data;
+
+	return rte_eth_dev_set_mtu(port_id, *mtu);
+}
+
+static int
+get_stats(uint8_t port_id, void *data, size_t *data_len)
+{
+	struct rte_eth_stats stats;
+	struct rtnl_link_stats64 *if_stats = data;
+	int ret;
+
+	ret = rte_eth_stats_get(port_id, &stats);
+	if (ret < 0)
+		return -EOPNOTSUPP;
+
+	if_stats->rx_packets = stats.ipackets;
+	if_stats->tx_packets = stats.opackets;
+	if_stats->rx_bytes = stats.ibytes;
+	if_stats->tx_bytes = stats.obytes;
+	if_stats->rx_errors = stats.ierrors;
+	if_stats->tx_errors = stats.oerrors;
+	if_stats->rx_dropped = stats.imissed;
+
+	*data_len = sizeof(struct rtnl_link_stats64);
+
+	return 0;
+}
+
+static int
+get_mac(uint8_t port_id, void *data, size_t *data_len)
+{
+	struct ether_addr addr;
+
+	rte_eth_macaddr_get(port_id, &addr);
+	memcpy(data, &addr, sizeof(struct ether_addr));
+
+	*data_len = sizeof(struct ether_addr);
+
+	return 0;
+}
+
+static int
+set_mac(uint8_t port_id, void *in_data)
+{
+	struct ether_addr addr;
+
+	memcpy(&addr, in_data, ETHER_ADDR_LEN);
+
+	return rte_eth_dev_default_mac_addr_set(port_id, &addr);
+}
+
+static int
+start_port(uint8_t port_id)
+{
+	rte_eth_dev_stop(port_id);
+	return rte_eth_dev_start(port_id);
+}
+
+static int
+stop_port(uint8_t port_id)
+{
+	rte_eth_dev_stop(port_id);
+	return 0;
+}
+
+static int
+set_promisc(uint8_t port_id, void *in_data)
+{
+	int *promisc = in_data;
+
+	if (*promisc)
+		rte_eth_promiscuous_enable(port_id);
+	else
+		rte_eth_promiscuous_disable(port_id);
+
+	return 0;
+}
+
+static int
+set_allmulti(uint8_t port_id, void *in_data)
+{
+	int *allmulti = in_data;
+
+	if (*allmulti)
+		rte_eth_allmulticast_enable(port_id);
+	else
+		rte_eth_allmulticast_disable(port_id);
+
+	return 0;
+}
+
+int
+rte_eth_dev_control_process(uint32_t cmd_id, uint8_t port_id, void *in_data,
+		void *out_data, size_t *out_data_len)
+{
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return -ENODEV;
+
+	switch (cmd_id) {
+	case UNCI_REQ_CHANGE_MTU:
+		return set_mtu(port_id, in_data);
+	case UNCI_REQ_GET_STATS:
+		return get_stats(port_id, out_data, out_data_len);
+	case UNCI_REQ_GET_MAC:
+		return get_mac(port_id, out_data, out_data_len);
+	case UNCI_REQ_SET_MAC:
+		return set_mac(port_id, in_data);
+	case UNCI_REQ_START_PORT:
+		return start_port(port_id);
+	case UNCI_REQ_STOP_PORT:
+		return stop_port(port_id);
+	case UNCI_REQ_SET_PROMISC:
+		return set_promisc(port_id, in_data);
+	case UNCI_REQ_SET_ALLMULTI:
+		return set_allmulti(port_id, in_data);
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
diff --git a/lib/librte_ctrl_if/rte_ctrl_process.h b/lib/librte_ctrl_if/rte_ctrl_process.h
new file mode 100644
index 000000000..f67c60107
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_process.h
@@ -0,0 +1,50 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 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_CTRL_ETHTOOL_H_
+#define _RTE_CTRL_ETHTOOL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <exec-env/rte_unci_common.h>
+
+int rte_eth_dev_control_process(uint32_t cmd_id, uint8_t port_id, void *in_data,
+		void *out_data, size_t *out_data_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_CTRL_ETHTOOL_H_ */
diff --git a/lib/librte_ctrl_if/rte_nl.c b/lib/librte_ctrl_if/rte_nl.c
index e88b3fc91..920d123a9 100644
--- a/lib/librte_ctrl_if/rte_nl.c
+++ b/lib/librte_ctrl_if/rte_nl.c
@@ -39,6 +39,7 @@
 
 #include <rte_spinlock.h>
 #include <rte_log.h>
+#include "rte_ctrl_process.h"
 #include "rte_nl.h"
 #include "rte_ctrl_if.h"
 
@@ -54,12 +55,139 @@ struct ctrl_if_nl {
 	struct sockaddr_nl dest_addr;
 };
 
+struct ctrl_if_msg_sync {
+	struct unci_nl_msg msg_storage;
+	pthread_mutex_t msg_lock;
+	uint32_t pending_process;
+};
+
+
+/**
+ * Flags values for rte_eth_control_interface_process_msg() API
+ */
+enum control_interface_process_flag {
+	/**< Process if msg available. */
+	RTE_ETHTOOL_CTRL_IF_PROCESS_MSG,
+
+	/**< Discard msg if available, respond with a error value. */
+	RTE_ETHTOOL_CTRL_IF_DISCARD_MSG,
+};
+
 static int sock_fd = -1;
 static pthread_t thread_id;
 
 static struct ctrl_if_nl nl_s;
 static struct ctrl_if_nl nl_r;
 
+static struct ctrl_if_msg_sync ctrl_if_sync = {
+	.msg_lock = PTHREAD_MUTEX_INITIALIZER,
+};
+
+static int
+nl_send(void *buf, size_t len)
+{
+	int ret;
+
+	if (nl_s.nlh.nlmsg_len < len) {
+		RTE_LOG(ERR, CTRL_IF, "Message is too big, len:%zu\n", len);
+		return -1;
+	}
+
+	if (!NLMSG_OK(&nl_s.nlh, NLMSG_SPACE(MAX_PAYLOAD))) {
+		RTE_LOG(ERR, CTRL_IF, "Message is not OK\n");
+		return -1;
+	}
+
+	/* Fill in the netlink message payload */
+	memcpy(NLMSG_DATA(nl_s.nlmsg), buf, len);
+
+	ret = sendmsg(sock_fd, &nl_s.msg, 0);
+
+	if (ret < 0)
+		RTE_LOG(ERR, CTRL_IF, "Failed nl msg send. ret:%d, err:%d\n",
+				ret, errno);
+	return ret;
+}
+
+/* each request sent expects a reply */
+static int
+nl_reply(struct unci_nl_msg *msg)
+{
+	return nl_send((void *)msg, sizeof(struct unci_nl_msg));
+}
+
+static void
+process_msg(struct unci_nl_msg *msg)
+{
+	if (msg->cmd_id > UNCI_REQ_UNKNOWN) {
+		msg->err = rte_eth_dev_control_process(msg->cmd_id,
+				msg->port_id, msg->input_buffer,
+				msg->output_buffer, &msg->output_buffer_len);
+	}
+
+	if (msg->err)
+		memset(msg->output_buffer, 0, msg->output_buffer_len);
+
+	nl_reply(msg);
+}
+
+static int
+control_interface_msg_process(uint32_t flag)
+{
+	struct unci_nl_msg msg_storage;
+	int ret = 0;
+
+	pthread_mutex_lock(&ctrl_if_sync.msg_lock);
+	if (ctrl_if_sync.pending_process == 0) {
+		pthread_mutex_unlock(&ctrl_if_sync.msg_lock);
+		return 0;
+	}
+
+	memcpy(&msg_storage, &ctrl_if_sync.msg_storage,
+			sizeof(struct unci_nl_msg));
+	ctrl_if_sync.pending_process = 0;
+	pthread_mutex_unlock(&ctrl_if_sync.msg_lock);
+
+	switch (flag) {
+	case RTE_ETHTOOL_CTRL_IF_PROCESS_MSG:
+		process_msg(&msg_storage);
+		break;
+
+	case RTE_ETHTOOL_CTRL_IF_DISCARD_MSG:
+		msg_storage.err = -1;
+		nl_reply(&msg_storage);
+		break;
+
+	default:
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
+
+static int
+msg_add_and_process(struct nlmsghdr *nlh)
+{
+	pthread_mutex_lock(&ctrl_if_sync.msg_lock);
+
+	if (ctrl_if_sync.pending_process) {
+		pthread_mutex_unlock(&ctrl_if_sync.msg_lock);
+		return -1;
+	}
+
+	memcpy(&ctrl_if_sync.msg_storage, NLMSG_DATA(nlh),
+			sizeof(struct unci_nl_msg));
+	ctrl_if_sync.msg_storage.flag = UNCI_MSG_FLAG_RESPONSE;
+	ctrl_if_sync.pending_process = 1;
+
+	pthread_mutex_unlock(&ctrl_if_sync.msg_lock);
+
+	control_interface_msg_process(RTE_ETHTOOL_CTRL_IF_PROCESS_MSG);
+
+	return 0;
+}
+
 static void *
 nl_recv(void *arg)
 {
@@ -76,6 +204,8 @@ nl_recv(void *arg)
 					ret, sizeof(struct unci_nl_msg));
 			continue;
 		}
+
+		msg_add_and_process(&nl_r.nlh);
 	}
 
 	return arg;
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 18/20] ctrl_if: process ethtool messages
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (16 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 17/20] ctrl_if: process control messages Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-06-30 16:51     ` [PATCH v9 19/20] doc: add control interface library documentation Ferruh Yigit
                       ` (2 subsequent siblings)
  20 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Process ethtool messages and rend response back to kernel.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ctrl_if/rte_ctrl_process.c | 223 ++++++++++++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_process.h |   4 +
 lib/librte_ctrl_if/rte_nl.c           |   4 +
 3 files changed, 231 insertions(+)

diff --git a/lib/librte_ctrl_if/rte_ctrl_process.c b/lib/librte_ctrl_if/rte_ctrl_process.c
index cfb243f64..55fd54351 100644
--- a/lib/librte_ctrl_if/rte_ctrl_process.c
+++ b/lib/librte_ctrl_if/rte_ctrl_process.c
@@ -38,8 +38,231 @@
 
 #include <rte_version.h>
 #include <rte_ethdev.h>
+#include <rte_ethtool.h>
 #include "rte_ctrl_process.h"
 
+#define ETHTOOL_GEEPROM_LEN 99
+#define ETHTOOL_GREGS_LEN 98
+#define ETHTOOL_GSSET_COUNT 97
+
+static int
+get_settings(uint8_t port_id __rte_unused, void *data, size_t *data_len)
+{
+	struct ethtool_cmd *ecmd = data;
+
+	/* No PMD equivalent, added to make get pauseparam work */
+	memset(ecmd, 0, sizeof(struct ethtool_cmd));
+
+	*data_len = sizeof(struct ethtool_cmd);
+	return 0;
+}
+
+static int
+get_drvinfo(uint8_t port_id, void *data, size_t *data_len)
+{
+	struct ethtool_drvinfo *info = data;
+	int ret;
+
+	ret = rte_ethtool_get_drvinfo(port_id, info);
+	if (ret < 0)
+		return ret;
+
+	*data_len = sizeof(struct ethtool_drvinfo);
+
+	return 0;
+}
+
+static int
+get_reg_len(uint8_t port_id, void *data, size_t *data_len)
+{
+	int reg_length = 0;
+
+	reg_length = rte_ethtool_get_regs_len(port_id);
+	if (reg_length < 0)
+		return reg_length;
+
+	*(int *)data = reg_length;
+	*data_len = sizeof(int);
+
+	return 0;
+}
+
+static int
+get_reg_len_internal(uint8_t port_id, size_t *reg_length)
+{
+	size_t reg_length_out_len;
+
+	return get_reg_len(port_id, reg_length, &reg_length_out_len);
+}
+
+static int
+get_reg(uint8_t port_id, void *in_data, void *out_data, size_t *out_data_len)
+{
+	size_t reg_length;
+	struct ethtool_regs *ethtool_regs = in_data;
+	int ret;
+
+	ret = get_reg_len_internal(port_id, &reg_length);
+	/* not enough space in out data buffer */
+	if (ret < 0 || reg_length > ethtool_regs->len)
+		return -1;
+
+	ret = rte_ethtool_get_regs(port_id, ethtool_regs, out_data);
+	if (ret < 0)
+		return ret;
+
+	*out_data_len = reg_length;
+
+	return 0;
+}
+
+static int
+get_link(uint8_t port_id, void *data, size_t *data_len)
+{
+	int ret;
+
+	ret = rte_ethtool_get_link(port_id);
+
+	*(int *)data = ret;
+	*data_len = sizeof(size_t);
+
+	return 0;
+}
+
+static int
+get_eeprom_length(uint8_t port_id, void *data, size_t *data_len)
+{
+	int eeprom_length = 0;
+
+	eeprom_length = rte_ethtool_get_eeprom_len(port_id);
+	if (eeprom_length < 0)
+		return eeprom_length;
+
+	*(int *)data = eeprom_length;
+	*data_len = sizeof(int);
+
+	return 0;
+}
+
+static int
+get_eeprom(uint8_t port_id, void *in_data, void *out_data,
+		size_t *out_data_len)
+{
+	struct ethtool_eeprom *eeprom = in_data;
+	int ret;
+
+	ret = rte_ethtool_get_eeprom(port_id, eeprom, out_data);
+	if (ret < 0)
+		return ret;
+
+	*out_data_len = eeprom->len;
+
+	return 0;
+}
+
+static int
+set_eeprom(uint8_t port_id, void *in_data)
+{
+	struct ethtool_eeprom *eeprom = in_data;
+	int ret;
+
+	ret = rte_ethtool_set_eeprom(port_id, eeprom, eeprom->data);
+	if (ret != 0)
+		return -1;
+
+	return 0;
+}
+
+static int
+get_ringparam(uint8_t port_id, void *data, size_t *data_len)
+{
+	struct ethtool_ringparam *ringparam = data;
+	int ret;
+
+	ret = rte_ethtool_get_ringparam(port_id, ringparam);
+	if (ret < 0)
+		return ret;
+
+	*data_len = sizeof(struct ethtool_ringparam);
+
+	return 0;
+}
+
+static int
+set_ringparam(uint8_t port_id, void *data)
+{
+	struct ethtool_ringparam *ringparam = data;
+	int ret;
+
+	ret = rte_ethtool_set_ringparam(port_id, ringparam);
+	if (ret != 0)
+		return -1;
+
+	return 0;
+}
+
+static int
+get_pauseparam(uint8_t port_id, void *data, size_t *data_len)
+{
+	struct ethtool_pauseparam *pauseparam = data;
+	int ret;
+
+	ret = rte_ethtool_get_pauseparam(port_id, pauseparam);
+	if (ret < 0)
+		return ret;
+
+	*data_len = sizeof(struct ethtool_pauseparam);
+
+	return 0;
+}
+
+static int
+set_pauseparam(uint8_t port_id, void *data)
+{
+	struct ethtool_pauseparam *pauseparam = data;
+
+	return rte_ethtool_set_pauseparam(port_id, pauseparam);
+}
+
+int
+rte_eth_dev_ethtool_process(uint32_t cmd_id, uint8_t port_id, void *in_data,
+		void *out_data, size_t *out_data_len)
+{
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return -ENODEV;
+
+	switch (cmd_id) {
+	case ETHTOOL_GSET:
+		return get_settings(port_id, out_data, out_data_len);
+	case ETHTOOL_GDRVINFO:
+		return get_drvinfo(port_id, out_data, out_data_len);
+	case ETHTOOL_GREGS_LEN:
+		return get_reg_len(port_id, out_data, out_data_len);
+	case ETHTOOL_GREGS:
+		return get_reg(port_id, in_data, out_data, out_data_len);
+	case ETHTOOL_GLINK:
+		return get_link(port_id, out_data, out_data_len);
+	case ETHTOOL_GEEPROM_LEN:
+		return get_eeprom_length(port_id, out_data, out_data_len);
+	case ETHTOOL_GEEPROM:
+		return get_eeprom(port_id, in_data, out_data, out_data_len);
+	case ETHTOOL_SEEPROM:
+		return set_eeprom(port_id, in_data);
+	case ETHTOOL_GRINGPARAM:
+		return get_ringparam(port_id, out_data, out_data_len);
+	case ETHTOOL_SRINGPARAM:
+		return set_ringparam(port_id, in_data);
+	case ETHTOOL_GPAUSEPARAM:
+		return get_pauseparam(port_id, out_data, out_data_len);
+	case ETHTOOL_SPAUSEPARAM:
+		return set_pauseparam(port_id, in_data);
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
 static int
 set_mtu(uint8_t port_id, void *in_data)
 {
diff --git a/lib/librte_ctrl_if/rte_ctrl_process.h b/lib/librte_ctrl_if/rte_ctrl_process.h
index f67c60107..caa4f15f3 100644
--- a/lib/librte_ctrl_if/rte_ctrl_process.h
+++ b/lib/librte_ctrl_if/rte_ctrl_process.h
@@ -38,8 +38,12 @@
 extern "C" {
 #endif
 
+#include <linux/ethtool.h>
+
 #include <exec-env/rte_unci_common.h>
 
+int rte_eth_dev_ethtool_process(uint32_t cmd_id, uint8_t port_id, void *in_data,
+		void *out_data, size_t *out_data_len);
 int rte_eth_dev_control_process(uint32_t cmd_id, uint8_t port_id, void *in_data,
 		void *out_data, size_t *out_data_len);
 
diff --git a/lib/librte_ctrl_if/rte_nl.c b/lib/librte_ctrl_if/rte_nl.c
index 920d123a9..d00a242d2 100644
--- a/lib/librte_ctrl_if/rte_nl.c
+++ b/lib/librte_ctrl_if/rte_nl.c
@@ -123,6 +123,10 @@ process_msg(struct unci_nl_msg *msg)
 		msg->err = rte_eth_dev_control_process(msg->cmd_id,
 				msg->port_id, msg->input_buffer,
 				msg->output_buffer, &msg->output_buffer_len);
+	} else {
+		msg->err = rte_eth_dev_ethtool_process(msg->cmd_id,
+				msg->port_id, msg->input_buffer,
+				msg->output_buffer, &msg->output_buffer_len);
 	}
 
 	if (msg->err)
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 19/20] doc: add control interface library documentation
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (17 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 18/20] ctrl_if: process ethtool messages Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-07-02 20:16       ` Mcnamara, John
  2017-06-30 16:51     ` [PATCH v9 20/20] ethdev: add control interface support Ferruh Yigit
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
  20 siblings, 1 reply; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 doc/api/doxy-api-index.md              |  3 +-
 doc/api/doxy-api.conf                  |  1 +
 doc/guides/prog_guide/ctrl_if_lib.rst  | 50 ++++++++++++++++++++++++++++++++++
 doc/guides/prog_guide/index.rst        |  1 +
 doc/guides/rel_notes/release_17_08.rst |  8 ++++++
 5 files changed, 62 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/prog_guide/ctrl_if_lib.rst

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 71350849f..ba45ff69a 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -162,4 +162,5 @@ There are many libraries, so their headers may be grouped by topics:
   [bitrate statistics] (@ref rte_bitrate.h),
   [latency statistics] (@ref rte_latencystats.h),
   [version]            (@ref rte_version.h),
-  [ethtool]            (@ref rte_ethtool.h)
+  [ethtool]            (@ref rte_ethtool.h),
+  [control interface]  (@ref rte_ctrl_if.h)
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index b66e86541..896c2b247 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -42,6 +42,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           lib/librte_cmdline \
                           lib/librte_compat \
                           lib/librte_cryptodev \
+                          lib/librte_ctrl_if \
                           lib/librte_distributor \
                           lib/librte_efd \
                           lib/librte_ether \
diff --git a/doc/guides/prog_guide/ctrl_if_lib.rst b/doc/guides/prog_guide/ctrl_if_lib.rst
new file mode 100644
index 000000000..7d60c2798
--- /dev/null
+++ b/doc/guides/prog_guide/ctrl_if_lib.rst
@@ -0,0 +1,50 @@
+..  BSD LICENSE
+    Copyright(c) 2016 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.
+
+.. _Ctrl_If_Library:
+
+Control Interface Library
+=========================
+
+This Library is to create/destroy control interfaces and process messages
+received by control interface.
+
+Control Interface is Linux network interface and it is possible to call
+various Linux commands to this interface and commands will be forwarded
+to the matching DPDK PMD, and response will be generated by PMD.
+
+Control interface required UNCI kernel module to be inserted to function.
+
+Control Interface APIS
+----------------------
+
+
+- ``rte_eth_control_interface_create_one()``
+- ``rte_eth_control_interface_destroy_one()``
diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index 54f9538ea..c7cb4b0f8 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -55,6 +55,7 @@ Programmer's Guide
     ip_fragment_reassembly_lib
     pdump_lib
     ethtool_lib
+    ctrl_if_lib
     multi_proc_support
     kernel_nic_interface
     thread_safety_dpdk_functions
diff --git a/doc/guides/rel_notes/release_17_08.rst b/doc/guides/rel_notes/release_17_08.rst
index e21d4e17c..0598a9ec0 100644
--- a/doc/guides/rel_notes/release_17_08.rst
+++ b/doc/guides/rel_notes/release_17_08.rst
@@ -80,6 +80,14 @@ New Features
   Ethtool library is wrapper for ethdev library and provides APIs to get data
   similar to Linux ethtool provides.
 
+* **Control interface support added.**
+
+  To enable controlling DPDK ports by common Linux tools.
+  Following modules added to DPDK:
+
+  * librte_ctrl_if library
+  * librte_eal/linuxapp/unci kernel module
+
 
 Resolved Issues
 ---------------
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v9 20/20] ethdev: add control interface support
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (18 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 19/20] doc: add control interface library documentation Ferruh Yigit
@ 2017-06-30 16:51     ` Ferruh Yigit
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
  20 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:51 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

To have the support corresponding kernel module (UNCI) needs to be
inserted.  If kernel module is not there, application will run as
it is without kernel control path support.

When UNCI module inserted, running application creates a virtual Linux
network interface (dpdk$) per DPDK port. This interface can be used by
traditional Linux tools.

If Userspace Network Control Interface (UNCI) kernel module
(rte_unci.ko) inserted, virtual interfaces created for each DPDK port
for control purposes.

Created interfaces are named as dpdk#, like:

    $ ifconfig dpdk0; ifconfig dpdk1
    dpdk0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
            ether 90:e2:ba:0e:49:b9  txqueuelen 1000  (Ethernet)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

    dpdk1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
            ether 00:1b:21:76:fa:21  txqueuelen 1000  (Ethernet)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Regular Linux commands can be issued on interfaces:

	$ ethtool -i dpdk0
	driver: net_ixgbe
	version: DPDK 17.08.0-rc0
	firmware-version: 0x61bf0001
	expansion-rom-version:
	bus-info: 0000:08:00.1
	supports-statistics: no
	supports-test: no
	supports-eeprom-access: yes
	supports-register-dump: yes
	supports-priv-flags: no

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
v9:
* fix shared build
---
 drivers/net/Makefile              |  4 ++++
 lib/librte_ether/rte_ethdev_pci.h | 15 ++++++++++++++-
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 35ed8135a..cdabc2349 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -39,6 +39,10 @@ endif
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
 core-libs += librte_net librte_kvargs
 
+ifeq ($(CONFIG_RTE_LIBRTE_CTRL_IF),y)
+core-libs += librte_ctrl_if
+endif
+
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += af_packet
 DEPDIRS-af_packet = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark
diff --git a/lib/librte_ether/rte_ethdev_pci.h b/lib/librte_ether/rte_ethdev_pci.h
index 69aab03fb..278c0301f 100644
--- a/lib/librte_ether/rte_ethdev_pci.h
+++ b/lib/librte_ether/rte_ethdev_pci.h
@@ -38,6 +38,13 @@
 #include <rte_pci.h>
 #include <rte_ethdev.h>
 
+#ifdef RTE_LIBRTE_CTRL_IF
+#include <rte_ctrl_if.h>
+#else
+#define rte_eth_control_interface_create_one(port_id) do { } while (0)
+#define rte_eth_control_interface_destroy_one(port_id) do { } while (0)
+#endif
+
 /**
  * Copy pci device info to the Ethernet device data.
  *
@@ -157,8 +164,12 @@ rte_eth_dev_pci_generic_probe(struct rte_pci_device *pci_dev,
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
 	ret = dev_init(eth_dev);
-	if (ret)
+	if (ret) {
 		rte_eth_dev_pci_release(eth_dev);
+		return ret;
+	}
+
+	rte_eth_control_interface_create_one(eth_dev->data->port_id);
 
 	return ret;
 }
@@ -179,6 +190,8 @@ rte_eth_dev_pci_generic_remove(struct rte_pci_device *pci_dev,
 	if (!eth_dev)
 		return -ENODEV;
 
+	rte_eth_control_interface_destroy_one(eth_dev->data->port_id);
+
 	if (dev_uninit) {
 		ret = dev_uninit(eth_dev);
 		if (ret)
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* Re: [PATCH v8 0/4] Userspace Network Control Interface (UNCI)
  2017-06-29 16:13     ` Ferruh Yigit
@ 2017-06-30 16:56       ` Ferruh Yigit
  0 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 16:56 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: dev, anatoly.burakov

On 6/29/2017 5:13 PM, Ferruh Yigit wrote:
<...>

>> 3. From a patchset split point of view, could this set be split up to be
>> a bit more granular. There are a lot of functions to be performed on
>> NICs called out in the code, e.g. start/stop, get stats, etc. etc. To
>> make review easier, should we initially add the kernel module and
>> userspace parts with just one function supported, and then add in each
>> additional function in a new patchset, so that we can clearly see the
>> code for each function isolated from the rest. This is the approach -
>> adding feature by feature - that is recommended for NIC drivers, and it
>> might make sense here too.
> 
> Let me try to split patches more.

Done, sent v9, patchset split into more patches.

> 
>>
>> Otherwise, great work. I think this is a huge improvement in usability
>> for DPDK, especially if we add in future support for controlling DPDK
>> interfaces in a (not interfering with the app) safe manner too.
>>
>> /Bruce
>>
> 

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v8 2/4] unci: add kernel control path kernel module
  2017-06-21 15:23     ` Stephen Hemminger
@ 2017-06-30 17:02       ` Ferruh Yigit
  0 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 17:02 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, anatoly.burakov, Bruce Richardson

On 6/21/2017 4:23 PM, Stephen Hemminger wrote:
> On Wed, 21 Jun 2017 12:06:49 +0100
> Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> 
>> +static struct ethtool_input_buffer {
>> +	int magic;
>> +	void *buffer;
>> +	size_t length;
>> +	struct completion *msg_received;
>> +	int *err;
>> +	u32 in_use;
>> +} ethtool_input_buffer
> 
> Naming in kernel is important. This isn't kernel ethtool, so  it shouldn't be named that.

I have updated naming on v9.

> 
> Having a single instance per system for a control interface means it won't work
> if multiple apps have control channel open or in containers.

This should work for multiple add and interfaces, unci_nl_exec()
serializes the requests, above struct used for output buffer indirection.

I am not sure how to handle requests without serializing them ...

> 
> You should also do policy validation on the netlink message.

I will send a new version with this.

> 

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v8 4/4] ethdev: add control interface support
  2017-06-21 15:24     ` Stephen Hemminger
@ 2017-06-30 17:06       ` Ferruh Yigit
  0 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-06-30 17:06 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, Burakov, Anatoly, Richardson, Bruce

On 6/21/2017 4:24 PM, Stephen Hemminger wrote:
> On Wed, 21 Jun 2017 12:06:51 +0100
> Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> 
>> To have the support corresponding kernel module (UNCI) needs to be
>> inserted.  If kernel module is not there, application will run as
>> it is without kernel control path support.
>>
>> When UNCI module inserted, running application creates a virtual Linux
>> network interface (dpdk$) per DPDK port. This interface can be used by
>> traditional Linux tools.
>>
>> If Userspace Network Control Interface (UNCI) kernel module
>> (rte_unci.ko) inserted, virtual interfaces created for each DPDK port
>> for control purposes.
>>
>> Created interfaces are named as dpdk#, like:
>>
>>     $ ifconfig dpdk0; ifconfig dpdk1
>>     dpdk0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
>>             ether 90:e2:ba:0e:49:b9  txqueuelen 1000  (Ethernet)
>>             RX packets 0  bytes 0 (0.0 B)
>>             RX errors 0  dropped 0  overruns 0  frame 0
>>             TX packets 0  bytes 0 (0.0 B)
>>             TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
>>
>>     dpdk1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
>>             ether 00:1b:21:76:fa:21  txqueuelen 1000  (Ethernet)
>>             RX packets 0  bytes 0 (0.0 B)
>>             RX errors 0  dropped 0  overruns 0  frame 0
>>             TX packets 0  bytes 0 (0.0 B)
>>             TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
> 
> 
> If you get the sysfs network links correct, then udev should be able to
> generate peristent network names.

I didn't get this one, currently interface names are requested from
userspace via IFLA_IFNAME, as dpdk# .

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v9 09/20] unci: add rtnl newlink
  2017-06-30 16:51     ` [PATCH v9 09/20] unci: add rtnl newlink Ferruh Yigit
@ 2017-06-30 17:27       ` Stephen Hemminger
  0 siblings, 0 replies; 91+ messages in thread
From: Stephen Hemminger @ 2017-06-30 17:27 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Bruce Richardson, Anatoly Burakov

On Fri, 30 Jun 2017 17:51:29 +0100
Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> +
> +#ifndef _RTE_UNCI_COMMON_H_
> +#define _RTE_UNCI_COMMON_H_
> +
> +#define UNCI_DEVICE "unci"
> +
> +enum {
> +	IFLA_UNCI_UNSPEC,
> +	IFLA_UNCI_PORTID,
> +	IFLA_UNCI_PID,
> +	__IFLA_UNCI_MAX,
> +};
> +
> +#define IFLA_UNCI_MAX (__IFLA_UNCI_MAX - 1)
> +
> +#endif /* _RTE_UNCI_COMMON_H_ */
> diff --git a/lib/librte_eal/linuxapp/unci/unci_dev.h b/lib/librte_eal/linuxapp/unci/unci_dev.h
> index 0337fa82b..b0a215f1b 100644
> --- a/lib/librte_eal/linuxapp/unci/unci_dev.h
> +++ b/lib/librte_eal/linuxapp/unci/unci_dev.h
> @@ -26,11 +26,16 @@
>  #define _UNCI_DEV_H_
>  
>  #include <linux/netdevice.h>
> +#include <exec-env/rte_unci_common.h>
>  
>  #ifdef pr_fmt
>  #undef pr_fmt
>  #endif
>  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>  
> +struct unci_dev {
> +	u8 port_id;
> +	u32 pid;
> +};

These are to/from user space so should be __u8, __u32.
Also, probably want to support more than 256 ports at some time in future.
So make them both __u32.

>  
>  #endif /* _UNCI_DEV_H_ */

Since you want to target this for upstream kernel. Please try and layout
the includes in an easy manner to do this and avoid using rte_ in names.

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v9 10/20] unci: init netlink
  2017-06-30 16:51     ` [PATCH v9 10/20] unci: init netlink Ferruh Yigit
@ 2017-06-30 17:28       ` Stephen Hemminger
  2017-06-30 17:29       ` Stephen Hemminger
  1 sibling, 0 replies; 91+ messages in thread
From: Stephen Hemminger @ 2017-06-30 17:28 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Bruce Richardson, Anatoly Burakov

On Fri, 30 Jun 2017 17:51:30 +0100
Ferruh Yigit <ferruh.yigit@intel.com> wrote:

>  #define UNCI_DEVICE "unci"
>  
> +#define UNCI_NL_GRP 31
> +
> +#define UNCI_NL_MSG_LEN 500
> +struct unci_nl_msg {
> +	uint32_t cmd_id;
> +	uint8_t port_id;
> +	uint32_t flag;
> +	uint8_t input_buffer[UNCI_NL_MSG_LEN];
> +	uint8_t output_buffer[UNCI_NL_MSG_LEN];
> +	size_t input_buffer_len;
> +	size_t output_buffer_len;
> +	int err;
> +};
> +
>  enum {
>  	IFLA_UNCI_UNSPEC,

Kernel code should not use uint32_t or uint8_t.
Stick to __u32 and __u8

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v9 10/20] unci: init netlink
  2017-06-30 16:51     ` [PATCH v9 10/20] unci: init netlink Ferruh Yigit
  2017-06-30 17:28       ` Stephen Hemminger
@ 2017-06-30 17:29       ` Stephen Hemminger
  1 sibling, 0 replies; 91+ messages in thread
From: Stephen Hemminger @ 2017-06-30 17:29 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Bruce Richardson, Anatoly Burakov

On Fri, 30 Jun 2017 17:51:30 +0100
Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> +static struct mutex sync_lock;
> +
> +static void nl_recv(struct sk_buff *skb)
> +{
> +	struct nlmsghdr *nlh;
> +	struct unci_nl_msg nl_msg;
> +
> +	nlh = (struct nlmsghdr *)skb->data;
> +
> +	memcpy(&nl_msg, NLMSG_DATA(nlh), sizeof(struct unci_nl_msg));
> +	pr_debug("CMD: %u\n", nl_msg.cmd_id);
> +}
> +
> +static struct netlink_kernel_cfg cfg = {
> +	.input = nl_recv,
> +};
> +
> +void unci_nl_init(void)
> +{
> +	nl_sock = netlink_kernel_create(&init_net, UNCI_NL_GRP, &cfg);
> +	mutex_init(&sync_lock);
> +}

What if netlink socket create fails?

Also, don't need to call mutex_init if you use simpler initailizer.

static DEFINE_MUTEX(sync_lock);

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v9 19/20] doc: add control interface library documentation
  2017-06-30 16:51     ` [PATCH v9 19/20] doc: add control interface library documentation Ferruh Yigit
@ 2017-07-02 20:16       ` Mcnamara, John
  0 siblings, 0 replies; 91+ messages in thread
From: Mcnamara, John @ 2017-07-02 20:16 UTC (permalink / raw)
  To: Yigit, Ferruh, dev
  Cc: Yigit, Ferruh, Stephen Hemminger, Richardson, Bruce, Burakov, Anatoly



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ferruh Yigit
> Sent: Friday, June 30, 2017 5:52 PM
> To: dev@dpdk.org
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; Stephen Hemminger
> <stephen@networkplumber.org>; Richardson, Bruce
> <bruce.richardson@intel.com>; Burakov, Anatoly <anatoly.burakov@intel.com>
> Subject: [dpdk-dev] [PATCH v9 19/20] doc: add control interface library
> documentation
> 
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>


Acked-by: John McNamara <john.mcnamara@intel.com>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v9 07/20] doc: update ethtool sample app doc
  2017-06-30 16:51     ` [PATCH v9 07/20] doc: update ethtool sample app doc Ferruh Yigit
@ 2017-07-02 20:17       ` Mcnamara, John
  0 siblings, 0 replies; 91+ messages in thread
From: Mcnamara, John @ 2017-07-02 20:17 UTC (permalink / raw)
  To: Yigit, Ferruh, dev
  Cc: Yigit, Ferruh, Stephen Hemminger, Richardson, Bruce, Burakov, Anatoly



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ferruh Yigit
> Sent: Friday, June 30, 2017 5:51 PM
> To: dev@dpdk.org
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; Stephen Hemminger
> <stephen@networkplumber.org>; Richardson, Bruce
> <bruce.richardson@intel.com>; Burakov, Anatoly <anatoly.burakov@intel.com>
> Subject: [dpdk-dev] [PATCH v9 07/20] doc: update ethtool sample app doc
> 
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>


Acked-by: John McNamara <john.mcnamara@intel.com>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v9 06/20] doc: add ethtool library documentation
  2017-06-30 16:51     ` [PATCH v9 06/20] doc: add ethtool library documentation Ferruh Yigit
@ 2017-07-02 20:18       ` Mcnamara, John
  0 siblings, 0 replies; 91+ messages in thread
From: Mcnamara, John @ 2017-07-02 20:18 UTC (permalink / raw)
  To: Yigit, Ferruh, dev
  Cc: Yigit, Ferruh, Stephen Hemminger, Richardson, Bruce, Burakov, Anatoly



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ferruh Yigit
> Sent: Friday, June 30, 2017 5:51 PM
> To: dev@dpdk.org
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; Stephen Hemminger
> <stephen@networkplumber.org>; Richardson, Bruce
> <bruce.richardson@intel.com>; Burakov, Anatoly <anatoly.burakov@intel.com>
> Subject: [dpdk-dev] [PATCH v9 06/20] doc: add ethtool library
> documentation
> 
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>


Acked-by: John McNamara <john.mcnamara@intel.com>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCH v10 00/20] Userspace Network Control Interface (UNCI)
  2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
                       ` (19 preceding siblings ...)
  2017-06-30 16:51     ` [PATCH v9 20/20] ethdev: add control interface support Ferruh Yigit
@ 2017-07-04 16:13     ` Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 01/20] ethtool: add library skeleton Ferruh Yigit
                         ` (19 more replies)
  20 siblings, 20 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Userspace Network Control Interface (UNCI), (formerly KCP).

When a NIC bound to the DPDK, it can't be controlled by Linux tools.

This patch creates a virtual network interface for each DPDK port,
initial target is to get some data from those interfaces, in next
step target is to control DPDK ports using virtual interfaces.

KNI control path already provides this capability and this work is
based on KNI, but current KNI only supports some devices and requires
application changes. UNCI is improved KNI control related part.

Control messages to the virtual interface moved to the underlying
PMD and response moved back to Linux:

  +-------+
  | dpdk0 |
  +---^---+
      |
      | netlink
      v
+-------------------+
| control interface |
+--------------+    |
+------------+ |    |
| ethtool lib| |    |
+------------+ +----+
+-------------------+
|      ethdev       |
+-------------------+
       |
  +---------+
  | Any PMD |
  +---------+


First patch in the set is moving DPDK ethtool library from sample
application folder to the lib. This library provides ethtool commands
on top of ethdev library.

Second patch introduces a control library, which gets some commands
via netlink and converts these into ethtool or ethdev APIs.
A background thread created to listen commands.

Third patch implements a kernel module, similar to KNI, which is a
simple virtual network driver with netlink communication capability.
This driver pass through all control commands to userspace via netlink.

Forth patch adds control interface create and destroy APIs for ethdev.
This will create Linux interfaces automatically if rte_unci  kernel
module is inserted. Will work as it is if module is not inserted.

The intension is to upstream the Linux kernel module, please provide
comments to make it ready for upstream.

Note:
To remove interfaces: ip l del dpdk0 type unci

Samples:

Run testpmd with no extra arguments: "testpmd -- -i"
If the rte_unci module inserted two new interfaces will show up:

$ ifconfig dpdk0 && ifconfig dpdk1
dpdk0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 90:e2:ba:0e:49:b8  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

dpdk1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 00:1b:21:76:fa:20  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

The MAC address information already get from actual HW.

(Interfaces are shown down by default)

When data transfer start in testpmd, stats updated accordingly:

$ ifconfig dpdk0 && ifconfig dpdk1
dpdk0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 90:e2:ba:0e:49:b8  txqueuelen 1000  (Ethernet)
        RX packets 9662125409  bytes 553368167417 (515.3 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 9605125821  bytes 518893560100 (483.2 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

dpdk1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 00:1b:21:76:fa:20  txqueuelen 1000  (Ethernet)
        RX packets 9605137856  bytes 552991297017 (515.0 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 9662138670  bytes 518732030928 (483.1 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Or able to get same data via ethtool:

$ ethtool -i dpdk0
driver: net_ixgbe
version: DPDK 17.08.0-rc0
firmware-version: 0x61bf0001
expansion-rom-version:
bus-info: 0000:08:00.0
supports-statistics: no
supports-test: no
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: no

$ ethtool -g dpdk0
Ring parameters for dpdk0:
Pre-set maximums:
RX:             4096
RX Mini:        0
RX Jumbo:       0
TX:             4096
Current hardware settings:
RX:             128
RX Mini:        0
RX Jumbo:       0
TX:             512

---

v10:
* switch to generic netlink
* update variable types for the ones accessed from userspace

v9:
* patchset split into more patches
* renamed some structs / variables

---
Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: Bruce Richardson <bruce.richardson@intel.com>
Cc: Anatoly Burakov <anatoly.burakov@intel.com>
---

Ferruh Yigit (20):
  ethtool: add library skeleton
  ethtool: move from sample folder into lib folder
  ethtool: remove PMD specific API call
  ethtool: update header doxygen syntax
  ethtool: enable library
  doc: add ethtool library documentation
  doc: update ethtool sample app doc
  unci: add module skeleton
  unci: add rtnl newlink
  unci: init netlink
  unci: add netlink exec
  unci: add netdevice ops
  unci: add ethtool support
  ctrl_if: add library skeleton
  ctrl_if: add create destroy interface APIs
  ctrl_if: initialize generic netlink interface
  ctrl_if: process control messages
  ctrl_if: process ethtool messages
  doc: add control interface library documentation
  ethdev: add control interface support

 MAINTAINERS                                        |   8 +
 config/common_base                                 |  15 +
 config/common_linuxapp                             |   3 +
 doc/api/doxy-api-index.md                          |   4 +-
 doc/api/doxy-api.conf                              |   2 +
 doc/guides/prog_guide/ctrl_if_lib.rst              |  50 +++
 doc/guides/prog_guide/ethtool_lib.rst              |  62 ++++
 doc/guides/prog_guide/index.rst                    |   2 +
 doc/guides/rel_notes/release_17_08.rst             |  15 +
 doc/guides/sample_app_ug/ethtool.rst               |  36 +-
 drivers/net/Makefile                               |   4 +
 examples/ethtool/Makefile                          |  24 +-
 examples/ethtool/{ethtool-app => }/ethapp.c        |   0
 examples/ethtool/{ethtool-app => }/ethapp.h        |   0
 examples/ethtool/{ethtool-app => }/main.c          |   0
 lib/Makefile                                       |   4 +
 lib/librte_ctrl_if/Makefile                        |  56 +++
 lib/librte_ctrl_if/rte_ctrl_if.c                   | 346 ++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_if.h                   |  93 +++++
 lib/librte_ctrl_if/rte_ctrl_if_version.map         |   8 +
 lib/librte_ctrl_if/rte_ctrl_process.c              | 390 +++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_process.h              |  54 +++
 lib/librte_ctrl_if/rte_nl.c                        | 387 ++++++++++++++++++++
 lib/librte_ctrl_if/rte_nl.h                        |  48 +++
 lib/librte_eal/common/eal_common_log.c             |   2 +
 lib/librte_eal/common/include/rte_log.h            |   2 +
 lib/librte_eal/linuxapp/Makefile                   |   4 +-
 lib/librte_eal/linuxapp/eal/Makefile               |   1 +
 .../linuxapp/eal/include/exec-env/unci.h           | 129 +++++++
 lib/librte_eal/linuxapp/unci/Makefile              |  54 +++
 lib/librte_eal/linuxapp/unci/unci_dev.h            |  51 +++
 lib/librte_eal/linuxapp/unci/unci_ethtool.c        | 293 ++++++++++++++++
 lib/librte_eal/linuxapp/unci/unci_net.c            | 234 +++++++++++++
 lib/librte_eal/linuxapp/unci/unci_nl.c             | 252 +++++++++++++
 lib/librte_ether/rte_ethdev_pci.h                  |  15 +-
 .../ethtool/lib => lib/librte_ethtool}/Makefile    |  35 +-
 .../lib => lib/librte_ethtool}/rte_ethtool.c       |  23 +-
 .../lib => lib/librte_ethtool}/rte_ethtool.h       |  57 +--
 lib/librte_ethtool/rte_ethtool_version.map         |  28 ++
 mk/rte.app.mk                                      |   2 +
 40 files changed, 2676 insertions(+), 117 deletions(-)
 create mode 100644 doc/guides/prog_guide/ctrl_if_lib.rst
 create mode 100644 doc/guides/prog_guide/ethtool_lib.rst
 rename examples/ethtool/{ethtool-app => }/ethapp.c (100%)
 rename examples/ethtool/{ethtool-app => }/ethapp.h (100%)
 rename examples/ethtool/{ethtool-app => }/main.c (100%)
 create mode 100644 lib/librte_ctrl_if/Makefile
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.c
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.h
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if_version.map
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_process.c
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_process.h
 create mode 100644 lib/librte_ctrl_if/rte_nl.c
 create mode 100644 lib/librte_ctrl_if/rte_nl.h
 create mode 100644 lib/librte_eal/linuxapp/eal/include/exec-env/unci.h
 create mode 100644 lib/librte_eal/linuxapp/unci/Makefile
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_dev.h
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_ethtool.c
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_net.c
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_nl.c
 rename {examples/ethtool/lib => lib/librte_ethtool}/Makefile (76%)
 rename {examples/ethtool/lib => lib/librte_ethtool}/rte_ethtool.c (95%)
 rename {examples/ethtool/lib => lib/librte_ethtool}/rte_ethtool.h (91%)
 create mode 100644 lib/librte_ethtool/rte_ethtool_version.map

-- 
2.13.0

^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCH v10 01/20] ethtool: add library skeleton
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 02/20] ethtool: move from sample folder into lib folder Ferruh Yigit
                         ` (18 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Library is disabled by default.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 MAINTAINERS                                | 3 +++
 config/common_base                         | 5 +++++
 doc/guides/rel_notes/release_17_08.rst     | 1 +
 lib/Makefile                               | 2 ++
 lib/librte_eal/common/eal_common_log.c     | 1 +
 lib/librte_eal/common/include/rte_log.h    | 1 +
 lib/librte_ethtool/rte_ethtool_version.map | 4 ++++
 mk/rte.app.mk                              | 1 +
 8 files changed, 18 insertions(+)
 create mode 100644 lib/librte_ethtool/rte_ethtool_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index 00351ff9a..cae791e21 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -754,6 +754,9 @@ Latency statistics
 M: Reshma Pattan <reshma.pattan@intel.com>
 F: lib/librte_latencystats/
 
+Ethtool
+M: Remy Horton <remy.horton@intel.com>
+F: lib/librte_ethtool/
 
 Test Applications
 -----------------
diff --git a/config/common_base b/config/common_base
index 660588a3d..0b86c3431 100644
--- a/config/common_base
+++ b/config/common_base
@@ -700,6 +700,11 @@ CONFIG_RTE_KNI_PREEMPT_DEFAULT=y
 CONFIG_RTE_LIBRTE_PDUMP=y
 
 #
+# Compile librte_ethtool
+#
+CONFIG_RTE_LIBRTE_ETHTOOL=n
+
+#
 # Compile vhost user library
 #
 CONFIG_RTE_LIBRTE_VHOST=n
diff --git a/doc/guides/rel_notes/release_17_08.rst b/doc/guides/rel_notes/release_17_08.rst
index 842f46f75..dbe1ee906 100644
--- a/doc/guides/rel_notes/release_17_08.rst
+++ b/doc/guides/rel_notes/release_17_08.rst
@@ -186,6 +186,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_distributor.so.1
      librte_eal.so.4
      librte_ethdev.so.6
+   + librte_ethtool.so.1
      librte_hash.so.2
      librte_ip_frag.so.1
      librte_jobstats.so.1
diff --git a/lib/Makefile b/lib/Makefile
index 07e1fd0c5..434237d6e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -106,6 +106,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += librte_reorder
 DEPDIRS-librte_reorder := librte_eal librte_mempool librte_mbuf
 DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += librte_pdump
 DEPDIRS-librte_pdump := librte_eal librte_mempool librte_mbuf librte_ether
+DIRS-$(CONFIG_RTE_LIBRTE_ETHTOOL) += librte_ethtool
+DEPDIRS-librte_ethtool := librte_eal librte_ether
 
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
diff --git a/lib/librte_eal/common/eal_common_log.c b/lib/librte_eal/common/eal_common_log.c
index 41ea92472..b177b82fa 100644
--- a/lib/librte_eal/common/eal_common_log.c
+++ b/lib/librte_eal/common/eal_common_log.c
@@ -270,6 +270,7 @@ static const struct logtype logtype_strings[] = {
 	{RTE_LOGTYPE_CRYPTODEV,  "cryptodev"},
 	{RTE_LOGTYPE_EFD,        "efd"},
 	{RTE_LOGTYPE_EVENTDEV,   "eventdev"},
+	{RTE_LOGTYPE_ETHTOOL,    "ethtool"},
 	{RTE_LOGTYPE_USER1,      "user1"},
 	{RTE_LOGTYPE_USER2,      "user2"},
 	{RTE_LOGTYPE_USER3,      "user3"},
diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
index 341913851..5b240e8b1 100644
--- a/lib/librte_eal/common/include/rte_log.h
+++ b/lib/librte_eal/common/include/rte_log.h
@@ -87,6 +87,7 @@ extern struct rte_logs rte_logs;
 #define RTE_LOGTYPE_CRYPTODEV 17 /**< Log related to cryptodev. */
 #define RTE_LOGTYPE_EFD       18 /**< Log related to EFD. */
 #define RTE_LOGTYPE_EVENTDEV  19 /**< Log related to eventdev. */
+#define RTE_LOGTYPE_ETHTOOL   20 /**< Log related to ethtool. */
 
 /* these log types can be used in an application */
 #define RTE_LOGTYPE_USER1     24 /**< User-defined log type 1. */
diff --git a/lib/librte_ethtool/rte_ethtool_version.map b/lib/librte_ethtool/rte_ethtool_version.map
new file mode 100644
index 000000000..b6d2840be
--- /dev/null
+++ b/lib/librte_ethtool/rte_ethtool_version.map
@@ -0,0 +1,4 @@
+DPDK_17.08 {
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 7d71a4975..897d89acf 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -90,6 +90,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_KVARGS)         += -lrte_kvargs
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF)           += -lrte_mbuf
 _LDLIBS-$(CONFIG_RTE_LIBRTE_NET)            += -lrte_net
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHER)          += -lrte_ethdev
+_LDLIBS-$(CONFIG_RTE_LIBRTE_ETHTOOL)        += -lrte_ethtool
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CRYPTODEV)      += -lrte_cryptodev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV)       += -lrte_eventdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 02/20] ethtool: move from sample folder into lib folder
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 01/20] ethtool: add library skeleton Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 03/20] ethtool: remove PMD specific API call Ferruh Yigit
                         ` (17 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

ethtool library initially developed for ethtool sample application,
moving it to library folder to reuse it.

Sample application will continue to use ethtool library.

Sample application disabled for now, it will be enabled again when
modifications to the ethtool library finished.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 examples/Makefile                                  |  2 +-
 examples/ethtool/Makefile                          | 24 ++++++++-------
 examples/ethtool/{ethtool-app => }/ethapp.c        |  0
 examples/ethtool/{ethtool-app => }/ethapp.h        |  0
 examples/ethtool/{ethtool-app => }/main.c          |  0
 .../ethtool/lib => lib/librte_ethtool}/Makefile    | 35 ++++++++--------------
 .../lib => lib/librte_ethtool}/rte_ethtool.c       |  0
 .../lib => lib/librte_ethtool}/rte_ethtool.h       |  0
 lib/librte_ethtool/rte_ethtool_version.map         | 24 +++++++++++++++
 9 files changed, 51 insertions(+), 34 deletions(-)
 rename examples/ethtool/{ethtool-app => }/ethapp.c (100%)
 rename examples/ethtool/{ethtool-app => }/ethapp.h (100%)
 rename examples/ethtool/{ethtool-app => }/main.c (100%)
 rename {examples/ethtool/lib => lib/librte_ethtool}/Makefile (76%)
 rename {examples/ethtool/lib => lib/librte_ethtool}/rte_ethtool.c (100%)
 rename {examples/ethtool/lib => lib/librte_ethtool}/rte_ethtool.h (100%)

diff --git a/examples/Makefile b/examples/Makefile
index c0e9c3be6..aa1696158 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -40,7 +40,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += bond
 DIRS-y += cmdline
 DIRS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += distributor
-DIRS-y += ethtool
+DIRS-n += ethtool
 DIRS-y += exception_path
 DIRS-$(CONFIG_RTE_LIBRTE_EFD) += server_node_efd
 DIRS-y += helloworld
diff --git a/examples/ethtool/Makefile b/examples/ethtool/Makefile
index 30b42b70e..a774eace0 100644
--- a/examples/ethtool/Makefile
+++ b/examples/ethtool/Makefile
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2015 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -33,20 +33,22 @@ ifeq ($(RTE_SDK),)
 $(error "Please define RTE_SDK environment variable")
 endif
 
-# Default target, can be overwritten by command line or environment
+# Default target, can be overridden by command line or environment
 RTE_TARGET ?= x86_64-native-linuxapp-gcc
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
-$(info This application can only operate in a linuxapp environment, \
-please change the definition of the RTE_TARGET environment variable)
-else
+# binary name
+APP = ethtool
 
-DIRS-y += lib ethtool-app
-endif
+# all source are stored in SRCS-y
+SRCS-y := main.c ethapp.c
+
+#CFLAGS += -O3 -D_GNU_SOURCE -pthread -I$(SRCDIR)/../lib
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
 
-DEPDIRS-ethtool-app := lib
-DEPDIRS-lib := librte_eal librte_ether
+#LDLIBS += -L$(subst ethtool-app,lib,$(RTE_OUTPUT))/lib
+#LDLIBS += -lrte_ethtool
 
-include $(RTE_SDK)/mk/rte.extsubdir.mk
+include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/ethtool/ethtool-app/ethapp.c b/examples/ethtool/ethapp.c
similarity index 100%
rename from examples/ethtool/ethtool-app/ethapp.c
rename to examples/ethtool/ethapp.c
diff --git a/examples/ethtool/ethtool-app/ethapp.h b/examples/ethtool/ethapp.h
similarity index 100%
rename from examples/ethtool/ethtool-app/ethapp.h
rename to examples/ethtool/ethapp.h
diff --git a/examples/ethtool/ethtool-app/main.c b/examples/ethtool/main.c
similarity index 100%
rename from examples/ethtool/ethtool-app/main.c
rename to examples/ethtool/main.c
diff --git a/examples/ethtool/lib/Makefile b/lib/librte_ethtool/Makefile
similarity index 76%
rename from examples/ethtool/lib/Makefile
rename to lib/librte_ethtool/Makefile
index 266babade..f41cad3da 100644
--- a/examples/ethtool/lib/Makefile
+++ b/lib/librte_ethtool/Makefile
@@ -29,35 +29,26 @@
 #   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 #   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-ifeq ($(RTE_SDK),)
-$(error "Please define RTE_SDK environment variable")
-endif
-
-# Default target, can be overwritten by command line or environment
-RTE_TARGET ?= x86_64-native-linuxapp-gcc
-
 include $(RTE_SDK)/mk/rte.vars.mk
 
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
-$(error This application can only operate in a linuxapp environment, \
-please change the definition of the RTE_TARGET environment variable)
-endif
-
+#
 # library name
+#
 LIB = librte_ethtool.a
 
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+EXPORT_MAP := rte_ethtool_version.map
+
 LIBABIVER := 1
 
 # all source are stored in SRC-Y
-SRCS-y := rte_ethtool.c
+SRCS-$(CONFIG_RTE_LIBRTE_ETHTOOL) := rte_ethtool.c
 
-CFLAGS += -O3
-CFLAGS += $(WERROR_FLAGS)
-
-ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
-ifeq ($(CONFIG_RTE_LIBRTE_IXGBE_PMD),y)
-LDLIBS += -lrte_pmd_ixgbe
-endif
-endif
+#
+# Export include files
+#
+SYMLINK-$(CONFIG_RTE_LIBRTE_ETHTOOL)-include += rte_ethtool.h
 
-include $(RTE_SDK)/mk/rte.extlib.mk
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/examples/ethtool/lib/rte_ethtool.c b/lib/librte_ethtool/rte_ethtool.c
similarity index 100%
rename from examples/ethtool/lib/rte_ethtool.c
rename to lib/librte_ethtool/rte_ethtool.c
diff --git a/examples/ethtool/lib/rte_ethtool.h b/lib/librte_ethtool/rte_ethtool.h
similarity index 100%
rename from examples/ethtool/lib/rte_ethtool.h
rename to lib/librte_ethtool/rte_ethtool.h
diff --git a/lib/librte_ethtool/rte_ethtool_version.map b/lib/librte_ethtool/rte_ethtool_version.map
index b6d2840be..a6e756c50 100644
--- a/lib/librte_ethtool/rte_ethtool_version.map
+++ b/lib/librte_ethtool/rte_ethtool_version.map
@@ -1,4 +1,28 @@
 DPDK_17.08 {
+	global:
+
+	rte_ethtool_get_drvinfo;
+	rte_ethtool_get_link;
+	rte_ethtool_get_regs_len;
+	rte_ethtool_get_regs;
+	rte_ethtool_get_eeprom_len;
+	rte_ethtool_get_eeprom;
+	rte_ethtool_set_eeprom;
+	rte_ethtool_get_pauseparam;
+	rte_ethtool_set_pauseparam;
+	rte_ethtool_get_ringparam;
+	rte_ethtool_set_ringparam;
+
+	rte_ethtool_net_open;
+	rte_ethtool_net_stop;
+	rte_ethtool_net_get_mac_addr;
+	rte_ethtool_net_set_mac_addr;
+	rte_ethtool_net_validate_addr;
+	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_net_set_rx_mode;
 
 	local: *;
 };
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 03/20] ethtool: remove PMD specific API call
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 01/20] ethtool: add library skeleton Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 02/20] ethtool: move from sample folder into lib folder Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 04/20] ethtool: update header doxygen syntax Ferruh Yigit
                         ` (16 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

ethtool library has ixgbe specific API call, this needs to be removed
when moved into lib folder, libraries shouldn't have PMD dependencies.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ethtool/rte_ethtool.c | 23 +----------------------
 1 file changed, 1 insertion(+), 22 deletions(-)

diff --git a/lib/librte_ethtool/rte_ethtool.c b/lib/librte_ethtool/rte_ethtool.c
index fabfcb2ba..2807a53ff 100644
--- a/lib/librte_ethtool/rte_ethtool.c
+++ b/lib/librte_ethtool/rte_ethtool.c
@@ -36,9 +36,6 @@
 #include <rte_version.h>
 #include <rte_ethdev.h>
 #include <rte_ether.h>
-#ifdef RTE_LIBRTE_IXGBE_PMD
-#include <rte_pmd_ixgbe.h>
-#endif
 #include "rte_ethtool.h"
 
 #define PKTPOOL_SIZE 512
@@ -361,26 +358,8 @@ rte_ethtool_net_vlan_rx_kill_vid(uint8_t port_id, uint16_t vid)
 int
 rte_ethtool_net_set_rx_mode(uint8_t port_id)
 {
-	uint16_t num_vfs;
-	struct rte_eth_dev_info dev_info;
-	uint16_t vf;
-
-	memset(&dev_info, 0, sizeof(dev_info));
-	rte_eth_dev_info_get(port_id, &dev_info);
-	num_vfs = dev_info.max_vfs;
-
-	/* Set VF vf_rx_mode, VF unsupport status is discard */
-	for (vf = 0; vf < num_vfs; vf++) {
-#ifdef RTE_LIBRTE_IXGBE_PMD
-		rte_pmd_ixgbe_set_vf_rxmode(port_id, vf,
-			ETH_VMDQ_ACCEPT_UNTAG, 0);
-#endif
-	}
-
 	/* Enable Rx vlan filter, VF unspport status is discard */
-	rte_eth_dev_set_vlan_offload(port_id, ETH_VLAN_FILTER_MASK);
-
-	return 0;
+	return rte_eth_dev_set_vlan_offload(port_id, ETH_VLAN_FILTER_MASK);
 }
 
 
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 04/20] ethtool: update header doxygen syntax
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (2 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 03/20] ethtool: remove PMD specific API call Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-06  9:18         ` Burakov, Anatoly
  2017-07-04 16:13       ` [PATCH v10 05/20] ethtool: enable library Ferruh Yigit
                         ` (15 subsequent siblings)
  19 siblings, 1 reply; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Minor corrections and doxygen syntax fixes on library header file.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ethtool/rte_ethtool.h | 57 +++++++++++++++++++++-------------------
 1 file changed, 30 insertions(+), 27 deletions(-)

diff --git a/lib/librte_ethtool/rte_ethtool.h b/lib/librte_ethtool/rte_ethtool.h
index 18f44404b..bcf20870c 100644
--- a/lib/librte_ethtool/rte_ethtool.h
+++ b/lib/librte_ethtool/rte_ethtool.h
@@ -34,11 +34,13 @@
 #ifndef _RTE_ETHTOOL_H_
 #define _RTE_ETHTOOL_H_
 
-/*
+/**
+ * @file
+ *
  * 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_drvinfo:         ethtool_ops::get_driverinfo
  * rte_ethtool_get_link:            ethtool_ops::get_link
  * rte_ethtool_get_regs_len:        ethtool_ops::get_regs_len
  * rte_ethtool_get_regs:            ethtool_ops::get_regs
@@ -47,6 +49,8 @@
  * rte_ethtool_set_eeprom:          ethtool_ops::set_eeprom
  * rte_ethtool_get_pauseparam:      ethtool_ops::get_pauseparam
  * rte_ethtool_set_pauseparam:      ethtool_ops::set_pauseparam
+ * rte_ethtool_get_ringparam:       ethtool_ops::set_ringparam
+ * rte_ethtool_set_ringparam:       ethtool_ops::set_ringparam
  *
  * rte_ethtool_net_open:            net_device_ops::ndo_open
  * rte_ethtool_net_stop:            net_device_ops::ndo_stop
@@ -101,7 +105,7 @@ int rte_ethtool_get_regs_len(uint8_t port_id);
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
- * @param reg
+ * @param regs
  *   A pointer to ethtool_regs that has register information
  * @param data
  *   A pointer to a buffer that is used to retrieve device register content
@@ -112,7 +116,7 @@ int rte_ethtool_get_regs_len(uint8_t port_id);
  *   - others depends on the specific operations implementation.
  */
 int rte_ethtool_get_regs(uint8_t port_id, struct ethtool_regs *regs,
-			    void *data);
+		void *data);
 
 /**
  * Retrieve the Ethernet device link status
@@ -135,7 +139,7 @@ int rte_ethtool_get_link(uint8_t port_id);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @return
- *	 - (> 0) device EEPROM size in bytes
+ *   - (> 0) device EEPROM size in bytes
  *   - (0) device has NO EEPROM
  *   - (-ENOTSUP) if hardware doesn't support.
  *   - (-ENODEV) if *port_id* invalid.
@@ -150,9 +154,9 @@ int rte_ethtool_get_eeprom_len(uint8_t port_id);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param eeprom
- *	 The pointer of ethtool_eeprom that provides eeprom range
+ *   The pointer of ethtool_eeprom that provides eeprom range
  * @param words
- *	 A buffer that holds data read from eeprom
+ *   A buffer that holds data read from eeprom
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -160,7 +164,7 @@ int rte_ethtool_get_eeprom_len(uint8_t port_id);
  *   - others depends on the specific operations implementation.
  */
 int rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
-			      void *words);
+		void *words);
 
 /**
  * Setting EEPROM content based upon eeprom range described in ethtool
@@ -169,9 +173,9 @@ int rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param eeprom
- *	 The pointer of ethtool_eeprom that provides eeprom range
+ *   The pointer of ethtool_eeprom that provides eeprom range
  * @param words
- *	 A buffer that holds data to be written into eeprom
+ *   A buffer that holds data to be written into eeprom
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -180,7 +184,7 @@ int rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
  *   - others depends on the specific operations implementation.
  */
 int rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
-			      void *words);
+		void *words);
 
 /**
  * Retrieve the Ethernet device pause frame configuration according to
@@ -190,8 +194,8 @@ int rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param pause_param
- *	 The pointer of ethtool_coalesce that gets pause frame
- *	 configuration parameters
+ *   The pointer of ethtool_coalesce that gets pause frame
+ *   configuration parameters
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -200,7 +204,7 @@ int rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
  *   - others depends on the specific operations implementation.
  */
 int rte_ethtool_get_pauseparam(uint8_t port_id,
-				   struct ethtool_pauseparam *pause_param);
+		struct ethtool_pauseparam *pause_param);
 
 /**
  * Setting the Ethernet device pause frame configuration according to
@@ -208,8 +212,8 @@ int rte_ethtool_get_pauseparam(uint8_t port_id,
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
- * @param pause_param
- *	 The pointer of ethtool_coalesce that gets ring configuration parameters
+ * @param param
+ *   The pointer of ethtool_coalesce that gets ring configuration parameters
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -218,7 +222,7 @@ int rte_ethtool_get_pauseparam(uint8_t port_id,
  *   - others depends on the specific operations implementation.
  */
 int rte_ethtool_set_pauseparam(uint8_t port_id,
-				   struct ethtool_pauseparam *param);
+		struct ethtool_pauseparam *param);
 
 /**
  * Start the Ethernet device.
@@ -250,7 +254,7 @@ int rte_ethtool_net_stop(uint8_t port_id);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param addr
- *	 MAC address of the Ethernet device.
+ *   MAC address of the Ethernet device.
  * @return
  *   - (0) if successful.
  *   - (-ENODEV) if *port_id* invalid.
@@ -263,7 +267,7 @@ int rte_ethtool_net_get_mac_addr(uint8_t port_id, struct ether_addr *addr);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param addr
- *	 The new MAC addr.
+ *   The new MAC addr.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -279,7 +283,7 @@ int rte_ethtool_net_set_mac_addr(uint8_t port_id, struct ether_addr *addr);
  * @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
+ *   A pointer to a buffer (6-byte, 48bit) for the target MAC address
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -295,7 +299,7 @@ int rte_ethtool_net_validate_addr(uint8_t port_id, struct ether_addr *addr);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param mtu
- *	 New MTU
+ *   New MTU
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -311,7 +315,7 @@ int rte_ethtool_net_change_mtu(uint8_t port_id, int mtu);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param stats
- *	 A pointer to struct rte_eth_stats for statistics parameters
+ *   A pointer to struct rte_eth_stats for statistics parameters
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -327,7 +331,7 @@ int rte_ethtool_net_get_stats64(uint8_t port_id, struct rte_eth_stats *stats);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param vid
- *	 A new VLAN id
+ *   A new VLAN id
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -342,7 +346,7 @@ int rte_ethtool_net_vlan_rx_add_vid(uint8_t port_id, uint16_t vid);
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param vid
- *	 A new VLAN id
+ *   A new VLAN id
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
@@ -381,7 +385,7 @@ int rte_ethtool_net_set_rx_mode(uint8_t port_id);
  *   are used, and the function only gets parameters for queue 0.
  */
 int rte_ethtool_get_ringparam(uint8_t port_id,
-	struct ethtool_ringparam *ring_param);
+		struct ethtool_ringparam *ring_param);
 
 /**
  * Setting ring parameters for Ethernet device.
@@ -400,8 +404,7 @@ int rte_ethtool_get_ringparam(uint8_t port_id,
  *   are used, and the function only sets parameters for queue 0.
  */
 int rte_ethtool_set_ringparam(uint8_t port_id,
-	struct ethtool_ringparam *ring_param);
-
+		struct ethtool_ringparam *ring_param);
 
 #ifdef __cplusplus
 }
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 05/20] ethtool: enable library
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (3 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 04/20] ethtool: update header doxygen syntax Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 06/20] doc: add ethtool library documentation Ferruh Yigit
                         ` (14 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Enable ethtool library for Linux by default.

Enable ethtool sample application that uses ethtool library.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 config/common_linuxapp | 1 +
 examples/Makefile      | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/config/common_linuxapp b/config/common_linuxapp
index 74c7d64ec..9a6bf868c 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -41,6 +41,7 @@ CONFIG_RTE_EAL_VFIO=y
 CONFIG_RTE_KNI_KMOD=y
 CONFIG_RTE_LIBRTE_KNI=y
 CONFIG_RTE_LIBRTE_PMD_KNI=y
+CONFIG_RTE_LIBRTE_ETHTOOL=y
 CONFIG_RTE_LIBRTE_VHOST=y
 CONFIG_RTE_LIBRTE_VHOST_NUMA=y
 CONFIG_RTE_LIBRTE_PMD_VHOST=y
diff --git a/examples/Makefile b/examples/Makefile
index aa1696158..c0e9c3be6 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -40,7 +40,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += bond
 DIRS-y += cmdline
 DIRS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += distributor
-DIRS-n += ethtool
+DIRS-y += ethtool
 DIRS-y += exception_path
 DIRS-$(CONFIG_RTE_LIBRTE_EFD) += server_node_efd
 DIRS-y += helloworld
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 06/20] doc: add ethtool library documentation
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (4 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 05/20] ethtool: enable library Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 07/20] doc: update ethtool sample app doc Ferruh Yigit
                         ` (13 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 doc/api/doxy-api-index.md              |  3 +-
 doc/api/doxy-api.conf                  |  1 +
 doc/guides/prog_guide/ethtool_lib.rst  | 62 ++++++++++++++++++++++++++++++++++
 doc/guides/prog_guide/index.rst        |  1 +
 doc/guides/rel_notes/release_17_08.rst |  5 +++
 5 files changed, 71 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/prog_guide/ethtool_lib.rst

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index f5f1f199f..71350849f 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -161,4 +161,5 @@ There are many libraries, so their headers may be grouped by topics:
   [device metrics]     (@ref rte_metrics.h),
   [bitrate statistics] (@ref rte_bitrate.h),
   [latency statistics] (@ref rte_latencystats.h),
-  [version]            (@ref rte_version.h)
+  [version]            (@ref rte_version.h),
+  [ethtool]            (@ref rte_ethtool.h)
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index ca9194fe0..b66e86541 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -45,6 +45,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           lib/librte_distributor \
                           lib/librte_efd \
                           lib/librte_ether \
+                          lib/librte_ethtool \
                           lib/librte_eventdev \
                           lib/librte_hash \
                           lib/librte_ip_frag \
diff --git a/doc/guides/prog_guide/ethtool_lib.rst b/doc/guides/prog_guide/ethtool_lib.rst
new file mode 100644
index 000000000..a667bcfe3
--- /dev/null
+++ b/doc/guides/prog_guide/ethtool_lib.rst
@@ -0,0 +1,62 @@
+..  BSD LICENSE
+    Copyright(c) 2017 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.
+
+.. _Ethtool_Library:
+
+Ethtool Library
+===============
+
+Ethtool interface
+-----------------
+
+The Ethtool interface is built as a separate library, and implements
+the following functions:
+
+- ``rte_ethtool_get_drvinfo()``
+- ``rte_ethtool_get_regs_len()``
+- ``rte_ethtool_get_regs()``
+- ``rte_ethtool_get_link()``
+- ``rte_ethtool_get_eeprom_len()``
+- ``rte_ethtool_get_eeprom()``
+- ``rte_ethtool_set_eeprom()``
+- ``rte_ethtool_get_pauseparam()``
+- ``rte_ethtool_set_pauseparam()``
+- ``rte_ethtool_net_open()``
+- ``rte_ethtool_net_stop()``
+- ``rte_ethtool_net_get_mac_addr()``
+- ``rte_ethtool_net_set_mac_addr()``
+- ``rte_ethtool_net_validate_addr()``
+- ``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_net_set_rx_mode()``
+- ``rte_ethtool_get_ringparam()``
+- ``rte_ethtool_set_ringparam()``
diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index ef5a02ad5..54f9538ea 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -54,6 +54,7 @@ Programmer's Guide
     reorder_lib
     ip_fragment_reassembly_lib
     pdump_lib
+    ethtool_lib
     multi_proc_support
     kernel_nic_interface
     thread_safety_dpdk_functions
diff --git a/doc/guides/rel_notes/release_17_08.rst b/doc/guides/rel_notes/release_17_08.rst
index dbe1ee906..423877f49 100644
--- a/doc/guides/rel_notes/release_17_08.rst
+++ b/doc/guides/rel_notes/release_17_08.rst
@@ -75,6 +75,11 @@ New Features
 
   Added support for firmwares with multiple Ethernet ports per physical port.
 
+* **Added ethtool library.**
+
+  Ethtool library is wrapper for ethdev library and provides APIs to get data
+  similar to Linux ethtool provides.
+
 
 Resolved Issues
 ---------------
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 07/20] doc: update ethtool sample app doc
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (5 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 06/20] doc: add ethtool library documentation Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 08/20] unci: add module skeleton Ferruh Yigit
                         ` (12 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 doc/guides/sample_app_ug/ethtool.rst | 36 ++++--------------------------------
 1 file changed, 4 insertions(+), 32 deletions(-)

diff --git a/doc/guides/sample_app_ug/ethtool.rst b/doc/guides/sample_app_ug/ethtool.rst
index 67797954d..def48985d 100644
--- a/doc/guides/sample_app_ug/ethtool.rst
+++ b/doc/guides/sample_app_ug/ethtool.rst
@@ -1,6 +1,6 @@
 
 ..  BSD LICENSE
-    Copyright(c) 2015 Intel Corporation. All rights reserved.
+    Copyright(c) 2015-2017 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -71,7 +71,7 @@ The only available options are the standard ones for the EAL:
 
 .. code-block:: console
 
-    ./ethtool-app/ethtool-app/${RTE_TARGET}/ethtool [EAL options]
+    ./${RTE_TARGET}/ethtool [EAL options]
 
 Refer to the *DPDK Getting Started Guide* for general information on
 running applications and the Environment Abstraction Layer (EAL)
@@ -128,33 +128,5 @@ Ethtool Shell
 The foreground part of the Ethtool sample is a console-based
 interface that accepts commands as described in `using the
 application`_. Individual call-back functions handle the detail
-associated with each command, which make use of the functions
-defined in the `Ethtool interface`_ to the DPDK functions.
-
-Ethtool interface
------------------
-
-The Ethtool interface is built as a separate library, and implements
-the following functions:
-
-- ``rte_ethtool_get_drvinfo()``
-- ``rte_ethtool_get_regs_len()``
-- ``rte_ethtool_get_regs()``
-- ``rte_ethtool_get_link()``
-- ``rte_ethtool_get_eeprom_len()``
-- ``rte_ethtool_get_eeprom()``
-- ``rte_ethtool_set_eeprom()``
-- ``rte_ethtool_get_pauseparam()``
-- ``rte_ethtool_set_pauseparam()``
-- ``rte_ethtool_net_open()``
-- ``rte_ethtool_net_stop()``
-- ``rte_ethtool_net_get_mac_addr()``
-- ``rte_ethtool_net_set_mac_addr()``
-- ``rte_ethtool_net_validate_addr()``
-- ``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_net_set_rx_mode()``
-- ``rte_ethtool_get_ringparam()``
-- ``rte_ethtool_set_ringparam()``
+associated with each command, which make use of librte_ethtool
+library.
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 08/20] unci: add module skeleton
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (6 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 07/20] doc: update ethtool sample app doc Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-06  9:25         ` Burakov, Anatoly
  2017-07-04 16:13       ` [PATCH v10 09/20] unci: add rtnl newlink Ferruh Yigit
                         ` (11 subsequent siblings)
  19 siblings, 1 reply; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Base files to have a new kernel module, without actual source code.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 MAINTAINERS                             |  4 +++
 config/common_base                      |  5 ++++
 config/common_linuxapp                  |  1 +
 lib/librte_eal/linuxapp/Makefile        |  4 ++-
 lib/librte_eal/linuxapp/unci/Makefile   | 52 +++++++++++++++++++++++++++++++++
 lib/librte_eal/linuxapp/unci/unci_dev.h | 34 +++++++++++++++++++++
 lib/librte_eal/linuxapp/unci/unci_net.c | 42 ++++++++++++++++++++++++++
 7 files changed, 141 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_eal/linuxapp/unci/Makefile
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_dev.h
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_net.c

diff --git a/MAINTAINERS b/MAINTAINERS
index cae791e21..cfc3d4bf3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -758,6 +758,10 @@ Ethtool
 M: Remy Horton <remy.horton@intel.com>
 F: lib/librte_ethtool/
 
+Linux Userspace Network Control Interface (UNCI)
+M: Ferruh Yigit <ferruh.yigit@intel.com>
+F: lib/librte_eal/linuxapp/unci/
+
 Test Applications
 -----------------
 
diff --git a/config/common_base b/config/common_base
index 0b86c3431..1582f703e 100644
--- a/config/common_base
+++ b/config/common_base
@@ -705,6 +705,11 @@ CONFIG_RTE_LIBRTE_PDUMP=y
 CONFIG_RTE_LIBRTE_ETHTOOL=n
 
 #
+# Compile Userspace Network Control Interface (UNCI) kernel module
+#
+CONFIG_RTE_UNCI_KMOD=n
+
+#
 # Compile vhost user library
 #
 CONFIG_RTE_LIBRTE_VHOST=n
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 9a6bf868c..b400b2c0e 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -42,6 +42,7 @@ CONFIG_RTE_KNI_KMOD=y
 CONFIG_RTE_LIBRTE_KNI=y
 CONFIG_RTE_LIBRTE_PMD_KNI=y
 CONFIG_RTE_LIBRTE_ETHTOOL=y
+CONFIG_RTE_UNCI_KMOD=y
 CONFIG_RTE_LIBRTE_VHOST=y
 CONFIG_RTE_LIBRTE_VHOST_NUMA=y
 CONFIG_RTE_LIBRTE_PMD_VHOST=y
diff --git a/lib/librte_eal/linuxapp/Makefile b/lib/librte_eal/linuxapp/Makefile
index 4794696b6..2d293f1a6 100644
--- a/lib/librte_eal/linuxapp/Makefile
+++ b/lib/librte_eal/linuxapp/Makefile
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,8 @@ DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal
 DIRS-$(CONFIG_RTE_EAL_IGB_UIO) += igb_uio
 DIRS-$(CONFIG_RTE_KNI_KMOD) += kni
 DEPDIRS-kni := eal
+DIRS-$(CONFIG_RTE_UNCI_KMOD) += unci
+DEPDIRS-unci := eal
 DIRS-$(CONFIG_RTE_LIBRTE_XEN_DOM0) += xen_dom0
 DEPDIRS-xen_dom0 := eal
 
diff --git a/lib/librte_eal/linuxapp/unci/Makefile b/lib/librte_eal/linuxapp/unci/Makefile
new file mode 100644
index 000000000..02e354814
--- /dev/null
+++ b/lib/librte_eal/linuxapp/unci/Makefile
@@ -0,0 +1,52 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 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
+
+#
+# module name and path
+#
+MODULE = rte_unci
+
+#
+# CFLAGS
+#
+MODULE_CFLAGS += -I$(SRCDIR)
+MODULE_CFLAGS += -I$(RTE_OUTPUT)/include
+MODULE_CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
+MODULE_CFLAGS += -Wall -Werror
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_UNCI_KMOD) := unci_net.c
+
+include $(RTE_SDK)/mk/rte.module.mk
diff --git a/lib/librte_eal/linuxapp/unci/unci_dev.h b/lib/librte_eal/linuxapp/unci/unci_dev.h
new file mode 100644
index 000000000..102409020
--- /dev/null
+++ b/lib/librte_eal/linuxapp/unci/unci_dev.h
@@ -0,0 +1,34 @@
+/*-
+ * GPL LICENSE SUMMARY
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;
+ *
+ *   The full GNU General Public License is included in this distribution
+ *   in the file called LICENSE.GPL.
+ *
+ *   Contact Information:
+ *   Intel Corporation
+ */
+
+#ifndef _UNCI_DEV_H_
+#define _UNCI_DEV_H_
+
+#ifdef pr_fmt
+#undef pr_fmt
+#endif
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+
+#endif /* _UNCI_DEV_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/unci_net.c b/lib/librte_eal/linuxapp/unci/unci_net.c
new file mode 100644
index 000000000..b8ef409d3
--- /dev/null
+++ b/lib/librte_eal/linuxapp/unci/unci_net.c
@@ -0,0 +1,42 @@
+/*-
+ * GPL LICENSE SUMMARY
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;
+ *
+ *   The full GNU General Public License is included in this distribution
+ *   in the file called LICENSE.GPL.
+ *
+ *   Contact Information:
+ *   Intel Corporation
+ */
+
+#include <linux/module.h>
+
+#include "unci_dev.h"
+
+static int __init unci_init(void)
+{
+	return 0;
+}
+module_init(unci_init);
+
+static void __exit unci_exit(void)
+{
+}
+module_exit(unci_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Kernel Module for managing unci devices");
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 09/20] unci: add rtnl newlink
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (7 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 08/20] unci: add module skeleton Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 10/20] unci: init netlink Ferruh Yigit
                         ` (10 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Use rtnl to create a new interface. Interface is not setup yet.

Pid and port_id should be provided by userspace application that does
the call for interface creation.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_eal/linuxapp/eal/Makefile               |  1 +
 .../linuxapp/eal/include/exec-env/unci.h           | 73 ++++++++++++++++++++++
 lib/librte_eal/linuxapp/unci/unci_dev.h            |  8 +++
 lib/librte_eal/linuxapp/unci/unci_net.c            | 50 ++++++++++++++-
 4 files changed, 131 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_eal/linuxapp/eal/include/exec-env/unci.h

diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 8651e2783..139e56033 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -130,6 +130,7 @@ CFLAGS_eal_thread.o += -Wno-return-type
 endif
 
 INC := rte_interrupts.h rte_kni_common.h rte_dom0_common.h
+INC += unci.h
 
 SYMLINK-$(CONFIG_RTE_EXEC_ENV_LINUXAPP)-include/exec-env := \
 	$(addprefix include/exec-env/,$(INC))
diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h b/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h
new file mode 100644
index 000000000..8d4a95777
--- /dev/null
+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h
@@ -0,0 +1,73 @@
+/*-
+ *   This file is provided under a dual BSD/LGPLv2 license.  When using or
+ *   redistributing this file, you may do so under either license.
+ *
+ *   GNU LESSER GENERAL PUBLIC LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2.1 of the GNU Lesser General Public License
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this program;
+ *
+ *   Contact Information:
+ *   Intel Corporation
+ *
+ *
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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 _UAPI_LINUX_UNCI_H_
+#define _UAPI_LINUX_UNCI_H_
+
+#define UNCI_DEVICE "unci"
+
+/* can go into include/uapi/linux/if_link.h */
+enum {
+	IFLA_UNCI_UNSPEC,
+	IFLA_UNCI_PORTID,
+	IFLA_UNCI_PID,
+	__IFLA_UNCI_MAX,
+};
+
+#define IFLA_UNCI_MAX (__IFLA_UNCI_MAX - 1)
+
+#endif /* _UAPI_LINUX_UNCI_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/unci_dev.h b/lib/librte_eal/linuxapp/unci/unci_dev.h
index 102409020..92b9b8383 100644
--- a/lib/librte_eal/linuxapp/unci/unci_dev.h
+++ b/lib/librte_eal/linuxapp/unci/unci_dev.h
@@ -25,10 +25,18 @@
 #ifndef _UNCI_DEV_H_
 #define _UNCI_DEV_H_
 
+#include <linux/netdevice.h>
+
+#include <exec-env/unci.h>
+
 #ifdef pr_fmt
 #undef pr_fmt
 #endif
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+struct unci_dev {
+	__u32 port_id;
+	__u32 pid;
+};
 
 #endif /* _UNCI_DEV_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/unci_net.c b/lib/librte_eal/linuxapp/unci/unci_net.c
index b8ef409d3..42fac3e63 100644
--- a/lib/librte_eal/linuxapp/unci/unci_net.c
+++ b/lib/librte_eal/linuxapp/unci/unci_net.c
@@ -23,20 +23,68 @@
  */
 
 #include <linux/module.h>
+#include <net/rtnetlink.h>
 
 #include "unci_dev.h"
 
-static int __init unci_init(void)
+static const struct net_device_ops unci_net_netdev_ops = { 0 };
+
+static void unci_net_setup(struct net_device *dev)
+{
+	ether_setup(dev);
+	dev->netdev_ops = &unci_net_netdev_ops;
+}
+
+static int unci_net_newlink(struct net *net, struct net_device *dev,
+		struct nlattr *tb[], struct nlattr *data[])
+{
+	struct unci_dev *unci = netdev_priv(dev);
+
+	unci->port_id = nla_get_u32(data[IFLA_UNCI_PORTID]);
+	unci->pid = nla_get_u32(data[IFLA_UNCI_PID]);
+
+	return register_netdevice(dev);
+}
+
+static const struct nla_policy unci_policy[IFLA_UNCI_MAX + 1] = {
+	[IFLA_UNCI_PORTID] = { .type = NLA_U32 },
+	[IFLA_UNCI_PID]    = { .type = NLA_U32 },
+};
+
+static int unci_validate(struct nlattr *tb[], struct nlattr *data[])
 {
+	if (!data)
+		return -EINVAL;
+
+	if (!data[IFLA_UNCI_PID] || !data[IFLA_UNCI_PORTID])
+		return -EINVAL;
+
 	return 0;
 }
+
+static struct rtnl_link_ops unci_link_ops __read_mostly = {
+	.kind = UNCI_DEVICE,
+	.priv_size = sizeof(struct unci_dev),
+	.maxtype = IFLA_UNCI_MAX,
+	.setup = unci_net_setup,
+	.newlink = unci_net_newlink,
+	.policy = unci_policy,
+	.validate = unci_validate,
+};
+
+static int __init unci_init(void)
+{
+	return rtnl_link_register(&unci_link_ops);
+}
 module_init(unci_init);
 
 static void __exit unci_exit(void)
 {
+	rtnl_link_unregister(&unci_link_ops);
 }
 module_exit(unci_exit);
 
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Intel Corporation");
 MODULE_DESCRIPTION("Kernel Module for managing unci devices");
+MODULE_ALIAS_RTNL_LINK(UNCI_DEVICE);
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 10/20] unci: init netlink
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (8 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 09/20] unci: add rtnl newlink Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-06  9:32         ` Burakov, Anatoly
  2017-07-04 16:13       ` [PATCH v10 11/20] unci: add netlink exec Ferruh Yigit
                         ` (9 subsequent siblings)
  19 siblings, 1 reply; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Initialize netlink socket.

Userspace application will connect to the socket for data transfer.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 .../linuxapp/eal/include/exec-env/unci.h           | 33 ++++++++++
 lib/librte_eal/linuxapp/unci/Makefile              |  1 +
 lib/librte_eal/linuxapp/unci/unci_dev.h            |  3 +
 lib/librte_eal/linuxapp/unci/unci_net.c            |  7 +++
 lib/librte_eal/linuxapp/unci/unci_nl.c             | 72 ++++++++++++++++++++++
 5 files changed, 116 insertions(+)
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_nl.c

diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h b/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h
index 8d4a95777..6d3490aee 100644
--- a/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h
+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h
@@ -60,6 +60,20 @@
 
 #define UNCI_DEVICE "unci"
 
+#define UNCI_GENL_MSG_LEN 1536
+
+#define UNCI_NL_MSG_LEN 500
+struct unci_nl_msg {
+	__u32 cmd_id;
+	__u32 port_id;
+	__u32 flag;
+	__u8 input_buffer[UNCI_NL_MSG_LEN];
+	__u8 output_buffer[UNCI_NL_MSG_LEN];
+	size_t input_buffer_len;
+	size_t output_buffer_len;
+	int err;
+};
+
 /* can go into include/uapi/linux/if_link.h */
 enum {
 	IFLA_UNCI_UNSPEC,
@@ -70,4 +84,23 @@ enum {
 
 #define IFLA_UNCI_MAX (__IFLA_UNCI_MAX - 1)
 
+
+#define UNCI_GENL_VERSION 1
+
+enum {
+	UNCI_ATTR_UNSPEC,
+	UNCI_ATTR_MSG,
+	__UNCI_ATTR_MAX,
+};
+
+#define UNCI_ATTR_MAX (__UNCI_ATTR_MAX - 1)
+
+enum {
+	UNCI_CMD_UNSPEC,
+	UNCI_CMD_MSG,
+	__UNCI_CMD_MAX,
+};
+
+#define UNCI_CMD_MAX (__UNCI_CMD_MAX - 1)
+
 #endif /* _UAPI_LINUX_UNCI_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/Makefile b/lib/librte_eal/linuxapp/unci/Makefile
index 02e354814..c2a81be7d 100644
--- a/lib/librte_eal/linuxapp/unci/Makefile
+++ b/lib/librte_eal/linuxapp/unci/Makefile
@@ -48,5 +48,6 @@ MODULE_CFLAGS += -Wall -Werror
 # all source are stored in SRCS-y
 #
 SRCS-$(CONFIG_RTE_UNCI_KMOD) := unci_net.c
+SRCS-$(CONFIG_RTE_UNCI_KMOD) += unci_nl.c
 
 include $(RTE_SDK)/mk/rte.module.mk
diff --git a/lib/librte_eal/linuxapp/unci/unci_dev.h b/lib/librte_eal/linuxapp/unci/unci_dev.h
index 92b9b8383..a748abf98 100644
--- a/lib/librte_eal/linuxapp/unci/unci_dev.h
+++ b/lib/librte_eal/linuxapp/unci/unci_dev.h
@@ -39,4 +39,7 @@ struct unci_dev {
 	__u32 pid;
 };
 
+int unci_nl_init(void);
+void unci_nl_release(void);
+
 #endif /* _UNCI_DEV_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/unci_net.c b/lib/librte_eal/linuxapp/unci/unci_net.c
index 42fac3e63..1989b6d23 100644
--- a/lib/librte_eal/linuxapp/unci/unci_net.c
+++ b/lib/librte_eal/linuxapp/unci/unci_net.c
@@ -74,6 +74,12 @@ static struct rtnl_link_ops unci_link_ops __read_mostly = {
 
 static int __init unci_init(void)
 {
+	int ret;
+
+	ret = unci_nl_init();
+	if (ret)
+		return ret;
+
 	return rtnl_link_register(&unci_link_ops);
 }
 module_init(unci_init);
@@ -81,6 +87,7 @@ module_init(unci_init);
 static void __exit unci_exit(void)
 {
 	rtnl_link_unregister(&unci_link_ops);
+	unci_nl_release();
 }
 module_exit(unci_exit);
 
diff --git a/lib/librte_eal/linuxapp/unci/unci_nl.c b/lib/librte_eal/linuxapp/unci/unci_nl.c
new file mode 100644
index 000000000..1461a3309
--- /dev/null
+++ b/lib/librte_eal/linuxapp/unci/unci_nl.c
@@ -0,0 +1,72 @@
+/*-
+ * GPL LICENSE SUMMARY
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;
+ *   The full GNU General Public License is included in this distribution
+ *   in the file called LICENSE.GPL.
+ *
+ *   Contact Information:
+ *   Intel Corporation
+ */
+
+#include <net/genetlink.h>
+#include <net/sock.h>
+
+#include "unci_dev.h"
+
+static int unci_genl_process(struct sk_buff *skb, struct genl_info *info)
+{
+	struct nlattr **attrs = info->attrs;
+	struct unci_nl_msg nl_msg;
+
+	if (!attrs[UNCI_ATTR_MSG])
+		return -EINVAL;
+
+	nla_memcpy(&nl_msg, attrs[UNCI_ATTR_MSG], sizeof(struct unci_nl_msg));
+	pr_debug("cmd: %u\n", nl_msg.cmd_id);
+
+	return 0;
+}
+
+static struct nla_policy unci_genl_policy[UNCI_ATTR_MAX + 1] = {
+	[UNCI_ATTR_MSG] = { .type = NLA_BINARY, .len = UNCI_GENL_MSG_LEN },
+};
+
+static const struct genl_ops unci_ops[] = {
+	{
+		.cmd = UNCI_CMD_MSG,
+		.doit = unci_genl_process,
+		.policy = unci_genl_policy,
+	},
+};
+
+static struct genl_family unci_genl_family __ro_after_init = {
+	.module = THIS_MODULE,
+	.name = UNCI_DEVICE,
+	.version = UNCI_GENL_VERSION,
+	.maxattr = UNCI_ATTR_MAX,
+	.ops = unci_ops,
+	.n_ops = ARRAY_SIZE(unci_ops),
+};
+
+int unci_nl_init(void)
+{
+	return genl_register_family(&unci_genl_family);
+}
+
+void unci_nl_release(void)
+{
+	genl_unregister_family(&unci_genl_family);
+}
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 11/20] unci: add netlink exec
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (9 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 10/20] unci: init netlink Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-05 19:07         ` Stephen Hemminger
  2017-07-05 19:15         ` Stephen Hemminger
  2017-07-04 16:13       ` [PATCH v10 12/20] unci: add netdevice ops Ferruh Yigit
                         ` (8 subsequent siblings)
  19 siblings, 2 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Add netlink exec function, which sends a message to userspace and waits
and receives the response from userspace.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 .../linuxapp/eal/include/exec-env/unci.h           |   6 +
 lib/librte_eal/linuxapp/unci/unci_dev.h            |   4 +
 lib/librte_eal/linuxapp/unci/unci_net.c            |   5 +
 lib/librte_eal/linuxapp/unci/unci_nl.c             | 180 +++++++++++++++++++++
 4 files changed, 195 insertions(+)

diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h b/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h
index 6d3490aee..3d88b7ef3 100644
--- a/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h
+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h
@@ -74,6 +74,12 @@ struct unci_nl_msg {
 	int err;
 };
 
+enum unci_ethtool_msg_flag {
+	UNCI_MSG_FLAG_NONE,
+	UNCI_MSG_FLAG_REQUEST,
+	UNCI_MSG_FLAG_RESPONSE,
+};
+
 /* can go into include/uapi/linux/if_link.h */
 enum {
 	IFLA_UNCI_UNSPEC,
diff --git a/lib/librte_eal/linuxapp/unci/unci_dev.h b/lib/librte_eal/linuxapp/unci/unci_dev.h
index a748abf98..8d9ca6970 100644
--- a/lib/librte_eal/linuxapp/unci/unci_dev.h
+++ b/lib/librte_eal/linuxapp/unci/unci_dev.h
@@ -37,9 +37,13 @@
 struct unci_dev {
 	__u32 port_id;
 	__u32 pid;
+	struct completion msg_received;
+	u32 nb_timedout_msg;
 };
 
 int unci_nl_init(void);
 void unci_nl_release(void);
+int unci_nl_exec(u32 cmd, struct net_device *dev, void *in_data,
+		size_t in_len, void *out_data, size_t out_len);
 
 #endif /* _UNCI_DEV_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/unci_net.c b/lib/librte_eal/linuxapp/unci/unci_net.c
index 1989b6d23..27b9f9f70 100644
--- a/lib/librte_eal/linuxapp/unci/unci_net.c
+++ b/lib/librte_eal/linuxapp/unci/unci_net.c
@@ -31,8 +31,13 @@ static const struct net_device_ops unci_net_netdev_ops = { 0 };
 
 static void unci_net_setup(struct net_device *dev)
 {
+	struct unci_dev *unci;
+
 	ether_setup(dev);
 	dev->netdev_ops = &unci_net_netdev_ops;
+
+	unci = netdev_priv(dev);
+	init_completion(&unci->msg_received);
 }
 
 static int unci_net_newlink(struct net *net, struct net_device *dev,
diff --git a/lib/librte_eal/linuxapp/unci/unci_nl.c b/lib/librte_eal/linuxapp/unci/unci_nl.c
index 1461a3309..fd79ec8f9 100644
--- a/lib/librte_eal/linuxapp/unci/unci_nl.c
+++ b/lib/librte_eal/linuxapp/unci/unci_nl.c
@@ -26,6 +26,180 @@
 
 #include "unci_dev.h"
 
+#define UNCI_GENL_MSG_LEN 1536
+
+#define UNCI_CMD_TIMEOUT 500 /* ms */
+
+static struct response_buffer {
+	int magic; /* for sanity check */
+	void *buffer;
+	size_t length;
+	struct completion *msg_received;
+	int *err;
+	u32 in_use;
+} response_buffer;
+
+static DEFINE_MUTEX(sync_lock);
+
+static int unci_response_buffer_register(int magic, void *buffer, size_t length,
+		struct completion *msg_received, int *err)
+{
+	if (!response_buffer.in_use) {
+		response_buffer.magic = magic;
+		response_buffer.buffer = buffer;
+		response_buffer.length = length;
+		response_buffer.msg_received = msg_received;
+		response_buffer.err = err;
+		response_buffer.in_use = 1;
+		return 0;
+	}
+
+	return 1;
+}
+
+static void unci_response_buffer_unregister(int magic)
+{
+	if (response_buffer.in_use) {
+		if (magic == response_buffer.magic) {
+			response_buffer.magic = -1;
+			response_buffer.buffer = NULL;
+			response_buffer.length = 0;
+			response_buffer.msg_received = NULL;
+			response_buffer.err = NULL;
+			response_buffer.in_use = 0;
+		} else {
+			pr_err("Unregister magic mismatch\n");
+		}
+	}
+}
+
+static void nl_recv_user_request(struct unci_nl_msg *nl_msg)
+{
+	/* Userspace requests not supported yet */
+	pr_debug("Request from userspace received\n");
+}
+
+static void nl_recv_user_response(struct unci_nl_msg *nl_msg)
+{
+	struct completion *msg_received;
+	size_t recv_len;
+	size_t expected_len;
+
+	if (response_buffer.in_use) {
+		if (response_buffer.buffer != NULL) {
+			recv_len = nl_msg->output_buffer_len;
+			expected_len = response_buffer.length;
+
+			memcpy(response_buffer.buffer,
+					nl_msg->output_buffer,
+					response_buffer.length);
+
+			if (nl_msg->err == 0 && recv_len != expected_len)
+				pr_info("Expected and received len not match "
+					"%zu - %zu\n", recv_len, expected_len);
+		}
+
+		*response_buffer.err = nl_msg->err;
+		msg_received = response_buffer.msg_received;
+		unci_response_buffer_unregister(response_buffer.magic);
+		complete(msg_received);
+	}
+}
+
+static struct genl_family unci_genl_family;
+
+static int unci_nl_send(u32 cmd_id, u32 port_id, u32 pid, void *in_data,
+		size_t in_data_len)
+{
+	struct unci_nl_msg nl_msg;
+	struct sk_buff *skb;
+	void *payload;
+	u32 size = 0;
+
+	if (pid == 0)
+		return -1;
+
+	memset(&nl_msg, 0, sizeof(struct unci_nl_msg));
+	nl_msg.cmd_id = cmd_id;
+	nl_msg.port_id = port_id;
+
+	if (in_data) {
+		if (in_data_len == 0 || in_data_len > UNCI_NL_MSG_LEN)
+			return -EINVAL;
+		nl_msg.input_buffer_len = in_data_len;
+		memcpy(nl_msg.input_buffer, in_data, in_data_len);
+	}
+
+	skb = genlmsg_new(UNCI_GENL_MSG_LEN, GFP_ATOMIC);
+	if (!skb)
+		return -ENOMEM;
+
+	size = sizeof(struct unci_nl_msg) + GENL_HDRLEN +
+		unci_genl_family.hdrsize;
+
+	payload = genlmsg_put(skb, 0, 0, &unci_genl_family, 0, UNCI_CMD_MSG);
+	if (payload == NULL) {
+		nlmsg_free(skb);
+		return -EMSGSIZE;
+	}
+
+	nla_put(skb, UNCI_ATTR_MSG, sizeof(struct unci_nl_msg), &nl_msg);
+
+	genlmsg_end(skb, payload);
+
+	genlmsg_unicast(&init_net, skb, pid);
+	pr_debug("Sent cmd:%u port:%u pid:%u\n", cmd_id, port_id, pid);
+
+	return 0;
+}
+
+int unci_nl_exec(u32 cmd, struct net_device *dev, void *in_data,
+		size_t in_data_len, void *out_data, size_t out_data_len)
+{
+	struct unci_dev *unci = netdev_priv(dev);
+	int err = -EINVAL;
+	int ret;
+
+	if (out_data_len > UNCI_NL_MSG_LEN) {
+		pr_err("Message is too big to receive:%zu\n", out_data_len);
+		return err;
+	}
+
+	mutex_lock(&sync_lock);
+	ret = unci_response_buffer_register(cmd, out_data, out_data_len,
+			&unci->msg_received, &err);
+	if (ret) {
+		mutex_unlock(&sync_lock);
+		return -EINVAL;
+	}
+
+	ret = unci_nl_send(cmd, unci->port_id, unci->pid, in_data, in_data_len);
+	if (ret) {
+		unci_response_buffer_unregister(response_buffer.magic);
+		mutex_unlock(&sync_lock);
+		return ret;
+	}
+
+	ret = wait_for_completion_interruptible_timeout(&unci->msg_received,
+			 msecs_to_jiffies(UNCI_CMD_TIMEOUT));
+	if (ret == 0 || err < 0) {
+		unci_response_buffer_unregister(response_buffer.magic);
+		mutex_unlock(&sync_lock);
+		if (ret == 0) { /* timeout */
+			unci->nb_timedout_msg++;
+			pr_info("Command timed-out for port:%u cmd:%u (%u)\n",
+				unci->port_id, cmd, unci->nb_timedout_msg);
+			return -EINVAL;
+		}
+		pr_debug("Command return error for port:%d cmd:%d err:%d\n",
+				unci->port_id, cmd, err);
+		return err;
+	}
+	mutex_unlock(&sync_lock);
+
+	return 0;
+}
+
 static int unci_genl_process(struct sk_buff *skb, struct genl_info *info)
 {
 	struct nlattr **attrs = info->attrs;
@@ -37,6 +211,12 @@ static int unci_genl_process(struct sk_buff *skb, struct genl_info *info)
 	nla_memcpy(&nl_msg, attrs[UNCI_ATTR_MSG], sizeof(struct unci_nl_msg));
 	pr_debug("cmd: %u\n", nl_msg.cmd_id);
 
+	if (nl_msg.flag & UNCI_MSG_FLAG_REQUEST) {
+		nl_recv_user_request(&nl_msg);
+		return 0;
+	}
+
+	nl_recv_user_response(&nl_msg);
 	return 0;
 }
 
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 12/20] unci: add netdevice ops
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (10 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 11/20] unci: add netlink exec Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-05 19:12         ` Stephen Hemminger
  2017-07-05 19:12         ` Stephen Hemminger
  2017-07-04 16:13       ` [PATCH v10 13/20] unci: add ethtool support Ferruh Yigit
                         ` (7 subsequent siblings)
  19 siblings, 2 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Add ndos for virtual interface. Almost all ndos use netlink exec
to pass command to userspace and read response.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 .../linuxapp/eal/include/exec-env/unci.h           |  17 +++
 lib/librte_eal/linuxapp/unci/unci_net.c            | 132 ++++++++++++++++++++-
 2 files changed, 148 insertions(+), 1 deletion(-)

diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h b/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h
index 3d88b7ef3..b39e3c062 100644
--- a/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h
+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h
@@ -109,4 +109,21 @@ enum {
 
 #define UNCI_CMD_MAX (__UNCI_CMD_MAX - 1)
 
+/*
+ * Request id.
+ */
+enum unci_req_id {
+	UNCI_REQ_UNKNOWN = (1 << 16),
+	UNCI_REQ_CHANGE_MTU,
+	UNCI_REQ_CFG_NETWORK_IF,
+	UNCI_REQ_GET_STATS,
+	UNCI_REQ_GET_MAC,
+	UNCI_REQ_SET_MAC,
+	UNCI_REQ_START_PORT,
+	UNCI_REQ_STOP_PORT,
+	UNCI_REQ_SET_PROMISC,
+	UNCI_REQ_SET_ALLMULTI,
+	UNCI_REQ_MAX,
+};
+
 #endif /* _UAPI_LINUX_UNCI_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/unci_net.c b/lib/librte_eal/linuxapp/unci/unci_net.c
index 27b9f9f70..7a7eebc15 100644
--- a/lib/librte_eal/linuxapp/unci/unci_net.c
+++ b/lib/librte_eal/linuxapp/unci/unci_net.c
@@ -22,12 +22,142 @@
  *   Intel Corporation
  */
 
+#include <linux/etherdevice.h>
 #include <linux/module.h>
+#include <linux/version.h>
 #include <net/rtnetlink.h>
 
 #include "unci_dev.h"
 
-static const struct net_device_ops unci_net_netdev_ops = { 0 };
+static int unci_net_init(struct net_device *dev)
+{
+	u8 mac[ETH_ALEN] = {0};
+
+	unci_nl_exec(UNCI_REQ_GET_MAC, dev, NULL, 0, mac, ETH_ALEN);
+	memcpy(dev->dev_addr, mac, dev->addr_len);
+	return 0;
+}
+
+static int unci_net_open(struct net_device *dev)
+{
+	/* DPDK port already started, stop it first */
+	unci_nl_exec(UNCI_REQ_STOP_PORT, dev, NULL, 0, NULL, 0);
+	unci_nl_exec(UNCI_REQ_START_PORT, dev, NULL, 0, NULL, 0);
+	netif_start_queue(dev);
+	return 0;
+}
+
+static int unci_net_close(struct net_device *dev)
+{
+	unci_nl_exec(UNCI_REQ_STOP_PORT, dev, NULL, 0, NULL, 0);
+	netif_stop_queue(dev);
+	return 0;
+}
+
+static int unci_net_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
+}
+
+static void unci_net_change_rx_flags(struct net_device *dev, int flags)
+{
+	u32 on = 1;
+	u32 off = 0;
+
+	if (flags & IFF_PROMISC)
+		unci_nl_exec(UNCI_REQ_SET_PROMISC, dev,
+				dev->flags & IFF_PROMISC ?  &on : &off,
+				sizeof(u32), NULL, 0);
+
+	if (flags & IFF_ALLMULTI)
+		unci_nl_exec(UNCI_REQ_SET_ALLMULTI, dev,
+				dev->flags & IFF_ALLMULTI ?  &on : &off,
+				sizeof(u32), NULL, 0);
+}
+
+static int unci_net_set_mac(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr = p;
+	int err;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	err = unci_nl_exec(UNCI_REQ_SET_MAC, dev, addr->sa_data,
+			dev->addr_len, NULL, 0);
+	if (err < 0)
+		return -EADDRNOTAVAIL;
+
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	return 0;
+}
+
+static int unci_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	return -EOPNOTSUPP;
+}
+
+/*
+ * Configuration changes (passed on by ifconfig)
+ */
+static int unci_net_config(struct net_device *dev, struct ifmap *map)
+{
+	if (dev->flags & IFF_UP)
+		return -EBUSY;
+
+	return -EOPNOTSUPP;
+}
+
+static int unci_net_change_mtu(struct net_device *dev, int new_mtu)
+{
+	int err = 0;
+
+	err = unci_nl_exec(UNCI_REQ_CHANGE_MTU, dev, &new_mtu, sizeof(int),
+			NULL, 0);
+
+	if (err == 0)
+		dev->mtu = new_mtu;
+
+	return err;
+}
+
+static void unci_net_stats64(struct net_device *dev,
+		struct rtnl_link_stats64 *stats)
+{
+	int err;
+
+	err = unci_nl_exec(UNCI_REQ_GET_STATS, dev, NULL, 0,
+			stats, sizeof(struct rtnl_link_stats64));
+}
+
+#if (KERNEL_VERSION(3, 9, 0) <= LINUX_VERSION_CODE)
+static int unci_net_change_carrier(struct net_device *dev, bool new_carrier)
+{
+	if (new_carrier)
+		netif_carrier_on(dev);
+	else
+		netif_carrier_off(dev);
+	return 0;
+}
+#endif
+
+static const struct net_device_ops unci_net_netdev_ops = {
+	.ndo_init = unci_net_init,
+	.ndo_open = unci_net_open,
+	.ndo_stop = unci_net_close,
+	.ndo_start_xmit = unci_net_xmit,
+	.ndo_change_rx_flags = unci_net_change_rx_flags,
+	.ndo_set_mac_address = unci_net_set_mac,
+	.ndo_do_ioctl = unci_net_ioctl,
+	.ndo_set_config = unci_net_config,
+	.ndo_change_mtu = unci_net_change_mtu,
+	.ndo_get_stats64 = unci_net_stats64,
+#if (KERNEL_VERSION(3, 9, 0) <= LINUX_VERSION_CODE)
+	.ndo_change_carrier = unci_net_change_carrier,
+#endif
+};
 
 static void unci_net_setup(struct net_device *dev)
 {
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 13/20] unci: add ethtool support
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (11 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 12/20] unci: add netdevice ops Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-05 19:07         ` Stephen Hemminger
  2017-07-05 19:08         ` Stephen Hemminger
  2017-07-04 16:13       ` [PATCH v10 14/20] ctrl_if: add library skeleton Ferruh Yigit
                         ` (6 subsequent siblings)
  19 siblings, 2 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Add ethtool support to the virtual interface. Ethtool functions also use
netlink exec to get data from userspace.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_eal/linuxapp/unci/Makefile       |   1 +
 lib/librte_eal/linuxapp/unci/unci_dev.h     |   2 +
 lib/librte_eal/linuxapp/unci/unci_ethtool.c | 293 ++++++++++++++++++++++++++++
 lib/librte_eal/linuxapp/unci/unci_net.c     |   2 +
 4 files changed, 298 insertions(+)
 create mode 100644 lib/librte_eal/linuxapp/unci/unci_ethtool.c

diff --git a/lib/librte_eal/linuxapp/unci/Makefile b/lib/librte_eal/linuxapp/unci/Makefile
index c2a81be7d..25d20d94d 100644
--- a/lib/librte_eal/linuxapp/unci/Makefile
+++ b/lib/librte_eal/linuxapp/unci/Makefile
@@ -49,5 +49,6 @@ MODULE_CFLAGS += -Wall -Werror
 #
 SRCS-$(CONFIG_RTE_UNCI_KMOD) := unci_net.c
 SRCS-$(CONFIG_RTE_UNCI_KMOD) += unci_nl.c
+SRCS-$(CONFIG_RTE_UNCI_KMOD) += unci_ethtool.c
 
 include $(RTE_SDK)/mk/rte.module.mk
diff --git a/lib/librte_eal/linuxapp/unci/unci_dev.h b/lib/librte_eal/linuxapp/unci/unci_dev.h
index 8d9ca6970..c33558b00 100644
--- a/lib/librte_eal/linuxapp/unci/unci_dev.h
+++ b/lib/librte_eal/linuxapp/unci/unci_dev.h
@@ -46,4 +46,6 @@ void unci_nl_release(void);
 int unci_nl_exec(u32 cmd, struct net_device *dev, void *in_data,
 		size_t in_len, void *out_data, size_t out_len);
 
+void unci_set_ethtool_ops(struct net_device *netdev);
+
 #endif /* _UNCI_DEV_H_ */
diff --git a/lib/librte_eal/linuxapp/unci/unci_ethtool.c b/lib/librte_eal/linuxapp/unci/unci_ethtool.c
new file mode 100644
index 000000000..13106fab3
--- /dev/null
+++ b/lib/librte_eal/linuxapp/unci/unci_ethtool.c
@@ -0,0 +1,293 @@
+/*-
+ * GPL LICENSE SUMMARY
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;
+ *
+ *   The full GNU General Public License is included in this distribution
+ *   in the file called LICENSE.GPL.
+ *
+ *   Contact Information:
+ *   Intel Corporation
+ */
+
+#include "unci_dev.h"
+
+#define ETHTOOL_GEEPROM_LEN 99
+#define ETHTOOL_GREGS_LEN 98
+#define ETHTOOL_GSSET_COUNT 97
+
+static int unci_check_if_running(struct net_device *dev)
+{
+	return 0;
+}
+
+static void unci_get_drvinfo(struct net_device *dev,
+		struct ethtool_drvinfo *info)
+{
+	int ret;
+
+	ret = unci_nl_exec(info->cmd, dev, NULL, 0,
+			info, sizeof(struct ethtool_drvinfo));
+	if (ret < 0)
+		memset(info, 0, sizeof(struct ethtool_drvinfo));
+}
+
+static int unci_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	return unci_nl_exec(ecmd->cmd, dev, NULL, 0,
+			ecmd, sizeof(struct ethtool_cmd));
+}
+
+static int unci_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	return unci_nl_exec(ecmd->cmd, dev, ecmd, sizeof(struct ethtool_cmd),
+			NULL, 0);
+}
+
+static void unci_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	int ret;
+
+	ret = unci_nl_exec(wol->cmd, dev, NULL, 0,
+			wol, sizeof(struct ethtool_wolinfo));
+	if (ret < 0)
+		memset(wol, 0, sizeof(struct ethtool_wolinfo));
+}
+
+static int unci_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	return unci_nl_exec(wol->cmd, dev, wol, sizeof(struct ethtool_wolinfo),
+			NULL, 0);
+}
+
+static int unci_nway_reset(struct net_device *dev)
+{
+	return unci_nl_exec(ETHTOOL_NWAY_RST, dev, NULL, 0, NULL, 0);
+}
+
+static u32 unci_get_link(struct net_device *dev)
+{
+	u32 data;
+	int ret;
+
+	ret = unci_nl_exec(ETHTOOL_GLINK, dev, NULL, 0, &data, sizeof(u32));
+	if (ret < 0)
+		return 0;
+
+	return data;
+}
+
+static int unci_get_eeprom_len(struct net_device *dev)
+{
+	int data;
+	int ret;
+
+	ret = unci_nl_exec(ETHTOOL_GEEPROM_LEN, dev, NULL, 0,
+			&data, sizeof(int));
+	if (ret < 0)
+		return 0;
+
+	return data;
+}
+
+static int unci_get_eeprom(struct net_device *dev,
+		struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct ethtool_eeprom eeprom_tmp;
+	int ret = 0;
+	int remaining;
+	u32 offset = 0;
+
+	eeprom_tmp = *eeprom;
+
+	remaining = eeprom_tmp.len;
+	while (remaining > 0 && ret == 0) {
+		eeprom_tmp.len = min(remaining, UNCI_NL_MSG_LEN);
+
+		ret = unci_nl_exec(eeprom_tmp.cmd, dev,
+				&eeprom_tmp, sizeof(struct ethtool_eeprom),
+				data + offset, eeprom_tmp.len);
+		eeprom_tmp.offset += eeprom_tmp.len;
+		offset += eeprom_tmp.len;
+		remaining -= eeprom_tmp.len;
+	}
+
+	return ret;
+}
+
+static int unci_set_eeprom(struct net_device *dev,
+		struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct ethtool_eeprom *eeprom_tmp;
+	int ret = 0;
+	u32 remaining;
+	u32 offset = 0;
+	u32 payload;
+
+	if (sizeof(struct ethtool_eeprom) > UNCI_NL_MSG_LEN)
+		return -1;
+
+	eeprom_tmp = kmalloc(UNCI_NL_MSG_LEN, GFP_KERNEL);
+	payload = UNCI_NL_MSG_LEN - sizeof(struct ethtool_eeprom);
+
+	*eeprom_tmp = *eeprom;
+	remaining = eeprom->len;
+
+	while (remaining > 0 && ret == 0) {
+		eeprom_tmp->len = min(remaining, payload);
+
+		memcpy(eeprom_tmp->data, data + offset, payload);
+
+		ret = unci_nl_exec(eeprom->cmd, dev, eeprom,
+				UNCI_NL_MSG_LEN, NULL, 0);
+
+		eeprom_tmp->offset += eeprom_tmp->len;
+		offset += eeprom_tmp->len;
+		remaining -= eeprom_tmp->len;
+	}
+
+	kfree(eeprom_tmp);
+
+	return ret;
+}
+
+static void unci_get_ringparam(struct net_device *dev,
+		struct ethtool_ringparam *ring)
+{
+	unci_nl_exec(ring->cmd, dev, NULL, 0,
+			ring, sizeof(struct ethtool_ringparam));
+}
+
+static int unci_set_ringparam(struct net_device *dev,
+		struct ethtool_ringparam *ring)
+{
+	return unci_nl_exec(ring->cmd, dev, ring,
+			sizeof(struct ethtool_ringparam), NULL, 0);
+}
+
+static void unci_get_pauseparam(struct net_device *dev,
+		struct ethtool_pauseparam *pause)
+{
+	unci_nl_exec(pause->cmd, dev, NULL, 0,
+			pause, sizeof(struct ethtool_pauseparam));
+}
+
+static int unci_set_pauseparam(struct net_device *dev,
+		struct ethtool_pauseparam *pause)
+{
+	return unci_nl_exec(pause->cmd, dev, pause,
+			sizeof(struct ethtool_pauseparam), NULL, 0);
+}
+
+static u32 unci_get_msglevel(struct net_device *dev)
+{
+	u32 data;
+	int ret;
+
+	ret = unci_nl_exec(ETHTOOL_GMSGLVL, dev, NULL, 0, &data, sizeof(u32));
+	if (ret < 0)
+		return 0;
+
+	return data;
+}
+
+static void unci_set_msglevel(struct net_device *dev, u32 data)
+{
+	unci_nl_exec(ETHTOOL_SMSGLVL, dev, &data, sizeof(u32), NULL, 0);
+}
+
+static int unci_get_regs_len(struct net_device *dev)
+{
+	int data;
+	int ret;
+
+	ret = unci_nl_exec(ETHTOOL_GREGS_LEN, dev, NULL, 0, &data, sizeof(int));
+	if (ret < 0)
+		return 0;
+
+	return data;
+}
+
+static void unci_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+		void *p)
+{
+	struct ethtool_regs regs_tmp;
+	u32 len = regs->len;
+
+	regs_tmp = *regs;
+
+	if (len > UNCI_NL_MSG_LEN) {
+		len = UNCI_NL_MSG_LEN;
+		regs_tmp.len = len;
+	}
+
+	unci_nl_exec(regs->cmd, dev, &regs_tmp, sizeof(struct ethtool_regs),
+			p, len);
+}
+
+static void unci_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+	unci_nl_exec(ETHTOOL_GSTRINGS, dev, &stringset, sizeof(u32), data, 0);
+}
+
+static int unci_get_sset_count(struct net_device *dev, int sset)
+{
+	int data;
+	int ret;
+
+	ret = unci_nl_exec(ETHTOOL_GSSET_COUNT, dev, &sset, sizeof(int),
+			&data, sizeof(int));
+	if (ret < 0)
+		return 0;
+
+	return data;
+}
+
+static void unci_get_ethtool_stats(struct net_device *dev,
+		struct ethtool_stats *stats, u64 *data)
+{
+	unci_nl_exec(stats->cmd, dev, stats, sizeof(struct ethtool_stats),
+			data, stats->n_stats);
+}
+
+static const struct ethtool_ops unci_ethtool_ops = {
+	.begin			= unci_check_if_running,
+	.get_drvinfo		= unci_get_drvinfo,
+	.get_settings		= unci_get_settings,
+	.set_settings		= unci_set_settings,
+	.get_regs_len		= unci_get_regs_len,
+	.get_regs		= unci_get_regs,
+	.get_wol		= unci_get_wol,
+	.set_wol		= unci_set_wol,
+	.nway_reset		= unci_nway_reset,
+	.get_link		= unci_get_link,
+	.get_eeprom_len		= unci_get_eeprom_len,
+	.get_eeprom		= unci_get_eeprom,
+	.set_eeprom		= unci_set_eeprom,
+	.get_ringparam		= unci_get_ringparam,
+	.set_ringparam		= unci_set_ringparam,
+	.get_pauseparam		= unci_get_pauseparam,
+	.set_pauseparam		= unci_set_pauseparam,
+	.get_msglevel		= unci_get_msglevel,
+	.set_msglevel		= unci_set_msglevel,
+	.get_strings		= unci_get_strings,
+	.get_sset_count		= unci_get_sset_count,
+	.get_ethtool_stats	= unci_get_ethtool_stats,
+};
+
+void unci_set_ethtool_ops(struct net_device *netdev)
+{
+	netdev->ethtool_ops = &unci_ethtool_ops;
+}
diff --git a/lib/librte_eal/linuxapp/unci/unci_net.c b/lib/librte_eal/linuxapp/unci/unci_net.c
index 7a7eebc15..5dbb46e22 100644
--- a/lib/librte_eal/linuxapp/unci/unci_net.c
+++ b/lib/librte_eal/linuxapp/unci/unci_net.c
@@ -168,6 +168,8 @@ static void unci_net_setup(struct net_device *dev)
 
 	unci = netdev_priv(dev);
 	init_completion(&unci->msg_received);
+
+	unci_set_ethtool_ops(dev);
 }
 
 static int unci_net_newlink(struct net *net, struct net_device *dev,
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 14/20] ctrl_if: add library skeleton
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (12 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 13/20] unci: add ethtool support Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 15/20] ctrl_if: add create destroy interface APIs Ferruh Yigit
                         ` (5 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Add base files for new control interface library.

Control interface is on top of ethtool and ethdev libraries.

Control interface connects to the netlink socket provided by Linux
kernel and passes commands received via netlink interface to the
network drivers.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 MAINTAINERS                                |  1 +
 config/common_base                         |  5 +++
 config/common_linuxapp                     |  1 +
 doc/guides/rel_notes/release_17_08.rst     |  1 +
 lib/Makefile                               |  2 +
 lib/librte_ctrl_if/Makefile                | 53 +++++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_if.c           | 34 +++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_if.h           | 59 ++++++++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_if_version.map |  4 ++
 lib/librte_eal/common/eal_common_log.c     |  1 +
 lib/librte_eal/common/include/rte_log.h    |  1 +
 mk/rte.app.mk                              |  1 +
 12 files changed, 163 insertions(+)
 create mode 100644 lib/librte_ctrl_if/Makefile
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.c
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.h
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_if_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index cfc3d4bf3..d2cd1c3c1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -761,6 +761,7 @@ F: lib/librte_ethtool/
 Linux Userspace Network Control Interface (UNCI)
 M: Ferruh Yigit <ferruh.yigit@intel.com>
 F: lib/librte_eal/linuxapp/unci/
+F: lib/librte_ctrl_if/
 
 Test Applications
 -----------------
diff --git a/config/common_base b/config/common_base
index 1582f703e..4bd80a5f9 100644
--- a/config/common_base
+++ b/config/common_base
@@ -710,6 +710,11 @@ CONFIG_RTE_LIBRTE_ETHTOOL=n
 CONFIG_RTE_UNCI_KMOD=n
 
 #
+# Compile librte_ctrl_if
+#
+CONFIG_RTE_LIBRTE_CTRL_IF=n
+
+#
 # Compile vhost user library
 #
 CONFIG_RTE_LIBRTE_VHOST=n
diff --git a/config/common_linuxapp b/config/common_linuxapp
index b400b2c0e..b4c2b88e4 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -43,6 +43,7 @@ CONFIG_RTE_LIBRTE_KNI=y
 CONFIG_RTE_LIBRTE_PMD_KNI=y
 CONFIG_RTE_LIBRTE_ETHTOOL=y
 CONFIG_RTE_UNCI_KMOD=y
+CONFIG_RTE_LIBRTE_CTRL_IF=y
 CONFIG_RTE_LIBRTE_VHOST=y
 CONFIG_RTE_LIBRTE_VHOST_NUMA=y
 CONFIG_RTE_LIBRTE_PMD_VHOST=y
diff --git a/doc/guides/rel_notes/release_17_08.rst b/doc/guides/rel_notes/release_17_08.rst
index 423877f49..e21d4e17c 100644
--- a/doc/guides/rel_notes/release_17_08.rst
+++ b/doc/guides/rel_notes/release_17_08.rst
@@ -188,6 +188,7 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_cfgfile.so.2
      librte_cmdline.so.2
      librte_cryptodev.so.2
+   + librte_ctrl_if.so.1
      librte_distributor.so.1
      librte_eal.so.4
      librte_ethdev.so.6
diff --git a/lib/Makefile b/lib/Makefile
index 434237d6e..99ee7e224 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -108,6 +108,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += librte_pdump
 DEPDIRS-librte_pdump := librte_eal librte_mempool librte_mbuf librte_ether
 DIRS-$(CONFIG_RTE_LIBRTE_ETHTOOL) += librte_ethtool
 DEPDIRS-librte_ethtool := librte_eal librte_ether
+DIRS-$(CONFIG_RTE_LIBRTE_CTRL_IF) += librte_ctrl_if
+DEPDIRS-librte_ctrl_if := librte_eal librte_ether librte_ethtool
 
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
diff --git a/lib/librte_ctrl_if/Makefile b/lib/librte_ctrl_if/Makefile
new file mode 100644
index 000000000..c682af4c4
--- /dev/null
+++ b/lib/librte_ctrl_if/Makefile
@@ -0,0 +1,53 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 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_ctrl_if.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+EXPORT_MAP := rte_ctrl_if_version.map
+
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) := rte_ctrl_if.c
+
+#
+# Export include files
+#
+SYMLINK-$(CONFIG_RTE_LIBRTE_CTRL_IF)-include += rte_ctrl_if.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_ctrl_if/rte_ctrl_if.c b/lib/librte_ctrl_if/rte_ctrl_if.c
new file mode 100644
index 000000000..45a3a07cf
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_if.c
@@ -0,0 +1,34 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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_ctrl_if.h"
diff --git a/lib/librte_ctrl_if/rte_ctrl_if.h b/lib/librte_ctrl_if/rte_ctrl_if.h
new file mode 100644
index 000000000..0bd4b88c9
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_if.h
@@ -0,0 +1,59 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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_CTRL_IF_H_
+#define _RTE_CTRL_IF_H_
+
+/**
+ * @file
+ *
+ * Control Interface Library for RTE
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <linux/types.h>
+
+#include <exec-env/unci.h>
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_CTRL_IF_H_ */
diff --git a/lib/librte_ctrl_if/rte_ctrl_if_version.map b/lib/librte_ctrl_if/rte_ctrl_if_version.map
new file mode 100644
index 000000000..b6d2840be
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_if_version.map
@@ -0,0 +1,4 @@
+DPDK_17.08 {
+
+	local: *;
+};
diff --git a/lib/librte_eal/common/eal_common_log.c b/lib/librte_eal/common/eal_common_log.c
index b177b82fa..e3339dbf7 100644
--- a/lib/librte_eal/common/eal_common_log.c
+++ b/lib/librte_eal/common/eal_common_log.c
@@ -271,6 +271,7 @@ static const struct logtype logtype_strings[] = {
 	{RTE_LOGTYPE_EFD,        "efd"},
 	{RTE_LOGTYPE_EVENTDEV,   "eventdev"},
 	{RTE_LOGTYPE_ETHTOOL,    "ethtool"},
+	{RTE_LOGTYPE_CTRL_IF,    "ctrl_if"},
 	{RTE_LOGTYPE_USER1,      "user1"},
 	{RTE_LOGTYPE_USER2,      "user2"},
 	{RTE_LOGTYPE_USER3,      "user3"},
diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
index 5b240e8b1..3727fc5f1 100644
--- a/lib/librte_eal/common/include/rte_log.h
+++ b/lib/librte_eal/common/include/rte_log.h
@@ -88,6 +88,7 @@ extern struct rte_logs rte_logs;
 #define RTE_LOGTYPE_EFD       18 /**< Log related to EFD. */
 #define RTE_LOGTYPE_EVENTDEV  19 /**< Log related to eventdev. */
 #define RTE_LOGTYPE_ETHTOOL   20 /**< Log related to ethtool. */
+#define RTE_LOGTYPE_CTRL_IF   21 /**< Log related to control interface. */
 
 /* these log types can be used in an application */
 #define RTE_LOGTYPE_USER1     24 /**< User-defined log type 1. */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 897d89acf..a68b87ee9 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -91,6 +91,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF)           += -lrte_mbuf
 _LDLIBS-$(CONFIG_RTE_LIBRTE_NET)            += -lrte_net
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHER)          += -lrte_ethdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHTOOL)        += -lrte_ethtool
+_LDLIBS-$(CONFIG_RTE_LIBRTE_CTRL_IF)        += -lrte_ctrl_if
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CRYPTODEV)      += -lrte_cryptodev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV)       += -lrte_eventdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 15/20] ctrl_if: add create destroy interface APIs
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (13 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 14/20] ctrl_if: add library skeleton Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 16/20] ctrl_if: initialize generic netlink interface Ferruh Yigit
                         ` (4 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Library provides two APIs to create and destroy interfaces.

rtnl used to create or destroy interfaces.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ctrl_if/rte_ctrl_if.c           | 302 +++++++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_if.h           |  34 ++++
 lib/librte_ctrl_if/rte_ctrl_if_version.map |   4 +
 3 files changed, 340 insertions(+)

diff --git a/lib/librte_ctrl_if/rte_ctrl_if.c b/lib/librte_ctrl_if/rte_ctrl_if.c
index 45a3a07cf..5dda9121a 100644
--- a/lib/librte_ctrl_if/rte_ctrl_if.c
+++ b/lib/librte_ctrl_if/rte_ctrl_if.c
@@ -31,4 +31,306 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/socket.h>
+#include <linux/rtnetlink.h>
+
+#include <rte_log.h>
 #include "rte_ctrl_if.h"
+
+#define NAMESZ 32
+#define IFNAME "dpdk"
+#define BUFSZ 1024
+
+static int unci_rtnl_fd = -1;
+static uint32_t unci_ref_cnt;
+
+struct unci_request {
+	struct nlmsghdr nlmsg;
+	uint8_t buf[BUFSZ];
+};
+
+static int
+control_interface_rtnl_init(void)
+{
+	struct sockaddr_nl src;
+	int ret;
+
+	unci_rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+	if (unci_rtnl_fd < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Socket create failed\n");
+		return -1;
+	}
+
+	memset(&src, 0, sizeof(struct sockaddr_nl));
+
+	src.nl_family = AF_NETLINK;
+	src.nl_pid = getpid();
+
+	ret = bind(unci_rtnl_fd, (struct sockaddr *)&src,
+			sizeof(struct sockaddr_nl));
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Bind to socket failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+control_interface_init(void)
+{
+	int ret;
+
+	ret = control_interface_rtnl_init();
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Failed to initialize rtnetlink\n");
+		return -1;
+	}
+
+	return ret;
+}
+
+static int
+control_interface_ref_get(void)
+{
+	int ret = 0;
+
+	if (unci_ref_cnt == 0)
+		ret = control_interface_init();
+
+	if (ret == 0)
+		unci_ref_cnt++;
+	else
+		RTE_LOG(ERR, CTRL_IF,
+				"Failed to initialize control interface\n");
+
+	return unci_ref_cnt;
+}
+
+static void
+control_interface_release(void)
+{
+	close(unci_rtnl_fd);
+	unci_rtnl_fd = -1;
+}
+
+static int
+control_interface_ref_put(void)
+{
+	if (unci_ref_cnt == 0)
+		return 0;
+
+	unci_ref_cnt--;
+
+	if (unci_ref_cnt == 0)
+		control_interface_release();
+
+	return unci_ref_cnt;
+}
+
+static int
+add_attr(struct unci_request *req, uint16_t type, void *buf, size_t len)
+{
+	struct rtattr *rta;
+	int nlmsg_len;
+
+	nlmsg_len = NLMSG_ALIGN(req->nlmsg.nlmsg_len);
+	rta = (struct rtattr *)((char *)&req->nlmsg + nlmsg_len);
+	if (nlmsg_len + RTA_LENGTH(len) > sizeof(struct unci_request))
+		return -1;
+	rta->rta_type = type;
+	rta->rta_len = RTA_LENGTH(len);
+	memcpy(RTA_DATA(rta), buf, len);
+	req->nlmsg.nlmsg_len = nlmsg_len + RTA_LENGTH(len);
+
+	return 0;
+}
+
+static struct
+rtattr *add_attr_nested(struct unci_request *req, unsigned short type)
+{
+	struct rtattr *rta;
+	uint32_t nlmsg_len;
+
+	nlmsg_len = NLMSG_ALIGN(req->nlmsg.nlmsg_len);
+	rta = (struct rtattr *)((uint8_t *)&req->nlmsg + nlmsg_len);
+	if (nlmsg_len + RTA_LENGTH(0) > sizeof(struct unci_request))
+		return NULL;
+	rta->rta_type = type;
+	rta->rta_len = nlmsg_len;
+	req->nlmsg.nlmsg_len = nlmsg_len + RTA_LENGTH(0);
+
+	return rta;
+}
+
+static void
+end_attr_nested(struct unci_request *req, struct rtattr *rta)
+{
+	rta->rta_len = req->nlmsg.nlmsg_len - rta->rta_len;
+}
+
+static int
+rte_eth_rtnl_create(uint8_t port_id)
+{
+	struct unci_request req;
+	struct ifinfomsg *info;
+	struct rtattr *rta1;
+	struct rtattr *rta2;
+	uint32_t pid = getpid();
+	char name[NAMESZ];
+	char type[NAMESZ];
+	struct iovec iov;
+	struct msghdr msg;
+	struct sockaddr_nl nladdr;
+	uint8_t buf[BUFSZ];
+	uint32_t port_id_local = port_id;
+	int ret;
+
+	memset(&req, 0, sizeof(struct unci_request));
+
+	req.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+	req.nlmsg.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
+	req.nlmsg.nlmsg_flags |= NLM_F_ACK;
+	req.nlmsg.nlmsg_type = RTM_NEWLINK;
+
+	info = NLMSG_DATA(&req.nlmsg);
+
+	info->ifi_family = AF_UNSPEC;
+	info->ifi_index = 0;
+
+	snprintf(name, NAMESZ, IFNAME"%u", port_id);
+	ret = add_attr(&req, IFLA_IFNAME, name, strlen(name) + 1);
+	if (ret < 0)
+		return -1;
+
+	rta1 = add_attr_nested(&req, IFLA_LINKINFO);
+	if (rta1 == NULL)
+		return -1;
+
+	snprintf(type, NAMESZ, UNCI_DEVICE);
+	ret = add_attr(&req, IFLA_INFO_KIND, type, strlen(type) + 1);
+	if (ret < 0)
+		return -1;
+
+	rta2 = add_attr_nested(&req, IFLA_INFO_DATA);
+	if (rta2 == NULL)
+		return -1;
+
+	ret = add_attr(&req, IFLA_UNCI_PORTID, &port_id_local,
+			sizeof(uint32_t));
+	if (ret < 0)
+		return -1;
+
+	ret = add_attr(&req, IFLA_UNCI_PID, &pid, sizeof(uint32_t));
+	if (ret < 0)
+		return -1;
+
+	end_attr_nested(&req, rta2);
+	end_attr_nested(&req, rta1);
+
+	memset(&nladdr, 0, sizeof(nladdr));
+	nladdr.nl_family = AF_NETLINK;
+
+	iov.iov_base = (void *)&req.nlmsg;
+	iov.iov_len = req.nlmsg.nlmsg_len;
+
+	memset(&msg, 0, sizeof(struct msghdr));
+	msg.msg_name = &nladdr;
+	msg.msg_namelen = sizeof(nladdr);
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+
+	ret = sendmsg(unci_rtnl_fd, &msg, 0);
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Send for create failed %d.\n", errno);
+		return -1;
+	}
+
+	memset(buf, 0, sizeof(buf));
+	iov.iov_base = buf;
+	iov.iov_len = sizeof(buf);
+
+	ret = recvmsg(unci_rtnl_fd, &msg, 0);
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Recv for create failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+int
+rte_eth_control_interface_create(uint8_t port_id)
+{
+	int ret;
+
+	if (control_interface_ref_get() != 0) {
+		ret = rte_eth_rtnl_create(port_id);
+		RTE_LOG(DEBUG, CTRL_IF,
+			"Control interface %s for port:%u\n",
+			ret < 0 ? "failed" : "created", port_id);
+	}
+
+	return 0;
+}
+
+static int
+rte_eth_rtnl_destroy(uint8_t port_id)
+{
+	struct unci_request req;
+	struct ifinfomsg *info;
+	char name[NAMESZ];
+	struct iovec iov;
+	struct msghdr msg;
+	struct sockaddr_nl nladdr;
+	int ret;
+
+	memset(&req, 0, sizeof(struct unci_request));
+
+	req.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+	req.nlmsg.nlmsg_flags = NLM_F_REQUEST;
+	req.nlmsg.nlmsg_type = RTM_DELLINK;
+
+	info = NLMSG_DATA(&req.nlmsg);
+
+	info->ifi_family = AF_UNSPEC;
+	info->ifi_index = 0;
+
+	snprintf(name, NAMESZ, IFNAME"%u", port_id);
+	ret = add_attr(&req, IFLA_IFNAME, name, strlen(name) + 1);
+	if (ret < 0)
+		return -1;
+
+	memset(&nladdr, 0, sizeof(nladdr));
+	nladdr.nl_family = AF_NETLINK;
+
+	iov.iov_base = (void *)&req.nlmsg;
+	iov.iov_len = req.nlmsg.nlmsg_len;
+
+	memset(&msg, 0, sizeof(struct msghdr));
+	msg.msg_name = &nladdr;
+	msg.msg_namelen = sizeof(nladdr);
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+
+	ret = sendmsg(unci_rtnl_fd, &msg, 0);
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Send for destroy failed\n");
+		return -1;
+	}
+	return 0;
+}
+
+int
+rte_eth_control_interface_destroy(uint8_t port_id)
+{
+	rte_eth_rtnl_destroy(port_id);
+	control_interface_ref_put();
+	RTE_LOG(DEBUG, CTRL_IF, "Control interface destroyed for port:%u\n",
+			port_id);
+
+	return 0;
+}
diff --git a/lib/librte_ctrl_if/rte_ctrl_if.h b/lib/librte_ctrl_if/rte_ctrl_if.h
index 0bd4b88c9..d37b2eacb 100644
--- a/lib/librte_ctrl_if/rte_ctrl_if.h
+++ b/lib/librte_ctrl_if/rte_ctrl_if.h
@@ -51,6 +51,40 @@ extern "C" {
 
 #include <exec-env/unci.h>
 
+/**
+ * Creates control interfaces (Linux virtual network interface)for
+ * given ethdev port.
+ *
+ * This API opens device created by supportive kernel module and initializes
+ * kernel communication interface.
+ *
+ * With first interface created, a pthread created to receive the control
+ * messages.
+ *
+ * If supportive kernel module is not inserted this API will return
+ * an error.
+ *
+ * @param port_id
+ *  port id to create virtual interface
+ * @return
+ *  0 on success.
+ *  Negative value on error.
+ */
+int rte_eth_control_interface_create(uint8_t port_id);
+
+/**
+ * Destroys control interfaces.
+ *
+ * This API close device created by supportive kernel module and release
+ * underlying communication interface.
+ *
+ * @return
+ * @param port_id
+ *  port id to destroy virtual interface
+ *  0 on success.
+ *  Negative value on error.
+ */
+int rte_eth_control_interface_destroy(uint8_t port_id);
 
 #ifdef __cplusplus
 }
diff --git a/lib/librte_ctrl_if/rte_ctrl_if_version.map b/lib/librte_ctrl_if/rte_ctrl_if_version.map
index b6d2840be..3cbe0d38f 100644
--- a/lib/librte_ctrl_if/rte_ctrl_if_version.map
+++ b/lib/librte_ctrl_if/rte_ctrl_if_version.map
@@ -1,4 +1,8 @@
 DPDK_17.08 {
+	global:
+
+	rte_eth_control_interface_create;
+	rte_eth_control_interface_destroy;
 
 	local: *;
 };
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 16/20] ctrl_if: initialize generic netlink interface
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (14 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 15/20] ctrl_if: add create destroy interface APIs Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 17/20] ctrl_if: process control messages Ferruh Yigit
                         ` (3 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Initialize generic netlink sockets to exchange data between
kernelspace.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ctrl_if/Makefile      |   2 +
 lib/librte_ctrl_if/rte_ctrl_if.c |  10 ++
 lib/librte_ctrl_if/rte_nl.c      | 231 +++++++++++++++++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_nl.h      |  48 ++++++++
 4 files changed, 291 insertions(+)
 create mode 100644 lib/librte_ctrl_if/rte_nl.c
 create mode 100644 lib/librte_ctrl_if/rte_nl.h

diff --git a/lib/librte_ctrl_if/Makefile b/lib/librte_ctrl_if/Makefile
index c682af4c4..0da04f7d0 100644
--- a/lib/librte_ctrl_if/Makefile
+++ b/lib/librte_ctrl_if/Makefile
@@ -38,12 +38,14 @@ LIB = librte_ctrl_if.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lpthread
 
 EXPORT_MAP := rte_ctrl_if_version.map
 
 LIBABIVER := 1
 
 SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) := rte_ctrl_if.c
+SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) += rte_nl.c
 
 #
 # Export include files
diff --git a/lib/librte_ctrl_if/rte_ctrl_if.c b/lib/librte_ctrl_if/rte_ctrl_if.c
index 5dda9121a..84a9023d5 100644
--- a/lib/librte_ctrl_if/rte_ctrl_if.c
+++ b/lib/librte_ctrl_if/rte_ctrl_if.c
@@ -39,6 +39,7 @@
 
 #include <rte_log.h>
 #include "rte_ctrl_if.h"
+#include "rte_nl.h"
 
 #define NAMESZ 32
 #define IFNAME "dpdk"
@@ -90,6 +91,13 @@ control_interface_init(void)
 		return -1;
 	}
 
+	ret = control_interface_nl_init();
+	if (ret < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Failed to initialize netlink\n");
+		close(unci_rtnl_fd);
+		unci_rtnl_fd = -1;
+	}
+
 	return ret;
 }
 
@@ -115,6 +123,8 @@ control_interface_release(void)
 {
 	close(unci_rtnl_fd);
 	unci_rtnl_fd = -1;
+
+	control_interface_nl_release();
 }
 
 static int
diff --git a/lib/librte_ctrl_if/rte_nl.c b/lib/librte_ctrl_if/rte_nl.c
new file mode 100644
index 000000000..8042d12fb
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_nl.c
@@ -0,0 +1,231 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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 <pthread.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include <linux/genetlink.h>
+
+#include <rte_log.h>
+#include <rte_lcore.h>
+#include "rte_nl.h"
+#include "rte_ctrl_if.h"
+
+#define GENLMSG_DATA(glh) (((char *)(NLMSG_DATA(glh)) + GENL_HDRLEN))
+#define NLA_DATA(na) ((void *)((char *)(na) + NLA_HDRLEN))
+
+struct ctrl_if_nl {
+	union {
+		struct hdr {
+			struct nlmsghdr nlh;
+			struct genlmsghdr genlh;
+		} h;
+		uint8_t nlmsg[UNCI_GENL_MSG_LEN];
+	};
+	struct msghdr msg;
+	struct iovec iov;
+	struct sockaddr_nl dest_addr;
+};
+
+static int sock_fd = -1;
+static pthread_t thread_id;
+
+static struct ctrl_if_nl nl_s;
+static struct ctrl_if_nl nl_r;
+
+static int nl_family_id;
+
+static void *
+nl_recv(void *arg)
+{
+	int ret;
+
+	for (;;) {
+		ret = recvmsg(sock_fd, &nl_r.msg, 0);
+		if (ret < 0)
+			continue;
+
+		if (nl_r.h.nlh.nlmsg_type == NLMSG_ERROR)
+			continue;
+
+		if ((unsigned int)ret < sizeof(struct unci_nl_msg)) {
+			RTE_LOG(WARNING, CTRL_IF,
+					"Received %d bytes, payload %zu\n",
+					ret, sizeof(struct unci_nl_msg));
+			continue;
+		}
+	}
+
+	return arg;
+}
+
+static void
+nl_setup_header(struct ctrl_if_nl *nl)
+{
+	memset(nl, 0, sizeof(struct ctrl_if_nl));
+
+	nl->dest_addr.nl_family = AF_NETLINK;
+
+	/* Fill the netlink message header */
+	nl->h.nlh.nlmsg_len = UNCI_GENL_MSG_LEN;
+	nl->h.nlh.nlmsg_pid = getpid();  /* self pid */
+	nl->h.nlh.nlmsg_flags = NLM_F_REQUEST;
+	nl->h.nlh.nlmsg_type = nl_family_id;
+
+	nl->h.genlh.cmd = UNCI_CMD_MSG;
+	nl->h.genlh.version = UNCI_GENL_VERSION;
+
+	nl->iov.iov_base = (void *)nl->nlmsg;
+	nl->iov.iov_len = nl->h.nlh.nlmsg_len;
+
+	nl->msg.msg_name = (void *)&nl->dest_addr;
+	nl->msg.msg_namelen = sizeof(struct sockaddr_nl);
+	nl->msg.msg_iov = &nl->iov;
+	nl->msg.msg_iovlen = 1;
+}
+
+static int
+unci_genl_family_get(int fd)
+{
+	struct nlattr *nl_na;
+	int id = -1;
+	int ret;
+
+	nl_setup_header(&nl_s);
+	nl_setup_header(&nl_r);
+
+	nl_s.h.nlh.nlmsg_type = GENL_ID_CTRL;
+	nl_s.h.nlh.nlmsg_flags = NLM_F_REQUEST;
+	nl_s.h.nlh.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
+
+	nl_s.h.genlh.cmd = CTRL_CMD_GETFAMILY;
+
+	nl_na = (struct nlattr *) GENLMSG_DATA(&nl_s);
+	nl_na->nla_type = CTRL_ATTR_FAMILY_NAME;
+	nl_na->nla_len = strlen(UNCI_DEVICE) + 1 + NLA_HDRLEN;
+	strcpy(NLA_DATA(nl_na), UNCI_DEVICE);
+
+	nl_s.h.nlh.nlmsg_len += NLMSG_ALIGN(nl_na->nla_len);
+
+	nl_s.iov.iov_len = nl_s.h.nlh.nlmsg_len;
+
+	ret = sendmsg(fd, &nl_s.msg, 0);
+
+	if ((uint32_t)ret != nl_s.h.nlh.nlmsg_len)
+		return -1;
+
+	ret = recvmsg(fd, &nl_r.msg, 0);
+	if (ret < 0)
+		return -1;
+
+	if (!NLMSG_OK((&nl_r.h.nlh), (uint32_t)ret))
+		return -1;
+
+	if (nl_r.h.nlh.nlmsg_type == NLMSG_ERROR)
+		return -1;
+
+	nl_na = (struct nlattr *) GENLMSG_DATA(&nl_r);
+	nl_na = (struct nlattr *) ((char *) nl_na + NLA_ALIGN(nl_na->nla_len));
+	if (nl_na->nla_type == CTRL_ATTR_FAMILY_ID)
+		id = *(__u16 *) NLA_DATA(nl_na);
+
+	return id;
+}
+
+static int
+nl_socket_init(void)
+{
+	struct sockaddr_nl src_addr;
+	int fd;
+	int ret;
+
+	fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+	if (fd < 0)
+		return -1;
+
+	memset(&src_addr, 0, sizeof(struct sockaddr_nl));
+	src_addr.nl_family = AF_NETLINK;
+	src_addr.nl_pid = getpid();
+
+	ret = bind(fd, (struct sockaddr *)&src_addr, sizeof(src_addr));
+	if (ret) {
+		close(fd);
+		return -1;
+	}
+
+	nl_family_id = unci_genl_family_get(fd);
+	if (!nl_family_id) {
+		close(fd);
+		return -1;
+	}
+
+	nl_setup_header(&nl_s);
+	nl_setup_header(&nl_r);
+
+	return fd;
+}
+
+int
+control_interface_nl_init(void)
+{
+	int ret;
+
+	sock_fd = nl_socket_init();
+	if (sock_fd < 0) {
+		RTE_LOG(ERR, CTRL_IF, "Failed to initialize netlink socket\n");
+		return -1;
+	}
+
+	ret = pthread_create(&thread_id, NULL, nl_recv, NULL);
+	if (ret != 0) {
+		RTE_LOG(ERR, CTRL_IF, "Failed to create receive thread\n");
+		return -1;
+	}
+
+	ret = rte_thread_setname(thread_id, "netlink-recv");
+	if (ret != 0)
+		RTE_LOG(ERR, CTRL_IF, "Failed to set thread name.\n");
+
+	return 0;
+}
+
+void
+control_interface_nl_release(void)
+{
+	pthread_cancel(thread_id);
+	pthread_join(thread_id, NULL);
+	close(sock_fd);
+}
diff --git a/lib/librte_ctrl_if/rte_nl.h b/lib/librte_ctrl_if/rte_nl.h
new file mode 100644
index 000000000..05a61e193
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_nl.h
@@ -0,0 +1,48 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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_NL_H_
+#define _RTE_NL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int control_interface_nl_init(void);
+void control_interface_nl_release(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_NL_H_ */
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 17/20] ctrl_if: process control messages
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (15 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 16/20] ctrl_if: initialize generic netlink interface Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 18/20] ctrl_if: process ethtool messages Ferruh Yigit
                         ` (2 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Receive the requests from virtual interface and process control
messages.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ctrl_if/Makefile           |   1 +
 lib/librte_ctrl_if/rte_ctrl_process.c | 167 ++++++++++++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_process.h |  50 ++++++++++
 lib/librte_ctrl_if/rte_nl.c           | 152 +++++++++++++++++++++++++++++++
 4 files changed, 370 insertions(+)
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_process.c
 create mode 100644 lib/librte_ctrl_if/rte_ctrl_process.h

diff --git a/lib/librte_ctrl_if/Makefile b/lib/librte_ctrl_if/Makefile
index 0da04f7d0..67b9967b4 100644
--- a/lib/librte_ctrl_if/Makefile
+++ b/lib/librte_ctrl_if/Makefile
@@ -46,6 +46,7 @@ LIBABIVER := 1
 
 SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) := rte_ctrl_if.c
 SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) += rte_nl.c
+SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) += rte_ctrl_process.c
 
 #
 # Export include files
diff --git a/lib/librte_ctrl_if/rte_ctrl_process.c b/lib/librte_ctrl_if/rte_ctrl_process.c
new file mode 100644
index 000000000..cfb243f64
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_process.c
@@ -0,0 +1,167 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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 <error.h>
+
+#include <linux/if_link.h>
+
+#include <rte_version.h>
+#include <rte_ethdev.h>
+#include "rte_ctrl_process.h"
+
+static int
+set_mtu(uint8_t port_id, void *in_data)
+{
+	int *mtu = in_data;
+
+	return rte_eth_dev_set_mtu(port_id, *mtu);
+}
+
+static int
+get_stats(uint8_t port_id, void *data, size_t *data_len)
+{
+	struct rte_eth_stats stats;
+	struct rtnl_link_stats64 *if_stats = data;
+	int ret;
+
+	ret = rte_eth_stats_get(port_id, &stats);
+	if (ret < 0)
+		return -EOPNOTSUPP;
+
+	if_stats->rx_packets = stats.ipackets;
+	if_stats->tx_packets = stats.opackets;
+	if_stats->rx_bytes = stats.ibytes;
+	if_stats->tx_bytes = stats.obytes;
+	if_stats->rx_errors = stats.ierrors;
+	if_stats->tx_errors = stats.oerrors;
+	if_stats->rx_dropped = stats.imissed;
+
+	*data_len = sizeof(struct rtnl_link_stats64);
+
+	return 0;
+}
+
+static int
+get_mac(uint8_t port_id, void *data, size_t *data_len)
+{
+	struct ether_addr addr;
+
+	rte_eth_macaddr_get(port_id, &addr);
+	memcpy(data, &addr, sizeof(struct ether_addr));
+
+	*data_len = sizeof(struct ether_addr);
+
+	return 0;
+}
+
+static int
+set_mac(uint8_t port_id, void *in_data)
+{
+	struct ether_addr addr;
+
+	memcpy(&addr, in_data, ETHER_ADDR_LEN);
+
+	return rte_eth_dev_default_mac_addr_set(port_id, &addr);
+}
+
+static int
+start_port(uint8_t port_id)
+{
+	rte_eth_dev_stop(port_id);
+	return rte_eth_dev_start(port_id);
+}
+
+static int
+stop_port(uint8_t port_id)
+{
+	rte_eth_dev_stop(port_id);
+	return 0;
+}
+
+static int
+set_promisc(uint8_t port_id, void *in_data)
+{
+	int *promisc = in_data;
+
+	if (*promisc)
+		rte_eth_promiscuous_enable(port_id);
+	else
+		rte_eth_promiscuous_disable(port_id);
+
+	return 0;
+}
+
+static int
+set_allmulti(uint8_t port_id, void *in_data)
+{
+	int *allmulti = in_data;
+
+	if (*allmulti)
+		rte_eth_allmulticast_enable(port_id);
+	else
+		rte_eth_allmulticast_disable(port_id);
+
+	return 0;
+}
+
+int
+rte_eth_dev_control_process(uint32_t cmd_id, uint8_t port_id, void *in_data,
+		void *out_data, size_t *out_data_len)
+{
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return -ENODEV;
+
+	switch (cmd_id) {
+	case UNCI_REQ_CHANGE_MTU:
+		return set_mtu(port_id, in_data);
+	case UNCI_REQ_GET_STATS:
+		return get_stats(port_id, out_data, out_data_len);
+	case UNCI_REQ_GET_MAC:
+		return get_mac(port_id, out_data, out_data_len);
+	case UNCI_REQ_SET_MAC:
+		return set_mac(port_id, in_data);
+	case UNCI_REQ_START_PORT:
+		return start_port(port_id);
+	case UNCI_REQ_STOP_PORT:
+		return stop_port(port_id);
+	case UNCI_REQ_SET_PROMISC:
+		return set_promisc(port_id, in_data);
+	case UNCI_REQ_SET_ALLMULTI:
+		return set_allmulti(port_id, in_data);
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
diff --git a/lib/librte_ctrl_if/rte_ctrl_process.h b/lib/librte_ctrl_if/rte_ctrl_process.h
new file mode 100644
index 000000000..3dd690a8e
--- /dev/null
+++ b/lib/librte_ctrl_if/rte_ctrl_process.h
@@ -0,0 +1,50 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 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_CTRL_ETHTOOL_H_
+#define _RTE_CTRL_ETHTOOL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <exec-env/unci.h>
+
+int rte_eth_dev_control_process(uint32_t cmd_id, uint8_t port_id, void *in_data,
+		void *out_data, size_t *out_data_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_CTRL_ETHTOOL_H_ */
diff --git a/lib/librte_ctrl_if/rte_nl.c b/lib/librte_ctrl_if/rte_nl.c
index 8042d12fb..1648dc706 100644
--- a/lib/librte_ctrl_if/rte_nl.c
+++ b/lib/librte_ctrl_if/rte_nl.c
@@ -41,6 +41,7 @@
 
 #include <rte_log.h>
 #include <rte_lcore.h>
+#include "rte_ctrl_process.h"
 #include "rte_nl.h"
 #include "rte_ctrl_if.h"
 
@@ -60,6 +61,24 @@ struct ctrl_if_nl {
 	struct sockaddr_nl dest_addr;
 };
 
+struct ctrl_if_msg_sync {
+	struct unci_nl_msg msg_storage;
+	pthread_mutex_t msg_lock;
+	uint32_t pending_process;
+};
+
+
+/**
+ * Flags values for rte_eth_control_interface_process_msg() API
+ */
+enum control_interface_process_flag {
+	/**< Process if msg available. */
+	RTE_ETHTOOL_CTRL_IF_PROCESS_MSG,
+
+	/**< Discard msg if available, respond with a error value. */
+	RTE_ETHTOOL_CTRL_IF_DISCARD_MSG,
+};
+
 static int sock_fd = -1;
 static pthread_t thread_id;
 
@@ -68,6 +87,137 @@ static struct ctrl_if_nl nl_r;
 
 static int nl_family_id;
 
+static struct ctrl_if_msg_sync ctrl_if_sync = {
+	.msg_lock = PTHREAD_MUTEX_INITIALIZER,
+};
+
+static int
+nl_send(void *buf, size_t len)
+{
+	struct nlattr *nl_na;
+	int ret;
+
+	nl_s.h.nlh.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
+	nl_s.h.nlh.nlmsg_type = nl_family_id;
+	nl_s.h.nlh.nlmsg_flags = NLM_F_REQUEST;
+	nl_s.h.nlh.nlmsg_seq = 0;
+	nl_s.h.nlh.nlmsg_pid = getpid();
+
+	nl_s.h.genlh.cmd = UNCI_CMD_MSG;
+	nl_s.h.genlh.version = UNCI_GENL_VERSION;
+	nl_s.h.genlh.reserved = 0;
+
+	nl_na = (struct nlattr *) GENLMSG_DATA(nl_s.nlmsg);
+	nl_na->nla_type = UNCI_ATTR_MSG;
+	nl_na->nla_len = len + NLA_HDRLEN;
+
+	nl_s.h.nlh.nlmsg_len += NLMSG_ALIGN(nl_na->nla_len);
+
+	if (nl_s.h.nlh.nlmsg_len > UNCI_GENL_MSG_LEN) {
+		RTE_LOG(ERR, CTRL_IF, "Message is too big, len:%zu\n", len);
+		return -1;
+	}
+
+	/* Fill in the netlink message payload */
+	memcpy(NLA_DATA(nl_na), buf, len);
+
+	ret = sendmsg(sock_fd, &nl_s.msg, 0);
+	if (ret < 0)
+		RTE_LOG(ERR, CTRL_IF, "Failed nl msg send. ret:%d, err:%d\n",
+				ret, errno);
+	return ret;
+}
+
+/* each request sent expects a reply */
+static int
+nl_reply(struct unci_nl_msg *msg)
+{
+	return nl_send((void *)msg, sizeof(struct unci_nl_msg));
+}
+
+static void
+process_msg(struct unci_nl_msg *msg)
+{
+	if (msg->cmd_id > UNCI_REQ_UNKNOWN) {
+		msg->err = rte_eth_dev_control_process(msg->cmd_id,
+				msg->port_id, msg->input_buffer,
+				msg->output_buffer, &msg->output_buffer_len);
+	}
+
+	if (msg->err)
+		memset(msg->output_buffer, 0, msg->output_buffer_len);
+
+	nl_reply(msg);
+}
+
+static int
+control_interface_msg_process(uint32_t flag)
+{
+	struct unci_nl_msg msg_storage;
+	int ret = 0;
+
+	pthread_mutex_lock(&ctrl_if_sync.msg_lock);
+	if (ctrl_if_sync.pending_process == 0) {
+		pthread_mutex_unlock(&ctrl_if_sync.msg_lock);
+		return 0;
+	}
+
+	memcpy(&msg_storage, &ctrl_if_sync.msg_storage,
+			sizeof(struct unci_nl_msg));
+	ctrl_if_sync.pending_process = 0;
+	pthread_mutex_unlock(&ctrl_if_sync.msg_lock);
+
+	switch (flag) {
+	case RTE_ETHTOOL_CTRL_IF_PROCESS_MSG:
+		process_msg(&msg_storage);
+		break;
+
+	case RTE_ETHTOOL_CTRL_IF_DISCARD_MSG:
+		msg_storage.err = -1;
+		nl_reply(&msg_storage);
+		break;
+
+	default:
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
+
+static int
+msg_add_and_process(struct nlmsghdr *nlh)
+{
+	struct nlattr *nl_na;
+	char *genlh;
+
+	pthread_mutex_lock(&ctrl_if_sync.msg_lock);
+
+	if (ctrl_if_sync.pending_process) {
+		pthread_mutex_unlock(&ctrl_if_sync.msg_lock);
+		return -1;
+	}
+
+	genlh = NLMSG_DATA(nlh);
+	nl_na = (struct nlattr *) (genlh + GENL_HDRLEN);
+
+	if (nl_na->nla_type != UNCI_ATTR_MSG) {
+		pthread_mutex_unlock(&ctrl_if_sync.msg_lock);
+		return -1;
+	}
+
+	memcpy(&ctrl_if_sync.msg_storage, NLA_DATA(nl_na),
+			sizeof(struct unci_nl_msg));
+	ctrl_if_sync.msg_storage.flag = UNCI_MSG_FLAG_RESPONSE;
+	ctrl_if_sync.pending_process = 1;
+
+	pthread_mutex_unlock(&ctrl_if_sync.msg_lock);
+
+	control_interface_msg_process(RTE_ETHTOOL_CTRL_IF_PROCESS_MSG);
+
+	return 0;
+}
+
 static void *
 nl_recv(void *arg)
 {
@@ -87,6 +237,8 @@ nl_recv(void *arg)
 					ret, sizeof(struct unci_nl_msg));
 			continue;
 		}
+
+		msg_add_and_process(&nl_r.h.nlh);
 	}
 
 	return arg;
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 18/20] ctrl_if: process ethtool messages
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (16 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 17/20] ctrl_if: process control messages Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 19/20] doc: add control interface library documentation Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 20/20] ethdev: add control interface support Ferruh Yigit
  19 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Process ethtool messages and rend response back to kernel.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ctrl_if/rte_ctrl_process.c | 223 ++++++++++++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_process.h |   4 +
 lib/librte_ctrl_if/rte_nl.c           |   4 +
 3 files changed, 231 insertions(+)

diff --git a/lib/librte_ctrl_if/rte_ctrl_process.c b/lib/librte_ctrl_if/rte_ctrl_process.c
index cfb243f64..55fd54351 100644
--- a/lib/librte_ctrl_if/rte_ctrl_process.c
+++ b/lib/librte_ctrl_if/rte_ctrl_process.c
@@ -38,8 +38,231 @@
 
 #include <rte_version.h>
 #include <rte_ethdev.h>
+#include <rte_ethtool.h>
 #include "rte_ctrl_process.h"
 
+#define ETHTOOL_GEEPROM_LEN 99
+#define ETHTOOL_GREGS_LEN 98
+#define ETHTOOL_GSSET_COUNT 97
+
+static int
+get_settings(uint8_t port_id __rte_unused, void *data, size_t *data_len)
+{
+	struct ethtool_cmd *ecmd = data;
+
+	/* No PMD equivalent, added to make get pauseparam work */
+	memset(ecmd, 0, sizeof(struct ethtool_cmd));
+
+	*data_len = sizeof(struct ethtool_cmd);
+	return 0;
+}
+
+static int
+get_drvinfo(uint8_t port_id, void *data, size_t *data_len)
+{
+	struct ethtool_drvinfo *info = data;
+	int ret;
+
+	ret = rte_ethtool_get_drvinfo(port_id, info);
+	if (ret < 0)
+		return ret;
+
+	*data_len = sizeof(struct ethtool_drvinfo);
+
+	return 0;
+}
+
+static int
+get_reg_len(uint8_t port_id, void *data, size_t *data_len)
+{
+	int reg_length = 0;
+
+	reg_length = rte_ethtool_get_regs_len(port_id);
+	if (reg_length < 0)
+		return reg_length;
+
+	*(int *)data = reg_length;
+	*data_len = sizeof(int);
+
+	return 0;
+}
+
+static int
+get_reg_len_internal(uint8_t port_id, size_t *reg_length)
+{
+	size_t reg_length_out_len;
+
+	return get_reg_len(port_id, reg_length, &reg_length_out_len);
+}
+
+static int
+get_reg(uint8_t port_id, void *in_data, void *out_data, size_t *out_data_len)
+{
+	size_t reg_length;
+	struct ethtool_regs *ethtool_regs = in_data;
+	int ret;
+
+	ret = get_reg_len_internal(port_id, &reg_length);
+	/* not enough space in out data buffer */
+	if (ret < 0 || reg_length > ethtool_regs->len)
+		return -1;
+
+	ret = rte_ethtool_get_regs(port_id, ethtool_regs, out_data);
+	if (ret < 0)
+		return ret;
+
+	*out_data_len = reg_length;
+
+	return 0;
+}
+
+static int
+get_link(uint8_t port_id, void *data, size_t *data_len)
+{
+	int ret;
+
+	ret = rte_ethtool_get_link(port_id);
+
+	*(int *)data = ret;
+	*data_len = sizeof(size_t);
+
+	return 0;
+}
+
+static int
+get_eeprom_length(uint8_t port_id, void *data, size_t *data_len)
+{
+	int eeprom_length = 0;
+
+	eeprom_length = rte_ethtool_get_eeprom_len(port_id);
+	if (eeprom_length < 0)
+		return eeprom_length;
+
+	*(int *)data = eeprom_length;
+	*data_len = sizeof(int);
+
+	return 0;
+}
+
+static int
+get_eeprom(uint8_t port_id, void *in_data, void *out_data,
+		size_t *out_data_len)
+{
+	struct ethtool_eeprom *eeprom = in_data;
+	int ret;
+
+	ret = rte_ethtool_get_eeprom(port_id, eeprom, out_data);
+	if (ret < 0)
+		return ret;
+
+	*out_data_len = eeprom->len;
+
+	return 0;
+}
+
+static int
+set_eeprom(uint8_t port_id, void *in_data)
+{
+	struct ethtool_eeprom *eeprom = in_data;
+	int ret;
+
+	ret = rte_ethtool_set_eeprom(port_id, eeprom, eeprom->data);
+	if (ret != 0)
+		return -1;
+
+	return 0;
+}
+
+static int
+get_ringparam(uint8_t port_id, void *data, size_t *data_len)
+{
+	struct ethtool_ringparam *ringparam = data;
+	int ret;
+
+	ret = rte_ethtool_get_ringparam(port_id, ringparam);
+	if (ret < 0)
+		return ret;
+
+	*data_len = sizeof(struct ethtool_ringparam);
+
+	return 0;
+}
+
+static int
+set_ringparam(uint8_t port_id, void *data)
+{
+	struct ethtool_ringparam *ringparam = data;
+	int ret;
+
+	ret = rte_ethtool_set_ringparam(port_id, ringparam);
+	if (ret != 0)
+		return -1;
+
+	return 0;
+}
+
+static int
+get_pauseparam(uint8_t port_id, void *data, size_t *data_len)
+{
+	struct ethtool_pauseparam *pauseparam = data;
+	int ret;
+
+	ret = rte_ethtool_get_pauseparam(port_id, pauseparam);
+	if (ret < 0)
+		return ret;
+
+	*data_len = sizeof(struct ethtool_pauseparam);
+
+	return 0;
+}
+
+static int
+set_pauseparam(uint8_t port_id, void *data)
+{
+	struct ethtool_pauseparam *pauseparam = data;
+
+	return rte_ethtool_set_pauseparam(port_id, pauseparam);
+}
+
+int
+rte_eth_dev_ethtool_process(uint32_t cmd_id, uint8_t port_id, void *in_data,
+		void *out_data, size_t *out_data_len)
+{
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return -ENODEV;
+
+	switch (cmd_id) {
+	case ETHTOOL_GSET:
+		return get_settings(port_id, out_data, out_data_len);
+	case ETHTOOL_GDRVINFO:
+		return get_drvinfo(port_id, out_data, out_data_len);
+	case ETHTOOL_GREGS_LEN:
+		return get_reg_len(port_id, out_data, out_data_len);
+	case ETHTOOL_GREGS:
+		return get_reg(port_id, in_data, out_data, out_data_len);
+	case ETHTOOL_GLINK:
+		return get_link(port_id, out_data, out_data_len);
+	case ETHTOOL_GEEPROM_LEN:
+		return get_eeprom_length(port_id, out_data, out_data_len);
+	case ETHTOOL_GEEPROM:
+		return get_eeprom(port_id, in_data, out_data, out_data_len);
+	case ETHTOOL_SEEPROM:
+		return set_eeprom(port_id, in_data);
+	case ETHTOOL_GRINGPARAM:
+		return get_ringparam(port_id, out_data, out_data_len);
+	case ETHTOOL_SRINGPARAM:
+		return set_ringparam(port_id, in_data);
+	case ETHTOOL_GPAUSEPARAM:
+		return get_pauseparam(port_id, out_data, out_data_len);
+	case ETHTOOL_SPAUSEPARAM:
+		return set_pauseparam(port_id, in_data);
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
 static int
 set_mtu(uint8_t port_id, void *in_data)
 {
diff --git a/lib/librte_ctrl_if/rte_ctrl_process.h b/lib/librte_ctrl_if/rte_ctrl_process.h
index 3dd690a8e..a61735f0d 100644
--- a/lib/librte_ctrl_if/rte_ctrl_process.h
+++ b/lib/librte_ctrl_if/rte_ctrl_process.h
@@ -38,8 +38,12 @@
 extern "C" {
 #endif
 
+#include <linux/ethtool.h>
+
 #include <exec-env/unci.h>
 
+int rte_eth_dev_ethtool_process(uint32_t cmd_id, uint8_t port_id, void *in_data,
+		void *out_data, size_t *out_data_len);
 int rte_eth_dev_control_process(uint32_t cmd_id, uint8_t port_id, void *in_data,
 		void *out_data, size_t *out_data_len);
 
diff --git a/lib/librte_ctrl_if/rte_nl.c b/lib/librte_ctrl_if/rte_nl.c
index 1648dc706..43abcbd35 100644
--- a/lib/librte_ctrl_if/rte_nl.c
+++ b/lib/librte_ctrl_if/rte_nl.c
@@ -142,6 +142,10 @@ process_msg(struct unci_nl_msg *msg)
 		msg->err = rte_eth_dev_control_process(msg->cmd_id,
 				msg->port_id, msg->input_buffer,
 				msg->output_buffer, &msg->output_buffer_len);
+	} else {
+		msg->err = rte_eth_dev_ethtool_process(msg->cmd_id,
+				msg->port_id, msg->input_buffer,
+				msg->output_buffer, &msg->output_buffer_len);
 	}
 
 	if (msg->err)
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 19/20] doc: add control interface library documentation
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (17 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 18/20] ctrl_if: process ethtool messages Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-04 16:13       ` [PATCH v10 20/20] ethdev: add control interface support Ferruh Yigit
  19 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 doc/api/doxy-api-index.md              |  3 +-
 doc/api/doxy-api.conf                  |  1 +
 doc/guides/prog_guide/ctrl_if_lib.rst  | 50 ++++++++++++++++++++++++++++++++++
 doc/guides/prog_guide/index.rst        |  1 +
 doc/guides/rel_notes/release_17_08.rst |  8 ++++++
 5 files changed, 62 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/prog_guide/ctrl_if_lib.rst

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 71350849f..ba45ff69a 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -162,4 +162,5 @@ There are many libraries, so their headers may be grouped by topics:
   [bitrate statistics] (@ref rte_bitrate.h),
   [latency statistics] (@ref rte_latencystats.h),
   [version]            (@ref rte_version.h),
-  [ethtool]            (@ref rte_ethtool.h)
+  [ethtool]            (@ref rte_ethtool.h),
+  [control interface]  (@ref rte_ctrl_if.h)
diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
index b66e86541..896c2b247 100644
--- a/doc/api/doxy-api.conf
+++ b/doc/api/doxy-api.conf
@@ -42,6 +42,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           lib/librte_cmdline \
                           lib/librte_compat \
                           lib/librte_cryptodev \
+                          lib/librte_ctrl_if \
                           lib/librte_distributor \
                           lib/librte_efd \
                           lib/librte_ether \
diff --git a/doc/guides/prog_guide/ctrl_if_lib.rst b/doc/guides/prog_guide/ctrl_if_lib.rst
new file mode 100644
index 000000000..496515301
--- /dev/null
+++ b/doc/guides/prog_guide/ctrl_if_lib.rst
@@ -0,0 +1,50 @@
+..  BSD LICENSE
+    Copyright(c) 2016 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.
+
+.. _Ctrl_If_Library:
+
+Control Interface Library
+=========================
+
+This Library is to create/destroy control interfaces and process messages
+received by control interface.
+
+Control Interface is Linux network interface and it is possible to call
+various Linux commands to this interface and commands will be forwarded
+to the matching DPDK PMD, and response will be generated by PMD.
+
+Control interface required UNCI kernel module to be inserted to function.
+
+Control Interface APIS
+----------------------
+
+
+- ``rte_eth_control_interface_create()``
+- ``rte_eth_control_interface_destroy()``
diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index 54f9538ea..c7cb4b0f8 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -55,6 +55,7 @@ Programmer's Guide
     ip_fragment_reassembly_lib
     pdump_lib
     ethtool_lib
+    ctrl_if_lib
     multi_proc_support
     kernel_nic_interface
     thread_safety_dpdk_functions
diff --git a/doc/guides/rel_notes/release_17_08.rst b/doc/guides/rel_notes/release_17_08.rst
index e21d4e17c..0598a9ec0 100644
--- a/doc/guides/rel_notes/release_17_08.rst
+++ b/doc/guides/rel_notes/release_17_08.rst
@@ -80,6 +80,14 @@ New Features
   Ethtool library is wrapper for ethdev library and provides APIs to get data
   similar to Linux ethtool provides.
 
+* **Control interface support added.**
+
+  To enable controlling DPDK ports by common Linux tools.
+  Following modules added to DPDK:
+
+  * librte_ctrl_if library
+  * librte_eal/linuxapp/unci kernel module
+
 
 Resolved Issues
 ---------------
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH v10 20/20] ethdev: add control interface support
  2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
                         ` (18 preceding siblings ...)
  2017-07-04 16:13       ` [PATCH v10 19/20] doc: add control interface library documentation Ferruh Yigit
@ 2017-07-04 16:13       ` Ferruh Yigit
  2017-07-08  6:28         ` Yuanhan Liu
  19 siblings, 1 reply; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-04 16:13 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Stephen Hemminger, Bruce Richardson, Anatoly Burakov

To have the support corresponding kernel module (UNCI) needs to be
inserted.  If kernel module is not there, application will run as
it is without kernel control path support.

When UNCI module inserted, running application creates a virtual Linux
network interface (dpdk$) per DPDK port. This interface can be used by
traditional Linux tools.

If Userspace Network Control Interface (UNCI) kernel module
(rte_unci.ko) inserted, virtual interfaces created for each DPDK port
for control purposes.

Created interfaces are named as dpdk#, like:

    $ ifconfig dpdk0; ifconfig dpdk1
    dpdk0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
            ether 90:e2:ba:0e:49:b9  txqueuelen 1000  (Ethernet)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

    dpdk1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
            ether 00:1b:21:76:fa:21  txqueuelen 1000  (Ethernet)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Regular Linux commands can be issued on interfaces:

	$ ethtool -i dpdk0
	driver: net_ixgbe
	version: DPDK 17.08.0-rc0
	firmware-version: 0x61bf0001
	expansion-rom-version:
	bus-info: 0000:08:00.1
	supports-statistics: no
	supports-test: no
	supports-eeprom-access: yes
	supports-register-dump: yes
	supports-priv-flags: no

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
v9:
* fix shared build
---
 drivers/net/Makefile              |  4 ++++
 lib/librte_ether/rte_ethdev_pci.h | 15 ++++++++++++++-
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 35ed8135a..cdabc2349 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -39,6 +39,10 @@ endif
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
 core-libs += librte_net librte_kvargs
 
+ifeq ($(CONFIG_RTE_LIBRTE_CTRL_IF),y)
+core-libs += librte_ctrl_if
+endif
+
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += af_packet
 DEPDIRS-af_packet = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark
diff --git a/lib/librte_ether/rte_ethdev_pci.h b/lib/librte_ether/rte_ethdev_pci.h
index 69aab03fb..fcdee9229 100644
--- a/lib/librte_ether/rte_ethdev_pci.h
+++ b/lib/librte_ether/rte_ethdev_pci.h
@@ -38,6 +38,13 @@
 #include <rte_pci.h>
 #include <rte_ethdev.h>
 
+#ifdef RTE_LIBRTE_CTRL_IF
+#include <rte_ctrl_if.h>
+#else
+#define rte_eth_control_interface_create(port_id) do { } while (0)
+#define rte_eth_control_interface_destroy(port_id) do { } while (0)
+#endif
+
 /**
  * Copy pci device info to the Ethernet device data.
  *
@@ -157,8 +164,12 @@ rte_eth_dev_pci_generic_probe(struct rte_pci_device *pci_dev,
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
 	ret = dev_init(eth_dev);
-	if (ret)
+	if (ret) {
 		rte_eth_dev_pci_release(eth_dev);
+		return ret;
+	}
+
+	rte_eth_control_interface_create(eth_dev->data->port_id);
 
 	return ret;
 }
@@ -179,6 +190,8 @@ rte_eth_dev_pci_generic_remove(struct rte_pci_device *pci_dev,
 	if (!eth_dev)
 		return -ENODEV;
 
+	rte_eth_control_interface_destroy(eth_dev->data->port_id);
+
 	if (dev_uninit) {
 		ret = dev_uninit(eth_dev);
 		if (ret)
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* Re: [PATCH v10 11/20] unci: add netlink exec
  2017-07-04 16:13       ` [PATCH v10 11/20] unci: add netlink exec Ferruh Yigit
@ 2017-07-05 19:07         ` Stephen Hemminger
  2017-07-06 10:45           ` Ferruh Yigit
  2017-07-05 19:15         ` Stephen Hemminger
  1 sibling, 1 reply; 91+ messages in thread
From: Stephen Hemminger @ 2017-07-05 19:07 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Bruce Richardson, Anatoly Burakov

On Tue,  4 Jul 2017 17:13:28 +0100
Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> +int unci_nl_exec(u32 cmd, struct net_device *dev, void *in_data,
> +		size_t in_data_len, void *out_data, size_t out_data_len)
> +{
> +	struct unci_dev *unci = netdev_priv(dev);
> +	int err = -EINVAL;
> +	int ret;
> +
> +	if (out_data_len > UNCI_NL_MSG_LEN) {
> +		pr_err("Message is too big to receive:%zu\n", out_data_len);
> +		return err;
> +	}
> +
> +	mutex_lock(&sync_lock);
> +	ret = unci_response_buffer_register(cmd, out_data, out_data_len,
> +			&unci->msg_received, &err);
> +	if (ret) {
> +		mutex_unlock(&sync_lock);
> +		return -EINVAL;
> +	}
> +
> +	ret = unci_nl_send(cmd, unci->port_id, unci->pid, in_data, in_data_len);
> +	if (ret) {
> +		unci_response_buffer_unregister(response_buffer.magic);
> +		mutex_unlock(&sync_lock);
> +		return ret;
> +	}
> +
> +	ret = wait_for_completion_interruptible_timeout(&unci->msg_received,
> +			 msecs_to_jiffies(UNCI_CMD_TIMEOUT));

Blocking for completion with mutex held? 
Sleeping with mutex held is not allowed in Linux.

You will see this if you run with lockdep and all the other kernel debug
config options.

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v10 13/20] unci: add ethtool support
  2017-07-04 16:13       ` [PATCH v10 13/20] unci: add ethtool support Ferruh Yigit
@ 2017-07-05 19:07         ` Stephen Hemminger
  2017-07-05 19:08         ` Stephen Hemminger
  1 sibling, 0 replies; 91+ messages in thread
From: Stephen Hemminger @ 2017-07-05 19:07 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Bruce Richardson, Anatoly Burakov

On Tue,  4 Jul 2017 17:13:30 +0100
Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> +static void unci_get_drvinfo(struct net_device *dev,
> +		struct ethtool_drvinfo *info)
> +{
> +	int ret;
> +
> +	ret = unci_nl_exec(info->cmd, dev, NULL, 0,
> +			info, sizeof(struct ethtool_drvinfo));
> +	if (ret < 0)
> +		memset(info, 0, sizeof(struct ethtool_drvinfo));
> +}

drvinfo is already zero'd in net/core/ethtool.c

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v10 13/20] unci: add ethtool support
  2017-07-04 16:13       ` [PATCH v10 13/20] unci: add ethtool support Ferruh Yigit
  2017-07-05 19:07         ` Stephen Hemminger
@ 2017-07-05 19:08         ` Stephen Hemminger
  1 sibling, 0 replies; 91+ messages in thread
From: Stephen Hemminger @ 2017-07-05 19:08 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Bruce Richardson, Anatoly Burakov

On Tue,  4 Jul 2017 17:13:30 +0100
Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> +static int unci_check_if_running(struct net_device *dev)
> +{
> +	return 0;
> +}

Don't define stub for this. If you leave ethtool_get_link as NULL
it will do the right thing.

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v10 12/20] unci: add netdevice ops
  2017-07-04 16:13       ` [PATCH v10 12/20] unci: add netdevice ops Ferruh Yigit
@ 2017-07-05 19:12         ` Stephen Hemminger
  2017-07-05 19:12         ` Stephen Hemminger
  1 sibling, 0 replies; 91+ messages in thread
From: Stephen Hemminger @ 2017-07-05 19:12 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Bruce Richardson, Anatoly Burakov

On Tue,  4 Jul 2017 17:13:29 +0100
Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> +#if (KERNEL_VERSION(3, 9, 0) <= LINUX_VERSION_CODE)
> +static int unci_net_change_carrier(struct net_device *dev, bool new_carrier)
> +{
> +	if (new_carrier)
> +		netif_carrier_on(dev);
> +	else
> +		netif_carrier_off(dev);
> +	return 0;
> +}
> +#endif

Don't really need ndo_change_carrier. It is meant for layered devices like team
device.

For unci, the carrier state should always track what the DPDK driver reports.

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v10 12/20] unci: add netdevice ops
  2017-07-04 16:13       ` [PATCH v10 12/20] unci: add netdevice ops Ferruh Yigit
  2017-07-05 19:12         ` Stephen Hemminger
@ 2017-07-05 19:12         ` Stephen Hemminger
  1 sibling, 0 replies; 91+ messages in thread
From: Stephen Hemminger @ 2017-07-05 19:12 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Bruce Richardson, Anatoly Burakov

On Tue,  4 Jul 2017 17:13:29 +0100
Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> +static void unci_net_stats64(struct net_device *dev,
> +		struct rtnl_link_stats64 *stats)
> +{
> +	int err;
> +
> +	err = unci_nl_exec(UNCI_REQ_GET_STATS, dev, NULL, 0,
> +			stats, sizeof(struct rtnl_link_stats64));

Do tail call here

	return unci_nl_exec(UNCI_REQ_GET_STATS, ...

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v10 11/20] unci: add netlink exec
  2017-07-04 16:13       ` [PATCH v10 11/20] unci: add netlink exec Ferruh Yigit
  2017-07-05 19:07         ` Stephen Hemminger
@ 2017-07-05 19:15         ` Stephen Hemminger
  1 sibling, 0 replies; 91+ messages in thread
From: Stephen Hemminger @ 2017-07-05 19:15 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Bruce Richardson, Anatoly Burakov

On Tue,  4 Jul 2017 17:13:28 +0100
Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> +
> +			if (nl_msg->err == 0 && recv_len != expected_len)
> +				pr_info("Expected and received len not match "
> +					"%zu - %zu\n", recv_len, expected_len);
> +		}
> +

Checkpatch complains about string split, just put the whole string on one line.

				pr_info("Expected and received len not match %zu - %zu\n", 
					recv_len, expected_len)

WARNING: quoted string split across lines
#99: FILE: lib/librte_eal/linuxapp/unci/unci_nl.c:99:
+				pr_info("Expected and received len not match "
+					"%zu - %zu\n", recv_len, expected_len);

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v10 04/20] ethtool: update header doxygen syntax
  2017-07-04 16:13       ` [PATCH v10 04/20] ethtool: update header doxygen syntax Ferruh Yigit
@ 2017-07-06  9:18         ` Burakov, Anatoly
  0 siblings, 0 replies; 91+ messages in thread
From: Burakov, Anatoly @ 2017-07-06  9:18 UTC (permalink / raw)
  To: Yigit, Ferruh, dev; +Cc: Stephen Hemminger, Richardson, Bruce

> From: Yigit, Ferruh
> Sent: Tuesday, July 4, 2017 5:13 PM
> To: dev@dpdk.org
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; Stephen Hemminger
> <stephen@networkplumber.org>; Richardson, Bruce
> <bruce.richardson@intel.com>; Burakov, Anatoly
> <anatoly.burakov@intel.com>
> Subject: [PATCH v10 04/20] ethtool: update header doxygen syntax
> 
> Minor corrections and doxygen syntax fixes on library header file.
> 
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> ---
>  lib/librte_ethtool/rte_ethtool.h | 57 +++++++++++++++++++++---------------
> ----
>  1 file changed, 30 insertions(+), 27 deletions(-)
> 
> diff --git a/lib/librte_ethtool/rte_ethtool.h b/lib/librte_ethtool/rte_ethtool.h
> index 18f44404b..bcf20870c 100644
> --- a/lib/librte_ethtool/rte_ethtool.h
> +++ b/lib/librte_ethtool/rte_ethtool.h
> @@ -34,11 +34,13 @@
>  #ifndef _RTE_ETHTOOL_H_
>  #define _RTE_ETHTOOL_H_
> 
> -/*
> +/**
> + * @file
> + *
>   * 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_drvinfo:         ethtool_ops::get_driverinfo
>   * rte_ethtool_get_link:            ethtool_ops::get_link
>   * rte_ethtool_get_regs_len:        ethtool_ops::get_regs_len
>   * rte_ethtool_get_regs:            ethtool_ops::get_regs
> @@ -47,6 +49,8 @@
>   * rte_ethtool_set_eeprom:          ethtool_ops::set_eeprom
>   * rte_ethtool_get_pauseparam:      ethtool_ops::get_pauseparam
>   * rte_ethtool_set_pauseparam:      ethtool_ops::set_pauseparam
> + * rte_ethtool_get_ringparam:       ethtool_ops::set_ringparam
> + * rte_ethtool_set_ringparam:       ethtool_ops::set_ringparam

Typo? set_ringparam appears two times.

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v10 08/20] unci: add module skeleton
  2017-07-04 16:13       ` [PATCH v10 08/20] unci: add module skeleton Ferruh Yigit
@ 2017-07-06  9:25         ` Burakov, Anatoly
  0 siblings, 0 replies; 91+ messages in thread
From: Burakov, Anatoly @ 2017-07-06  9:25 UTC (permalink / raw)
  To: Yigit, Ferruh, dev; +Cc: Stephen Hemminger, Richardson, Bruce

> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Tuesday, July 4, 2017 5:13 PM
> To: dev@dpdk.org
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; Stephen Hemminger
> <stephen@networkplumber.org>; Richardson, Bruce
> <bruce.richardson@intel.com>; Burakov, Anatoly
> <anatoly.burakov@intel.com>
> Subject: [PATCH v10 08/20] unci: add module skeleton
> 
> Base files to have a new kernel module, without actual source code.
> 
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> ---
>  MAINTAINERS                             |  4 +++
>  config/common_base                      |  5 ++++
>  config/common_linuxapp                  |  1 +
>  lib/librte_eal/linuxapp/Makefile        |  4 ++-
>  lib/librte_eal/linuxapp/unci/Makefile   | 52
> +++++++++++++++++++++++++++++++++
>  lib/librte_eal/linuxapp/unci/unci_dev.h | 34 +++++++++++++++++++++
> lib/librte_eal/linuxapp/unci/unci_net.c | 42
> ++++++++++++++++++++++++++
>  7 files changed, 141 insertions(+), 1 deletion(-)  create mode 100644
> lib/librte_eal/linuxapp/unci/Makefile
>  create mode 100644 lib/librte_eal/linuxapp/unci/unci_dev.h
>  create mode 100644 lib/librte_eal/linuxapp/unci/unci_net.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index cae791e21..cfc3d4bf3 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -758,6 +758,10 @@ Ethtool
>  M: Remy Horton <remy.horton@intel.com>
>  F: lib/librte_ethtool/
> 
> +Linux Userspace Network Control Interface (UNCI)
> +M: Ferruh Yigit <ferruh.yigit@intel.com>
> +F: lib/librte_eal/linuxapp/unci/
> +
>  Test Applications
>  -----------------
> 
> diff --git a/config/common_base b/config/common_base index
> 0b86c3431..1582f703e 100644
> --- a/config/common_base
> +++ b/config/common_base
> @@ -705,6 +705,11 @@ CONFIG_RTE_LIBRTE_PDUMP=y
> CONFIG_RTE_LIBRTE_ETHTOOL=n
> 
>  #
> +# Compile Userspace Network Control Interface (UNCI) kernel module #
> +CONFIG_RTE_UNCI_KMOD=n
> +
> +#
>  # Compile vhost user library
>  #
>  CONFIG_RTE_LIBRTE_VHOST=n
> diff --git a/config/common_linuxapp b/config/common_linuxapp index
> 9a6bf868c..b400b2c0e 100644
> --- a/config/common_linuxapp
> +++ b/config/common_linuxapp
> @@ -42,6 +42,7 @@ CONFIG_RTE_KNI_KMOD=y
>  CONFIG_RTE_LIBRTE_KNI=y
>  CONFIG_RTE_LIBRTE_PMD_KNI=y
>  CONFIG_RTE_LIBRTE_ETHTOOL=y
> +CONFIG_RTE_UNCI_KMOD=y
>  CONFIG_RTE_LIBRTE_VHOST=y
>  CONFIG_RTE_LIBRTE_VHOST_NUMA=y
>  CONFIG_RTE_LIBRTE_PMD_VHOST=y
> diff --git a/lib/librte_eal/linuxapp/Makefile
> b/lib/librte_eal/linuxapp/Makefile
> index 4794696b6..2d293f1a6 100644
> --- a/lib/librte_eal/linuxapp/Makefile
> +++ b/lib/librte_eal/linuxapp/Makefile
> @@ -1,6 +1,6 @@
>  #   BSD LICENSE
>  #
> -#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> +#   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
>  #   All rights reserved.
>  #
>  #   Redistribution and use in source and binary forms, with or without
> @@ -35,6 +35,8 @@ DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal
>  DIRS-$(CONFIG_RTE_EAL_IGB_UIO) += igb_uio
>  DIRS-$(CONFIG_RTE_KNI_KMOD) += kni
>  DEPDIRS-kni := eal
> +DIRS-$(CONFIG_RTE_UNCI_KMOD) += unci
> +DEPDIRS-unci := eal
>  DIRS-$(CONFIG_RTE_LIBRTE_XEN_DOM0) += xen_dom0
>  DEPDIRS-xen_dom0 := eal
> 
> diff --git a/lib/librte_eal/linuxapp/unci/Makefile
> b/lib/librte_eal/linuxapp/unci/Makefile
> new file mode 100644
> index 000000000..02e354814
> --- /dev/null
> +++ b/lib/librte_eal/linuxapp/unci/Makefile
> @@ -0,0 +1,52 @@
> +#   BSD LICENSE
> +#
> +#   Copyright(c) 2017 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
> +
> +#
> +# module name and path
> +#
> +MODULE = rte_unci
> +
> +#
> +# CFLAGS
> +#
> +MODULE_CFLAGS += -I$(SRCDIR)
> +MODULE_CFLAGS += -I$(RTE_OUTPUT)/include MODULE_CFLAGS += -
> include
> +$(RTE_OUTPUT)/include/rte_config.h
> +MODULE_CFLAGS += -Wall -Werror
> +
> +#
> +# all source are stored in SRCS-y
> +#
> +SRCS-$(CONFIG_RTE_UNCI_KMOD) := unci_net.c
> +
> +include $(RTE_SDK)/mk/rte.module.mk
> diff --git a/lib/librte_eal/linuxapp/unci/unci_dev.h
> b/lib/librte_eal/linuxapp/unci/unci_dev.h
> new file mode 100644
> index 000000000..102409020
> --- /dev/null
> +++ b/lib/librte_eal/linuxapp/unci/unci_dev.h
> @@ -0,0 +1,34 @@
> +/*-
> + * GPL LICENSE SUMMARY
> + *
> + *   Copyright(c) 2017 Intel Corporation. All rights reserved.
> + *
> + *   This program is free software; you can redistribute it and/or modify
> + *   it under the terms of version 2 of the GNU General Public License as
> + *   published by the Free Software Foundation.
> + *
> + *   This program is distributed in the hope that it will be useful, but
> + *   WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> GNU
> + *   General Public License for more details.
> + *
> + *   You should have received a copy of the GNU General Public License
> + *   along with this program;
> + *
> + *   The full GNU General Public License is included in this distribution
> + *   in the file called LICENSE.GPL.
> + *
> + *   Contact Information:
> + *   Intel Corporation
> + */
> +
> +#ifndef _UNCI_DEV_H_
> +#define _UNCI_DEV_H_
> +
> +#ifdef pr_fmt
> +#undef pr_fmt
> +#endif
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +
> +#endif /* _UNCI_DEV_H_ */
> diff --git a/lib/librte_eal/linuxapp/unci/unci_net.c
> b/lib/librte_eal/linuxapp/unci/unci_net.c
> new file mode 100644
> index 000000000..b8ef409d3
> --- /dev/null
> +++ b/lib/librte_eal/linuxapp/unci/unci_net.c
> @@ -0,0 +1,42 @@
> +/*-
> + * GPL LICENSE SUMMARY
> + *
> + *   Copyright(c) 2017 Intel Corporation. All rights reserved.
> + *
> + *   This program is free software; you can redistribute it and/or modify
> + *   it under the terms of version 2 of the GNU General Public License as
> + *   published by the Free Software Foundation.
> + *
> + *   This program is distributed in the hope that it will be useful, but
> + *   WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> GNU
> + *   General Public License for more details.
> + *
> + *   You should have received a copy of the GNU General Public License
> + *   along with this program;
> + *
> + *   The full GNU General Public License is included in this distribution
> + *   in the file called LICENSE.GPL.
> + *
> + *   Contact Information:
> + *   Intel Corporation
> + */
> +
> +#include <linux/module.h>
> +
> +#include "unci_dev.h"
> +
> +static int __init unci_init(void)
> +{
> +	return 0;
> +}
> +module_init(unci_init);
> +
> +static void __exit unci_exit(void)
> +{
> +}
> +module_exit(unci_exit);
> +
> +MODULE_LICENSE("Dual BSD/GPL");

The module license says it's dual BSD/GPL, but the file only contains a GPL license. So either make it GPL-only, or add the BSD license header :) igb_uio is GPL-only, is there any particular reason why this one has to be dual licensed? 

> +MODULE_AUTHOR("Intel Corporation");
> +MODULE_DESCRIPTION("Kernel Module for managing unci devices");
> --
> 2.13.0

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v10 10/20] unci: init netlink
  2017-07-04 16:13       ` [PATCH v10 10/20] unci: init netlink Ferruh Yigit
@ 2017-07-06  9:32         ` Burakov, Anatoly
  0 siblings, 0 replies; 91+ messages in thread
From: Burakov, Anatoly @ 2017-07-06  9:32 UTC (permalink / raw)
  To: Yigit, Ferruh, dev; +Cc: Stephen Hemminger, Richardson, Bruce

> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Tuesday, July 4, 2017 5:13 PM
> To: dev@dpdk.org
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; Stephen Hemminger
> <stephen@networkplumber.org>; Richardson, Bruce
> <bruce.richardson@intel.com>; Burakov, Anatoly
> <anatoly.burakov@intel.com>
> Subject: [PATCH v10 10/20] unci: init netlink
> 
> Initialize netlink socket.
> 
> Userspace application will connect to the socket for data transfer.
> 
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> ---
>  .../linuxapp/eal/include/exec-env/unci.h           | 33 ++++++++++
>  lib/librte_eal/linuxapp/unci/Makefile              |  1 +
>  lib/librte_eal/linuxapp/unci/unci_dev.h            |  3 +
>  lib/librte_eal/linuxapp/unci/unci_net.c            |  7 +++
>  lib/librte_eal/linuxapp/unci/unci_nl.c             | 72
> ++++++++++++++++++++++
>  5 files changed, 116 insertions(+)
>  create mode 100644 lib/librte_eal/linuxapp/unci/unci_nl.c
> 
> diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h
> b/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h
> index 8d4a95777..6d3490aee 100644
> --- a/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h
> +++ b/lib/librte_eal/linuxapp/eal/include/exec-env/unci.h
> @@ -60,6 +60,20 @@
> 
>  #define UNCI_DEVICE "unci"
> 
> +#define UNCI_GENL_MSG_LEN 1536
> +
> +#define UNCI_NL_MSG_LEN 500
> +struct unci_nl_msg {
> +	__u32 cmd_id;
> +	__u32 port_id;
> +	__u32 flag;
> +	__u8 input_buffer[UNCI_NL_MSG_LEN];
> +	__u8 output_buffer[UNCI_NL_MSG_LEN];
> +	size_t input_buffer_len;
> +	size_t output_buffer_len;
> +	int err;
> +};
> +
>  /* can go into include/uapi/linux/if_link.h */  enum {
>  	IFLA_UNCI_UNSPEC,
> @@ -70,4 +84,23 @@ enum {
> 
>  #define IFLA_UNCI_MAX (__IFLA_UNCI_MAX - 1)
> 
> +
> +#define UNCI_GENL_VERSION 1
> +
> +enum {
> +	UNCI_ATTR_UNSPEC,
> +	UNCI_ATTR_MSG,
> +	__UNCI_ATTR_MAX,
> +};
> +
> +#define UNCI_ATTR_MAX (__UNCI_ATTR_MAX - 1)
> +
> +enum {
> +	UNCI_CMD_UNSPEC,
> +	UNCI_CMD_MSG,
> +	__UNCI_CMD_MAX,
> +};
> +
> +#define UNCI_CMD_MAX (__UNCI_CMD_MAX - 1)
> +
>  #endif /* _UAPI_LINUX_UNCI_H_ */
> diff --git a/lib/librte_eal/linuxapp/unci/Makefile
> b/lib/librte_eal/linuxapp/unci/Makefile
> index 02e354814..c2a81be7d 100644
> --- a/lib/librte_eal/linuxapp/unci/Makefile
> +++ b/lib/librte_eal/linuxapp/unci/Makefile
> @@ -48,5 +48,6 @@ MODULE_CFLAGS += -Wall -Werror  # all source are
> stored in SRCS-y  #
>  SRCS-$(CONFIG_RTE_UNCI_KMOD) := unci_net.c
> +SRCS-$(CONFIG_RTE_UNCI_KMOD) += unci_nl.c
> 
>  include $(RTE_SDK)/mk/rte.module.mk
> diff --git a/lib/librte_eal/linuxapp/unci/unci_dev.h
> b/lib/librte_eal/linuxapp/unci/unci_dev.h
> index 92b9b8383..a748abf98 100644
> --- a/lib/librte_eal/linuxapp/unci/unci_dev.h
> +++ b/lib/librte_eal/linuxapp/unci/unci_dev.h
> @@ -39,4 +39,7 @@ struct unci_dev {
>  	__u32 pid;
>  };
> 
> +int unci_nl_init(void);
> +void unci_nl_release(void);
> +
>  #endif /* _UNCI_DEV_H_ */
> diff --git a/lib/librte_eal/linuxapp/unci/unci_net.c
> b/lib/librte_eal/linuxapp/unci/unci_net.c
> index 42fac3e63..1989b6d23 100644
> --- a/lib/librte_eal/linuxapp/unci/unci_net.c
> +++ b/lib/librte_eal/linuxapp/unci/unci_net.c
> @@ -74,6 +74,12 @@ static struct rtnl_link_ops unci_link_ops __read_mostly
> = {
> 
>  static int __init unci_init(void)
>  {
> +	int ret;
> +
> +	ret = unci_nl_init();
> +	if (ret)
> +		return ret;
> +
>  	return rtnl_link_register(&unci_link_ops);
>  }
>  module_init(unci_init);
> @@ -81,6 +87,7 @@ module_init(unci_init);  static void __exit
> unci_exit(void)  {
>  	rtnl_link_unregister(&unci_link_ops);
> +	unci_nl_release();
>  }
>  module_exit(unci_exit);
> 
> diff --git a/lib/librte_eal/linuxapp/unci/unci_nl.c
> b/lib/librte_eal/linuxapp/unci/unci_nl.c
> new file mode 100644
> index 000000000..1461a3309
> --- /dev/null
> +++ b/lib/librte_eal/linuxapp/unci/unci_nl.c
> @@ -0,0 +1,72 @@
> +/*-
> + * GPL LICENSE SUMMARY
> + *
> + *   Copyright(c) 2017 Intel Corporation. All rights reserved.
> + *
> + *   This program is free software; you can redistribute it and/or modify
> + *   it under the terms of version 2 of the GNU General Public License as
> + *   published by the Free Software Foundation.
> + *
> + *   This program is distributed in the hope that it will be useful, but
> + *   WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> GNU
> + *   General Public License for more details.
> + *
> + *   You should have received a copy of the GNU General Public License
> + *   along with this program;
> + *   The full GNU General Public License is included in this distribution
> + *   in the file called LICENSE.GPL.
> + *
> + *   Contact Information:
> + *   Intel Corporation
> + */

Again, GPL-only, but the module says it's dual BSD-GPL (and some files indeed are licensed under dual license).

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v10 11/20] unci: add netlink exec
  2017-07-05 19:07         ` Stephen Hemminger
@ 2017-07-06 10:45           ` Ferruh Yigit
  2017-07-07  0:25             ` Stephen Hemminger
  0 siblings, 1 reply; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-06 10:45 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, Bruce Richardson, Anatoly Burakov

On 7/5/2017 8:07 PM, Stephen Hemminger wrote:
> On Tue,  4 Jul 2017 17:13:28 +0100
> Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> 
>> +int unci_nl_exec(u32 cmd, struct net_device *dev, void *in_data,
>> +		size_t in_data_len, void *out_data, size_t out_data_len)
>> +{
>> +	struct unci_dev *unci = netdev_priv(dev);
>> +	int err = -EINVAL;
>> +	int ret;
>> +
>> +	if (out_data_len > UNCI_NL_MSG_LEN) {
>> +		pr_err("Message is too big to receive:%zu\n", out_data_len);
>> +		return err;
>> +	}
>> +
>> +	mutex_lock(&sync_lock);
>> +	ret = unci_response_buffer_register(cmd, out_data, out_data_len,
>> +			&unci->msg_received, &err);
>> +	if (ret) {
>> +		mutex_unlock(&sync_lock);
>> +		return -EINVAL;
>> +	}
>> +
>> +	ret = unci_nl_send(cmd, unci->port_id, unci->pid, in_data, in_data_len);
>> +	if (ret) {
>> +		unci_response_buffer_unregister(response_buffer.magic);
>> +		mutex_unlock(&sync_lock);
>> +		return ret;
>> +	}
>> +
>> +	ret = wait_for_completion_interruptible_timeout(&unci->msg_received,
>> +			 msecs_to_jiffies(UNCI_CMD_TIMEOUT));
> 
> Blocking for completion with mutex held? 
> Sleeping with mutex held is not allowed in Linux.
> 
> You will see this if you run with lockdep and all the other kernel debug
> config options.

Thank you for the review,

I will send a new version addressing all comments.

Thanks,
ferruh

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v10 11/20] unci: add netlink exec
  2017-07-06 10:45           ` Ferruh Yigit
@ 2017-07-07  0:25             ` Stephen Hemminger
  0 siblings, 0 replies; 91+ messages in thread
From: Stephen Hemminger @ 2017-07-07  0:25 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Bruce Richardson, Anatoly Burakov

On Thu, 6 Jul 2017 11:45:48 +0100
Ferruh Yigit <ferruh.yigit@intel.com> wrote:

>  
> > Blocking for completion with mutex held? 
> > Sleeping with mutex held is not allowed in Linux.
> > 
> > You will see this if you run with lockdep and all the other kernel debug
> > config options.  
> 
> Thank you for the review,
> 
> I will send a new version addressing all comments.
> 
> Thanks,
> ferruh
> 

I was wrong, it is okay to sleep with mutex held.
You might find it easier to use a spin_lock and waitqueue directly
via wait_event_interruptible_locked

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v10 20/20] ethdev: add control interface support
  2017-07-04 16:13       ` [PATCH v10 20/20] ethdev: add control interface support Ferruh Yigit
@ 2017-07-08  6:28         ` Yuanhan Liu
  2017-07-20 14:55           ` Ferruh Yigit
  0 siblings, 1 reply; 91+ messages in thread
From: Yuanhan Liu @ 2017-07-08  6:28 UTC (permalink / raw)
  To: Ferruh Yigit
  Cc: dev, Stephen Hemminger, Bruce Richardson, Anatoly Burakov,
	Thomas Monjalon

On Tue, Jul 04, 2017 at 05:13:37PM +0100, Ferruh Yigit wrote:
> @@ -157,8 +164,12 @@ rte_eth_dev_pci_generic_probe(struct rte_pci_device *pci_dev,
>  
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
>  	ret = dev_init(eth_dev);
> -	if (ret)
> +	if (ret) {
>  		rte_eth_dev_pci_release(eth_dev);
> +		return ret;
> +	}
> +
> +	rte_eth_control_interface_create(eth_dev->data->port_id);

Hi,

So you are creating a virtual kernel interface for each PCI port. What
about the VDEVs? If you plan to create one for each port, why not create
it at the stage while allocating the eth device, or at the stage while
starting the port if the former is too earlier?

Another thing comes to my mind is have you tried it with multi-process
model? Looks like it will create the control interface twice? Or it will
just be failed since the interface already exists?


I also have few questions regarding the whole design. So seems that the
ctrl_if only exports two APIs and they all will be only used in the EAL
layer. Thus, one question is did you plan to let APP use them? Judging
EAL already calls them automatically, I don't think it makes sense to
let the APP call it again. That being said, what's the point of the making
it be an lib? Why not just put it under EAL or somewhere else, and let
EAL invoke it as normal helper functions (instead of by public APIs)?

I will avoid adding a new lib if possible. Otherwise, it increases the
chance of ABI/API breakage is needed in future for extensions.

The same question goes to the ethtool lib. Since your solution can work
well with the well-known ethtool, which is also way more widely available
than the DPDK ethtool app, what's the point of keeping the ethtool app
then? Like above, I also don't think those APIs are meant for APPs (or
are they?). Thus, with the ethtool app removed, we then could again avoid
introducing a new lib.

	--yliu

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH v10 20/20] ethdev: add control interface support
  2017-07-08  6:28         ` Yuanhan Liu
@ 2017-07-20 14:55           ` Ferruh Yigit
  0 siblings, 0 replies; 91+ messages in thread
From: Ferruh Yigit @ 2017-07-20 14:55 UTC (permalink / raw)
  To: Yuanhan Liu
  Cc: dev, Stephen Hemminger, Bruce Richardson, Anatoly Burakov,
	Thomas Monjalon

On 7/8/2017 7:28 AM, Yuanhan Liu wrote:
> On Tue, Jul 04, 2017 at 05:13:37PM +0100, Ferruh Yigit wrote:
>> @@ -157,8 +164,12 @@ rte_eth_dev_pci_generic_probe(struct rte_pci_device *pci_dev,
>>  
>>  	RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
>>  	ret = dev_init(eth_dev);
>> -	if (ret)
>> +	if (ret) {
>>  		rte_eth_dev_pci_release(eth_dev);
>> +		return ret;
>> +	}
>> +
>> +	rte_eth_control_interface_create(eth_dev->data->port_id);
> 
> Hi,
> 
> So you are creating a virtual kernel interface for each PCI port. What
> about the VDEVs? If you plan to create one for each port, why not create
> it at the stage while allocating the eth device, or at the stage while
> starting the port if the former is too earlier?

Technically it is possible to support vdevs, but I don't know if there
is usecase for it. If this is required, the change is simple, as you
said this can be possible by moving create API to port start.

> 
> Another thing comes to my mind is have you tried it with multi-process
> model? Looks like it will create the control interface twice? Or it will
> just be failed since the interface already exists?

I didn't test mult-process scenarios, I will test.

> 
> 
> I also have few questions regarding the whole design. So seems that the
> ctrl_if only exports two APIs and they all will be only used in the EAL
> layer. Thus, one question is did you plan to let APP use them? Judging
> EAL already calls them automatically, I don't think it makes sense to
> let the APP call it again. That being said, what's the point of the making
> it be an lib? Why not just put it under EAL or somewhere else, and let
> EAL invoke it as normal helper functions (instead of by public APIs)?

Public APIs are from previous version of the patchset, where user
application was in control on create/destroy and processing messages.
With interfaces automatically created as you said these APIs are not
very meaningful for application.

But code is not so small to put into another library, I believe it is
good to separate this code.

> 
> I will avoid adding a new lib if possible. Otherwise, it increases the
> chance of ABI/API breakage is needed in future for extensions.

Those API are required for other libraries, not sure how to include the
code otherwise.

> 
> The same question goes to the ethtool lib. Since your solution can work
> well with the well-known ethtool, which is also way more widely available
> than the DPDK ethtool app, what's the point of keeping the ethtool app
> then? Like above, I also don't think those APIs are meant for APPs (or
> are they?). Thus, with the ethtool app removed, we then could again avoid
> introducing a new lib.

Ethtool library is ready to use abstraction on ethdev layer, I don't
insist on having it as a separate library, but I believe it is good to
reuse that code instead of re-writing it.

> 
> 	--yliu
> 

^ permalink raw reply	[flat|nested] 91+ messages in thread

end of thread, other threads:[~2017-07-20 14:55 UTC | newest]

Thread overview: 91+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-26 16:52 [RFC] Kernel Control Path (KCP) Ferruh Yigit
2017-05-28 16:55 ` Wiles, Keith
2017-05-29  9:26   ` Bruce Richardson
2017-05-29 17:29     ` Wiles, Keith
2017-06-16 15:54   ` Ferruh Yigit
2017-06-20 12:33     ` Ferruh Yigit
2017-05-30 10:55 ` Thomas Monjalon
2017-06-13 17:21   ` Ferruh Yigit
2017-06-13 18:00     ` Jay Rolette
2017-06-13 18:04       ` Dumitrescu, Cristian
2017-06-13 18:18         ` Wiles, Keith
2017-06-15 12:07           ` Alex Rosenbaum
2017-06-16 15:27             ` Ferruh Yigit
2017-06-16 16:48               ` Stephen Hemminger
2017-06-13 18:17       ` Wiles, Keith
2017-06-21 11:06 ` [PATCH v8 0/4] Userspace Network Control Interface (UNCI) Ferruh Yigit
2017-06-21 11:06   ` [PATCH v8 1/4] ethtool: move from sample folder to lib folder Ferruh Yigit
2017-06-26 11:02     ` Bruce Richardson
2017-06-21 11:06   ` [PATCH v8 2/4] unci: add kernel control path kernel module Ferruh Yigit
2017-06-21 15:23     ` Stephen Hemminger
2017-06-30 17:02       ` Ferruh Yigit
2017-06-21 11:06   ` [PATCH v8 3/4] rte_ctrl_if: add control interface library Ferruh Yigit
2017-06-26 11:09     ` Bruce Richardson
2017-06-26 11:30     ` Bruce Richardson
2017-06-21 11:06   ` [PATCH v8 4/4] ethdev: add control interface support Ferruh Yigit
2017-06-21 15:24     ` Stephen Hemminger
2017-06-30 17:06       ` Ferruh Yigit
2017-06-26 11:39   ` [PATCH v8 0/4] Userspace Network Control Interface (UNCI) Bruce Richardson
2017-06-29 16:13     ` Ferruh Yigit
2017-06-30 16:56       ` Ferruh Yigit
2017-06-30 16:51   ` [PATCH v9 00/20] " Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 01/20] ethtool: add library skeleton Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 02/20] ethtool: move from sample folder into lib folder Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 03/20] ethtool: remove PMD specific API call Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 04/20] ethtool: update header doxygen syntax Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 05/20] ethtool: enable library Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 06/20] doc: add ethtool library documentation Ferruh Yigit
2017-07-02 20:18       ` Mcnamara, John
2017-06-30 16:51     ` [PATCH v9 07/20] doc: update ethtool sample app doc Ferruh Yigit
2017-07-02 20:17       ` Mcnamara, John
2017-06-30 16:51     ` [PATCH v9 08/20] unci: add module skeleton Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 09/20] unci: add rtnl newlink Ferruh Yigit
2017-06-30 17:27       ` Stephen Hemminger
2017-06-30 16:51     ` [PATCH v9 10/20] unci: init netlink Ferruh Yigit
2017-06-30 17:28       ` Stephen Hemminger
2017-06-30 17:29       ` Stephen Hemminger
2017-06-30 16:51     ` [PATCH v9 11/20] unci: add netlink exec Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 12/20] unci: add netdevice ops Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 13/20] unci: add ethtool support Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 14/20] ctrl_if: add library skeleton Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 15/20] ctrl_if: add create destroy interface APIs Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 16/20] ctrl_if: initialize netlink interface Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 17/20] ctrl_if: process control messages Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 18/20] ctrl_if: process ethtool messages Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 19/20] doc: add control interface library documentation Ferruh Yigit
2017-07-02 20:16       ` Mcnamara, John
2017-06-30 16:51     ` [PATCH v9 20/20] ethdev: add control interface support Ferruh Yigit
2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 01/20] ethtool: add library skeleton Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 02/20] ethtool: move from sample folder into lib folder Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 03/20] ethtool: remove PMD specific API call Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 04/20] ethtool: update header doxygen syntax Ferruh Yigit
2017-07-06  9:18         ` Burakov, Anatoly
2017-07-04 16:13       ` [PATCH v10 05/20] ethtool: enable library Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 06/20] doc: add ethtool library documentation Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 07/20] doc: update ethtool sample app doc Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 08/20] unci: add module skeleton Ferruh Yigit
2017-07-06  9:25         ` Burakov, Anatoly
2017-07-04 16:13       ` [PATCH v10 09/20] unci: add rtnl newlink Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 10/20] unci: init netlink Ferruh Yigit
2017-07-06  9:32         ` Burakov, Anatoly
2017-07-04 16:13       ` [PATCH v10 11/20] unci: add netlink exec Ferruh Yigit
2017-07-05 19:07         ` Stephen Hemminger
2017-07-06 10:45           ` Ferruh Yigit
2017-07-07  0:25             ` Stephen Hemminger
2017-07-05 19:15         ` Stephen Hemminger
2017-07-04 16:13       ` [PATCH v10 12/20] unci: add netdevice ops Ferruh Yigit
2017-07-05 19:12         ` Stephen Hemminger
2017-07-05 19:12         ` Stephen Hemminger
2017-07-04 16:13       ` [PATCH v10 13/20] unci: add ethtool support Ferruh Yigit
2017-07-05 19:07         ` Stephen Hemminger
2017-07-05 19:08         ` Stephen Hemminger
2017-07-04 16:13       ` [PATCH v10 14/20] ctrl_if: add library skeleton Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 15/20] ctrl_if: add create destroy interface APIs Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 16/20] ctrl_if: initialize generic netlink interface Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 17/20] ctrl_if: process control messages Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 18/20] ctrl_if: process ethtool messages Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 19/20] doc: add control interface library documentation Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 20/20] ethdev: add control interface support Ferruh Yigit
2017-07-08  6:28         ` Yuanhan Liu
2017-07-20 14:55           ` Ferruh Yigit

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.