Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next V2 3/3] net: Add GRO support for vxlan traffic
From: Tom Herbert @ 2014-01-07 18:08 UTC (permalink / raw)
  To: Or Gerlitz
  Cc: Jerry Chu, Eric Dumazet, Herbert Xu, Linux Netdev List,
	David Miller, Yan Burman, Shlomo Pongratz
In-Reply-To: <1389108594-665-4-git-send-email-ogerlitz@mellanox.com>

On Tue, Jan 7, 2014 at 7:29 AM, Or Gerlitz <ogerlitz@mellanox.com> wrote:
> Add gro handlers for vxlan using the udp gro infrastructure
>
> On my setup, which is net-next (now with the mlx4 vxlan offloads patches) --
> for single TCP session that goes through vxlan tunneling I got nice improvement
> from 6.8Gbs to 11.5Gbs
>
> --> UDP/VXLAN GRO disabled
> $ netperf  -H 192.168.52.147 -c -C
>
> $ netperf -t TCP_STREAM -H 192.168.52.147 -c -C
> MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.52.147 () port 0 AF_INET
> Recv   Send    Send                          Utilization       Service Demand
> Socket Socket  Message  Elapsed              Send     Recv     Send    Recv
> Size   Size    Size     Time     Throughput  local    remote   local   remote
> bytes  bytes   bytes    secs.    10^6bits/s  % S      % S      us/KB   us/KB
>
>  87380  65536  65536    10.00      6799.75   12.54    24.79    0.604   1.195
>
> --> UDP/VXLAN GRO enabled
>
> $ netperf -t TCP_STREAM -H 192.168.52.147 -c -C
> MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.52.147 () port 0 AF_INET
> Recv   Send    Send                          Utilization       Service Demand
> Socket Socket  Message  Elapsed              Send     Recv     Send    Recv
> Size   Size    Size     Time     Throughput  local    remote   local   remote
> bytes  bytes   bytes    secs.    10^6bits/s  % S      % S      us/KB   us/KB
>
>  87380  65536  65536    10.00      11562.72   24.90    20.34    0.706   0.577
>
> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
> ---
>  drivers/net/vxlan.c |  101 ++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 99 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
> index 481f85d..b51823b 100644
> --- a/drivers/net/vxlan.c
> +++ b/drivers/net/vxlan.c
> @@ -40,6 +40,7 @@
>  #include <net/net_namespace.h>
>  #include <net/netns/generic.h>
>  #include <net/vxlan.h>
> +#include <net/protocol.h>
>  #if IS_ENABLED(CONFIG_IPV6)
>  #include <net/ipv6.h>
>  #include <net/addrconf.h>
> @@ -554,6 +555,98 @@ static int vxlan_fdb_append(struct vxlan_fdb *f,
>         return 1;
>  }
>
> +static struct sk_buff **vxlan_gro_receive(struct sk_buff **head, struct sk_buff *skb)
> +{
> +       struct sk_buff *p, **pp = NULL;
> +       struct vxlanhdr *vh, *vh2;
> +       struct ethhdr *eh;
> +       unsigned int hlen, off, off_eth;
> +       const struct packet_offload *ptype;
> +       __be16 type;
> +       int flush = 1;
> +
> +       off  = skb_gro_offset(skb);
> +       hlen = off + sizeof(*vh);
> +       vh   = skb_gro_header_fast(skb, off);
> +       if (skb_gro_header_hard(skb, hlen)) {
> +               vh = skb_gro_header_slow(skb, hlen, off);
> +               if (unlikely(!vh))
> +                       goto out;
> +       }
> +
> +       flush = 0;
> +
> +       for (p = *head; p; p = p->next) {
> +               if (!NAPI_GRO_CB(p)->same_flow)
> +                       continue;
> +
> +               vh2 = (struct vxlanhdr   *)(p->data + off);
> +               if (vh->vx_vni ^ vh2->vx_vni) {

Why ^ instead of != ?

> +                       NAPI_GRO_CB(p)->same_flow = 0;
> +                       continue;
> +               }
> +               goto found;
> +       }
> +
> +found:
> +       skb_gro_pull(skb, sizeof(struct vxlanhdr)); /* pull vxlan header */
> +
> +       off_eth = skb_gro_offset(skb);
> +       hlen = off_eth + sizeof(*eh);
> +       eh   = skb_gro_header_fast(skb, off_eth);
> +       if (skb_gro_header_hard(skb, hlen)) {
> +               eh = skb_gro_header_slow(skb, hlen, off_eth);
> +               if (unlikely(!eh))
> +                       goto out;
> +       }
> +       type = eh->h_proto;
> +
> +       rcu_read_lock();
> +       ptype = gro_find_receive_by_type(type);
> +       if (ptype == NULL) {
> +               flush = 1;
> +               goto out_unlock;
> +       }
> +
> +       skb_gro_pull(skb, sizeof(*eh)); /* pull inner eth header */
> +       pp = ptype->callbacks.gro_receive(head, skb);
> +
> +out_unlock:
> +       rcu_read_unlock();
> +out:
> +       NAPI_GRO_CB(skb)->flush |= flush;
> +
> +       return pp;
> +}
> +
> +static int vxlan_gro_complete(struct sk_buff *skb, int nhoff)
> +{
> +       struct ethhdr *eh;
> +       struct packet_offload *ptype;
> +       __be16 type;
> +       /* 22 = 8 bytes for the vlxan header + 14 bytes for the inner eth header */
> +       int vxlan_len  = 22;
> +       int err = -ENOSYS;
> +
> +       eh = (struct ethhdr *)(skb->data + nhoff + sizeof (struct vxlanhdr));
> +       type = eh->h_proto;
> +
> +       rcu_read_lock();
> +       ptype = gro_find_complete_by_type(type);
> +       if (ptype != NULL)
> +               err = ptype->callbacks.gro_complete(skb, nhoff + vxlan_len);
> +
> +       rcu_read_unlock();
> +       return err;
> +}
> +
> +static const struct net_offload vxlan_offload = {
> +       .callbacks = {
> +               .gro_receive  = vxlan_gro_receive,
> +               .gro_complete = vxlan_gro_complete,
> +       },
> +};
> +
>  /* Notify netdevs that UDP port started listening */
>  static void vxlan_notify_add_rx_port(struct sock *sk)
>  {
> @@ -568,6 +661,8 @@ static void vxlan_notify_add_rx_port(struct sock *sk)
>                         dev->netdev_ops->ndo_add_vxlan_port(dev, sa_family,
>                                                             port);
>         }
> +       if (sa_family == AF_INET)
> +               udp_add_offload(&vxlan_offload, port);
>         rcu_read_unlock();
>  }
>
> @@ -585,6 +680,8 @@ static void vxlan_notify_del_rx_port(struct sock *sk)
>                         dev->netdev_ops->ndo_del_vxlan_port(dev, sa_family,
>                                                             port);
>         }
> +       if (sa_family == AF_INET)
> +               udp_del_offload(&vxlan_offload, port);
>         rcu_read_unlock();
>  }
>
> @@ -1125,8 +1222,8 @@ static void vxlan_rcv(struct vxlan_sock *vs,
>          * leave the CHECKSUM_UNNECESSARY, the device checksummed it
>          * for us. Otherwise force the upper layers to verify it.
>          */
> -       if (skb->ip_summed != CHECKSUM_UNNECESSARY || !skb->encapsulation ||
> -           !(vxlan->dev->features & NETIF_F_RXCSUM))
> +       if ((skb->ip_summed != CHECKSUM_UNNECESSARY && skb->ip_summed != CHECKSUM_PARTIAL) ||
> +           !skb->encapsulation || !(vxlan->dev->features & NETIF_F_RXCSUM))
>                 skb->ip_summed = CHECKSUM_NONE;
>
>         skb->encapsulation = 0;
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH net-next 0/2] Pack struct xfrm_usersa_info and struct xfrm_userpolicy_info
From: David Miller @ 2014-01-07 18:07 UTC (permalink / raw)
  To: fan.du; +Cc: steffen.klassert, stephen, dev, netdev
In-Reply-To: <1389077339-12814-1-git-send-email-fan.du@windriver.com>

From: Fan Du <fan.du@windriver.com>
Date: Tue, 7 Jan 2014 14:48:57 +0800

> When trying to setup IPsec configuration on a 64bits host with
> iproute2(32bits compiled), the intened xfrm policy and sa is
> either deficit or wrong when kernel trying to parse user land
> information.

You can't make this change without breaking userspace.

We'll have to translate the data structures somehow with a compat
layer like we have for 32/64 bit compatability for system calls.

^ permalink raw reply

* Re: [PATCH net v2 1/9] bridge: Fix the way to find old local fdb entries in br_fdb_changeaddr
From: Vlad Yasevich @ 2014-01-07 17:45 UTC (permalink / raw)
  To: Toshiaki Makita
  Cc: Toshiaki Makita, David S . Miller, Stephen Hemminger, netdev
In-Reply-To: <1389112385.1751.17.camel@localhost.localdomain>

