Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net 2/3] udp_offload: Set encapsulation before inner completes.
From: Alexander Duyck @ 2016-05-02 22:54 UTC (permalink / raw)
  To: Jarno Rajahalme; +Cc: Netdev, Jesse Gross
In-Reply-To: <DB78A60B-3899-4767-AD0B-DCDCC65C04E1@ovn.org>

On Mon, May 2, 2016 at 2:21 PM, Jarno Rajahalme <jarno@ovn.org> wrote:
>
>> On Apr 29, 2016, at 8:46 PM, Alexander Duyck <alexander.duyck@gmail.com> wrote:
>>
>> On Fri, Apr 29, 2016 at 3:28 PM, Jarno Rajahalme <jarno@ovn.org> wrote:
>>> UDP tunnel segmentation code relies on the inner offsets being set for
>>> an UDP tunnel GSO packet.  The inner *_complete() functions will set
>>> the inner offsets only if the encapsulation is set before calling
>>> them, but udp_gro_complete() set it only after the inner *_complete()
>>> functions were done.
>>>
>>> Also, remove the setting of the inner_mac_header in udp_gro_complete()
>>> as it was wrongly set to the beginning of the UDP tunnel header rather
>>> than the inner MAC header.
>>>
>>> Signed-off-by: Jarno Rajahalme <jarno@ovn.org>
>>> ---
>>> net/ipv4/udp_offload.c | 8 +++++---
>>> 1 file changed, 5 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
>>> index 0ed2daf..e330c0e 100644
>>> --- a/net/ipv4/udp_offload.c
>>> +++ b/net/ipv4/udp_offload.c
>>> @@ -399,6 +399,11 @@ int udp_gro_complete(struct sk_buff *skb, int nhoff)
>>>
>>>        uh->len = newlen;
>>>
>>> +       /* Set encapsulation before calling into inner gro_complete() functions
>>> +        * to make them set up the inner offsets.
>>> +        */
>>> +       skb->encapsulation = 1;
>>> +
>>>        rcu_read_lock();
>>>
>>>        uo_priv = rcu_dereference(udp_offload_base);
>>> @@ -421,9 +426,6 @@ int udp_gro_complete(struct sk_buff *skb, int nhoff)
>>>        if (skb->remcsum_offload)
>>>                skb_shinfo(skb)->gso_type |= SKB_GSO_TUNNEL_REMCSUM;
>>>
>>> -       skb->encapsulation = 1;
>>> -       skb_set_inner_mac_header(skb, nhoff + sizeof(struct udphdr));
>>> -
>>>        return err;
>>> }
>>>
>>> --
>>> 2.7.4
>>>
>>
>> So looking over this I think this patch is just a band-aid and it
>> isn't really fixing much of anything.  For example I cannot see where
>
> It fixes the immediate bug/problem that segmentation of GRO UDP tunnel packet fails due to incorrectly set inner MAC offset and/or missing inner network offset.

The problem is I think this will introduce other issues as there are
now situations where the inner MAC offset never gets set.  For example
did you try testing with GUE carrying either an IPIP or SIT tunnel?

>From what I can tell it looks like you are trying to fix VXLAN and
similar offloads, and Tom is focused on GUE.  What you will probably
need to do is add some code to ipip_gro_complete and sit_gro_complete
so that if skb->encapsulation is set before you call the function it
will set the inner MAC offset to the same offset as the inner network
header.  Otherwise you run the risk of screwing up segmentation
because the UDP tunnel segment code will use the inner mac header
offset when computing the tunnel header length and get it completely
wrong.

>> the inner transport offset is ever set.  From what I can tell it never
>> is.
>>
>
> inner transport offset is set in validate_xmit_skb(), but you are right, it is not set by the GRO complete code path. AFAIK no-one uses it before reaching validate_xmit_skb(), though. The documentation in (net-next) Documentation/networking/segmentation-offloads.txt could be fixed by removing the inner transport header from UDP/GRE tunnel case, as it is not used by either the GRE or UDP tunnel code.

Actually that is an interesting point.  Right now we need to keep the
inner transport header around because that is getting set.  If we were
to enforce the use of csum_start as the inner transport header offset,
then we could assume that transport_header is always the outer-most
transport header.  We might be able to drop a bit of space from the
skbuff by getting rid of it.  If nothing else it means one less header
offset we would have to copy.

- Alex

^ permalink raw reply

* Re: [PATCH 0/2] sctp: Add GSO support
From: David Miller @ 2016-05-02 23:16 UTC (permalink / raw)
  To: marcelo.leitner
  Cc: netdev, vyasevich, nhorman, linux-sctp, David.Laight,
	alexander.duyck
In-Reply-To: <cover.1461965035.git.marcelo.leitner@gmail.com>

From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Date: Fri, 29 Apr 2016 18:33:31 -0300

> This patchset adds sctp GSO support.
> 
> Performance tests indicates that increases throughput by 10% if using
> bigger chunk sizes, specially if bigger than MTU. For small chunks, it
> doesn't help much if not using heavy firewall rules.
> 
> For small chunks it will probably be of more use once we get something
> like MSG_MORE as David Laight had suggested.
> 
> I believe I could address all comments from the RFC attempt.

Are these packets idempotent?

Ie. if we GRO a bunch of SCTP frames on receive and that GRO frame is
forwarded rather than received locally, is the same exact packet
stream emitted on transmit?

^ permalink raw reply

* Re: [PATCHv2 bluetooth-next 00/10] 6lowpan: introduce basic 6lowpan-nd
From: Marcel Holtmann @ 2016-05-02 23:17 UTC (permalink / raw)
  To: Hannes Frederic Sowa, David S. Miller
  Cc: Alexander Aring, linux-wpan-u79uwXL29TY76Z2rM5mHXA,
	kernel-bIcnvbaLZ9MEGnE8C9+IrQ, Jukka Rissanen, Stefan Schmidt,
	mcr-SWp7JaYWvAQV+D8aMU/kSg, Werner Almesberger, Linux Bluetooth,
	Network Development, Alexey Kuznetsov, James Morris,
	Hideaki YOSHIFUJI, Patrick McHardy
In-Reply-To: <870fdf5f-82ed-b621-a8d5-625bf9d81d0d-tFNcAqjVMyqKXQKiL6tip0B+6BGkLq7r@public.gmane.org>

Hi Hannes,

>>> this patch series introduces a layer for IPv6 neighbour discovery. At first
>>> it introduce the "ndisc_ops" to run a different handling for recv/send of
>>> NA/NS messages. The use case for such ndisc operation is RFC 6775 [0].
>>> Which describes a different neighbour discovery handling for 6LoWPAN networks.
>>> 
>>> I didn't implement RFC 6775 in this patch series, but introduce callback
>>> structure for replace different functions in ndisc implementation might be
>>> the right direction.
>>> 
>>> Another use case would be RFC 7400 [1] which describes a new option field to
>>> getting capabilities of 6LoWPAN next header compression methods.
>>> 
>>> What I implemented is a necessary functionality to handle short address for
>>> 802.15.4 6LoWPAN networks. The L2-Layer "802.15.4" can have two different
>>> link-layer addresses which can be used mixed at the same time inside 802.15.4
>>> networks. To deal with such behaviour in ndisc, it is defined at RFC 4944 [2].
>>> The bad news is, that I saw different handling of such handling. What Linux
>>> will do is to add two source/target address information option fields, each
>>> with different length, if short address is valid (can also not be given).
>>> Example:
>>> 
>>> - WPAN interface address settings
>>> - extended addr (must always be there)
>>> - short addr (0xfffe or 0xffff -> invalid)
>>> 
>>> Will add an extended addr to source/target address information option field.
>>> If short addr is in some valid range, then both address will be added to
>>> the option fields. Indicated are these different address types by the length
>>> field (extended -> length=2, short -> length=1), according to [1].
>>> 
>>> The tested 6LoWPAN implementation (RIOT-OS) allows only one source/target
>>> option field which is short XOR extended, otherwise it will be dropped.
>>> There is some lack of information there [2] and I don't know how do deal with
>>> it right, maybe we need to update the implementation there if it's really
>>> wrong.
>>> 
>>> To save such information for each neighbour we use the already implemented
>>> neighbour private data which some casting strategy for 6LoWPAN and 6LoWPAN
>>> link-layer specific data e.g. 802.15.4 short address handling.
>>> 
>>> Additional I implemented to add 6CO to the is_useropt callback in case of
>>> 6LoWPAN interface. The 6CO option will currently parsed in userspace which
>>> are placed in RA-Messages.
>>> 
>>> The ndisc_ops are not finished yet, of course we need handling for RS messages
>>> to place the 802.15.4 short address there as well and then also processing
>>> of RA messages for the 802.15.4 SLLAO option field.
>>> 
>>> - Alex
>>> 
>>> [0] https://tools.ietf.org/html/rfc6775
>>> [1] https://tools.ietf.org/html/rfc7400#section-3.3
>>> [2] https://tools.ietf.org/html/rfc4944#section-8
>>> 
>>> Cc: David S. Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
>>> Cc: Alexey Kuznetsov <kuznet-v/Mj1YrvjDBInbfyfbPRSQ@public.gmane.org>
>>> Cc: James Morris <jmorris-gx6/JNMH7DfYtjvyW6yDsg@public.gmane.org>
>>> Cc: Hideaki YOSHIFUJI <yoshfuji-VfPWfsRibaP+Ru+s062T9g@public.gmane.org>
>>> Cc: Patrick McHardy <kaber-dcUjhNyLwpNeoWH0uzbU5w@public.gmane.org>
>>> 
>>> changes since v2:
>>> - replace #ifdef CONFIG_IPV6 to #if IS_ENABLED(...)
>>> - replace #ifdef CONFIG_IEEE802154... to #if IS_ENABLED(...)
>>> - add more #if IS_ENABLED(CONFIG_IPV6) in ndisc.h
>>> 
>>> Alexander Aring (10):
>>> 6lowpan: add private neighbour data
>>> 6lowpan: add 802.15.4 short addr slaac
>>> 6lowpan: remove ipv6 module request
>>> ndisc: add addr_len parameter to ndisc_opt_addr_space
>>> ndisc: add addr_len parameter to ndisc_opt_addr_data
>>> ndisc: add addr_len parameter to ndisc_fill_addr_option
>>> ipv6: introduce neighbour discovery ops
>>> ipv6: export ndisc functions
>>> 6lowpan: introduce 6lowpan-nd
>>> 6lowpan: add support for 802.15.4 short addr handling
>>> 
>>> include/linux/netdevice.h     |   6 +-
>>> include/net/6lowpan.h         |  24 ++
>>> include/net/addrconf.h        |   3 +
>>> include/net/ndisc.h           | 124 ++++++++-
>>> net/6lowpan/6lowpan_i.h       |   2 +
>>> net/6lowpan/Makefile          |   2 +-
>>> net/6lowpan/core.c            |  50 +++-
>>> net/6lowpan/iphc.c            | 167 +++++++++--
>>> net/6lowpan/ndisc.c           | 633 ++++++++++++++++++++++++++++++++++++++++++
>>> net/bluetooth/6lowpan.c       |   2 +
>>> net/ieee802154/6lowpan/core.c |  12 +
>>> net/ieee802154/6lowpan/tx.c   | 107 ++++---
>>> net/ipv6/addrconf.c           |   7 +-
>>> net/ipv6/ndisc.c              | 132 +++++----
>>> net/ipv6/route.c              |   4 +-
>>> 15 files changed, 1117 insertions(+), 158 deletions(-)
>>> create mode 100644 net/6lowpan/ndisc.c
>> 
>> is there a chance that we get input into this patch set? I wonder also if it would be acceptable to take this through bluetooth-next or should it better go straight into net-next?
> 
> My proposal would be that the IPv6 patches go via net-next to reduce
> merge conflicts with maybe upcoming changes. If they are split up, they
> seem very much self contained and easy to review. The rest seems to be
> also very much self contained and can go in via bluetooth-next, then.
> What do you think?