On 01/07/2014 11:33 AM, Toshiaki Makita wrote:
> On Tue, 2014-01-07 at 09:44 -0500, Vlad Yasevich wrote:
>> On 01/07/2014 07:42 AM, Toshiaki Makita wrote:
>>> On Mon, 2014-01-06 at 06:29 -0500, Vlad Yasevich wrote:
>>>> On 01/05/2014 10:26 AM, Toshiaki Makita wrote:
>>>>> On Fri, 2014-01-03 at 15:46 -0500, Vlad Yasevich wrote:
>>>>>> On 01/03/2014 02:28 PM, Vlad Yasevich wrote:
>>>>>>> On 12/17/2013 07:03 AM, Toshiaki Makita wrote:
>>>>>>>> br_fdb_changeaddr() assumes that there is at most one local entry per port
>>>>>>>> per vlan. It used to be true, but since commit 36fd2b63e3b4 ("bridge: allow
>>>>>>>> creating/deleting fdb entries via netlink"), it has not been so.
>>>>>>>> Therefore, the function might fail to search a correct previous address
>>>>>>>> to be deleted and delete an arbitrary local entry if user has added local
>>>>>>>> entries manually.
>>>>>>>>
>>>>>>>> Example of problematic case:
>>>>>>>>   ip link set eth0 address ee:ff:12:34:56:78
>>>>>>>>   brctl addif br0 eth0
>>>>>>>>   bridge fdb add 12:34:56:78:90:ab dev eth0 master
>>>>>>>>   ip link set eth0 address aa:bb:cc:dd:ee:ff
>>>>>>>> Then, the address 12:34:56:78:90:ab might be deleted instead of
>>>>>>>> ee:ff:12:34:56:78, the original mac address of eth0.
>>>>>>>>
>>>>>>>> Address this issue by introducing a new flag, added_by_user, to struct
>>>>>>>> net_bridge_fdb_entry.
>>>>>>>>
>>>>>>>> Note that br_fdb_delete_by_port() has to set added_by_user to 0 in case
>>>>>>>> like:
>>>>>>>>   ip link set eth0 address 12:34:56:78:90:ab
>>>>>>>>   ip link set eth1 address aa:bb:cc:dd:ee:ff
>>>>>>>>   brctl addif br0 eth0
>>>>>>>>   bridge fdb add aa:bb:cc:dd:ee:ff dev eth0 master
>>>>>>>>   brctl addif br0 eth1
>>>>>>>>   brctl delif br0 eth0
>>>>>>>> In this case, kernel should delete the user-added entry aa:bb:cc:dd:ee:ff,
>>>>>>>> but it also should have been added by "brctl addif br0 eth1" originally,
>>>>>>>> so we don't delete it and treat it a new kernel-created entry.
>>>>>>>>
>>>>>>>
>>>>>>> I was looking over my patch series that adds something similar to this
>>>>>>> and noticed that you are not handing the NTF_USE case.  That case was
>>>>>>> always troublesome for me as it allows for 2 different way to create
>>>>>>> the same FDB: one through br_fdb_update() and one through fdb_add_entry().
>>>>>>>
>>>>>>> It is possible, though I haven't found any users yet, that NTF_USE
>>>>>>> may be used and in that case, bridge will create a dynamic fdb and
>>>>>>> disregard all NUD flags.  In case case, add_by_user will not be set
>>>>>>> either.
>>>>>>>
>>>>>>> I think that the above is broken and plan to submit a fix shortly.
>>>>>>
>>>>>> Just looked again at my NTF_USE patch and while it seems ok, the whole
>>>>>> NTF_USE usage is racy to begin with and I am really starting to question
>>>>>> it's validity.
>>>>>>
>>>>>> Presently, br_fdb_update() will not update local fdb entries.   Instead
>>>>>> it will log a misleading warning...  It will only let you update
>>>>>> non-local entries.  This is fine for user-created entries, but any
>>>>>> operation on dynamically created entries will only persist until
>>>>>> the next packet.  It also races against the packet, so there is
>>>>>> absolutely no guarantee that the values of fdb->dst and fdb->updated
>>>>>> will be consistent..
>>>>>>
>>>>>> It seems to me that the update capability of NTF_USE would actually be
>>>>>> of more value on local or user-created fdb entries.
>>>>>>
>>>>>> The fdb creation capability of NTF_USE should be disabled.
>>>>>>
>>>>>> Thoughts?
>>>>>
>>>>> I ignored NTF_USE in this patch because I regard it as emulating kernel
>>>>> creating entries after investigating git log.
>>>>>
>>>>> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=0c5c2d3089068d4aa378f7a40d2b5ad9d4f52ce8
>>>>> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=292d1398983f3514a0eab13b7606df7f4730b498
>>>>>
>>>>> So I think NTF_USE shouldn't set added_by_user.
>>>>> And to emulate kernel creating entries, simply calling br_fdb_update()
>>>>> is the right way, isn't it?
>>>>
>>>> You can create dynamic entries (emulating the kernel) without NTF_USE.
>>>> Just set the NUD_REACHABLE.  Notice that arp cache only uses NTF_USE
>>>> to trigger and arp notification.  The creation is still triggered via
>>>> other netlink flags.
>>>>
>>>> The more I look at this the more I think NTF_USE should not create
>>>> an entry all by itself.
>>>
>>> I haven't fully understood you yet.
>>> Currently NTF_USE behaves as if the port receives a frame and it seems
>>> to work, though the ability to create entries is different from neigh
>>> subsystem.
>>> Why do you want to change the behavior?
>>> Are you worried about inconsistency of NLM-flags/NUD-state with NTF_USE
>>> between neigh and bridge?
>>
>> No, it is inconsistent with other NLM/NUD-state within bridge.  As
>> an fdb creation flag NTF_USE is confusing.  It will create an entry
>> without NLM_F_CREATE being set.  It will ignore NLM_F_EXCL flag as
>> well.  It will additionally ignore any NUD-state flags that may be set
>> in the netlink message.  So it may not be doing what the user wishes.
> 
> I don't know which of NTF-flags and NLM-flags/NUD-state should be given
> high priority on setting. For now, in bridge, NTF_USE masks any other
> flags. If this is not proper way for netlink/neighbour, I will agree
> with you. If not sure, I have no motivation to change existing behavior
> that might be expected by some users.
> 
>>
>> It also provides duplicate functionality.  The same results are achieved
>> by setting NLM_F_CREATE flag and NUD_REACHABLE state in the message.
> 
> br_fdb_update() never updates fdb->used, which is visible by user,
> unlike fdb_add_entry().

Thanks for pointing this out.  It looks like there are some
inconsistencies in the fdb->used markings as well.

> 
> If it is duplicate functionality, isn't NTF_USE itself no use?
> What can be achieved by changing capability of creation and update of
> local entries?

Update of local entries gives you port redirection, but doing it under
rcu.  Not sure if it really makes much sense though...

NTF_USE makes since for neighbor cache as it triggers an ARP and a
refresh of the entry.  Suppose, NTF_USE on the fdb entry should
trigger a refresh as well, but causing a create has to be explicit.

I think I'll just send my patch and we can continue this discussion
there.

-vlad
> 
> Thanks,
> Toshiaki Makita
> 

^ permalink raw reply

* Re: Multicast routing stops functioning after 4G multicast packets recived.
From: Hannes Frederic Sowa @ 2014-01-07 17:43 UTC (permalink / raw)
  To: Bob Falken; +Cc: Julian Anastasov, netdev
In-Reply-To: <20140107170145.317040@gmx.com>

On Tue, Jan 07, 2014 at 06:01:44PM +0100, Bob Falken wrote:
> Hello,
> 
> I patched, kernel 3.2.53 yesterday,
> 8774002632packets, and ~9.1TB later, the multicast routing seems to function properly. :)
> 
> Kudos for fixing this.
> 
> I will keep checking the next days.
> 
> As for IPv6 MR, my current setup i.e: the Multicast source, does not support IPv6, so cannot do a check for that natively.
> 
> Unless I can translate IPv4 multicast into IPv6 multicast easily, using some iptable prerouting rules(?).

Thank you for testing!

I'll review the RCU regions again and will prepare the patches (before
introduction of ebc0ffae5dfb44 ("fib: RCU conversion of fib_lookup()")
and after.

^ permalink raw reply

* Re: [PATCH v3 2/6] net: rfkill: gpio: convert to descriptor-based GPIO interface
From: Linus Walleij @ 2014-01-07 17:43 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Mika Westerberg, David S. Miller, linux-netdev,
	netdev@vger.kernel.org, ACPI Devel Maling List, Rafael J. Wysocki,
	Chris Ball, Rhyland Klein, Adrian Hunter, Alexandre Courbot,
	Mathias Nyman, Rob Landley, Heikki Krogerus, Stephen Warren,
	Thierry Reding, linux-gpio@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <1387833287.4412.6.camel@jlt4.sipsolutions.net>

On Mon, Dec 23, 2013 at 10:14 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Mon, 2013-12-23 at 12:54 +0200, Mika Westerberg wrote:
>> On Wed, Dec 11, 2013 at 01:00:18PM +0100, Linus Walleij wrote:
>> > On Tue, Nov 26, 2013 at 11:05 AM, Mika Westerberg
>> > <mika.westerberg@linux.intel.com> wrote:
>> >
>> > > From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
>> > >
>> > > Convert to the safer gpiod_* family of API functions.
>> > >
>> > > Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
>> > > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
>> > > Tested-by: Stephen Warren <swarren@nvidia.com>
>>
>> Johannes B, David M,
>>
>> Are you fine with this patch? If yes, could you ack it so that we could get
>> it merged for 3.14.
>
> I have no objection to this particular patch. I can't really comment on
> it, but I never really delved too deeply into the rfkill-gpio thing - I
> guess it works for whoever needed it :)

I take that as an ACK ;-)

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply

* Re: Multicast routing stops functioning after 4G multicast packets recived.
From: Bob Falken @ 2014-01-07 17:01 UTC (permalink / raw)
  To: Hannes Frederic Sowa, Julian Anastasov; +Cc: netdev

Hello,

I patched, kernel 3.2.53 yesterday,
8774002632packets, and ~9.1TB later, the multicast routing seems to function properly. :)

Kudos for fixing this.

I will keep checking the next days.

As for IPv6 MR, my current setup i.e: the Multicast source, does not support IPv6, so cannot do a check for that natively.

Unless I can translate IPv4 multicast into IPv6 multicast easily, using some iptable prerouting rules(?).

Thanks again.


----- Original Message -----
From: Hannes Frederic Sowa
Sent: 01/05/14 12:38 AM
To: Julian Anastasov
Subject: Re: Multicast routing stops functioning after 4G multicast packets recived.
 On Sat, Jan 04, 2014 at 09:55:51PM +0200, Julian Anastasov wrote:
> 
> Hello,
> 
> On Thu, 19 Dec 2013, Bob Falken wrote:
> 
> > Hello, I have an issue after kernel 2.6.37 and above.
> > If i roll back to kernel 2.6.36.4 everything is fine.
> > if recive more than 4294967295 multicast packets, the kernel does not register the multicast packets. and multicast routing does not functioning.
> 
> ...
> 
> > I think there might be a variable in the kernel that get overflown. though i cannot be sure as im not a programmer. 
> > 
> > Let me know if you need more debug information.
> > 
> > Please help.  
> 
> As Hannes guessed, may be it is really the missing
> flags = FIB_LOOKUP_NOREF in ipmr_fib_lookup() when calling
> fib_rules_lookup(), we have an atomic_inc_not_zero() there that
> can stop to work after 4G lookups when rule's refcnt reaches 0.
> As result, fib_rules_lookup() can start to return -ESRCH.

I guess we should just try. I somehow forgot to look after that. Thanks
for reminding, Julian.

Bob, can you try with this patch again?

diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 421a249..b9b3472 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -157,9 +157,12 @@ static struct mr_table *ipmr_get_table(struct net *net, u32 id)
 static int ipmr_fib_lookup(struct net *net, struct flowi4 *flp4,
 struct mr_table **mrt)
 {
- struct ipmr_result res;
- struct fib_lookup_arg arg = { .result = &res};
 int err;
+ struct ipmr_result res;
+ struct fib_lookup_arg arg = {
+ .result = &res,
+ .flags = FIB_LOOKUP_NOREF,
+ };
 
 err = fib_rules_lookup(net->ipv4.mr_rules_ops,
 flowi4_to_flowi(flp4), 0, &arg); 

^ permalink raw reply related

* [PATCH] ixgbevf: delete unneeded call to pci_set_power_state
From: Julia Lawall @ 2014-01-07 17:00 UTC (permalink / raw)
  To: Jeff Kirsher
  Cc: e1000-devel, kernel-janitors, Bruce Allan, Jesse Brandeburg,
	linux-kernel, John Ronciak, netdev

From: Julia Lawall <Julia.Lawall@lip6.fr>

This driver does not need to adjust the power state on suspend, so the
call to pci_set_power_state in the resume function is a no-op.  Drop it, to
make the code more understandable.

Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>

---
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index a5d3167..5709fb0 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -3226,7 +3226,6 @@ static int ixgbevf_resume(struct pci_dev *pdev)
 	struct net_device *netdev = adapter->netdev;
 	u32 err;
 
-	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 	/*
 	 * pci_restore_state clears dev->state_saved so call


------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel&#174; Ethernet, visit http://communities.intel.com/community/wired

^ permalink raw reply related

* Re: [PATCH net-next V2 0/3] net: Add GRO support for UDP encapsulating protocols
From: Eric Dumazet @ 2014-01-07 16:45 UTC (permalink / raw)
  To: Or Gerlitz; +Cc: hkchu, edumazet, herbert, netdev, davem, yanb, shlomop
In-Reply-To: <1389108594-665-1-git-send-email-ogerlitz@mellanox.com>

On Tue, 2014-01-07 at 17:29 +0200, Or Gerlitz wrote:

> On my setup, which is net-next (now with the mlx4 vxlan offloads patches) -- 
> for single TCP session that goes through vxlan tunneling I got nice improvement
> from 6.8Gbs to 11.5Gbs

It would be nice to check how performance is impacted on a router, using
pktgen to inject UDP traffic on random UDP ports.

^ permalink raw reply

* [PATCH net-next] xen-netback: stop vif thread spinning if frontend is unresponsive
From: Paul Durrant @ 2014-01-07 16:25 UTC (permalink / raw)
  To: netdev, xen-devel; +Cc: Paul Durrant, Wei Liu, Ian Campbell, David Vrabel

The recent patch to improve guest receive side flow control (ca2f09f2) had a
slight flaw in the wait condition for the vif thread in that any remaining
skbs in the guest receive side netback internal queue would prevent the
thread from sleeping. An unresponsive frontend can lead to a permanently
non-empty internal queue and thus the thread will spin. In this case the
thread should really sleep until the frontend becomes responsive again.

This patch adds an extra flag to the vif which is set if the shared ring
is full and cleared when skbs are drained into the shared ring. Thus,
if the thread runs, finds the shared ring full and can make no progress the
flag remains set. If the flag remains set then the thread will sleep,
regardless of a non-empty queue, until the next event from the frontend.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: David Vrabel <david.vrabel@citrix.com>
---
 drivers/net/xen-netback/common.h  |    1 +
 drivers/net/xen-netback/netback.c |   12 ++++++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
index c955fc3..4c76bcb 100644
--- a/drivers/net/xen-netback/common.h
+++ b/drivers/net/xen-netback/common.h
@@ -143,6 +143,7 @@ struct xenvif {
 	char rx_irq_name[IFNAMSIZ+4]; /* DEVNAME-rx */
 	struct xen_netif_rx_back_ring rx;
 	struct sk_buff_head rx_queue;
+	bool rx_queue_stopped;
 	/* Set when the RX interrupt is triggered by the frontend.
 	 * The worker thread may need to wake the queue.
 	 */
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 4f81ac0..1c31ac5 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -477,6 +477,7 @@ static void xenvif_rx_action(struct xenvif *vif)
 	unsigned long offset;
 	struct skb_cb_overlay *sco;
 	int need_to_notify = 0;
+	int ring_full = 0;
 
 	struct netrx_pending_operations npo = {
 		.copy  = vif->grant_copy_op,
@@ -509,6 +510,7 @@ static void xenvif_rx_action(struct xenvif *vif)
 		if (!xenvif_rx_ring_slots_available(vif, max_slots_needed)) {
 			skb_queue_head(&vif->rx_queue, skb);
 			need_to_notify = 1;
+			ring_full = 1;
 			break;
 		}
 
@@ -521,8 +523,13 @@ static void xenvif_rx_action(struct xenvif *vif)
 
 	BUG_ON(npo.meta_prod > ARRAY_SIZE(vif->meta));
 
-	if (!npo.copy_prod)
+	if (!npo.copy_prod) {
+		if (ring_full)
+			vif->rx_queue_stopped = true;
 		goto done;
+	}
+
+	vif->rx_queue_stopped = false;
 
 	BUG_ON(npo.copy_prod > MAX_GRANT_COPY_OPS);
 	gnttab_batch_copy(vif->grant_copy_op, npo.copy_prod);
@@ -1724,7 +1731,8 @@ static struct xen_netif_rx_response *make_rx_response(struct xenvif *vif,
 
 static inline int rx_work_todo(struct xenvif *vif)
 {
-	return !skb_queue_empty(&vif->rx_queue) || vif->rx_event;
+	return (!skb_queue_empty(&vif->rx_queue) && !vif->rx_queue_stopped) ||
+		vif->rx_event;
 }
 
 static inline int tx_work_todo(struct xenvif *vif)
-- 
1.7.10.4

^ permalink raw reply related

* Re: [PATCH net-next] net-gre-gro: Add GRE support to the GRO stack
From: Jerry Chu @ 2014-01-07 16:42 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David Miller, Eric Dumazet, Herbert Xu, Or Gerlitz,
	netdev@vger.kernel.org
In-Reply-To: <1389044441.26646.1.camel@edumazet-glaptop2.roam.corp.google.com>

On Tue, Jan 7, 2014 at 5:40 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Mon, 2014-01-06 at 16:18 -0500, David Miller wrote:
>> From: David Miller <davem@davemloft.net>
>> Date: Mon, 06 Jan 2014 15:43:30 -0500 (EST)
>>
>> > That the gre offload bits won't be registered unless GRE is enabled and
>> > initialized/loaded, right?
>>
>> In fact, it's utterly and completely bogus to make only this change.
>> It breaks the build, I'm reverting:
>>
>> ERROR: "gre_offload_exit" [net/ipv4/gre.ko] undefined!
>> ERROR: "gre_offload_init" [net/ipv4/gre.ko] undefined!
>> --
>
> Jerry, I'll send the patch to do this preparatory work in a small
> and tested unit in the following hour.

Thanks and sorry for breaking the build :(. I knew it was a bad idea
to make a last minute change, especially on something I don't fully
understand, and I did not remember/fully understand all the details/
implication of the two lines in net/ipv4/Makefile:

gre-y := gre_demux.o gre_offload.o
obj-$(CONFIG_NET_IPGRE_DEMUX) += gre.o

Will resubmit the GRE-GRO patch shortly.

Best,

Jerry

>
> Thanks.
>
>

^ permalink raw reply

* Re: [PATCH net-next V2 3/3] net: Add GRO support for vxlan traffic
From: Eric Dumazet @ 2014-01-07 16:34 UTC (permalink / raw)
  To: Or Gerlitz; +Cc: hkchu, edumazet, herbert, netdev, davem, yanb, shlomop
In-Reply-To: <1389108594-665-4-git-send-email-ogerlitz@mellanox.com>

On Tue, 2014-01-07 at 17:29 +0200, Or Gerlitz wrote:
> Add gro handlers for vxlan using the udp gro infrastructure
> 


>  static void vxlan_notify_add_rx_port(struct sock *sk)
>  {
> @@ -568,6 +661,8 @@ static void vxlan_notify_add_rx_port(struct sock *sk)
>  			dev->netdev_ops->ndo_add_vxlan_port(dev, sa_family,
>  							    port);
>  	}
> +	if (sa_family == AF_INET)
> +		udp_add_offload(&vxlan_offload, port);
>  	rcu_read_unlock();
>  }
>  

This means two vxlan tunnels can not share same port.

Is that a valid assertion ?

^ permalink raw reply

* Re: [PATCH net-next V2 1/3] net: Add GRO support for UDP encapsulating protocols
From: Eric Dumazet @ 2014-01-07 16:33 UTC (permalink / raw)
  To: Or Gerlitz; +Cc: hkchu, edumazet, herbert, netdev, davem, yanb, shlomop
In-Reply-To: <1389108594-665-2-git-send-email-ogerlitz@mellanox.com>

On Tue, 2014-01-07 at 17:29 +0200, Or Gerlitz wrote:
>  
> +
> +#define MAX_UDP_PORT (1 << 16)
> +extern const struct net_offload __rcu *udp_offloads[MAX_UDP_PORT];

Thats 512 KB of memory.

This will greatly impact forwarding performance of UDP packets with
random ports, and will increase kernel memory size for embedded devices.

^ permalink raw reply

* Re: [PATCH net v2 1/9] bridge: Fix the way to find old local fdb entries in br_fdb_changeaddr
From: Toshiaki Makita @ 2014-01-07 16:33 UTC (permalink / raw)
  To: vyasevic; +Cc: Toshiaki Makita, David S . Miller, Stephen Hemminger, netdev
In-Reply-To: <52CC12CA.7030001@redhat.com>

On Tue, 2014-01-07 at 09:44 -0500, Vlad Yasevich wrote:
> On 01/07/2014 07:42 AM, Toshiaki Makita wrote:
> > On Mon, 2014-01-06 at 06:29 -0500, Vlad Yasevich wrote:
> >> On 01/05/2014 10:26 AM, Toshiaki Makita wrote:
> >>> On Fri, 2014-01-03 at 15:46 -0500, Vlad Yasevich wrote:
> >>>> On 01/03/2014 02:28 PM, Vlad Yasevich wrote:
> >>>>> On 12/17/2013 07:03 AM, Toshiaki Makita wrote:
> >>>>>> br_fdb_changeaddr() assumes that there is at most one local entry per port
> >>>>>> per vlan. It used to be true, but since commit 36fd2b63e3b4 ("bridge: allow
> >>>>>> creating/deleting fdb entries via netlink"), it has not been so.
> >>>>>> Therefore, the function might fail to search a correct previous address
> >>>>>> to be deleted and delete an arbitrary local entry if user has added local
> >>>>>> entries manually.
> >>>>>>
> >>>>>> Example of problematic case:
> >>>>>>   ip link set eth0 address ee:ff:12:34:56:78
> >>>>>>   brctl addif br0 eth0
> >>>>>>   bridge fdb add 12:34:56:78:90:ab dev eth0 master
> >>>>>>   ip link set eth0 address aa:bb:cc:dd:ee:ff
> >>>>>> Then, the address 12:34:56:78:90:ab might be deleted instead of
> >>>>>> ee:ff:12:34:56:78, the original mac address of eth0.
> >>>>>>
> >>>>>> Address this issue by introducing a new flag, added_by_user, to struct
> >>>>>> net_bridge_fdb_entry.
> >>>>>>
> >>>>>> Note that br_fdb_delete_by_port() has to set added_by_user to 0 in case
> >>>>>> like:
> >>>>>>   ip link set eth0 address 12:34:56:78:90:ab
> >>>>>>   ip link set eth1 address aa:bb:cc:dd:ee:ff
> >>>>>>   brctl addif br0 eth0
> >>>>>>   bridge fdb add aa:bb:cc:dd:ee:ff dev eth0 master
> >>>>>>   brctl addif br0 eth1
> >>>>>>   brctl delif br0 eth0
> >>>>>> In this case, kernel should delete the user-added entry aa:bb:cc:dd:ee:ff,
> >>>>>> but it also should have been added by "brctl addif br0 eth1" originally,
> >>>>>> so we don't delete it and treat it a new kernel-created entry.
> >>>>>>
> >>>>>
> >>>>> I was looking over my patch series that adds something similar to this
> >>>>> and noticed that you are not handing the NTF_USE case.  That case was
> >>>>> always troublesome for me as it allows for 2 different way to create
> >>>>> the same FDB: one through br_fdb_update() and one through fdb_add_entry().
> >>>>>
> >>>>> It is possible, though I haven't found any users yet, that NTF_USE
> >>>>> may be used and in that case, bridge will create a dynamic fdb and
> >>>>> disregard all NUD flags.  In case case, add_by_user will not be set
> >>>>> either.
> >>>>>
> >>>>> I think that the above is broken and plan to submit a fix shortly.
> >>>>
> >>>> Just looked again at my NTF_USE patch and while it seems ok, the whole
> >>>> NTF_USE usage is racy to begin with and I am really starting to question
> >>>> it's validity.
> >>>>
> >>>> Presently, br_fdb_update() will not update local fdb entries.   Instead
> >>>> it will log a misleading warning...  It will only let you update
> >>>> non-local entries.  This is fine for user-created entries, but any
> >>>> operation on dynamically created entries will only persist until
> >>>> the next packet.  It also races against the packet, so there is
> >>>> absolutely no guarantee that the values of fdb->dst and fdb->updated
> >>>> will be consistent..
> >>>>
> >>>> It seems to me that the update capability of NTF_USE would actually be
> >>>> of more value on local or user-created fdb entries.
> >>>>
> >>>> The fdb creation capability of NTF_USE should be disabled.
> >>>>
> >>>> Thoughts?
> >>>
> >>> I ignored NTF_USE in this patch because I regard it as emulating kernel
> >>> creating entries after investigating git log.
> >>>
> >>> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=0c5c2d3089068d4aa378f7a40d2b5ad9d4f52ce8
> >>> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=292d1398983f3514a0eab13b7606df7f4730b498
> >>>
> >>> So I think NTF_USE shouldn't set added_by_user.
> >>> And to emulate kernel creating entries, simply calling br_fdb_update()
> >>> is the right way, isn't it?
> >>
> >> You can create dynamic entries (emulating the kernel) without NTF_USE.
> >> Just set the NUD_REACHABLE.  Notice that arp cache only uses NTF_USE
> >> to trigger and arp notification.  The creation is still triggered via
> >> other netlink flags.
> >>
> >> The more I look at this the more I think NTF_USE should not create
> >> an entry all by itself.
> > 
> > I haven't fully understood you yet.
> > Currently NTF_USE behaves as if the port receives a frame and it seems
> > to work, though the ability to create entries is different from neigh
> > subsystem.
> > Why do you want to change the behavior?
> > Are you worried about inconsistency of NLM-flags/NUD-state with NTF_USE
> > between neigh and bridge?
> 
> No, it is inconsistent with other NLM/NUD-state within bridge.  As
> an fdb creation flag NTF_USE is confusing.  It will create an entry
> without NLM_F_CREATE being set.  It will ignore NLM_F_EXCL flag as
> well.  It will additionally ignore any NUD-state flags that may be set
> in the netlink message.  So it may not be doing what the user wishes.

I don't know which of NTF-flags and NLM-flags/NUD-state should be given
high priority on setting. For now, in bridge, NTF_USE masks any other
flags. If this is not proper way for netlink/neighbour, I will agree
with you. If not sure, I have no motivation to change existing behavior
that might be expected by some users.

> 
> It also provides duplicate functionality.  The same results are achieved
> by setting NLM_F_CREATE flag and NUD_REACHABLE state in the message.

br_fdb_update() never updates fdb->used, which is visible by user,
unlike fdb_add_entry().

If it is duplicate functionality, isn't NTF_USE itself no use?
What can be achieved by changing capability of creation and update of
local entries?

Thanks,
Toshiaki Makita

^ permalink raw reply

* Re: [PATCH v2 2/2] ipv6 addrconf: don't cleanup route prefix for IFA_F_NOPREFIXROUTE
From: Hannes Frederic Sowa @ 2014-01-07 16:28 UTC (permalink / raw)
  To: Thomas Haller; +Cc: Jiri Pirko, netdev, stephen, dcbw
In-Reply-To: <1389105553-21230-3-git-send-email-thaller@redhat.com>

On Tue, Jan 07, 2014 at 03:39:13PM +0100, Thomas Haller wrote:
> Also, when adding the NOPREFIXROUTE flag to an already existing address,
> check if there there is a prefix that was likly added by the kernel
> and delete it.

Hmm, could you give a bit more details why you have done this? I find
that a bit counterintuitive. Maybe it has a reason?

^ permalink raw reply

* Re: [PATCH RFC v2 0/13] vti4: prepare namespace and interfamily support.
From: Christophe Gouault @ 2014-01-07 16:11 UTC (permalink / raw)
  To: Steffen Klassert, netdev; +Cc: Saurabh Mohan
In-Reply-To: <20131216091835.GQ31491@secunet.com>

On 12/16/2013 10:18 AM, Steffen Klassert wrote:
> This patchset prepares vti4 for proper namespace and interfamily support.
>
> Currently the receive hook is in the middle of the decapsulation
> process, some of the header pointers point still into the IPsec packet
> others point already into the decapsulated packet. This makes it
> very unflexible and proper namespace and interfamily support can't
> be done as it is.
>
> The patchset that implements an IPsec protocol multiplexer, so that vti
> can register it's own receive path hooks. Further it makes the i_key
> usable for vti and changes the vti4 code to do the following:
>
> vti uses the IPsec protocol multiplexer to register it's
> own receive side hooks for ESP, AH and IPCOMP.
>
> Vti does the following on receive side:
>
> 1. Do an input policy check for the IPsec packet we received.
>     This is required because this packet could be already
>     processed by IPsec (tunnel in tunnel or a block policy
>     is present), so an inbound policy check is needed.
>
> 2. Clean the skb to not leak informations on namespace
>     transitions.
>
> 3. Mark the packet with the i_key. The policy and the state
>     must match this key now. Policy and state belong to the vti
>     namespace and policy enforcement is done at the further layers.
>
> 4. Call the generic xfrm layer to do decryption and decapsulation.
>
> 5. Wait for a callback from the xfrm layer to properly update
>     the device statistics.

Sorry for my late comments, I had to delay my tests due to Christmas and
New Year's celebrations.

I have a few comments about your proposed patches:

In input, the vti tunnel processing does not follow the usual tunnel
processing. Conventionally, the packets are first decapsulated, then
only the skbuff interface is changed to the tunnel interface. In the vti
code, the interface is changed before IPsec decryption, hence before
decapsulation.

It results in a configuration asymmetry when we later support cross
netns: the outer SAs and SPs must be defined in the outer netns, while
the inner SAs and SPs must be defined in the inner netns. This is a
little disturbing.

> On transmit side:
>
> 1. Mark the packet with the o_key. The policy and the state
>     must match this key now.
>
> 2. Do a xfrm_lookup on the original packet with the mark applied.
>
> 3. Check if we got an IPsec route.
>
> 4. Clean the skb to not leak informations on namespace
>     transitions.
>
> 5. Attach the dst_enty we got from the xfrm_lookup to the skb.
>
> 6. Call dst_output to do the IPsec processing.
>
> 7. Do the device statistics.

In output, when the route points to a vti interface, the global SPD
lookup is not bypassed: an SPD lookup is still performed for a global
SPD (i.e. without applying the vti mark). Then only the packet can enter
the vti interface, in which a second SPD lookup is done, in the vti
interface SPD (i.e. after applying the vti mark). Of course if the
global SPD lookup returned a tunnel mode policy, then the packet may
finally not enter the vti interface, because a new route is looked up
after the IPsec encapsulation.

My understanding of the vti interface interest is enabling to use
routing (possibly dynamic routes) *instead* of complex security
policies. And in this use case I expect that entering a vti interface
will *override* the global policies (in the same manner as socket
policies override the global policies).

Otherwise, if we want to mix global and vti policies on the same
machine, then we must carefully define global policies that do not match
traffic destined to vti interfaces.

Note that setting the NOXFRM flag on the vti interface does not work
around this issue, it disables both the global and vti SPD lookup and
the traffic is finally dropped.

> Changes from v1:
>
> - Rebased to current net-next.
> - Fix a rcu lockdep complaint in xfrm protocol registration/deregistration.
> - Fix usage of a ipv4 specific callback handler in generic code.
> - Use skb_scrub_packet() to clear the skb in vti_rcv(), suggested by
>    Nicolas Dichtel.
> - Add support for IPCOMP.
> - Support inter address family tunneling.
>
> I'd take this into the ipsec-next tree after some testing if noone
> has further suggestions or objections.
>
> I have the ipv6 side ready too, this will be a separate patchset.
> The ipv6 patchset has dependencies against the ipv4 patchset, so I
> hold it back until we have got the ipv4 side merged.
>

^ permalink raw reply

* Re: [PATCH v2 0/2] ipv6 addrconf: add IFA_F_NOPREFIXROUTE flag to suppress creation of IP6 routes
From: Hannes Frederic Sowa @ 2014-01-07 16:03 UTC (permalink / raw)
  To: Thomas Haller; +Cc: Jiri Pirko, netdev, stephen, dcbw
In-Reply-To: <1389105553-21230-1-git-send-email-thaller@redhat.com>

On Tue, Jan 07, 2014 at 03:39:11PM +0100, Thomas Haller wrote:
> Now, the IFA_F_NOPREFIXROUTE flag is saved in ifp->flags.
> The second patch reworks the deletion of addresses/cleanup of prefix
> routes and considers IFA_F_NOPREFIXROUTE.
> 
> Thomas Haller (2):
>   ipv6 addrconf: add IFA_F_NOPREFIXROUTE flag to suppress creation of
>     IP6 routes
>   ipv6 addrconf: don't cleanup route prefix for IFA_F_NOPREFIXROUTE

Maybe you could look into if a small patch implementing noprefixroute would be
doable. That would help testing these changes a lot. ;)

Greetings,

  Hannes

^ permalink raw reply

* Re: single process receives own frames due to PACKET_MMAP
From: Daniel Borkmann @ 2014-01-07 15:57 UTC (permalink / raw)
  To: Norbert van Bolhuis; +Cc: Jesper Dangaard Brouer, netdev, David Miller, uaca
In-Reply-To: <52CC2168.9060401@aimvalley.nl>

On 01/07/2014 04:46 PM, Norbert van Bolhuis wrote:
> On 01/07/14 16:26, Daniel Borkmann wrote:
>> On 01/07/2014 04:16 PM, Norbert van Bolhuis wrote:
>>> On 01/07/14 15:09, Jesper Dangaard Brouer wrote:
>>>> On Tue, 07 Jan 2014 14:16:03 +0100
>>>> Norbert van Bolhuis<nvbolhuis@aimvalley.nl> wrote:
>>>>> On 01/07/14 11:06, Jesper Dangaard Brouer wrote:
>>>>>> On Tue, 07 Jan 2014 10:32:01 +0100
>>>>>> Daniel Borkmann<dborkman@redhat.com> wrote:
>>>>>>
>>>>>>> On 01/06/2014 11:58 PM, Norbert van Bolhuis wrote:
>>>>>>>>
>>>> [...]
>>>>>>>
>>>>>>>> I'd say it makes no sense to make the same process receive its
>>>>>>>> own transmitted frames on that same interface (unless its lo).
>>>>>>
>>>>>> Have you setup:
>>>>>> ring->s_ll.sll_protocol = 0
>>>>>>
>>>>>> This is what I did in trafgen to avoid this problem.
>>>>>>
>>>>>> See line 55 in netsniff-ng/ring.c:
>>>>>> https://github.com/borkmann/netsniff-ng/blob/c3602a995b21e8133c7f4fd1fb1e7e21b6a844f1/ring.c#L55
>>>>>>
>>>>>> Commit:
>>>>>> https://github.com/borkmann/netsniff-ng/commit/c3602a995b21e8133c7f4fd1fb1e7e21b6a844f1
>>>>>>
>>>>>
>>>>>
>>>>> No I did not do that, I was checking my code against netsniff-ng-0.5.8-rc4.
>>>>>
>>>>> But I just tried it, I believe I do the same as netsniff-ng-0.5.8-rc5, but it doesn't
>>>>> work for me. Maybe because I have an old FC14 system (kernel 2.6.35.14-106.fc14.x86_64).
>>>>>
>>>>> So I tried to see whether netsniff-ng-0.5.8-rc5/trafgen still makes the
>>>>> kernel call packet_rcv() on my FC14 system. So I build and run it, but I'm not sure
>>>>> how to (easily) check that.
>>>>
>>>> The easiest way is to:
>>>> cat /proc/net/ptype
>>>> And look if someone registered a proto handler/function: packet_rcv (or tpacket_rcv).
>>>>
>>>> The more exact method is, to run "perf record -a -g" and then look (at
>>>> the result with "perf report") for a lock contention, and "expand" the
>>>> spin_lock and see if packet_rcv() is calling this spin lock.
>>>>
>>>
>>>
>>> I checked the easy way.
>>> Even on my old FC14 system the "protocol=0 patch" seems to make a difference
>>> for trafgen.
>>> Without the patch I see for each CPU in use by trafgen a "packet_rcv entry" in
>>> /proc/net/ptype.
>>> With the patch I see no additional "packet_rcv entry".
>>
>> Yes, that is expected behaviour. ;-) See more below.
>>
>>> It could be my Appl is wrong or maybe the "protocol=0 patch" does not help.
>>> I think the latter, afterall my Appl has, unlike trafgen, another RX
>>> (AF_PACKET) socket.
>>>
>>>
>>>>
>>>>> In anyway, Wireshark does capture the trafgen generated
>>>>> frames, does that say anything ?
>>>>
>>>> Be careful not to start a wireshark/tcpdump, at the sametime, as this
>>>> will slow you down.
>>>>
>>>>> In the future, I can at least use PACKET_QDISC_BYPASS as a "workaround".
>>>>
>>>> And in the future with PACKET_QDISC_BYPASS, your wireshark will not
>>>> catch these packets, remember that.
>>>>
>>>
>>>
>>> Yes, this is why I would love to see the "protocol=0 patch" work for my Appl.
>>>
>>> So I will try my Appl with the latest net-next kernel to see if that makes
>>> it work. Hopefully I can find some time in the next coming days, I will keep
>>> you informed.
>>
>> As long as there's at least one single PF_PACKET receive socket open and you
>> do not make use of PACKET_QDISC_BYPASS on your tx socket, then those packets go
>> back the dev_queue_xmit_nit() path, even if your tx socket uses protocol=0.
>>
>> If you make use of PACKET_QDISC_BYPASS [1] for your particular tx socket, then
>> packets generated by that socket will not hit the dev_queue_xmit_nit() path
>> back to other possible rx listeners that are present on your system (w/ the
>> side-effects for tx as described in [1]).
>>
>> [1] Documentation/networking/packet_mmap.txt +960
>>
>
>
> Ok, that's clear.
>
> But this means my PF_PACKET socket application performs worse because of
> using PACKET_MMAP. I expected the opposit.
>
> Afterall my old PF_PACKET socket application (which does not use PACKET_MMAP)
> uses only one PF_PACKET socket (for TX and RX). Because packets are never sent
> back to the socket they originated from, my old PF_PACKET socket application
> performs better.
>
> Is there a way to use one PF_PACKET socket for both TX and RX and use PACKET_MMAP ?

Yep:

http://thread.gmane.org/gmane.linux.network/269129/focus=269188

Feel free to make a patch and add this to Documentation/networking/packet_mmap.txt
I think could be useful for others as well.

^ permalink raw reply

* Re: question about ixgbevf/ixgbevf_main.c
From: Alexander Duyck @ 2014-01-07 15:55 UTC (permalink / raw)
  To: Julia Lawall; +Cc: donald.c.skidmore, e1000-devel, netdev
In-Reply-To: <alpine.DEB.2.10.1401071643340.2094@hadrien>

On 01/07/2014 07:44 AM, Julia Lawall wrote:
> On Tue, 7 Jan 2014, Alexander Duyck wrote:
>
>> A VF isn't a real device so it shouldn't really have the concept of a
>> power state.  The power state for the device is controlled via the PF.
>> I suspect the fact that ixgbevf is modifying power state on resume is
>> likely a bug.
> Thanks for the information, which is very helpful.  Should I submit a
> patch to remove it in the resume function?  I don't have the ability ot
> test it, though.
>
> julia
>

You could submit a patch.  The issue should just be cosmetic.  Setting
the power state to D0 should have no impact on things one way or another
since that is the state VFs are normally in when they are created.

Thanks,

Alex

^ permalink raw reply

* Re: single process receives own frames due to PACKET_MMAP
From: Norbert van Bolhuis @ 2014-01-07 15:46 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: Jesper Dangaard Brouer, netdev, David Miller, uaca
In-Reply-To: <52CC1C94.2060808@redhat.com>

On 01/07/14 16:26, Daniel Borkmann wrote:
> On 01/07/2014 04:16 PM, Norbert van Bolhuis wrote:
>> On 01/07/14 15:09, Jesper Dangaard Brouer wrote:
>>> On Tue, 07 Jan 2014 14:16:03 +0100
>>> Norbert van Bolhuis<nvbolhuis@aimvalley.nl> wrote:
>>>> On 01/07/14 11:06, Jesper Dangaard Brouer wrote:
>>>>> On Tue, 07 Jan 2014 10:32:01 +0100
>>>>> Daniel Borkmann<dborkman@redhat.com> wrote:
>>>>>
>>>>>> On 01/06/2014 11:58 PM, Norbert van Bolhuis wrote:
>>>>>>>
>>> [...]
>>>>>>
>>>>>>> I'd say it makes no sense to make the same process receive its
>>>>>>> own transmitted frames on that same interface (unless its lo).
>>>>>
>>>>> Have you setup:
>>>>> ring->s_ll.sll_protocol = 0
>>>>>
>>>>> This is what I did in trafgen to avoid this problem.
>>>>>
>>>>> See line 55 in netsniff-ng/ring.c:
>>>>> https://github.com/borkmann/netsniff-ng/blob/c3602a995b21e8133c7f4fd1fb1e7e21b6a844f1/ring.c#L55
>>>>>
>>>>> Commit:
>>>>> https://github.com/borkmann/netsniff-ng/commit/c3602a995b21e8133c7f4fd1fb1e7e21b6a844f1
>>>>>
>>>>
>>>>
>>>> No I did not do that, I was checking my code against netsniff-ng-0.5.8-rc4.
>>>>
>>>> But I just tried it, I believe I do the same as netsniff-ng-0.5.8-rc5, but it doesn't
>>>> work for me. Maybe because I have an old FC14 system (kernel 2.6.35.14-106.fc14.x86_64).
>>>>
>>>> So I tried to see whether netsniff-ng-0.5.8-rc5/trafgen still makes the
>>>> kernel call packet_rcv() on my FC14 system. So I build and run it, but I'm not sure
>>>> how to (easily) check that.
>>>
>>> The easiest way is to:
>>> cat /proc/net/ptype
>>> And look if someone registered a proto handler/function: packet_rcv (or tpacket_rcv).
>>>
>>> The more exact method is, to run "perf record -a -g" and then look (at
>>> the result with "perf report") for a lock contention, and "expand" the
>>> spin_lock and see if packet_rcv() is calling this spin lock.
>>>
>>
>>
>> I checked the easy way.
>> Even on my old FC14 system the "protocol=0 patch" seems to make a difference
>> for trafgen.
>> Without the patch I see for each CPU in use by trafgen a "packet_rcv entry" in
>> /proc/net/ptype.
>> With the patch I see no additional "packet_rcv entry".
>
> Yes, that is expected behaviour. ;-) See more below.
>
>> It could be my Appl is wrong or maybe the "protocol=0 patch" does not help.
>> I think the latter, afterall my Appl has, unlike trafgen, another RX
>> (AF_PACKET) socket.
>>
>>
>>>
>>>> In anyway, Wireshark does capture the trafgen generated
>>>> frames, does that say anything ?
>>>
>>> Be careful not to start a wireshark/tcpdump, at the sametime, as this
>>> will slow you down.
>>>
>>>> In the future, I can at least use PACKET_QDISC_BYPASS as a "workaround".
>>>
>>> And in the future with PACKET_QDISC_BYPASS, your wireshark will not
>>> catch these packets, remember that.
>>>
>>
>>
>> Yes, this is why I would love to see the "protocol=0 patch" work for my Appl.
>>
>> So I will try my Appl with the latest net-next kernel to see if that makes
>> it work. Hopefully I can find some time in the next coming days, I will keep
>> you informed.
>
> As long as there's at least one single PF_PACKET receive socket open and you
> do not make use of PACKET_QDISC_BYPASS on your tx socket, then those packets go
> back the dev_queue_xmit_nit() path, even if your tx socket uses protocol=0.
>
> If you make use of PACKET_QDISC_BYPASS [1] for your particular tx socket, then
> packets generated by that socket will not hit the dev_queue_xmit_nit() path
> back to other possible rx listeners that are present on your system (w/ the
> side-effects for tx as described in [1]).
>
> [1] Documentation/networking/packet_mmap.txt +960
>


Ok, that's clear.

But this means my PF_PACKET socket application performs worse because of
using PACKET_MMAP. I expected the opposit.

Afterall my old PF_PACKET socket application (which does not use PACKET_MMAP)
uses only one PF_PACKET socket (for TX and RX). Because packets are never sent
back to the socket they originated from, my old PF_PACKET socket application
performs better.

Is there a way to use one PF_PACKET socket for both TX and RX and use PACKET_MMAP ?

---
Norbert

^ permalink raw reply

* Re: question about ixgbevf/ixgbevf_main.c
From: Julia Lawall @ 2014-01-07 15:44 UTC (permalink / raw)
  To: Alexander Duyck; +Cc: Julia Lawall, donald.c.skidmore, e1000-devel, netdev
In-Reply-To: <52CC2066.1030303@intel.com>

On Tue, 7 Jan 2014, Alexander Duyck wrote:

> A VF isn't a real device so it shouldn't really have the concept of a
> power state.  The power state for the device is controlled via the PF.
> I suspect the fact that ixgbevf is modifying power state on resume is
> likely a bug.

Thanks for the information, which is very helpful.  Should I submit a
patch to remove it in the resume function?  I don't have the ability ot
test it, though.

julia

>
> Thanks,
>
> Alex
>
> On 01/07/2014 06:46 AM, Julia Lawall wrote:
> > I was wondering why ixgbevf_suspend doesn't call pci_set_power_state?  It
> > is called in the corresponding resume function, and most other PCI drivers
> > with a suspend functyion also call it in suspend.
> >
> > thanks,
> > julia
> > --
> > To unsubscribe from this list: send the line "unsubscribe netdev" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >
>
>

^ permalink raw reply

* Re: question about ixgbevf/ixgbevf_main.c
From: Alexander Duyck @ 2014-01-07 15:42 UTC (permalink / raw)
  To: Julia Lawall, donald.c.skidmore, e1000-devel, netdev
In-Reply-To: <alpine.DEB.2.10.1401071542370.2094@hadrien>

A VF isn't a real device so it shouldn't really have the concept of a
power state.  The power state for the device is controlled via the PF.
I suspect the fact that ixgbevf is modifying power state on resume is
likely a bug.

Thanks,

Alex

On 01/07/2014 06:46 AM, Julia Lawall wrote:
> I was wondering why ixgbevf_suspend doesn't call pci_set_power_state?  It
> is called in the corresponding resume function, and most other PCI drivers
> with a suspend functyion also call it in suspend.
> 
> thanks,
> julia
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* [PATCH net-next V2 2/3] net: Export gro_find_by_type helpers
From: Or Gerlitz @ 2014-01-07 15:29 UTC (permalink / raw)
  To: hkchu, edumazet, herbert; +Cc: netdev, davem, yanb, shlomop, Or Gerlitz
In-Reply-To: <1389108594-665-1-git-send-email-ogerlitz@mellanox.com>

Export the gro_find_receive/complete_by_type helpers to they can be invoked
by the gro callbacks of encapsulation protocols such as vxlan.

Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 net/core/dev.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index ca520ed..03c249f 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3935,6 +3935,7 @@ struct packet_offload *gro_find_receive_by_type(__be16 type)
 	}
 	return NULL;
 }