I am actually fine with having this all go via net-next. We only have driver patches pending in bluetooth-next for the next merge window. Which means I can just pull net-next back into bluetooth-next at any time.

Regards

Marcel

^ permalink raw reply

* Re: [PATCH net 2/3] udp_offload: Set encapsulation before inner completes.
From: Tom Herbert @ 2016-05-02 23:18 UTC (permalink / raw)
  To: Alexander Duyck; +Cc: Jarno Rajahalme, Netdev, Jesse Gross
In-Reply-To: <CAKgT0Uf-dvDj2KDnt4GZoMJONMC6LgLBtEUcsO0JJ1jqiFDfaw@mail.gmail.com>

On Mon, May 2, 2016 at 3:54 PM, Alexander Duyck
<alexander.duyck@gmail.com> wrote:
> On Mon, May 2, 2016 at 2:21 PM, Jarno Rajahalme <jarno@ovn.org> wrote:
>>
>>> On Apr 29, 2016, at 8:46 PM, Alexander Duyck <alexander.duyck@gmail.com> wrote:
>>>
>>> On Fri, Apr 29, 2016 at 3:28 PM, Jarno Rajahalme <jarno@ovn.org> wrote:
>>>> UDP tunnel segmentation code relies on the inner offsets being set for
>>>> an UDP tunnel GSO packet.  The inner *_complete() functions will set
>>>> the inner offsets only if the encapsulation is set before calling
>>>> them, but udp_gro_complete() set it only after the inner *_complete()
>>>> functions were done.
>>>>
>>>> Also, remove the setting of the inner_mac_header in udp_gro_complete()
>>>> as it was wrongly set to the beginning of the UDP tunnel header rather
>>>> than the inner MAC header.
>>>>
>>>> Signed-off-by: Jarno Rajahalme <jarno@ovn.org>
>>>> ---
>>>> net/ipv4/udp_offload.c | 8 +++++---
>>>> 1 file changed, 5 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
>>>> index 0ed2daf..e330c0e 100644
>>>> --- a/net/ipv4/udp_offload.c
>>>> +++ b/net/ipv4/udp_offload.c
>>>> @@ -399,6 +399,11 @@ int udp_gro_complete(struct sk_buff *skb, int nhoff)
>>>>
>>>>        uh->len = newlen;
>>>>
>>>> +       /* Set encapsulation before calling into inner gro_complete() functions
>>>> +        * to make them set up the inner offsets.
>>>> +        */
>>>> +       skb->encapsulation = 1;
>>>> +
>>>>        rcu_read_lock();
>>>>
>>>>        uo_priv = rcu_dereference(udp_offload_base);
>>>> @@ -421,9 +426,6 @@ int udp_gro_complete(struct sk_buff *skb, int nhoff)
>>>>        if (skb->remcsum_offload)
>>>>                skb_shinfo(skb)->gso_type |= SKB_GSO_TUNNEL_REMCSUM;
>>>>
>>>> -       skb->encapsulation = 1;
>>>> -       skb_set_inner_mac_header(skb, nhoff + sizeof(struct udphdr));
>>>> -
>>>>        return err;
>>>> }
>>>>
>>>> --
>>>> 2.7.4
>>>>
>>>
>>> So looking over this I think this patch is just a band-aid and it
>>> isn't really fixing much of anything.  For example I cannot see where
>>
>> It fixes the immediate bug/problem that segmentation of GRO UDP tunnel packet fails due to incorrectly set inner MAC offset and/or missing inner network offset.
>
> The problem is I think this will introduce other issues as there are
> now situations where the inner MAC offset never gets set.  For example
> did you try testing with GUE carrying either an IPIP or SIT tunnel?
>
> From what I can tell it looks like you are trying to fix VXLAN and
> similar offloads, and Tom is focused on GUE.  What you will probably
> need to do is add some code to ipip_gro_complete and sit_gro_complete
> so that if skb->encapsulation is set before you call the function it
> will set the inner MAC offset to the same offset as the inner network
> header.  Otherwise you run the risk of screwing up segmentation
> because the UDP tunnel segment code will use the inner mac header
> offset when computing the tunnel header length and get it completely
> wrong.
>
>>> the inner transport offset is ever set.  From what I can tell it never
>>> is.
>>>
>>
>> inner transport offset is set in validate_xmit_skb(), but you are right, it is not set by the GRO complete code path. AFAIK no-one uses it before reaching validate_xmit_skb(), though. The documentation in (net-next) Documentation/networking/segmentation-offloads.txt could be fixed by removing the inner transport header from UDP/GRE tunnel case, as it is not used by either the GRE or UDP tunnel code.
>
> Actually that is an interesting point.  Right now we need to keep the
> inner transport header around because that is getting set.  If we were
> to enforce the use of csum_start as the inner transport header offset,
> then we could assume that transport_header is always the outer-most
> transport header.  We might be able to drop a bit of space from the
> skbuff by getting rid of it.  If nothing else it means one less header
> offset we would have to copy.
>
Or can we just eliminate the inner headers altogether? IIRC the only
sticking point for GSO needing this was ipid, all the inner headers
are just copied per packet assuming segment lengths are the same. Is
this possible yet?

Tom

> - Alex

^ permalink raw reply

* Re: [PATCH next-next 0/7] net: Cleanup IPv6 ip tunnels
From: David Miller @ 2016-05-02 23:23 UTC (permalink / raw)
  To: tom; +Cc: netdev, kernel-team
In-Reply-To: <1461975141-954269-1-git-send-email-tom@herbertland.com>

From: Tom Herbert <tom@herbertland.com>
Date: Fri, 29 Apr 2016 17:12:14 -0700

> The IPv6 tunnel code is very different from IPv4 code. There is a lot
> of redundancy with the IPv4 code, particularly in the GRE tunneling.
> 
> This patch set cleans up the tunnel code to make the IPv6 code look
> more like the IPv4 code and use common functions between the two
> stacks where possible.

Series applied, nice work Tom.

^ permalink raw reply

* Re: [iproute2 1/1] man: tc-ife.8: man page for ife action
From: Jamal Hadi Salim @ 2016-05-02 23:40 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, phil, lucasb
In-Reply-To: <20160502151032.5701009e@xeon-e3>

On 16-05-02 06:10 PM, Stephen Hemminger wrote:
> On Sat, 30 Apr 2016 06:58:04 -0400
> Jamal Hadi Salim <jhs@mojatatu.com> wrote:
>
>> From: Lucas Bates <lucasb@mojatatu.com>
>>
>> Signed-off-by: Lucas Bates <lucasb@mojatatu.com>
>> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
>
> Still waiting for a you to respond to my earlier suggestions about tc-ife.
>

I did respond.

> Last version I saw was expecting header in include/linux which is not in
> kernel source.
>
> ~/kernel/net-next$ ls include/uapi/linux/tc_ife.h
> ls: cannot access include/uapi/linux/tc_ife.h: No such file or directory
>

What version of net-next are you looking at? This is what i see:

linux-gits/net-next$ ls  include/uapi/linux/tc_act/
Kbuild         tc_csum.h      tc_ife.h       tc_nat.h       tc_vlan.h
tc_bpf.h       tc_defact.h    tc_ipt.h       tc_pedit.h
tc_connmark.h  tc_gact.h      tc_mirred.h    tc_skbedit.h


> You need to get that header in right place, and get it exported correctly.

And I saw you sending a patch which tried to export everything. What
did i miss? ;-> If that didnt make i will send one just for IFE.


cheers,
jamal