+EXPORT_SYMBOL(gro_find_receive_by_type);
 
 struct packet_offload *gro_find_complete_by_type(__be16 type)
 {
@@ -3948,6 +3949,7 @@ struct packet_offload *gro_find_complete_by_type(__be16 type)
 	}
 	return NULL;
 }
+EXPORT_SYMBOL(gro_find_complete_by_type);
 
 static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb)
 {
-- 
1.7.1

^ permalink raw reply related

* [PATCH net-next V2 0/3] net: Add GRO support for UDP encapsulating protocols
From: Or Gerlitz @ 2014-01-07 15:29 UTC (permalink / raw)
  To: hkchu, edumazet, herbert; +Cc: netdev, davem, yanb, shlomop, Or Gerlitz

These series adds GRO handlers for protocols that do UDP encapsulation, with the 
intent of being able to coalesce packets which encapsulate packets belonging to
the same TCP session.

For GRO purposes, the destination UDP port takes the role of the ether type 
field in the ethernet header or the next protocol in the IP header.

The UDP GRO handler will only attempt to coalesce packets whose destination
port is registered to have gro handler.

Patches are against net-next 4a8deae2f4653 "r8152: correct some messages" plus
Jerry's gro-gre patch which adds the gro_find_receive/complete_by_type helpers

On my setup, which is net-next (now with the mlx4 vxlan offloads patches) -- 
for single TCP session that goes through vxlan tunneling I got nice improvement
from 6.8Gbs to 11.5Gbs

TODO:
 - identify udp encapsulated packets whose inner VM packet is udp and happen
   to carry a port which has registered offloads - and flush it.

 - invoke the udp offload protocol de-registration from the vxlan driver from 
   sleepable context

Or Gerlitz (3):
  net: Add GRO support for UDP encapsulating protocols
  net: Export gro_find_by_type helpers
  net: Add GRO support for vxlan traffic

 drivers/net/vxlan.c    |  101 +++++++++++++++++++++++++++++++++++++++++++++++-
 include/net/protocol.h |    6 +++
 net/core/dev.c         |    2 +
 net/ipv4/protocol.c    |   21 ++++++++++
 net/ipv4/udp_offload.c |   69 ++++++++++++++++++++++++++++++++
 5 files changed, 197 insertions(+), 2 deletions(-)

^ permalink raw reply

* [PATCH net-next V2 1/3] net: Add GRO support for UDP encapsulating protocols
From: Or Gerlitz @ 2014-01-07 15:29 UTC (permalink / raw)
  To: hkchu, edumazet, herbert; +Cc: netdev, davem, yanb, shlomop, Or Gerlitz
In-Reply-To: <1389108594-665-1-git-send-email-ogerlitz@mellanox.com>

Add GRO handlers for protocols that do UDP encapsulation, with the intent of
being able to coalesce packets which encapsulate packets belonging to
the same TCP session.

For GRO purposes, the destination UDP port takes the role of the ether type 
field in the ethernet header or the next protocol in the IP header.

The UDP GRO handler will only attempt to coalesce packets whose destination
port is registered to have gro handler.

Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 include/net/protocol.h |    6 ++++
 net/ipv4/protocol.c    |   21 ++++++++++++++
 net/ipv4/udp_offload.c |   69 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 96 insertions(+), 0 deletions(-)

diff --git a/include/net/protocol.h b/include/net/protocol.h
index fbf7676..d776c08 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -92,6 +92,10 @@ extern const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS];
 extern const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS];
 extern const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS];
 