PS:- I have other patches which fix a small issue with some actions
(which include ife) - but they are depending on this other one going
in.

^ permalink raw reply

* Re: [PATCH net-next 0/4] net: hns: update DT properties according to Rob's comments
From: Yisen Zhuang @ 2016-05-03  0:54 UTC (permalink / raw)
  To: David Miller
  Cc: devicetree, netdev, linux-arm-kernel, robh+dt, pawel.moll,
	mark.rutland, ijc+devicetree, galak, will.deacon, catalin.marinas,
	yankejian, huangdaode, salil.mehta, lipeng321, liguozhu,
	xieqianqian, xuwei5, linuxarm
In-Reply-To: <20160429.133949.1719521222260369497.davem@davemloft.net>

Hi David,

Thanks for applying the patches.

The series which i reposted is my misoperation. Please ignore them.

Thanks,

Yisen

在 2016/4/30 1:39, David Miller 写道:
> From: Yisen Zhuang <Yisen.Zhuang@huawei.com>
> Date: Thu, 28 Apr 2016 15:09:00 +0800
> 
>> There are some inappropriate properties definition in hns DT. We update the definition
>> according to Rob's review comments and fix some typos in binding.
>>
>> For more details, please see individual patches.
> 
> Series applied, thanks.
> 
> BTW, you reposted your 10 part series for adding the dsaf-debug device, but I
> already applied the series you posted for that nearly a week ago.
> 
> .
> 

^ permalink raw reply

* Re: [PATCH net-next] fq_codel: add batch ability to fq_codel_drop()
From: Dave Taht @ 2016-05-03  1:07 UTC (permalink / raw)
  To: Jesper Dangaard Brouer
  Cc: Eric Dumazet, David Miller, netdev, Jonathan Morton
In-Reply-To: <20160502191543.170fc046@redhat.com>

I have duplicated the issue on my own hardware. I would like to
explore also upping the codel count in this scenario at some point,
but:

Acked-by: Dave Taht

^ permalink raw reply

* Re: [PATCH net 2/3] udp_offload: Set encapsulation before inner completes.
From: Alexander Duyck @ 2016-05-03  1:22 UTC (permalink / raw)
  To: Tom Herbert; +Cc: Jarno Rajahalme, Netdev, Jesse Gross
In-Reply-To: <CALx6S35QFms9KUE1K4c5odN7QCuvpBaeeL=yjfMBFxqFfcTSWg@mail.gmail.com>

On Mon, May 2, 2016 at 4:18 PM, Tom Herbert <tom@herbertland.com> wrote:
> On Mon, May 2, 2016 at 3:54 PM, Alexander Duyck
> <alexander.duyck@gmail.com> wrote:
>> On Mon, May 2, 2016 at 2:21 PM, Jarno Rajahalme <jarno@ovn.org> wrote:
>>>
>>>> On Apr 29, 2016, at 8:46 PM, Alexander Duyck <alexander.duyck@gmail.com> wrote:
>>>>
>>>> On Fri, Apr 29, 2016 at 3:28 PM, Jarno Rajahalme <jarno@ovn.org> wrote:
>>>>> UDP tunnel segmentation code relies on the inner offsets being set for
>>>>> an UDP tunnel GSO packet.  The inner *_complete() functions will set
>>>>> the inner offsets only if the encapsulation is set before calling
>>>>> them, but udp_gro_complete() set it only after the inner *_complete()
>>>>> functions were done.
>>>>>
>>>>> Also, remove the setting of the inner_mac_header in udp_gro_complete()
>>>>> as it was wrongly set to the beginning of the UDP tunnel header rather
>>>>> than the inner MAC header.
>>>>>
>>>>> Signed-off-by: Jarno Rajahalme <jarno@ovn.org>
>>>>> ---
>>>>> net/ipv4/udp_offload.c | 8 +++++---
>>>>> 1 file changed, 5 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
>>>>> index 0ed2daf..e330c0e 100644
>>>>> --- a/net/ipv4/udp_offload.c
>>>>> +++ b/net/ipv4/udp_offload.c
>>>>> @@ -399,6 +399,11 @@ int udp_gro_complete(struct sk_buff *skb, int nhoff)
>>>>>
>>>>>        uh->len = newlen;
>>>>>
>>>>> +       /* Set encapsulation before calling into inner gro_complete() functions
>>>>> +        * to make them set up the inner offsets.
>>>>> +        */
>>>>> +       skb->encapsulation = 1;
>>>>> +
>>>>>        rcu_read_lock();
>>>>>
>>>>>        uo_priv = rcu_dereference(udp_offload_base);
>>>>> @@ -421,9 +426,6 @@ int udp_gro_complete(struct sk_buff *skb, int nhoff)
>>>>>        if (skb->remcsum_offload)
>>>>>                skb_shinfo(skb)->gso_type |= SKB_GSO_TUNNEL_REMCSUM;
>>>>>
>>>>> -       skb->encapsulation = 1;
>>>>> -       skb_set_inner_mac_header(skb, nhoff + sizeof(struct udphdr));
>>>>> -
>>>>>        return err;
>>>>> }
>>>>>
>>>>> --
>>>>> 2.7.4
>>>>>
>>>>
>>>> So looking over this I think this patch is just a band-aid and it
>>>> isn't really fixing much of anything.  For example I cannot see where
>>>
>>> It fixes the immediate bug/problem that segmentation of GRO UDP tunnel packet fails due to incorrectly set inner MAC offset and/or missing inner network offset.
>>
>> The problem is I think this will introduce other issues as there are
>> now situations where the inner MAC offset never gets set.  For example
>> did you try testing with GUE carrying either an IPIP or SIT tunnel?
>>
>> From what I can tell it looks like you are trying to fix VXLAN and
>> similar offloads, and Tom is focused on GUE.  What you will probably
>> need to do is add some code to ipip_gro_complete and sit_gro_complete
>> so that if skb->encapsulation is set before you call the function it
>> will set the inner MAC offset to the same offset as the inner network
>> header.  Otherwise you run the risk of screwing up segmentation
>> because the UDP tunnel segment code will use the inner mac header
>> offset when computing the tunnel header length and get it completely
>> wrong.
>>
>>>> the inner transport offset is ever set.  From what I can tell it never
>>>> is.
>>>>
>>>
>>> inner transport offset is set in validate_xmit_skb(), but you are right, it is not set by the GRO complete code path. AFAIK no-one uses it before reaching validate_xmit_skb(), though. The documentation in (net-next) Documentation/networking/segmentation-offloads.txt could be fixed by removing the inner transport header from UDP/GRE tunnel case, as it is not used by either the GRE or UDP tunnel code.
>>
>> Actually that is an interesting point.  Right now we need to keep the
>> inner transport header around because that is getting set.  If we were
>> to enforce the use of csum_start as the inner transport header offset,
>> then we could assume that transport_header is always the outer-most
>> transport header.  We might be able to drop a bit of space from the
>> skbuff by getting rid of it.  If nothing else it means one less header
>> offset we would have to copy.
>>
> Or can we just eliminate the inner headers altogether? IIRC the only
> sticking point for GSO needing this was ipid, all the inner headers
> are just copied per packet assuming segment lengths are the same. Is
> this possible yet?

Actually the big two we need are the inner MAC offset and the inner
network offset.  We end up needing the MAC header in order to be able
to UDP checksum offloads because that is how we are currently
measuring the length of the header itself.  As you said we end up
needing the inner network header offset in order to handle the inner
IP ID field and checksum.

I was doing a bit of digging and found that the whole reason for
csum_start is essentially for the same use cases as the
inner_transport_header.  It was a means of storing off the pointer to
the transport header in the event that you have a packet that goes
through some receive processing that we then have to transmit.  On top
of that the only two spots where we actually set it are in
skb_reset_inner_headers which should only be called if we are
performing an offload of some sort on the inner headers, and
validate_xmit_skb when we are supposed to be performing a checksum and
in that case we just overwrite the inner_transport_header offset
anyway.

- Alex

^ permalink raw reply

* [PATCH next] netdevice: shrink size of struct netdev_queue
From: Florian Westphal @ 2016-05-03  1:29 UTC (permalink / raw)
  To: netdev; +Cc: Florian Westphal

- trans_timeout is incremented when tx queue timed out (tx watchdog).
- tx_maxrate is set via sysfs

Moving tx_maxrate to read-mostly part shrinks the struct by 64 bytes.
While at it, also move trans_timeout (it is out-of-place in the
'write-mostly' part).

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 include/linux/netdevice.h | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 52914a8..f218259 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -569,6 +569,12 @@ struct netdev_queue {
 #if defined(CONFIG_XPS) && defined(CONFIG_NUMA)
 	int			numa_node;
 #endif
+	unsigned long		tx_maxrate;
+	/*
+	 * Number of TX timeouts for this queue
+	 * (/sys/class/net/DEV/Q/trans_timeout)
+	 */
+	unsigned long		trans_timeout;
 /*
  * write-mostly part
  */
@@ -579,18 +585,11 @@ struct netdev_queue {
 	 */
 	unsigned long		trans_start;
 
-	/*
-	 * Number of TX timeouts for this queue
-	 * (/sys/class/net/DEV/Q/trans_timeout)
-	 */
-	unsigned long		trans_timeout;
-
 	unsigned long		state;
 
 #ifdef CONFIG_BQL
 	struct dql		dql;
 #endif
-	unsigned long		tx_maxrate;
 } ____cacheline_aligned_in_smp;
 
 static inline int netdev_queue_numa_node_read(const struct netdev_queue *q)
-- 
2.7.3

^ permalink raw reply related

* [PATCH net] net: macb: Probe MDIO bus before registering netdev
From: Florian Fainelli @ 2016-05-03  1:38 UTC (permalink / raw)
  To: netdev; +Cc: nicolas.ferre, davem, Florian Fainelli

The current sequence makes us register for a network device prior to
registering and probing the MDIO bus which could lead to some unwanted
consequences, like a thread of execution calling into ndo_open before
register_netdev() returns, while the MDIO bus is not ready yet.

Rework the sequence to register for the MDIO bus, and therefore attach
to a PHY prior to calling register_netdev(), which implies reworking the
error path a bit.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Tracking down the exact commit which started doing that was a little
difficult, so I can't really provide a proper Fixes tag yet that does
not reference 4-5 commits

 drivers/net/ethernet/cadence/macb.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 48a7d7dee846..e9b470a5ddd0 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -441,7 +441,7 @@ static int macb_mii_init(struct macb *bp)
 	snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
 		bp->pdev->name, bp->pdev->id);
 	bp->mii_bus->priv = bp;