+
+#define MAX_UDP_PORT (1 << 16)
+extern const struct net_offload __rcu *udp_offloads[MAX_UDP_PORT];
+
 #if IS_ENABLED(CONFIG_IPV6)
 extern const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS];
 #endif
@@ -102,6 +106,8 @@ int inet_add_offload(const struct net_offload *prot, unsigned char num);
 int inet_del_offload(const struct net_offload *prot, unsigned char num);
 void inet_register_protosw(struct inet_protosw *p);
 void inet_unregister_protosw(struct inet_protosw *p);
+int udp_add_offload(const struct net_offload *prot, __be16 port);
+int udp_del_offload(const struct net_offload *prot, __be16 port);
 
 #if IS_ENABLED(CONFIG_IPV6)
 int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char num);
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c
index 46d6a1c..426eae5 100644
--- a/net/ipv4/protocol.c
+++ b/net/ipv4/protocol.c
@@ -30,6 +30,7 @@
 
 const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS] __read_mostly;
 const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS] __read_mostly;
+const struct net_offload __rcu *udp_offloads[MAX_UDP_PORT] __read_mostly;
 
 int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol)
 {
@@ -51,6 +52,13 @@ int inet_add_offload(const struct net_offload *prot, unsigned char protocol)
 }
 EXPORT_SYMBOL(inet_add_offload);
 