-	bp->mii_bus->parent = &bp->dev->dev;
+	bp->mii_bus->parent = &bp->pdev->dev;
 	pdata = dev_get_platdata(&bp->pdev->dev);
 
 	dev_set_drvdata(&bp->dev->dev, bp->mii_bus);
@@ -3019,29 +3019,36 @@ static int macb_probe(struct platform_device *pdev)
 	if (err)
 		goto err_out_free_netdev;
 
+	err = macb_mii_init(bp);
+	if (err)
+		goto err_out_free_netdev;
+
+	phydev = bp->phy_dev;
+
+	netif_carrier_off(dev);
+
 	err = register_netdev(dev);
 	if (err) {
 		dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
-		goto err_out_unregister_netdev;
+		goto err_out_unregister_mdio;
 	}
 
-	err = macb_mii_init(bp);
-	if (err)
-		goto err_out_unregister_netdev;
-
-	netif_carrier_off(dev);
+	phy_attached_info(phydev);
 
 	netdev_info(dev, "Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\n",
 		    macb_is_gem(bp) ? "GEM" : "MACB", macb_readl(bp, MID),
 		    dev->base_addr, dev->irq, dev->dev_addr);
 
-	phydev = bp->phy_dev;
-	phy_attached_info(phydev);
-
 	return 0;
 
-err_out_unregister_netdev:
-	unregister_netdev(dev);
+err_out_unregister_mdio:
+	phy_disconnect(bp->phy_dev);
+	mdiobus_unregister(bp->mii_bus);
+	mdiobus_free(bp->mii_bus);
+
+	/* Shutdown the PHY if there is a GPIO reset */
+	if (bp->reset_gpio)
+		gpiod_set_value(bp->reset_gpio, 0);
 
 err_out_free_netdev:
 	free_netdev(dev);
-- 
2.1.0

^ permalink raw reply related

* Re: [PATCH next] netdevice: shrink size of struct netdev_queue
From: Eric Dumazet @ 2016-05-03  1:49 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netdev
In-Reply-To: <1462238949-3271-1-git-send-email-fw@strlen.de>

On Tue, 2016-05-03 at 03:29 +0200, Florian Westphal wrote:
> - trans_timeout is incremented when tx queue timed out (tx watchdog).
> - tx_maxrate is set via sysfs
> 
> Moving tx_maxrate to read-mostly part shrinks the struct by 64 bytes.
> While at it, also move trans_timeout (it is out-of-place in the
> 'write-mostly' part).
> 
> Signed-off-by: Florian Westphal <fw@strlen.de>
> ---

Acked-by: Eric Dumazet <edumazet@google.com>

^ permalink raw reply

* Re: [PATCH next-next 0/7] net: Cleanup IPv6 ip tunnels
From: Alexander Duyck @ 2016-05-03  2:03 UTC (permalink / raw)
  To: Tom Herbert; +Cc: David Miller, Netdev, Kernel Team
In-Reply-To: <1461975141-954269-1-git-send-email-tom@herbertland.com>

On Fri, Apr 29, 2016 at 5:12 PM, Tom Herbert <tom@herbertland.com> wrote:
> The IPv6 tunnel code is very different from IPv4 code. There is a lot
> of redundancy with the IPv4 code, particularly in the GRE tunneling.
>
> This patch set cleans up the tunnel code to make the IPv6 code look
> more like the IPv4 code and use common functions between the two
> stacks where possible.
>
> This work should make it easier to maintain and extend the IPv6 ip
> tunnels.
>
> Items in this patch set:
>   - Cleanup IPv6 tunnel receive path (ip6_tnl_rcv). Includes using
>     gro_cells and exporting ip6_tnl_rcv so the ip6_gre can call it
>   - Move GRE functions to common header file (tx functions) or
>     gre_demux.c (rx functions like gre_parse_header)
>   - Call common GRE functions from IPv6 GRE
>   - Create ip6_tnl_xmit (to be like ip_tunnel_xmit)
>
> Tested:
>   Ran super_netperf tests for TCP_RR and TCP_STREAM for:
>     - IPv4 over gre, gretap, gre6, gre6tap
>     - IPv6 over gre, gretap, gre6, gre6tap
>     - ipip
>     - ip6ip6
>     - ipip/gue
>     - IPv6 over gre/gue
>     - IPv4 over gre/gue
>
> Tom Herbert (7):
>   ipv6: Cleanup IPv6 tunnel receive path
>   gre: Move utility functions to common headers
>   gre6: Cleanup GREv6 receive path, call common GRE functions
>   ipv6: Create ip6_tnl_xmit
>   gre: Create common functions for transmit
>   ipv6: Generic tunnel cleanup
>   gre6: Cleanup GREv6 transmit path, call common GRE functions
>
>  include/net/gre.h        | 104 +++++++++++++
>  include/net/ip6_tunnel.h |  11 +-
>  net/ipv4/gre_demux.c     |  64 ++++++++
>  net/ipv4/ip_gre.c        | 199 +++---------------------
>  net/ipv6/ip6_gre.c       | 392 +++++++++--------------------------------------
>  net/ipv6/ip6_tunnel.c    | 266 +++++++++++++++++++++-----------
>  6 files changed, 452 insertions(+), 584 deletions(-)
>
> --
> 2.8.0.rc2
>

I was wondering if you have more work going on in this area or not?  I
ask because I was just going through and auditing the calls to
skb_reset_inner_headers and I think the only spot left that is calling
it without verifying that either GSO or CHECKSUM_PARTIAL is set is in
ip6_tnl_xmit.  If we can get that moved over to using
iptunnel_handle_offloads like the other functions then we should be
guaranteed that skb->encapsulation is only ever set if an offload is
requested, and that in turn guarantees that csum_start and
inner_transport_offset will always be the same value.

Thanks.

- Alex

^ permalink raw reply

* Re: [PATCH net-next v3 0/4] bridge: per-vlan stats
From: David Miller @ 2016-05-03  2:27 UTC (permalink / raw)
  To: nikolay; +Cc: netdev, roopa, stephen
In-Reply-To: <1462004729-12185-1-git-send-email-nikolay@cumulusnetworks.com>

From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Date: Sat, 30 Apr 2016 10:25:25 +0200

> This set adds support for bridge per-vlan statistics.

This looks a lot better, series applied, thanks!

^ permalink raw reply

* Re: [PATCH net-next] ipv6: add new struct ipcm6_cookie
From: David Miller @ 2016-05-03  2:39 UTC (permalink / raw)
  To: weiwan; +Cc: netdev, edumazet
In-Reply-To: <1461976272-10738-1-git-send-email-tracywwnj@gmail.com>

From: Wei Wang <weiwan@google.com>
Date: Fri, 29 Apr 2016 17:31:12 -0700

> From: Wei Wang <weiwan@google.com>
> 
> In the sendmsg function of UDP, raw, ICMP and l2tp sockets, we use local
> variables like hlimits, tclass, opt and dontfrag and pass them to corresponding
> functions like ip6_make_skb, ip6_append_data and xxx_push_pending_frames.
> This is not a good practice and makes it hard to add new parameters.
> This fix introduces a new struct ipcm6_cookie similar to ipcm_cookie in
> ipv4 and include the above mentioned variables. And we only pass the
> pointer to this structure to corresponding functions. This makes it easier
> to add new parameters in the future and makes the function cleaner.
> 
> Signed-off-by: Wei Wang <weiwan@google.com>

Looks good, applied, thank you.

^ permalink raw reply

* Re: [PATCH] ip: add udp_csum, udp6_csum_tx, udp6_csum_rx control flags to ip l2tp add tunnel
From: Wang Shanker @ 2016-05-03  2:40 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: James Chapman, netdev
In-Reply-To: <20160502151910.3a1f6f3d@xeon-e3>

[-- Attachment #1: Type: text/plain, Size: 2198 bytes --]

Thanks a lot.

I feel it excited to contribute to the development of kernel. I’ll do 
better next time.

> 在 2016年5月3日,06:19,Stephen Hemminger <stephen@networkplumber.org> 写道:
> 
> On Thu, 28 Apr 2016 15:50:47 +0100
> James Chapman <jchapman@katalix.com> wrote:
> 
>> Yes, that looks like the problem.
>> 
>> The comments in l2tp.h which indicate that the csum attributes are u8
>> values are wrong. Code in net/l2tp/l2tp_netlink.c accesses these
>> attributes using nla_get_flag().
>> 
>> Please submit a patch to fix l2tp_tunnel_sock_create(). Include good
>> change notes and your signed-off-by tag so that it gets reviewed. See
>> Documentation/SubmittingPatches if you haven't submitted a kernel
>> patch here before.
> 
> Thank you for fixing this. James is is correct.
> Please format the patch according to the submission guidelines.
> For example, checkpatch complains about current patch.
> 
> ERROR: code indent should use tabs where possible
> #156: FILE: net/l2tp/l2tp_core.c:1379:
> +                         ! cfg->udp6_zero_tx_checksums;$
> 
> WARNING: please, no spaces at the start of a line
> #156: FILE: net/l2tp/l2tp_core.c:1379:
> +                         ! cfg->udp6_zero_tx_checksums;$
> 
> ERROR: space prohibited after that '!' (ctx:ExW)
> #156: FILE: net/l2tp/l2tp_core.c:1379:
> +                         ! cfg->udp6_zero_tx_checksums;
>                          ^
> 
> ERROR: code indent should use tabs where possible
> #159: FILE: net/l2tp/l2tp_core.c:1381:
> +                         ! cfg->udp6_zero_rx_checksums;$
> 
> WARNING: please, no spaces at the start of a line
> #159: FILE: net/l2tp/l2tp_core.c:1381:
> +                         ! cfg->udp6_zero_rx_checksums;$
> 
> ERROR: space prohibited after that '!' (ctx:ExW)
> #159: FILE: net/l2tp/l2tp_core.c:1381:
> +                         ! cfg->udp6_zero_rx_checksums;
>                          ^
> 
> ERROR: Missing Signed-off-by: line(s)
> 
> 
> I am sorry that maintainers may seem like picky teachers in school
> always putting redline around spelling errors, but this is how we work to teach
> others how to follow the process.
> 


[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 4130 bytes --]

^ permalink raw reply

* Re: [PATCH net-next] ipv6: add new struct ipcm6_cookie
From: David Miller @ 2016-05-03  2:46 UTC (permalink / raw)
  To: weiwan; +Cc: netdev, edumazet
In-Reply-To: <20160502.223945.1841569316439730448.davem@davemloft.net>

From: David Miller <davem@davemloft.net>
Date: Mon, 02 May 2016 22:39:45 -0400 (EDT)

> From: Wei Wang <weiwan@google.com>
> Date: Fri, 29 Apr 2016 17:31:12 -0700
> 
>> From: Wei Wang <weiwan@google.com>
>> 
>> In the sendmsg function of UDP, raw, ICMP and l2tp sockets, we use local
>> variables like hlimits, tclass, opt and dontfrag and pass them to corresponding
>> functions like ip6_make_skb, ip6_append_data and xxx_push_pending_frames.
>> This is not a good practice and makes it hard to add new parameters.
>> This fix introduces a new struct ipcm6_cookie similar to ipcm_cookie in
>> ipv4 and include the above mentioned variables. And we only pass the
>> pointer to this structure to corresponding functions. This makes it easier
>> to add new parameters in the future and makes the function cleaner.
>> 
>> Signed-off-by: Wei Wang <weiwan@google.com>
> 
> Looks good, applied, thank you.

Actually I had to revert, this break the build.

net/l2tp/l2tp_ip6.c: In function ‘l2tp_ip6_sendmsg’:
net/l2tp/l2tp_ip6.c:634:10: error: invalid operands to binary & (have ‘struct ipcm6_cookie *’ and ‘struct flowi6’)
          &fl6, (struct rt6_info *)dst,
          ^
net/l2tp/l2tp_ip6.c:634:16: warning: passing argument 7 of ‘ip6_append_data’ from incompatible pointer type
          &fl6, (struct rt6_info *)dst,
                ^

and so on and so forth...

^ permalink raw reply

* Re: [PATCH next] netdevice: shrink size of struct netdev_queue
From: David Miller @ 2016-05-03  2:51 UTC (permalink / raw)
  To: fw; +Cc: netdev
In-Reply-To: <1462238949-3271-1-git-send-email-fw@strlen.de>

From: Florian Westphal <fw@strlen.de>
Date: Tue,  3 May 2016 03:29:09 +0200

> - trans_timeout is incremented when tx queue timed out (tx watchdog).
> - tx_maxrate is set via sysfs
> 
> Moving tx_maxrate to read-mostly part shrinks the struct by 64 bytes.
> While at it, also move trans_timeout (it is out-of-place in the
> 'write-mostly' part).
> 
> Signed-off-by: Florian Westphal <fw@strlen.de>

Applied, thanks Florian.

^ permalink raw reply

* Re: [PATCH] vhost_net: stop polling socket during rx processing
From: Jason Wang @ 2016-05-03  2:52 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: netdev, linux-kernel, kvm, virtualization
In-Reply-To: <5721AB7B.8070806@redhat.com>



On 04/28/2016 02:19 PM, Jason Wang wrote:
> On 04/27/2016 07:28 PM, Michael S. Tsirkin wrote:
>> > On Tue, Apr 26, 2016 at 03:35:53AM -0400, Jason Wang wrote:
>>> >> We don't stop polling socket during rx processing, this will lead
>>> >> unnecessary wakeups from under layer net devices (E.g
>>> >> sock_def_readable() form tun). Rx will be slowed down in this
>>> >> way. This patch avoids this by stop polling socket during rx
>>> >> processing. A small drawback is that this introduces some overheads in
>>> >> light load case because of the extra start/stop polling, but single
>>> >> netperf TCP_RR does not notice any change. In a super heavy load case,
>>> >> e.g using pktgen to inject packet to guest, we get about ~17%
>>> >> improvement on pps:
>>> >>
>>> >> before: ~1370000 pkt/s
>>> >> after:  ~1500000 pkt/s
>>> >>
>>> >> Signed-off-by: Jason Wang <jasowang@redhat.com>
>> > Acked-by: Michael S. Tsirkin <mst@redhat.com>
>> >
>> > There is one other possible enhancement: we actually have the wait queue
>> > lock taken in _wake_up, but we give it up only to take it again in the
>> > handler.
>> >
>> > It would be nicer to just remove the entry when we wake
>> > the vhost thread. Re-add it if required.
>> > I think that something like the below would give you the necessary API.
>> > Pls feel free to use it if you are going to implement a patch on top
>> > doing this - that's not a reason not to include this simple patch
>> > though.
> Thanks, this looks useful, will give it a try.

Want to try, but looks like this will result a strange API:

- poll were removed automatically during wakeup, handler does not need
to care about this
- but handler still need to re-add the poll explicitly in the code

?

^ permalink raw reply

* linux-next: manual merge of the net-next tree with Linus' tree
From: Stephen Rothwell @ 2016-05-03  3:15 UTC (permalink / raw)
  To: David Miller, netdev; +Cc: linux-next, linux-kernel, Jiri Benc, Tom Herbert

Hi all,

Today's linux-next merge of the net-next tree got a conflict in:

  net/ipv4/ip_gre.c

between commits:

  2090714e1d6e ("gre: build header correctly for collect metadata tunnels")
  b7f8fe251e46 ("gre: do not pull header in ICMP error processing")

from Linus' tree and commit:

  95f5c64c3c13 ("gre: Move utility functions to common headers")
  182a352d2d5e ("gre: Create common functions for transmit")

from the net-next tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

-- 
Cheers,
Stephen Rothwell

diff --cc net/ipv4/ip_gre.c
index 205a2b8a5a84,2480d79b0e37..000000000000
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@@ -341,8 -221,9 +221,9 @@@ static void gre_err(struct sk_buff *skb
  	const int code = icmp_hdr(skb)->code;
  	struct tnl_ptk_info tpi;
  	bool csum_err = false;
+ 	int hdr_len;
  
- 	if (parse_gre_header(skb, &tpi, &csum_err) < 0) {
 -	if (gre_parse_header(skb, &tpi, &csum_err, &hdr_len)) {
++	if (gre_parse_header(skb, &tpi, &csum_err, &hdr_len) < 0) {
  		if (!csum_err)		/* ignore csum errors. */
  			return;
  	}
@@@ -574,15 -414,12 +415,12 @@@ static void gre_fb_xmit(struct sk_buff 
  	}
  
  	/* Push Tunnel header. */
- 	skb = gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM));
- 	if (IS_ERR(skb)) {
- 		skb = NULL;
+ 	if (gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM)))
  		goto err_free_rt;
- 	}
  
  	flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY);
- 	build_header(skb, tunnel_hlen, flags, proto,
- 		     tunnel_id_to_key(tun_info->key.tun_id), 0);
 -	gre_build_header(skb, tunnel_hlen, flags, htons(ETH_P_TEB),
++	gre_build_header(skb, tunnel_hlen, flags, proto,
+ 			 tunnel_id_to_key(tun_info->key.tun_id), 0);
  
  	df = key->tun_flags & TUNNEL_DONT_FRAGMENT ?  htons(IP_DF) : 0;
  

^ permalink raw reply

* Re: [PATCH net] vlan: Propagate MAC address changes properly
From: David Miller @ 2016-05-03  4:16 UTC (permalink / raw)
  To: mmanning; +Cc: netdev
In-Reply-To: <572489C5.3020502@brocade.com>

From: Mike Manning <mmanning@brocade.com>
Date: Sat, 30 Apr 2016 11:32:37 +0100

> The MAC address of the physical interface is only copied to the VLAN
> when it is first created, resulting in an inconsistency after MAC
> address changes of only newly created VLANs having an up-to-date MAC.
> 
> Continuing to inherit the MAC address unless explicitly changed for
> the VLAN allows IPv6 EUI64 addresses for the VLAN to reflect the change
> and thus for DAD to behave as expected for the given MAC.
> 
> Signed-off-by: Mike Manning <mmanning@brocade.com>

What is this code really trying to achieve?

Is it "Propagate real device MAC changes to undelying vlan device,
but not if the user set the vlan MAC explicitly."?

If so, implement that instead of all of these confusing tests.

If the vlan device's set_mac_address operation is ever called,
set a boolean value in the vlan device private to true and test
it here.

^ permalink raw reply

* Re: pull request [net]: batman-adv 20160430
From: David Miller @ 2016-05-03  4:18 UTC (permalink / raw)
  To: a
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
In-Reply-To: <1462035963-28970-1-git-send-email-a-2CpIooy/SPIKlTDg6p0iyA@public.gmane.org>

From: Antonio Quartulli <a@unstable.cc>
Date: Sun,  1 May 2016 01:05:59 +0800

> this is another pull request intended for net.
> 
> I know that I sent another batch a few days ago, but after having gone
> through my queue I thought that merging these last 4 patches would still
> be worth it (there won't be any other pull request for linux-4.6 :)).
> 
> The description of the changes follows below.

Pulled, thanks Antonio.

^ permalink raw reply

* Re: [PATCH net-next] net: relax expensive skb_unclone() in iptunnel_handle_offloads()
From: David Miller @ 2016-05-03  4:23 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev
In-Reply-To: <1462036769.5535.180.camel@edumazet-glaptop3.roam.corp.google.com>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sat, 30 Apr 2016 10:19:29 -0700

> From: Eric Dumazet <edumazet@google.com>
> 
> Locally generated TCP GSO packets having to go through a GRE/SIT/IPIP
> tunnel have to go through an expensive skb_unclone()
> 
> Reallocating skb->head is a lot of work.
> 
> Test should really check if a 'real clone' of the packet was done.
> 
> TCP does not care if the original gso_type is changed while the packet
> travels in the stack.
> 
> This adds skb_header_unclone() which is a variant of skb_clone()
> using skb_header_cloned() check instead of skb_cloned().
> 
> This variant can probably be used from other points.
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Nice observation, applied, thanks Eric.

^ permalink raw reply

* Re: [PATCHv4] netem: Segment GSO packets on enqueue
From: David Miller @ 2016-05-03  4:34 UTC (permalink / raw)
  To: nhorman; +Cc: netdev, jhs, netem, eric.dumazet, stephen
In-Reply-To: <1462206015-3484-1-git-send-email-nhorman@tuxdriver.com>

From: Neil Horman <nhorman@tuxdriver.com>
Date: Mon,  2 May 2016 12:20:15 -0400

> This was recently reported to me, and reproduced on the latest net kernel,
> when attempting to run netperf from a host that had a netem qdisc attached
> to the egress interface:
 ...
> The problem occurs because netem is not prepared to handle GSO packets (as it
> uses skb_checksum_help in its enqueue path, which cannot manipulate these
> frames).
> 
> The solution I think is to simply segment the skb in a simmilar fashion to the
> way we do in __dev_queue_xmit (via validate_xmit_skb), with some minor changes.
> When we decide to corrupt an skb, if the frame is GSO, we segment it, corrupt
> the first segment, and enqueue the remaining ones.
> 
> tested successfully by myself on the latest net kernel, to which this applies
> 
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>

Applied and queued up for -stable, thanks Neil.

^ permalink raw reply

* [PATCH net-next v2] ipv6: add new struct ipcm6_cookie
From: Wei Wang @ 2016-05-03  4:40 UTC (permalink / raw)
  To: netdev; +Cc: Wei Wang

From: Wei Wang <weiwan@google.com>

In the sendmsg function of UDP, raw, ICMP and l2tp sockets, we use local
variables like hlimits, tclass, opt and dontfrag and pass them to corresponding
functions like ip6_make_skb, ip6_append_data and xxx_push_pending_frames.
This is not a good practice and makes it hard to add new parameters.
This fix introduces a new struct ipcm6_cookie similar to ipcm_cookie in
ipv4 and include the above mentioned variables. And we only pass the
pointer to this structure to corresponding functions. This makes it easier
to add new parameters in the future and makes the function cleaner.

Signed-off-by: Wei Wang <weiwan@google.com>
---
 include/net/ipv6.h       | 18 ++++++++++++------
 include/net/transp_v6.h  |  3 +--
 net/ipv6/datagram.c      | 13 ++++++-------
 net/ipv6/icmp.c          | 28 ++++++++++++++++------------
 net/ipv6/ip6_flowlabel.c |  6 +++---
 net/ipv6/ip6_output.c    | 42 ++++++++++++++++++++----------------------
 net/ipv6/ipv6_sockglue.c |  6 +++---
 net/ipv6/ping.c          | 12 +++++++-----
 net/ipv6/raw.c           | 33 ++++++++++++++++++---------------
 net/ipv6/udp.c           | 38 +++++++++++++++++++-------------------
 net/l2tp/l2tp_ip6.c      | 33 ++++++++++++++++++---------------
 11 files changed, 123 insertions(+), 109 deletions(-)

diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 415213d..11a0452 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -251,6 +251,13 @@ struct ipv6_fl_socklist {
 	struct rcu_head			rcu;
 };
 
+struct ipcm6_cookie {
+	__s16 hlimit;
+	__s16 tclass;
+	__s8  dontfrag;
+	struct ipv6_txoptions *opt;
+};
+
 static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np)
 {
 	struct ipv6_txoptions *opt;
@@ -863,9 +870,9 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr);
 int ip6_append_data(struct sock *sk,
 		    int getfrag(void *from, char *to, int offset, int len,
 				int odd, struct sk_buff *skb),
-		    void *from, int length, int transhdrlen, int hlimit,
-		    int tclass, struct ipv6_txoptions *opt, struct flowi6 *fl6,
-		    struct rt6_info *rt, unsigned int flags, int dontfrag,
+		    void *from, int length, int transhdrlen,
+		    struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
+		    struct rt6_info *rt, unsigned int flags,
 		    const struct sockcm_cookie *sockc);
 
 int ip6_push_pending_frames(struct sock *sk);
@@ -881,9 +888,8 @@ struct sk_buff *ip6_make_skb(struct sock *sk,
 			     int getfrag(void *from, char *to, int offset,
 					 int len, int odd, struct sk_buff *skb),
 			     void *from, int length, int transhdrlen,
-			     int hlimit, int tclass, struct ipv6_txoptions *opt,
-			     struct flowi6 *fl6, struct rt6_info *rt,
-			     unsigned int flags, int dontfrag,
+			     struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
+			     struct rt6_info *rt, unsigned int flags,
 			     const struct sockcm_cookie *sockc);
 
 static inline struct sk_buff *ip6_finish_skb(struct sock *sk)
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index 2b1c345..276f976 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -41,8 +41,7 @@ void ip6_datagram_recv_specific_ctl(struct sock *sk, struct msghdr *msg,
 				    struct sk_buff *skb);
 
 int ip6_datagram_send_ctl(struct net *net, struct sock *sk, struct msghdr *msg,
-			  struct flowi6 *fl6, struct ipv6_txoptions *opt,
-			  int *hlimit, int *tclass, int *dontfrag,
+			  struct flowi6 *fl6, struct ipcm6_cookie *ipc6,
 			  struct sockcm_cookie *sockc);
 
 void ip6_dgram_sock_seq_show(struct seq_file *seq, struct sock *sp,
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index ea9ee5c..00d0c29 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -727,14 +727,13 @@ EXPORT_SYMBOL_GPL(ip6_datagram_recv_ctl);
 
 int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
 			  struct msghdr *msg, struct flowi6 *fl6,
-			  struct ipv6_txoptions *opt,
-			  int *hlimit, int *tclass, int *dontfrag,
-			  struct sockcm_cookie *sockc)
+			  struct ipcm6_cookie *ipc6, struct sockcm_cookie *sockc)
 {
 	struct in6_pktinfo *src_info;
 	struct cmsghdr *cmsg;
 	struct ipv6_rt_hdr *rthdr;
 	struct ipv6_opt_hdr *hdr;
+	struct ipv6_txoptions *opt = ipc6->opt;
 	int len;
 	int err = 0;
 
@@ -953,8 +952,8 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
 				goto exit_f;
 			}
 
-			*hlimit = *(int *)CMSG_DATA(cmsg);
-			if (*hlimit < -1 || *hlimit > 0xff) {
+			ipc6->hlimit = *(int *)CMSG_DATA(cmsg);
+			if (ipc6->hlimit < -1 || ipc6->hlimit > 0xff) {
 				err = -EINVAL;
 				goto exit_f;
 			}
@@ -974,7 +973,7 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
 				goto exit_f;
 
 			err = 0;
-			*tclass = tc;
+			ipc6->tclass = tc;
 
 			break;
 		    }
@@ -992,7 +991,7 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
 				goto exit_f;
 
 			err = 0;
-			*dontfrag = df;
+			ipc6->dontfrag = df;
 
 			break;
 		    }
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 23b9a4c..9554b99 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -401,10 +401,10 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
 	struct flowi6 fl6;
 	struct icmpv6_msg msg;
 	struct sockcm_cookie sockc_unused = {0};
+	struct ipcm6_cookie ipc6;
 	int iif = 0;
 	int addr_type = 0;
 	int len;
-	int hlimit;
 	int err = 0;
 	u32 mark = IP6_REPLY_MARK(net, skb->mark);
 
@@ -507,7 +507,10 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
 	if (IS_ERR(dst))
 		goto out;
 
-	hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
+	ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
+	ipc6.tclass = np->tclass;
+	ipc6.dontfrag = np->dontfrag;
+	ipc6.opt = NULL;
 
 	msg.skb = skb;
 	msg.offset = skb_network_offset(skb);
@@ -526,9 +529,9 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
 
 	err = ip6_append_data(sk, icmpv6_getfrag, &msg,
 			      len + sizeof(struct icmp6hdr),
-			      sizeof(struct icmp6hdr), hlimit,
-			      np->tclass, NULL, &fl6, (struct rt6_info *)dst,
-			      MSG_DONTWAIT, np->dontfrag, &sockc_unused);
+			      sizeof(struct icmp6hdr),
+			      &ipc6, &fl6, (struct rt6_info *)dst,
+			      MSG_DONTWAIT, &sockc_unused);
 	if (err) {
 		ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS);
 		ip6_flush_pending_frames(sk);
@@ -563,9 +566,8 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
 	struct flowi6 fl6;
 	struct icmpv6_msg msg;
 	struct dst_entry *dst;
+	struct ipcm6_cookie ipc6;
 	int err = 0;
-	int hlimit;
-	u8 tclass;
 	u32 mark = IP6_REPLY_MARK(net, skb->mark);
 	struct sockcm_cookie sockc_unused = {0};
 
@@ -607,19 +609,21 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
 	if (IS_ERR(dst))
 		goto out;
 
-	hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
-
 	idev = __in6_dev_get(skb->dev);
 
 	msg.skb = skb;
 	msg.offset = 0;
 	msg.type = ICMPV6_ECHO_REPLY;
 
-	tclass = ipv6_get_dsfield(ipv6_hdr(skb));
+	ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
+	ipc6.tclass = ipv6_get_dsfield(ipv6_hdr(skb));
+	ipc6.dontfrag = np->dontfrag;
+	ipc6.opt = NULL;
+
 	err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
-				sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl6,
+				sizeof(struct icmp6hdr), &ipc6, &fl6,
 				(struct rt6_info *)dst, MSG_DONTWAIT,
-				np->dontfrag, &sockc_unused);
+				&sockc_unused);
 
 	if (err) {
 		__ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS);
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 35d3ddc..b912f0d 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -373,7 +373,7 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
 		struct msghdr msg;
 		struct flowi6 flowi6;
 		struct sockcm_cookie sockc_junk;
-		int junk;
+		struct ipcm6_cookie ipc6;
 
 		err = -ENOMEM;
 		fl->opt = kmalloc(sizeof(*fl->opt) + olen, GFP_KERNEL);
@@ -390,8 +390,8 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
 		msg.msg_control = (void *)(fl->opt+1);
 		memset(&flowi6, 0, sizeof(flowi6));
 
-		err = ip6_datagram_send_ctl(net, sk, &msg, &flowi6, fl->opt,
-					    &junk, &junk, &junk, &sockc_junk);
+		ipc6.opt = fl->opt;
+		err = ip6_datagram_send_ctl(net, sk, &msg, &flowi6, &ipc6, &sockc_junk);
 		if (err)
 			goto done;
 		err = -EINVAL;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 2b3ffc5..cbf127a 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1182,12 +1182,12 @@ static void ip6_append_data_mtu(unsigned int *mtu,
 }
 
 static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
-			  struct inet6_cork *v6_cork,
-			  int hlimit, int tclass, struct ipv6_txoptions *opt,
+			  struct inet6_cork *v6_cork, struct ipcm6_cookie *ipc6,
 			  struct rt6_info *rt, struct flowi6 *fl6)
 {
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	unsigned int mtu;
+	struct ipv6_txoptions *opt = ipc6->opt;
 
 	/*
 	 * setup for corking
@@ -1229,8 +1229,8 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
 	dst_hold(&rt->dst);
 	cork->base.dst = &rt->dst;
 	cork->fl.u.ip6 = *fl6;
-	v6_cork->hop_limit = hlimit;
-	v6_cork->tclass = tclass;
+	v6_cork->hop_limit = ipc6->hlimit;
+	v6_cork->tclass = ipc6->tclass;
 	if (rt->dst.flags & DST_XFRM_TUNNEL)
 		mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
 		      rt->dst.dev->mtu : dst_mtu(&rt->dst);
@@ -1258,7 +1258,7 @@ static int __ip6_append_data(struct sock *sk,
 			     int getfrag(void *from, char *to, int offset,
 					 int len, int odd, struct sk_buff *skb),
 			     void *from, int length, int transhdrlen,
-			     unsigned int flags, int dontfrag,
+			     unsigned int flags, struct ipcm6_cookie *ipc6,
 			     const struct sockcm_cookie *sockc)
 {
 	struct sk_buff *skb, *skb_prev = NULL;
@@ -1298,7 +1298,7 @@ static int __ip6_append_data(struct sock *sk,
 		      sizeof(struct frag_hdr) : 0) +
 		     rt->rt6i_nfheader_len;
 
-	if (cork->length + length > mtu - headersize && dontfrag &&
+	if (cork->length + length > mtu - headersize && ipc6->dontfrag &&
 	    (sk->sk_protocol == IPPROTO_UDP ||
 	     sk->sk_protocol == IPPROTO_RAW)) {
 		ipv6_local_rxpmtu(sk, fl6, mtu - headersize +
@@ -1564,9 +1564,9 @@ error:
 int ip6_append_data(struct sock *sk,
 		    int getfrag(void *from, char *to, int offset, int len,
 				int odd, struct sk_buff *skb),
-		    void *from, int length, int transhdrlen, int hlimit,
-		    int tclass, struct ipv6_txoptions *opt, struct flowi6 *fl6,
-		    struct rt6_info *rt, unsigned int flags, int dontfrag,
+		    void *from, int length, int transhdrlen,
+		    struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
+		    struct rt6_info *rt, unsigned int flags,
 		    const struct sockcm_cookie *sockc)
 {
 	struct inet_sock *inet = inet_sk(sk);
@@ -1580,12 +1580,12 @@ int ip6_append_data(struct sock *sk,
 		/*
 		 * setup for corking
 		 */
-		err = ip6_setup_cork(sk, &inet->cork, &np->cork, hlimit,
-				     tclass, opt, rt, fl6);
+		err = ip6_setup_cork(sk, &inet->cork, &np->cork,
+				     ipc6, rt, fl6);
 		if (err)
 			return err;
 
-		exthdrlen = (opt ? opt->opt_flen : 0);
+		exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen : 0);
 		length += exthdrlen;
 		transhdrlen += exthdrlen;
 	} else {
@@ -1595,8 +1595,7 @@ int ip6_append_data(struct sock *sk,
 
 	return __ip6_append_data(sk, fl6, &sk->sk_write_queue, &inet->cork.base,
 				 &np->cork, sk_page_frag(sk), getfrag,
-				 from, length, transhdrlen, flags, dontfrag,
-				 sockc);
+				 from, length, transhdrlen, flags, ipc6, sockc);
 }
 EXPORT_SYMBOL_GPL(ip6_append_data);
 
@@ -1752,15 +1751,14 @@ struct sk_buff *ip6_make_skb(struct sock *sk,
 			     int getfrag(void *from, char *to, int offset,
 					 int len, int odd, struct sk_buff *skb),
 			     void *from, int length, int transhdrlen,
-			     int hlimit, int tclass,
-			     struct ipv6_txoptions *opt, struct flowi6 *fl6,
+			     struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
 			     struct rt6_info *rt, unsigned int flags,
-			     int dontfrag, const struct sockcm_cookie *sockc)
+			     const struct sockcm_cookie *sockc)
 {
 	struct inet_cork_full cork;
 	struct inet6_cork v6_cork;
 	struct sk_buff_head queue;
-	int exthdrlen = (opt ? opt->opt_flen : 0);
+	int exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen : 0);
 	int err;
 
 	if (flags & MSG_PROBE)
@@ -1772,17 +1770,17 @@ struct sk_buff *ip6_make_skb(struct sock *sk,
 	cork.base.addr = 0;
 	cork.base.opt = NULL;
 	v6_cork.opt = NULL;
-	err = ip6_setup_cork(sk, &cork, &v6_cork, hlimit, tclass, opt, rt, fl6);
+	err = ip6_setup_cork(sk, &cork, &v6_cork, ipc6, rt, fl6);
 	if (err)
 		return ERR_PTR(err);
 
-	if (dontfrag < 0)
-		dontfrag = inet6_sk(sk)->dontfrag;
+	if (ipc6->dontfrag < 0)
+		ipc6->dontfrag = inet6_sk(sk)->dontfrag;
 
 	err = __ip6_append_data(sk, fl6, &queue, &cork.base, &v6_cork,
 				&current->task_frag, getfrag, from,
 				length + exthdrlen, transhdrlen + exthdrlen,
-				flags, dontfrag, sockc);
+				flags, ipc6, sockc);
 	if (err) {
 		__ip6_flush_pending_frames(sk, &queue, &cork, &v6_cork);
 		return ERR_PTR(err);
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 4ff4b29..a9895e1 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -473,7 +473,7 @@ sticky_done:
 		struct msghdr msg;
 		struct flowi6 fl6;
 		struct sockcm_cookie sockc_junk;
-		int junk;
+		struct ipcm6_cookie ipc6;
 
 		memset(&fl6, 0, sizeof(fl6));
 		fl6.flowi6_oif = sk->sk_bound_dev_if;
@@ -503,9 +503,9 @@ sticky_done:
 
 		msg.msg_controllen = optlen;
 		msg.msg_control = (void *)(opt+1);
+		ipc6.opt = opt;
 
-		retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, opt, &junk,
-					     &junk, &junk, &sockc_junk);
+		retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, &ipc6, &sockc_junk);
 		if (retv)
 			goto done;
 update:
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index da1cff7..3ee3e44 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -58,11 +58,11 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	int iif = 0;
 	struct flowi6 fl6;
 	int err;
-	int hlimit;
 	struct dst_entry *dst;
 	struct rt6_info *rt;
 	struct pingfakehdr pfh;
 	struct sockcm_cookie junk = {0};
+	struct ipcm6_cookie ipc6;
 
 	pr_debug("ping_v6_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num);
 
@@ -139,13 +139,15 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	pfh.wcheck = 0;
 	pfh.family = AF_INET6;
 
-	hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
+	ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
+	ipc6.tclass = np->tclass;
+	ipc6.dontfrag = np->dontfrag;
+	ipc6.opt = NULL;
 
 	lock_sock(sk);
 	err = ip6_append_data(sk, ping_getfrag, &pfh, len,
-			      0, hlimit,
-			      np->tclass, NULL, &fl6, rt,
-			      MSG_DONTWAIT, np->dontfrag, &junk);
+			      0, &ipc6, &fl6, rt,
+			      MSG_DONTWAIT, &junk);
 
 	if (err) {
 		ICMP6_INC_STATS(sock_net(sk), rt->rt6i_idev,
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index b07ce21..896350d 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -746,10 +746,8 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	struct raw6_frag_vec rfv;
 	struct flowi6 fl6;
 	struct sockcm_cookie sockc;
+	struct ipcm6_cookie ipc6;
 	int addr_len = msg->msg_namelen;
-	int hlimit = -1;
-	int tclass = -1;
-	int dontfrag = -1;
 	u16 proto;
 	int err;
 
@@ -770,6 +768,11 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 
 	fl6.flowi6_mark = sk->sk_mark;
 
+	ipc6.hlimit = -1;
+	ipc6.tclass = -1;
+	ipc6.dontfrag = -1;
+	ipc6.opt = NULL;
+
 	if (sin6) {
 		if (addr_len < SIN6_LEN_RFC2133)
 			return -EINVAL;
@@ -827,10 +830,9 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 		opt = &opt_space;
 		memset(opt, 0, sizeof(struct ipv6_txoptions));
 		opt->tot_len = sizeof(struct ipv6_txoptions);
+		ipc6.opt = opt;
 
-		err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
-					    &hlimit, &tclass, &dontfrag,
-					    &sockc);
+		err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, &ipc6, &sockc);
 		if (err < 0) {
 			fl6_sock_release(flowlabel);
 			return err;
@@ -846,7 +848,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	if (!opt) {
 		opt = txopt_get(np);
 		opt_to_free = opt;
-		}
+	}
 	if (flowlabel)
 		opt = fl6_merge_options(&opt_space, flowlabel, opt);
 	opt = ipv6_fixup_options(&opt_space, opt);
@@ -881,14 +883,14 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 		err = PTR_ERR(dst);
 		goto out;
 	}
-	if (hlimit < 0)
-		hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
+	if (ipc6.hlimit < 0)
+		ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
 
-	if (tclass < 0)
-		tclass = np->tclass;
+	if (ipc6.tclass < 0)
+		ipc6.tclass = np->tclass;
 
-	if (dontfrag < 0)
-		dontfrag = np->dontfrag;
+	if (ipc6.dontfrag < 0)
+		ipc6.dontfrag = np->dontfrag;
 
 	if (msg->msg_flags&MSG_CONFIRM)
 		goto do_confirm;
@@ -897,10 +899,11 @@ back_from_confirm:
 	if (inet->hdrincl)
 		err = rawv6_send_hdrinc(sk, msg, len, &fl6, &dst, msg->msg_flags);
 	else {
+		ipc6.opt = opt;
 		lock_sock(sk);
 		err = ip6_append_data(sk, raw6_getfrag, &rfv,
-			len, 0, hlimit, tclass, opt, &fl6, (struct rt6_info *)dst,
-			msg->msg_flags, dontfrag, &sockc);
+			len, 0, &ipc6, &fl6, (struct rt6_info *)dst,
+			msg->msg_flags, &sockc);
 
 		if (err)
 			ip6_flush_pending_frames(sk);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 1ba5a74..a4dc7ba 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1064,11 +1064,9 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	struct ip6_flowlabel *flowlabel = NULL;
 	struct flowi6 fl6;
 	struct dst_entry *dst;
+	struct ipcm6_cookie ipc6;
 	int addr_len = msg->msg_namelen;
 	int ulen = len;
-	int hlimit = -1;
-	int tclass = -1;
-	int dontfrag = -1;
 	int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
 	int err;
 	int connected = 0;
@@ -1076,6 +1074,10 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
 	struct sockcm_cookie sockc;
 
+	ipc6.hlimit = -1;
+	ipc6.tclass = -1;
+	ipc6.dontfrag = -1;
+
 	/* destination address check */
 	if (sin6) {
 		if (addr_len < offsetof(struct sockaddr, sa_data))
@@ -1200,10 +1202,9 @@ do_udp_sendmsg:
 		opt = &opt_space;
 		memset(opt, 0, sizeof(struct ipv6_txoptions));
 		opt->tot_len = sizeof(*opt);
+		ipc6.opt = opt;
 
-		err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
-					    &hlimit, &tclass, &dontfrag,
-					    &sockc);
+		err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, &ipc6, &sockc);
 		if (err < 0) {
 			fl6_sock_release(flowlabel);
 			return err;
@@ -1224,6 +1225,7 @@ do_udp_sendmsg:
 	if (flowlabel)
 		opt = fl6_merge_options(&opt_space, flowlabel, opt);
 	opt = ipv6_fixup_options(&opt_space, opt);
+	ipc6.opt = opt;
 
 	fl6.flowi6_proto = sk->sk_protocol;
 	if (!ipv6_addr_any(daddr))
@@ -1253,11 +1255,11 @@ do_udp_sendmsg:
 		goto out;
 	}
 
-	if (hlimit < 0)
-		hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
+	if (ipc6.hlimit < 0)
+		ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
 
-	if (tclass < 0)
-		tclass = np->tclass;
+	if (ipc6.tclass < 0)
+		ipc6.tclass = np->tclass;
 
 	if (msg->msg_flags&MSG_CONFIRM)
 		goto do_confirm;
@@ -1268,9 +1270,9 @@ back_from_confirm:
 		struct sk_buff *skb;
 
 		skb = ip6_make_skb(sk, getfrag, msg, ulen,
-				   sizeof(struct udphdr), hlimit, tclass, opt,
+				   sizeof(struct udphdr), &ipc6,
 				   &fl6, (struct rt6_info *)dst,
-				   msg->msg_flags, dontfrag, &sockc);
+				   msg->msg_flags, &sockc);
 		err = PTR_ERR(skb);
 		if (!IS_ERR_OR_NULL(skb))
 			err = udp_v6_send_skb(skb, &fl6);
@@ -1291,14 +1293,12 @@ back_from_confirm:
 	up->pending = AF_INET6;
 
 do_append_data:
-	if (dontfrag < 0)
-		dontfrag = np->dontfrag;
+	if (ipc6.dontfrag < 0)
+		ipc6.dontfrag = np->dontfrag;
 	up->len += ulen;
-	err = ip6_append_data(sk, getfrag, msg, ulen,
-		sizeof(struct udphdr), hlimit, tclass, opt, &fl6,
-		(struct rt6_info *)dst,
-		corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, dontfrag,
-		&sockc);
+	err = ip6_append_data(sk, getfrag, msg, ulen, sizeof(struct udphdr),
+			      &ipc6, &fl6, (struct rt6_info *)dst,
+			      corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, &sockc);
 	if (err)
 		udp_v6_flush_pending_frames(sk);
 	else if (!corkreq)
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index 46e0726..ca215e7 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -495,10 +495,8 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	struct dst_entry *dst = NULL;
 	struct flowi6 fl6;
 	struct sockcm_cookie sockc_unused = {0};
+	struct ipcm6_cookie ipc6;
 	int addr_len = msg->msg_namelen;
-	int hlimit = -1;
-	int tclass = -1;
-	int dontfrag = -1;
 	int transhdrlen = 4; /* zero session-id */
 	int ulen = len + transhdrlen;
 	int err;
@@ -520,6 +518,10 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 
 	fl6.flowi6_mark = sk->sk_mark;
 
+	ipc6.hlimit = -1;
+	ipc6.tclass = -1;
+	ipc6.dontfrag = -1;
+
 	if (lsa) {
 		if (addr_len < SIN6_LEN_RFC2133)
 			return -EINVAL;
@@ -564,11 +566,11 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 		opt = &opt_space;
 		memset(opt, 0, sizeof(struct ipv6_txoptions));
 		opt->tot_len = sizeof(struct ipv6_txoptions);
+		ipc6.opt = opt;
 
-                err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
-                                            &hlimit, &tclass, &dontfrag,
-                                            &sockc_unused);
-                if (err < 0) {
+		err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, &ipc6,
+					    &sockc_unused);
+		if (err < 0) {
 			fl6_sock_release(flowlabel);
 			return err;
 		}
@@ -588,6 +590,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	if (flowlabel)
 		opt = fl6_merge_options(&opt_space, flowlabel, opt);
 	opt = ipv6_fixup_options(&opt_space, opt);
+	ipc6.opt = opt;
 
 	fl6.flowi6_proto = sk->sk_protocol;
 	if (!ipv6_addr_any(daddr))
@@ -612,14 +615,14 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 		goto out;
 	}
 
-	if (hlimit < 0)
-		hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
+	if (ipc6.hlimit < 0)
+		ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
 
-	if (tclass < 0)
-		tclass = np->tclass;
+	if (ipc6.tclass < 0)
+		ipc6.tclass = np->tclass;
 
-	if (dontfrag < 0)
-		dontfrag = np->dontfrag;
+	if (ipc6.dontfrag < 0)
+		ipc6.dontfrag = np->dontfrag;
 
 	if (msg->msg_flags & MSG_CONFIRM)
 		goto do_confirm;
@@ -627,9 +630,9 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 back_from_confirm:
 	lock_sock(sk);
 	err = ip6_append_data(sk, ip_generic_getfrag, msg,
-			      ulen, transhdrlen, hlimit, tclass, opt,
+			      ulen, transhdrlen, &ipc6,
 			      &fl6, (struct rt6_info *)dst,
-			      msg->msg_flags, dontfrag, &sockc_unused);
+			      msg->msg_flags, &sockc_unused);
 	if (err)
 		ip6_flush_pending_frames(sk);
 	else if (!(msg->msg_flags & MSG_MORE))
-- 
2.8.0.rc3.226.g39d4020

^ 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