+int udp_add_offload(const struct net_offload *prot, __be16 port)
+{
+	return !cmpxchg((const struct net_offload **)&udp_offloads[port],
+			NULL, prot) ? 0 : -1;
+}
+EXPORT_SYMBOL(udp_add_offload);
+
 int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol)
 {
 	int ret;
@@ -76,3 +84,16 @@ int inet_del_offload(const struct net_offload *prot, unsigned char protocol)
 	return ret;
 }
 EXPORT_SYMBOL(inet_del_offload);
+
+int udp_del_offload(const struct net_offload *prot, __be16 port)
+{
+	int ret;
+
+	ret = (cmpxchg((const struct net_offload **)&udp_offloads[port],
+		       prot, NULL) == prot) ? 0 : -1;
+
+	synchronize_net();
+
+	return ret;
+}
+EXPORT_SYMBOL(udp_del_offload);
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index 79c62bd..0a8fdd6 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -89,10 +89,79 @@ out:
 	return segs;
 }
 
+
+static struct sk_buff **udp_gro_receive(struct sk_buff **head, struct sk_buff *skb)
+{
+	const struct net_offload *ops;
+	struct sk_buff *p, **pp = NULL;
+	struct udphdr *uh, *uh2;
+	unsigned int hlen, off;
+	int flush = 1;
+
+	off  = skb_gro_offset(skb);
+	hlen = off + sizeof(*uh);
+	uh   = skb_gro_header_fast(skb, off);
+	if (skb_gro_header_hard(skb, hlen)) {
+		uh = skb_gro_header_slow(skb, hlen, off);
+		if (unlikely(!uh))
+			goto out;
+	}
+
+	rcu_read_lock();
+	ops = rcu_dereference(udp_offloads[uh->dest]);
+	if (!ops || !ops->callbacks.gro_receive)
+		goto out_unlock;
+
+	flush = 0;
+
+	for (p = *head; p; p = p->next) {
+		if (!NAPI_GRO_CB(p)->same_flow)
+			continue;
+
+		uh2 = (struct udphdr   *)(p->data + off);
+		if ((*(u32 *)&uh->source ^ *(u32 *)&uh2->source)) {
+			NAPI_GRO_CB(p)->same_flow = 0;
+			continue;
+		}
+		goto found;
+	}
+
+found:
+	skb_gro_pull(skb, sizeof(struct udphdr)); /* pull encapsulating udp header */
+	pp = ops->callbacks.gro_receive(head, skb);
+
+out_unlock:
+	rcu_read_unlock();
+out:
+	NAPI_GRO_CB(skb)->flush |= flush;
+
+	return pp;
+}
+
+static int udp_gro_complete(struct sk_buff *skb, int nhoff)
+{
+	const struct net_offload *ops;
+	__be16 newlen = htons(skb->len - nhoff);
+	struct udphdr *uh = (struct udphdr *)(skb->data + nhoff);
+	int err = -ENOSYS;
+
+	uh->len = newlen;
+
+	rcu_read_lock();
+	ops = rcu_dereference(udp_offloads[uh->dest]);
+	if (ops && ops->callbacks.gro_complete)
+		err = ops->callbacks.gro_complete(skb, nhoff + sizeof(struct udphdr));
+
+	rcu_read_unlock();
+	return err;
+}
+
 static const struct net_offload udpv4_offload = {
 	.callbacks = {
 		.gso_send_check = udp4_ufo_send_check,
 		.gso_segment = udp4_ufo_fragment,
+		.gro_receive  =	udp_gro_receive,
+		.gro_complete =	udp_gro_complete,
 	},
 };
 
-- 
1.7.1

^ permalink raw reply related

* [PATCH net-next V2 3/3] net: Add GRO support for vxlan traffic
From: Or Gerlitz @ 2014-01-07 15:29 UTC (permalink / raw)
  To: hkchu, edumazet, herbert; +Cc: netdev, davem, yanb, shlomop, Or Gerlitz
In-Reply-To: <1389108594-665-1-git-send-email-ogerlitz@mellanox.com>

Add gro handlers for vxlan using the udp gro infrastructure

On my setup, which is net-next (now with the mlx4 vxlan offloads patches) -- 
for single TCP session that goes through vxlan tunneling I got nice improvement
from 6.8Gbs to 11.5Gbs

--> UDP/VXLAN GRO disabled
$ netperf  -H 192.168.52.147 -c -C

$ netperf -t TCP_STREAM -H 192.168.52.147 -c -C
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.52.147 () port 0 AF_INET
Recv   Send    Send                          Utilization       Service Demand
Socket Socket  Message  Elapsed              Send     Recv     Send    Recv
Size   Size    Size     Time     Throughput  local    remote   local   remote
bytes  bytes   bytes    secs.    10^6bits/s  % S      % S      us/KB   us/KB

 87380  65536  65536    10.00      6799.75   12.54    24.79    0.604   1.195

--> UDP/VXLAN GRO enabled

$ netperf -t TCP_STREAM -H 192.168.52.147 -c -C
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.52.147 () port 0 AF_INET
Recv   Send    Send                          Utilization       Service Demand
Socket Socket  Message  Elapsed              Send     Recv     Send    Recv
Size   Size    Size     Time     Throughput  local    remote   local   remote
bytes  bytes   bytes    secs.    10^6bits/s  % S      % S      us/KB   us/KB

 87380  65536  65536    10.00      11562.72   24.90    20.34    0.706   0.577

Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/net/vxlan.c |  101 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 481f85d..b51823b 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -40,6 +40,7 @@
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 #include <net/vxlan.h>
+#include <net/protocol.h>
 #if IS_ENABLED(CONFIG_IPV6)
 #include <net/ipv6.h>
 #include <net/addrconf.h>
@@ -554,6 +555,98 @@ static int vxlan_fdb_append(struct vxlan_fdb *f,
 	return 1;
 }
 
+static struct sk_buff **vxlan_gro_receive(struct sk_buff **head, struct sk_buff *skb)
+{
+	struct sk_buff *p, **pp = NULL;
+	struct vxlanhdr *vh, *vh2;
+	struct ethhdr *eh;
+	unsigned int hlen, off, off_eth;
+	const struct packet_offload *ptype;
+	__be16 type;
+	int flush = 1;
+
+	off  = skb_gro_offset(skb);
+	hlen = off + sizeof(*vh);
+	vh   = skb_gro_header_fast(skb, off);
+	if (skb_gro_header_hard(skb, hlen)) {
+		vh = skb_gro_header_slow(skb, hlen, off);
+		if (unlikely(!vh))
+			goto out;
+	}
+
+	flush = 0;
+
+	for (p = *head; p; p = p->next) {
+		if (!NAPI_GRO_CB(p)->same_flow)
+			continue;
+
+		vh2 = (struct vxlanhdr   *)(p->data + off);
+		if (vh->vx_vni ^ vh2->vx_vni) {
+			NAPI_GRO_CB(p)->same_flow = 0;
+			continue;
+		}
+		goto found;
+	}
+
+found:
+	skb_gro_pull(skb, sizeof(struct vxlanhdr)); /* pull vxlan header */
+
+	off_eth = skb_gro_offset(skb);
+	hlen = off_eth + sizeof(*eh);
+	eh   = skb_gro_header_fast(skb, off_eth);
+	if (skb_gro_header_hard(skb, hlen)) {
+		eh = skb_gro_header_slow(skb, hlen, off_eth);
+		if (unlikely(!eh))
+			goto out;
+	}
+	type = eh->h_proto;
+
+	rcu_read_lock();
+	ptype = gro_find_receive_by_type(type);
+	if (ptype == NULL) {
+		flush = 1;
+		goto out_unlock;
+	}
+
+	skb_gro_pull(skb, sizeof(*eh)); /* pull inner eth header */
+	pp = ptype->callbacks.gro_receive(head, skb);
+
+out_unlock:
+	rcu_read_unlock();
+out:
+	NAPI_GRO_CB(skb)->flush |= flush;
+
+	return pp;
+}
+
+static int vxlan_gro_complete(struct sk_buff *skb, int nhoff)
+{
+	struct ethhdr *eh;
+	struct packet_offload *ptype;
+	__be16 type;
+	/* 22 = 8 bytes for the vlxan header + 14 bytes for the inner eth header */
+	int vxlan_len  = 22;
+	int err = -ENOSYS;
+
+	eh = (struct ethhdr *)(skb->data + nhoff + sizeof (struct vxlanhdr));
+	type = eh->h_proto;
+
+	rcu_read_lock();
+	ptype = gro_find_complete_by_type(type);
+	if (ptype != NULL)
+		err = ptype->callbacks.gro_complete(skb, nhoff + vxlan_len);
+
+	rcu_read_unlock();
+	return err;
+}
+
+static const struct net_offload vxlan_offload = {
+	.callbacks = {
+		.gro_receive  =	vxlan_gro_receive,
+		.gro_complete =	vxlan_gro_complete,
+	},
+};
+
 /* Notify netdevs that UDP port started listening */
 static void vxlan_notify_add_rx_port(struct sock *sk)
 {
@@ -568,6 +661,8 @@ static void vxlan_notify_add_rx_port(struct sock *sk)
 			dev->netdev_ops->ndo_add_vxlan_port(dev, sa_family,
 							    port);
 	}
+	if (sa_family == AF_INET)
+		udp_add_offload(&vxlan_offload, port);
 	rcu_read_unlock();
 }
 
@@ -585,6 +680,8 @@ static void vxlan_notify_del_rx_port(struct sock *sk)
 			dev->netdev_ops->ndo_del_vxlan_port(dev, sa_family,
 							    port);
 	}
+	if (sa_family == AF_INET)
+		udp_del_offload(&vxlan_offload, port);
 	rcu_read_unlock();
 }
 
@@ -1125,8 +1222,8 @@ static void vxlan_rcv(struct vxlan_sock *vs,
 	 * leave the CHECKSUM_UNNECESSARY, the device checksummed it
 	 * for us. Otherwise force the upper layers to verify it.
 	 */
-	if (skb->ip_summed != CHECKSUM_UNNECESSARY || !skb->encapsulation ||
-	    !(vxlan->dev->features & NETIF_F_RXCSUM))
+	if ((skb->ip_summed != CHECKSUM_UNNECESSARY && skb->ip_summed != CHECKSUM_PARTIAL) ||
+	    !skb->encapsulation || !(vxlan->dev->features & NETIF_F_RXCSUM))
 		skb->ip_summed = CHECKSUM_NONE;
 
 	skb->encapsulation = 0;
-- 
1.7.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox