Netdev List
 help / color / mirror / Atom feed
* Re: [PATCHv5 net-next 0/3] sunvnet: add jumbo frames support
From: Sowmini Varadhan @ 2014-09-17 22:33 UTC (permalink / raw)
  To: David L Stevens; +Cc: David Miller, netdev
In-Reply-To: <5419F3DC.60104@oracle.com>

> 
>  arch/sparc/include/asm/vio.h       |   44 ++++++++++-
>  arch/sparc/kernel/ldc.c            |    2 +-
>  arch/sparc/kernel/viohs.c          |   14 +++-
>  drivers/net/ethernet/sun/sunvnet.c |  146 +++++++++++++++++++++++++++++++-----
>  drivers/net/ethernet/sun/sunvnet.h |    7 ++-
>  5 files changed, 187 insertions(+), 26 deletions(-)
> 

A logistical question- this patch-set spans both sparc-next/sparclinux 
net-next/netdev, and there are obviously some dependancies here. 
What's the prescribed way to handle this sort of thing? 

(I ask, because I expect to soon be confronting a similar question with
some Rx side latency improvements that I'm working on, which will require
new functions for enabling/disabling interrupts in arch/sparc/kernel,
and I am wondering how that should get sequenced).

--Sowmini

^ permalink raw reply

* Re: [PATCH v11 net-next 12/12] bpf: mini eBPF library, test stubs and verifier testsuite
From: Alexei Starovoitov @ 2014-09-17 22:16 UTC (permalink / raw)
  To: Daniel Borkmann
  Cc: David S. Miller, Ingo Molnar, Linus Torvalds, Andy Lutomirski,
	Steven Rostedt, Hannes Frederic Sowa, Chema Gonzalez,
	Eric Dumazet, Peter Zijlstra, Pablo Neira Ayuso, H. Peter Anvin,
	Andrew Morton, Kees Cook, Linux API, Network Development, LKML
In-Reply-To: <541A045E.3030206@redhat.com>

On Wed, Sep 17, 2014 at 2:59 PM, Daniel Borkmann <dborkman@redhat.com> wrote:
>>
>> 3.
>> kernel/bpf/test_stubs.c can be removed once real tracing
>> or socket use case is in.
>
>
> Yes, please, lets go for point 3 at the very least.

agree. test_stubs is a way to have verifier testsuite
as the first ebpf user in this patch set.
There are multiple ways of connecting ebpf to tracing/sockets
and these discussions cannot happen all at once.
So test_stubs to some degree is scaffolding to bring
other pieces in place slowly with required due diligence.
I don't think there will be a need for test_stubs when
tracing+ebpf is in place. That's why I didn't introduce
special prog_type and map_type for it and instead used
'unspec' type which is invalid type and used for testing
temporarily.
verifier testsuite, of course, will stay. It will switch from
'unspec' type to real types when they're ready.

^ permalink raw reply

* Upgrade
From: "Spletna pošta Administracija" @ 2014-09-17 20:10 UTC (permalink / raw)



Spoštovani uporabnik spletne pošte.

Zaradi zastojev na vse uporabnike Webmail vam predstavlja
morali posodobiti svoj ​​račun z našo novo F-Secure Internet sprosti
Safety 2014 Nova različica najboljših značilnosti spam in virusi.

Da bi posodobili svoj ​​nabiralnik prosimo, izpolnite podatke spodaj, da
vam omogočajo, da posodobite
vaš e-poštni račun takoj.

ime:
Uporabniško ime:
geslo:
Potrdi geslo:
Mobilna številka:
E-mail:

Neuspeh ponovno preveri vaš račun obdeluje začasno
blokirana ali začasno našega omrežja, in morda ne boste mogli pošiljati ali
prejemanje e-pošte, dokler ne boste ponovno potrditi svoj nabiralnik.

Webmail Uporabniki © 2014 Vse pravice pridržane.

^ permalink raw reply

* Re: [patch net-next 01/13] openvswitch: split flow structures into ovs specific and generic ones
From: Jesse Gross @ 2014-09-17 22:07 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Pravin Shelar, netdev, David Miller, nhorman, Andy Gospodarek,
	Thomas Graf, Daniel Borkmann, Or Gerlitz, Andy Zhou,
	Ben Hutchings, Stephen Hemminger, jeffrey.t.kirsher, vyasevic,
	Cong Wang, john.r.fastabend, Eric Dumazet, Jamal Hadi Salim,
	sfeldma, Florian Fainelli, roopa, John Linville,
	dev@openvswitch.org, jasowang, ebie
In-Reply-To: <20140917083421.GB1863@nanopsycho.orion>

On Wed, Sep 17, 2014 at 1:34 AM, Jiri Pirko <jiri@resnulli.us> wrote:
> Thu, Sep 04, 2014 at 10:46:28PM CEST, pshelar@nicira.com wrote:
>>On the other hand if vswitchd uses common interface (switchdev) there
>>is no need to extend ovs kernel interface. For example specifying
>>extra metadata, like (sw only, hw olny, both).
>
> I understand you point of view. However from the offloading perspective
> it makes much more sense to push the flows through a single interface
> (ovs genl) and only offload selected flows to hw (pushing further).
> Having vswitchd to handle 2 different ifaces for the same/similar thing
> does not seem like a clean solution to me. And it really breaks the
> offloading view.
>
> Plus the amount of code needed to be pushed into ovs kernel dp code in
> order to enable this is small.

This is missing the point: software forwarding and a hardware driver
interface are doing totally different things. Over time, these will
diverge and you will essentially up with two separate paths packed
together which doesn't help anything. This is not a theoretical
concern as different directions either already exist or have been
proposed. On the software side, there is the BPF proposal which is not
likely to map to hardware any time soon. On the other hand, hardware
is usually composed of multiple tables/functions with varying
capabilities. Sooner or later you will want to take advantage of these
and doing so isn't really possible with the software optimized flows
that the kernel handles. At that point, you will likely introduce a
new interface to userspace to expose this and get flows processed in a
different way.

^ permalink raw reply

* Re: [PATCH net] openvswitch: restore OVS_FLOW_CMD_NEW notifications
From: Pravin Shelar @ 2014-09-17 22:04 UTC (permalink / raw)
  To: Nicolas Dichtel
  Cc: David Miller, dev@openvswitch.org, netdev, Samuel Gauthier
In-Reply-To: <CALnjE+rzvxC1-SvkkF237JitBTqHWaria6mw4EmDygMUSzUcUQ@mail.gmail.com>

On Wed, Sep 17, 2014 at 2:56 PM, Pravin Shelar <pshelar@nicira.com> wrote:
> On Wed, Sep 17, 2014 at 9:13 AM, Nicolas Dichtel
> <nicolas.dichtel@6wind.com> wrote:
>> From: Samuel Gauthier <samuel.gauthier@6wind.com>
>>
>> Since commit fb5d1e9e127a ("openvswitch: Build flow cmd netlink reply only if needed."),
>> the new flows are not notified to the listeners of OVS_FLOW_MCGROUP.
>>
>> This commit fixes the problem by checking that there are listeners in
>> the actual OVS_FLOW_MCGROUP group, instead of 0.
>>
>
> right, this is bug. group id should be one.
>
>> Signed-off-by: Samuel Gauthier <samuel.gauthier@6wind.com>
>> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
>> ---
>>  net/openvswitch/datapath.c | 6 +++---
>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
>> index 91d66b7e64ac..8396f6063343 100644
>> --- a/net/openvswitch/datapath.c
>> +++ b/net/openvswitch/datapath.c
>> @@ -79,10 +79,10 @@ static const struct genl_multicast_group ovs_dp_vport_multicast_group = {
>>  /* Check if need to build a reply message.
>>   * OVS userspace sets the NLM_F_ECHO flag if it needs the reply. */
>>  static bool ovs_must_notify(struct genl_info *info,
>> -                           const struct genl_multicast_group *grp)
>> +                           unsigned int group)
>>  {
>>         return info->nlhdr->nlmsg_flags & NLM_F_ECHO ||
>> -               netlink_has_listeners(genl_info_net(info)->genl_sock, 0);
>> +               netlink_has_listeners(genl_info_net(info)->genl_sock, group);
>>  }
>>
>>  static void ovs_notify(struct genl_family *family,
>> @@ -763,7 +763,7 @@ static struct sk_buff *ovs_flow_cmd_alloc_info(const struct sw_flow_actions *act
>>  {
>>         struct sk_buff *skb;
>>
>> -       if (!always && !ovs_must_notify(info, &ovs_dp_flow_multicast_group))
>> +       if (!always && !ovs_must_notify(info, dp_flow_genl_family.mcgrp_offset))
>>                 return NULL;
>>
>
>
> I do not think mcgrp_offset is right group id. It is starting offset
> of groups in a family and it is marked as private member of genl
> module.
> Rather we can just define enum for ovs_dp_flow_multicast_group and
> directly use that as group-id.
>

I just realized that there is no equivalent netlink_has_listeners()
function in genl, so we have to add such function first.

^ permalink raw reply

* Re: [PATCHv5 net-next 3/3] sunvnet: generate ICMP PTMUD messages for smaller port MTUs
From: David L Stevens @ 2014-09-17 22:03 UTC (permalink / raw)
  To: Sergei Shtylyov, David Miller; +Cc: netdev
In-Reply-To: <5419F97C.1080105@cogentembedded.com>



On 09/17/2014 05:13 PM, Sergei Shtylyov wrote:

>> +        }
>> +#if IS_ENABLED(CONFIG_IPV6)
> 
>    This #if could be avoided by extending the *if* statement below, no?
> 
>> +        else if (skb->protocol == htons(ETH_P_IPV6))
>> +            icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, localmtu);
>> +#endif
>>           goto out_dropped;
>> +    }

I'm not sure I understand your point, but the #if must be there to
avoid a reference to icmpv6_send() which will not be defined if
CONFIG_IPV6=n.

						+-DLS

^ permalink raw reply

* Re: [PATCH v11 net-next 12/12] bpf: mini eBPF library, test stubs and verifier testsuite
From: Daniel Borkmann @ 2014-09-17 21:59 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: David S. Miller, Ingo Molnar, Linus Torvalds, Andy Lutomirski,
	Steven Rostedt, Hannes Frederic Sowa, Chema Gonzalez,
	Eric Dumazet, Peter Zijlstra, Pablo Neira Ayuso, H. Peter Anvin,
	Andrew Morton, Kees Cook, Linux API, Network Development, LKML
In-Reply-To: <CAMEtUuzaCEX9RKDBMnQBZSHdTjjidp81myfSVVi4qQqtSGgtmw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On 09/17/2014 06:17 PM, Alexei Starovoitov wrote:
> On Wed, Sep 17, 2014 at 12:16 AM, Daniel Borkmann <dborkman-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>>
>> That actually still doesn't answer my question why the test stub
>> cannot live in lib/test_bpf where we have our actual testing
>> framework for eBPF/BPF, also since you exactly only build test_stub.c
>> when TEST_BPF is enabled which is the Kconfig for lib/test_bpf.
>
> multiple reasons:
> 1.
> lib/test_bpf.c is a module, whereas test_stub.c is kernel builtin.
>
> 2.
> I wasn't sure that reusing CONFIG_TEST_BPF for this
> purpose was a good idea. May be it's better to introduce
> CONFIG_BPF_VERIFIER_TEST_STUBS or something.
>
> 3.
> kernel/bpf/test_stubs.c can be removed once real tracing
> or socket use case is in.

Yes, please, lets go for point 3 at the very least.

^ permalink raw reply

* Re: [PATCH net] openvswitch: restore OVS_FLOW_CMD_NEW notifications
From: Pravin Shelar @ 2014-09-17 21:56 UTC (permalink / raw)
  To: Nicolas Dichtel
  Cc: David Miller, dev@openvswitch.org, netdev, Samuel Gauthier
In-Reply-To: <1410970400-9797-1-git-send-email-nicolas.dichtel@6wind.com>

On Wed, Sep 17, 2014 at 9:13 AM, Nicolas Dichtel
<nicolas.dichtel@6wind.com> wrote:
> From: Samuel Gauthier <samuel.gauthier@6wind.com>
>
> Since commit fb5d1e9e127a ("openvswitch: Build flow cmd netlink reply only if needed."),
> the new flows are not notified to the listeners of OVS_FLOW_MCGROUP.
>
> This commit fixes the problem by checking that there are listeners in
> the actual OVS_FLOW_MCGROUP group, instead of 0.
>

right, this is bug. group id should be one.

> Signed-off-by: Samuel Gauthier <samuel.gauthier@6wind.com>
> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
> ---
>  net/openvswitch/datapath.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
> index 91d66b7e64ac..8396f6063343 100644
> --- a/net/openvswitch/datapath.c
> +++ b/net/openvswitch/datapath.c
> @@ -79,10 +79,10 @@ static const struct genl_multicast_group ovs_dp_vport_multicast_group = {
>  /* Check if need to build a reply message.
>   * OVS userspace sets the NLM_F_ECHO flag if it needs the reply. */
>  static bool ovs_must_notify(struct genl_info *info,
> -                           const struct genl_multicast_group *grp)
> +                           unsigned int group)
>  {
>         return info->nlhdr->nlmsg_flags & NLM_F_ECHO ||
> -               netlink_has_listeners(genl_info_net(info)->genl_sock, 0);
> +               netlink_has_listeners(genl_info_net(info)->genl_sock, group);
>  }
>
>  static void ovs_notify(struct genl_family *family,
> @@ -763,7 +763,7 @@ static struct sk_buff *ovs_flow_cmd_alloc_info(const struct sw_flow_actions *act
>  {
>         struct sk_buff *skb;
>
> -       if (!always && !ovs_must_notify(info, &ovs_dp_flow_multicast_group))
> +       if (!always && !ovs_must_notify(info, dp_flow_genl_family.mcgrp_offset))
>                 return NULL;
>


I do not think mcgrp_offset is right group id. It is starting offset
of groups in a family and it is marked as private member of genl
module.
Rather we can just define enum for ovs_dp_flow_multicast_group and
directly use that as group-id.


>         skb = genlmsg_new_unicast(ovs_flow_cmd_msg_size(acts), info, GFP_KERNEL);
> --
> 2.1.0
>

^ permalink raw reply

* Re: Cannot move macvlan interface on top of bonding device
From: Florian Westphal @ 2014-09-17 21:28 UTC (permalink / raw)
  To: Vlad Yasevich
  Cc: Florian Westphal, Cong Wang, Francesco Ruggeri, netdev,
	David S. Miller, Weilong Chen
In-Reply-To: <5419F17D.2090409@gmail.com>

Vlad Yasevich <vyasevich@gmail.com> wrote:
> On 09/17/2014 03:06 PM, Florian Westphal wrote:
> > Cong Wang <cwang@twopensource.com> wrote:
> >> On Wed, Sep 17, 2014 at 8:56 AM, Francesco Ruggeri <fruggeri@arista.com> wrote:
> >>> This used to work in older releases.
> >>> The problem seems to be that commit f939981492 sets NETIF_F_NETNS_LOCAL
> >>> on bonding interfaces, and commit 797f87f83 causes macvlan interfaces
> >>> to inherit its features from the lower device.
> >>>
> >>> Is there a reason why NETIF_F_NETNS_LOCAL should be inherited from the
> >>> lower device
> >>> by macvlan interfaces?
> >>
> >> commit 797f87f83 looks wrong, it should not inherit NETIF_F_NETNS_LOCAL,
> >> so just clear this flag. Please submit a patch.
> > 
> > Under which conditions would NETIF_F_NETNS_LOCAL have to be inherited?
> > (i.e., why is it inheritable in the first place?)

To answer my own question:  Its inherited since lowerdev->features is
passed as 'all' flag, so we would 'decrement' feature set if we'd remove
it in _increment_features().

> macvlan code calls
>         features = netdev_increment_features(vlan->lowerdev->features,
>                                              features,
>                                              mask);
> 
> where lowerdev->features contains the NETIF_F_NETNS_LOCAL bit.  That

[..]

> May be a better solution is:
> 
>         features = netdev_increment_features(vlan->lowerdev->features & MACVLAN_FEATURS,
>                                              features,
>                                              mask);
> 
> This way we start with only the feature MACVLAN is interested in.

Seems correct, since it will also prevent other non-macvlan features from
appearing.

Thanks Vlad.

^ permalink raw reply

* [PATCH net-next] net: fix sparse warnings in SNMP_UPD_PO_STATS(_BH)
From: Sabrina Dubroca @ 2014-09-17 21:23 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

ptr used to be a non __percpu pointer (result of a this_cpu_ptr
assignment, 7d720c3e4f0c4 ("percpu: add __percpu sparse annotations to
net")). Since d25398df59b56 ("net: avoid reloads in SNMP_UPD_PO_STATS"),
that's no longer the case, SNMP_UPD_PO_STATS uses this_cpu_add and ptr
is now __percpu.

Silence sparse warnings by preserving the original type and
annotation, and remove the out-of-date comment.

warning: incorrect type in initializer (different address spaces)
   expected unsigned long long *ptr
   got unsigned long long [noderef] <asn:3>*<noident>
warning: incorrect type in initializer (different address spaces)
   expected void const [noderef] <asn:3>*__vpp_verify
   got unsigned long long *<noident>
warning: incorrect type in initializer (different address spaces)
   expected void const [noderef] <asn:3>*__vpp_verify
   got unsigned long long *<noident>

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
---
 include/net/snmp.h | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/include/net/snmp.h b/include/net/snmp.h
index f1f27fdbb0d5..8fd2f498782e 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -146,19 +146,15 @@ struct linux_xfrm_mib {
 
 #define SNMP_ADD_STATS(mib, field, addend)	\
 			this_cpu_add(mib->mibs[field], addend)
-/*
- * Use "__typeof__(*mib) *ptr" instead of "__typeof__(mib) ptr"
- * to make @ptr a non-percpu pointer.
- */
 #define SNMP_UPD_PO_STATS(mib, basefield, addend)	\
 	do { \
-		__typeof__(*mib->mibs) *ptr = mib->mibs;	\
+		__typeof__((mib->mibs) + 0) ptr = mib->mibs;	\
 		this_cpu_inc(ptr[basefield##PKTS]);		\
 		this_cpu_add(ptr[basefield##OCTETS], addend);	\
 	} while (0)
 #define SNMP_UPD_PO_STATS_BH(mib, basefield, addend)	\
 	do { \
-		__typeof__(*mib->mibs) *ptr = mib->mibs;	\
+		__typeof__((mib->mibs) + 0) ptr = mib->mibs;	\
 		__this_cpu_inc(ptr[basefield##PKTS]);		\
 		__this_cpu_add(ptr[basefield##OCTETS], addend);	\
 	} while (0)
-- 
2.1.0

^ permalink raw reply related

* Re: [PATCHv5 net-next 3/3] sunvnet: generate ICMP PTMUD messages for smaller port MTUs
From: Sergei Shtylyov @ 2014-09-17 21:13 UTC (permalink / raw)
  To: David L Stevens, David Miller; +Cc: netdev
In-Reply-To: <5419F3E5.4050708@oracle.com>

Hello.

On 9/17/2014 11:49 PM, David L Stevens wrote:

> This patch sends ICMP and ICMPv6 messages for Path MTU Discovery when a remote
> port MTU is smaller than the device MTU. This allows mixing newer VIO protocol
> devices that support MTU negotiation with older devices that do not on the
> same vswitch. It also allows Linux-Linux LDOMs to use 64K-1 data packets even
> though Solaris vswitch is limited to <16K MTU.

> Signed-off-by: David L Stevens <david.stevens@oracle.com>
> ---
>   drivers/net/ethernet/sun/sunvnet.c |   37 +++++++++++++++++++++++++++++++++++-
>   1 files changed, 36 insertions(+), 1 deletions(-)

> diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
> index 5e64e60..3c4ee18 100644
> --- a/drivers/net/ethernet/sun/sunvnet.c
> +++ b/drivers/net/ethernet/sun/sunvnet.c
[...]
> @@ -791,8 +798,36 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
>   	if (unlikely(!port))
>   		goto out_dropped;
>
> -	if (skb->len > port->rmtu)
> +	if (skb->len > port->rmtu) {
> +		unsigned long localmtu = port->rmtu - ETH_HLEN;
> +
> +		if (vio_version_after_eq(&port->vio, 1, 3))
> +			localmtu -= VLAN_HLEN;
> +
> +		if (skb->protocol == htons(ETH_P_IP)) {
> +			struct flowi4 fl4;
> +			struct rtable *rt = NULL;
> +
> +			memset(&fl4, 0, sizeof(fl4));
> +			fl4.flowi4_oif = dev->ifindex;
> +			fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
> +			fl4.daddr = ip_hdr(skb)->daddr;
> +			fl4.saddr = ip_hdr(skb)->saddr;
> +
> +			rt = ip_route_output_key(dev_net(dev), &fl4);
> +			if (!IS_ERR(rt)) {
> +				skb_dst_set(skb, &rt->dst);
> +				icmp_send(skb, ICMP_DEST_UNREACH,
> +					  ICMP_FRAG_NEEDED,
> +					  htonl(localmtu));
> +			}
> +		}
> +#if IS_ENABLED(CONFIG_IPV6)

    This #if could be avoided by extending the *if* statement below, no?

> +		else if (skb->protocol == htons(ETH_P_IPV6))
> +			icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, localmtu);
> +#endif
>   		goto out_dropped;
> +	}

WBR, Sergei

^ permalink raw reply

* Re: [net-next PATCH 2/2] net: sched: cls_u32 changes to knode must appear atomic to readers
From: Cong Wang @ 2014-09-17 21:11 UTC (permalink / raw)
  To: John Fastabend
  Cc: Cong Wang, David Miller, Eric Dumazet, netdev, Jamal Hadi Salim
In-Reply-To: <20140917191202.20529.87231.stgit@nitbit.x32>

On Wed, Sep 17, 2014 at 12:12 PM, John Fastabend
<john.fastabend@gmail.com> wrote:
>
> -static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n)
> +static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n, bool pf)
>  {
>         tcf_unbind_filter(tp, &n->res);
>         tcf_exts_destroy(tp, &n->exts);
>         if (n->ht_down)
>                 n->ht_down->refcnt--;
>  #ifdef CONFIG_CLS_U32_PERF
> -       free_percpu(n->pf);
> +       if (pf)

Nit: 'free_pf' is a better name than just 'pf'.

> +               free_percpu(n->pf);
>  #endif
>  #ifdef CONFIG_CLS_U32_MARK
> -       free_percpu(n->pcpu_success);
> +       if (pf)
> +               free_percpu(n->pcpu_success);
>  #endif
>         kfree(n);
>         return 0;
>  }
>
> +static void u32_delete_key_rcu_pf(struct rcu_head *rcu)
> +{
> +       struct tc_u_knode *key = container_of(rcu, struct tc_u_knode, rcu);
> +
> +       u32_destroy_key(key->tp, key, false);
> +}

I think you need a comment here to explain why you free it partially
on purpose, it is not that clear, at least I spent some time to figure
it out when I read your cls_tcindex patch.

Thanks!

^ permalink raw reply

* Re: [PATCH 1/1] net: allow macvlans to move to net namespace
From: Cong Wang @ 2014-09-17 20:55 UTC (permalink / raw)
  To: Francesco Ruggeri
  Cc: netdev, Francesco Ruggeri, Florian Westphal, chenweilong,
	David Miller
In-Reply-To: <20140917181227.09F4E480087@fruggeri-Arora18.sjc.aristanetworks.com>

On Wed, Sep 17, 2014 at 11:12 AM, Francesco Ruggeri
<fruggeri@aristanetworks.com> wrote:
> diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
> index a969555..7652fd1 100644
> --- a/drivers/net/macvlan.c
> +++ b/drivers/net/macvlan.c
> @@ -806,6 +806,7 @@ static netdev_features_t macvlan_fix_features(struct net_device *dev,
>                                              features,
>                                              mask);
>         features |= ALWAYS_ON_FEATURES;
> +       features &= ~NETIF_F_NETNS_LOCAL;
>
>         return features;
>  }


Even if we have some other way to clear this flag (maybe clearing it
in mask etc.),
explicitly clearing it is more readable, I don't want to spin my head to
read netdev_increment_features(), so,

Acked-by: Cong Wang <cwang@twopensource.com>

^ permalink raw reply

* Re: Cannot move macvlan interface on top of bonding device
From: Vlad Yasevich @ 2014-09-17 20:51 UTC (permalink / raw)
  To: Cong Wang
  Cc: Florian Westphal, Francesco Ruggeri, netdev, David S. Miller,
	Weilong Chen
In-Reply-To: <CAHA+R7M5+1gbfx7pv=bPdNempL1eeXRu-J79c29z1k6Mr-aXfA@mail.gmail.com>

On 09/17/2014 04:46 PM, Cong Wang wrote:
> On Wed, Sep 17, 2014 at 1:39 PM, Vlad Yasevich <vyasevich@gmail.com> wrote:
>> On 09/17/2014 03:06 PM, Florian Westphal wrote:
>>> Cong Wang <cwang@twopensource.com> wrote:
>>>> On Wed, Sep 17, 2014 at 8:56 AM, Francesco Ruggeri <fruggeri@arista.com> wrote:
>>>>> This used to work in older releases.
>>>>> The problem seems to be that commit f939981492 sets NETIF_F_NETNS_LOCAL
>>>>> on bonding interfaces, and commit 797f87f83 causes macvlan interfaces
>>>>> to inherit its features from the lower device.
>>>>>
>>>>> Is there a reason why NETIF_F_NETNS_LOCAL should be inherited from the
>>>>> lower device
>>>>> by macvlan interfaces?
>>>>
>>>> commit 797f87f83 looks wrong, it should not inherit NETIF_F_NETNS_LOCAL,
>>>> so just clear this flag. Please submit a patch.
>>>
>>> Under which conditions would NETIF_F_NETNS_LOCAL have to be inherited?
>>> (i.e., why is it inheritable in the first place?)
>>
>> macvlan code calls
>>         features = netdev_increment_features(vlan->lowerdev->features,
>>                                              features,
>>                                              mask);
>>
>> where lowerdev->features contains the NETIF_F_NETNS_LOCAL bit.  That
>> bit is not set in features or in mask.  It is also not one of the ALL_FOR_ALL
>> bits so it's not turned off.
>>
>> As an example, here are the values from a quit test I ran:
>>
>> bond features = 0x400f3888
>> features = 0x3b5a09  (mask is the same).
>> incremented features = 0x41bf389
>>
>> NETIF_F_NETNS_LOCAL is still on.
> 

No, it is not.  NETIF_F_NETNS_LOCAL is bit 13 and that's off.  Bits
14 (GRO) and 12 (LLTX) are set.

-vlad

> I think the comment on netdev_increment_features() is clear:
> 
>  *      Computes a new feature set after adding a device with feature set
>  *      @one to the master device with current feature set @all.  Will not
>  *      enable anything that is off in @mask. Returns the new feature set.
> 
> And NETIF_F_NETNS_LOCAL is on in mask.
> 
>>
>> May be a better solution is:
>>
>>         features = netdev_increment_features(vlan->lowerdev->features & MACVLAN_FEATURS,
>>                                              features,
>>                                              mask);
>>
>> This way we start with only the feature MACVLAN is interested in.
>>
> 
> Or clear it in mask?
> 

^ permalink raw reply

* [PATCHv5 net-next 2/3] sunvnet: allow admin to set sunvnet MTU
From: David L Stevens @ 2014-09-17 20:50 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

This patch allows an admin to set the MTU on a sunvnet device to arbitrary
values between the minimum (68) and maximum (65535) IPv4 packet sizes.

Signed-off-by: David L Stevens <david.stevens@oracle.com>
---
 arch/sparc/kernel/ldc.c            |    2 +-
 drivers/net/ethernet/sun/sunvnet.c |    7 +++++--
 drivers/net/ethernet/sun/sunvnet.h |    6 ++++--
 3 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c
index 66dacd5..0af28b9 100644
--- a/arch/sparc/kernel/ldc.c
+++ b/arch/sparc/kernel/ldc.c
@@ -2159,7 +2159,7 @@ int ldc_map_single(struct ldc_channel *lp,
 	state.pte_idx = (base - iommu->page_table);
 	state.nc = 0;
 	fill_cookies(&state, (pa & PAGE_MASK), (pa & ~PAGE_MASK), len);
-	BUG_ON(state.nc != 1);
+	BUG_ON(state.nc > ncookies);
 
 	return state.nc;
 }
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index a9638c1..5e64e60 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -791,6 +791,9 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (unlikely(!port))
 		goto out_dropped;
 
+	if (skb->len > port->rmtu)
+		goto out_dropped;
+
 	spin_lock_irqsave(&port->vio.lock, flags);
 
 	dr = &port->vio.drings[VIO_DRIVER_TX_RING];
@@ -1038,7 +1041,7 @@ static void vnet_set_rx_mode(struct net_device *dev)
 
 static int vnet_change_mtu(struct net_device *dev, int new_mtu)
 {
-	if (new_mtu != ETH_DATA_LEN)
+	if (new_mtu < 68 || new_mtu > 65535)
 		return -EINVAL;
 
 	dev->mtu = new_mtu;
@@ -1131,7 +1134,7 @@ static int vnet_port_alloc_tx_bufs(struct vnet_port *port)
 		}
 
 		err = ldc_map_single(port->vio.lp, buf, map_len,
-				     port->tx_bufs[i].cookies, 2,
+				     port->tx_bufs[i].cookies, VNET_MAXCOOKIES,
 				     (LDC_MAP_SHADOW |
 				      LDC_MAP_DIRECT |
 				      LDC_MAP_RW));
diff --git a/drivers/net/ethernet/sun/sunvnet.h b/drivers/net/ethernet/sun/sunvnet.h
index 986e04b..a39a801 100644
--- a/drivers/net/ethernet/sun/sunvnet.h
+++ b/drivers/net/ethernet/sun/sunvnet.h
@@ -11,7 +11,7 @@
  */
 #define VNET_TX_TIMEOUT			(5 * HZ)
 
-#define VNET_MAXPACKET			1518ULL /* ETH_FRAMELEN + VLAN_HDR */
+#define VNET_MAXPACKET			(65535ULL + ETH_HLEN + VLAN_HLEN)
 #define VNET_TX_RING_SIZE		512
 #define VNET_TX_WAKEUP_THRESH(dr)	((dr)->pending / 4)
 
@@ -21,10 +21,12 @@
  */
 #define VNET_PACKET_SKIP		6
 
+#define VNET_MAXCOOKIES			(VNET_MAXPACKET/PAGE_SIZE + 1)
+
 struct vnet_tx_entry {
 	void			*buf;
 	unsigned int		ncookies;
-	struct ldc_trans_cookie	cookies[2];
+	struct ldc_trans_cookie	cookies[VNET_MAXCOOKIES];
 };
 
 struct vnet;
-- 
1.7.1

^ permalink raw reply related

* [PATCHv5 net-next 1/3] sunvnet: upgrade to VIO protocol version 1.6
From: David L Stevens @ 2014-09-17 20:49 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

This patch upgrades the sunvnet driver to support VIO protocol version 1.6.
In particular, it adds per-port MTU negotiation, allowing MTUs other than
ETH_FRAMELEN with ports using newer VIO protocol versions.

Signed-off-by: David L Stevens <david.stevens@oracle.com>
---
 arch/sparc/include/asm/vio.h       |   44 ++++++++++++++-
 arch/sparc/kernel/viohs.c          |   14 ++++-
 drivers/net/ethernet/sun/sunvnet.c |  104 +++++++++++++++++++++++++++++------
 drivers/net/ethernet/sun/sunvnet.h |    3 +
 4 files changed, 143 insertions(+), 22 deletions(-)

diff --git a/arch/sparc/include/asm/vio.h b/arch/sparc/include/asm/vio.h
index 5c0ebe7..107d4a4 100644
--- a/arch/sparc/include/asm/vio.h
+++ b/arch/sparc/include/asm/vio.h
@@ -65,6 +65,7 @@ struct vio_dring_register {
 	u16			options;
 #define VIO_TX_DRING		0x0001
 #define VIO_RX_DRING		0x0002
+#define VIO_RX_DRING_DATA	0x0004
 	u16			resv;
 	u32			num_cookies;
 	struct ldc_trans_cookie	cookies[0];
@@ -80,6 +81,8 @@ struct vio_dring_unregister {
 #define VIO_PKT_MODE		0x01 /* Packet based transfer	*/
 #define VIO_DESC_MODE		0x02 /* In-band descriptors	*/
 #define VIO_DRING_MODE		0x03 /* Descriptor rings	*/
+/* in vers >= 1.2, VIO_DRING_MODE is 0x04 and transfer mode is a bitmask */
+#define VIO_NEW_DRING_MODE	0x04
 
 struct vio_dring_data {
 	struct vio_msg_tag	tag;
@@ -209,10 +212,20 @@ struct vio_net_attr_info {
 	u8			addr_type;
 #define VNET_ADDR_ETHERMAC	0x01
 	u16			ack_freq;
-	u32			resv1;
+	u8			plnk_updt;
+#define PHYSLINK_UPDATE_NONE		0x00
+#define PHYSLINK_UPDATE_STATE		0x01
+#define PHYSLINK_UPDATE_STATE_ACK	0x02
+#define PHYSLINK_UPDATE_STATE_NACK	0x03
+	u8			options;
+	u16			resv1;
 	u64			addr;
 	u64			mtu;
-	u64			resv2[3];
+	u16			cflags;
+#define VNET_LSO_IPV4_CAPAB		0x0001
+	u16			ipv4_lso_maxlen;
+	u32			resv2;
+	u64			resv3[2];
 };
 
 #define VNET_NUM_MCAST		7
@@ -370,6 +383,33 @@ struct vio_driver_state {
 	struct vio_driver_ops	*ops;
 };
 
+static inline bool vio_version_before(struct vio_driver_state *vio,
+				      u16 major, u16 minor)
+{
+	u32 have = (u32)vio->ver.major << 16 | vio->ver.minor;
+	u32 want = (u32)major << 16 | minor;
+
+	return have < want;
+}
+
+static inline bool vio_version_after(struct vio_driver_state *vio,
+				      u16 major, u16 minor)
+{
+	u32 have = (u32)vio->ver.major << 16 | vio->ver.minor;
+	u32 want = (u32)major << 16 | minor;
+
+	return have > want;
+}
+
+static inline bool vio_version_after_eq(struct vio_driver_state *vio,
+					u16 major, u16 minor)
+{
+	u32 have = (u32)vio->ver.major << 16 | vio->ver.minor;
+	u32 want = (u32)major << 16 | minor;
+
+	return have >= want;
+}
+
 #define viodbg(TYPE, f, a...) \
 do {	if (vio->debug & VIO_DEBUG_##TYPE) \
 		printk(KERN_INFO "vio: ID[%lu] " f, \
diff --git a/arch/sparc/kernel/viohs.c b/arch/sparc/kernel/viohs.c
index f8e7dd5..7ef081a 100644
--- a/arch/sparc/kernel/viohs.c
+++ b/arch/sparc/kernel/viohs.c
@@ -426,6 +426,13 @@ static int process_dreg_info(struct vio_driver_state *vio,
 	if (vio->dr_state & VIO_DR_STATE_RXREG)
 		goto send_nack;
 
+	/* v1.6 and higher, ACK with desired, supported mode, or NACK */
+	if (vio_version_after_eq(vio, 1, 6)) {
+		if (!(pkt->options & VIO_TX_DRING))
+			goto send_nack;
+		pkt->options = VIO_TX_DRING;
+	}
+
 	BUG_ON(vio->desc_buf);
 
 	vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC);
@@ -453,8 +460,11 @@ static int process_dreg_info(struct vio_driver_state *vio,
 	pkt->tag.stype = VIO_SUBTYPE_ACK;
 	pkt->dring_ident = ++dr->ident;
 
-	viodbg(HS, "SEND DRING_REG ACK ident[%llx]\n",
-	       (unsigned long long) pkt->dring_ident);
+	viodbg(HS, "SEND DRING_REG ACK ident[%llx] "
+	       "ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n",
+	       (unsigned long long) pkt->dring_ident,
+	       pkt->num_descr, pkt->descr_size, pkt->options,
+	       pkt->num_cookies);
 
 	len = (sizeof(*pkt) +
 	       (dr->ncookies * sizeof(struct ldc_trans_cookie)));
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index 763cdfc..a9638c1 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -15,6 +15,7 @@
 #include <linux/ethtool.h>
 #include <linux/etherdevice.h>
 #include <linux/mutex.h>
+#include <linux/if_vlan.h>
 
 #include <asm/vio.h>
 #include <asm/ldc.h>
@@ -41,6 +42,7 @@ static int __vnet_tx_trigger(struct vnet_port *port, u32 start);
 
 /* Ordered from largest major to lowest */
 static struct vio_version vnet_versions[] = {
+	{ .major = 1, .minor = 6 },
 	{ .major = 1, .minor = 0 },
 };
 
@@ -67,6 +69,7 @@ static int vnet_send_attr(struct vio_driver_state *vio)
 	struct vnet_port *port = to_vnet_port(vio);
 	struct net_device *dev = port->vp->dev;
 	struct vio_net_attr_info pkt;
+	int framelen = ETH_FRAME_LEN;
 	int i;
 
 	memset(&pkt, 0, sizeof(pkt));
@@ -74,19 +77,41 @@ static int vnet_send_attr(struct vio_driver_state *vio)
 	pkt.tag.stype = VIO_SUBTYPE_INFO;
 	pkt.tag.stype_env = VIO_ATTR_INFO;
 	pkt.tag.sid = vio_send_sid(vio);
-	pkt.xfer_mode = VIO_DRING_MODE;
+	if (vio_version_before(vio, 1, 2))
+		pkt.xfer_mode = VIO_DRING_MODE;
+	else
+		pkt.xfer_mode = VIO_NEW_DRING_MODE;
 	pkt.addr_type = VNET_ADDR_ETHERMAC;
 	pkt.ack_freq = 0;
 	for (i = 0; i < 6; i++)
 		pkt.addr |= (u64)dev->dev_addr[i] << ((5 - i) * 8);
-	pkt.mtu = ETH_FRAME_LEN;
+	if (vio_version_after(vio, 1, 3)) {
+		if (port->rmtu) {
+			port->rmtu = min(VNET_MAXPACKET, port->rmtu);
+			pkt.mtu = port->rmtu;
+		} else {
+			port->rmtu = VNET_MAXPACKET;
+			pkt.mtu = port->rmtu;
+		}
+		if (vio_version_after_eq(vio, 1, 6))
+			pkt.options = VIO_TX_DRING;
+	} else if (vio_version_before(vio, 1, 3)) {
+		pkt.mtu = framelen;
+	} else { /* v1.3 */
+		pkt.mtu = framelen + VLAN_HLEN;
+	}
+
+	pkt.plnk_updt = PHYSLINK_UPDATE_NONE;
+	pkt.cflags = 0;
 
 	viodbg(HS, "SEND NET ATTR xmode[0x%x] atype[0x%x] addr[%llx] "
-	       "ackfreq[%u] mtu[%llu]\n",
+	       "ackfreq[%u] plnk_updt[0x%02x] opts[0x%02x] mtu[%llu] "
+	       "cflags[0x%04x] lso_max[%u]\n",
 	       pkt.xfer_mode, pkt.addr_type,
-	       (unsigned long long) pkt.addr,
-	       pkt.ack_freq,
-	       (unsigned long long) pkt.mtu);
+	       (unsigned long long)pkt.addr,
+	       pkt.ack_freq, pkt.plnk_updt, pkt.options,
+	       (unsigned long long)pkt.mtu, pkt.cflags, pkt.ipv4_lso_maxlen);
+
 
 	return vio_ldc_send(vio, &pkt, sizeof(pkt));
 }
@@ -94,18 +119,52 @@ static int vnet_send_attr(struct vio_driver_state *vio)
 static int handle_attr_info(struct vio_driver_state *vio,
 			    struct vio_net_attr_info *pkt)
 {
-	viodbg(HS, "GOT NET ATTR INFO xmode[0x%x] atype[0x%x] addr[%llx] "
-	       "ackfreq[%u] mtu[%llu]\n",
+	struct vnet_port *port = to_vnet_port(vio);
+	u64	localmtu;
+	u8	xfer_mode;
+
+	viodbg(HS, "GOT NET ATTR xmode[0x%x] atype[0x%x] addr[%llx] "
+	       "ackfreq[%u] plnk_updt[0x%02x] opts[0x%02x] mtu[%llu] "
+	       " (rmtu[%llu]) cflags[0x%04x] lso_max[%u]\n",
 	       pkt->xfer_mode, pkt->addr_type,
-	       (unsigned long long) pkt->addr,
-	       pkt->ack_freq,
-	       (unsigned long long) pkt->mtu);
+	       (unsigned long long)pkt->addr,
+	       pkt->ack_freq, pkt->plnk_updt, pkt->options,
+	       (unsigned long long)pkt->mtu, port->rmtu, pkt->cflags,
+	       pkt->ipv4_lso_maxlen);
 
 	pkt->tag.sid = vio_send_sid(vio);
 
-	if (pkt->xfer_mode != VIO_DRING_MODE ||
+	xfer_mode = pkt->xfer_mode;
+	/* for version < 1.2, VIO_DRING_MODE = 0x3 and no bitmask */
+	if (vio_version_before(vio, 1, 2) && xfer_mode == VIO_DRING_MODE)
+		xfer_mode = VIO_NEW_DRING_MODE;
+
+	/* MTU negotiation:
+	 *	< v1.3 - ETH_FRAME_LEN exactly
+	 *	> v1.3 - MIN(pkt.mtu, VNET_MAX_PACKET, port->rmtu) and change
+	 *			pkt->mtu for ACK
+	 *	= v1.3 - ETH_FRAME_LEN + VLAN_HLEN exactly
+	 */
+	if (vio_version_before(vio, 1, 3)) {
+		localmtu = ETH_FRAME_LEN;
+	} else if (vio_version_after(vio, 1, 3)) {
+		localmtu = port->rmtu ? port->rmtu : VNET_MAXPACKET;
+		localmtu = min(pkt->mtu, localmtu);
+		pkt->mtu = localmtu;
+	} else { /* v1.3 */
+		localmtu = ETH_FRAME_LEN + VLAN_HLEN;
+	}
+	port->rmtu = localmtu;
+
+	/* for version >= 1.6, ACK packet mode we support */
+	if (vio_version_after_eq(vio, 1, 6)) {
+		pkt->xfer_mode = VIO_NEW_DRING_MODE;
+		pkt->options = VIO_TX_DRING;
+	}
+
+	if (!(xfer_mode | VIO_NEW_DRING_MODE) ||
 	    pkt->addr_type != VNET_ADDR_ETHERMAC ||
-	    pkt->mtu != ETH_FRAME_LEN) {
+	    pkt->mtu != localmtu) {
 		viodbg(HS, "SEND NET ATTR NACK\n");
 
 		pkt->tag.stype = VIO_SUBTYPE_NACK;
@@ -114,7 +173,14 @@ static int handle_attr_info(struct vio_driver_state *vio,
 
 		return -ECONNRESET;
 	} else {
-		viodbg(HS, "SEND NET ATTR ACK\n");
+		viodbg(HS, "SEND NET ATTR ACK xmode[0x%x] atype[0x%x] "
+		       "addr[%llx] ackfreq[%u] plnk_updt[0x%02x] opts[0x%02x] "
+		       "mtu[%llu] (rmtu[%llu]) cflags[0x%04x] lso_max[%u]\n",
+		       pkt->xfer_mode, pkt->addr_type,
+		       (unsigned long long)pkt->addr,
+		       pkt->ack_freq, pkt->plnk_updt, pkt->options,
+		       (unsigned long long)pkt->mtu, port->rmtu, pkt->cflags,
+		       pkt->ipv4_lso_maxlen);
 
 		pkt->tag.stype = VIO_SUBTYPE_ACK;
 
@@ -210,7 +276,7 @@ static int vnet_rx_one(struct vnet_port *port, unsigned int len,
 	int err;
 
 	err = -EMSGSIZE;
-	if (unlikely(len < ETH_ZLEN || len > ETH_FRAME_LEN)) {
+	if (unlikely(len < ETH_ZLEN || len > port->rmtu)) {
 		dev->stats.rx_length_errors++;
 		goto out_dropped;
 	}
@@ -555,8 +621,10 @@ static void vnet_event(void *arg, int event)
 		vio_link_state_change(vio, event);
 		spin_unlock_irqrestore(&vio->lock, flags);
 
-		if (event == LDC_EVENT_RESET)
+		if (event == LDC_EVENT_RESET) {
+			port->rmtu = 0;
 			vio_port_up(vio);
+		}
 		return;
 	}
 
@@ -1048,8 +1116,8 @@ static int vnet_port_alloc_tx_bufs(struct vnet_port *port)
 	void *dring;
 
 	for (i = 0; i < VNET_TX_RING_SIZE; i++) {
-		void *buf = kzalloc(ETH_FRAME_LEN + 8, GFP_KERNEL);
-		int map_len = (ETH_FRAME_LEN + 7) & ~7;
+		void *buf = kzalloc(VNET_MAXPACKET + 8, GFP_KERNEL);
+		int map_len = (VNET_MAXPACKET + 7) & ~7;
 
 		err = -ENOMEM;
 		if (!buf)
diff --git a/drivers/net/ethernet/sun/sunvnet.h b/drivers/net/ethernet/sun/sunvnet.h
index da49337..986e04b 100644
--- a/drivers/net/ethernet/sun/sunvnet.h
+++ b/drivers/net/ethernet/sun/sunvnet.h
@@ -11,6 +11,7 @@
  */
 #define VNET_TX_TIMEOUT			(5 * HZ)
 
+#define VNET_MAXPACKET			1518ULL /* ETH_FRAMELEN + VLAN_HDR */
 #define VNET_TX_RING_SIZE		512
 #define VNET_TX_WAKEUP_THRESH(dr)	((dr)->pending / 4)
 
@@ -44,6 +45,8 @@ struct vnet_port {
 	u32			stop_rx_idx;
 	bool			stop_rx;
 	bool			start_cons;
+
+	u64			rmtu;
 };
 
 static inline struct vnet_port *to_vnet_port(struct vio_driver_state *vio)
-- 
1.7.1

^ permalink raw reply related

* Re: Cannot move macvlan interface on top of bonding device
From: Francesco Ruggeri @ 2014-09-17 20:49 UTC (permalink / raw)
  To: Cong Wang
  Cc: Vlad Yasevich, Florian Westphal, netdev, David S. Miller,
	Weilong Chen
In-Reply-To: <CAHA+R7M5+1gbfx7pv=bPdNempL1eeXRu-J79c29z1k6Mr-aXfA@mail.gmail.com>

>>
>> May be a better solution is:
>>
>>         features = netdev_increment_features(vlan->lowerdev->features & MACVLAN_FEATURS,
>>                                              features,
>>                                              mask);
>>
>> This way we start with only the feature MACVLAN is interested in.
>>
>
> Or clear it in mask?

Do you guys see a problem with the patch I submitted (net: allow
macvlans to move to net namespace)?

Francesco

^ permalink raw reply

* [PATCHv5 net-next 3/3] sunvnet: generate ICMP PTMUD messages for smaller port MTUs
From: David L Stevens @ 2014-09-17 20:49 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

This patch sends ICMP and ICMPv6 messages for Path MTU Discovery when a remote
port MTU is smaller than the device MTU. This allows mixing newer VIO protocol
devices that support MTU negotiation with older devices that do not on the
same vswitch. It also allows Linux-Linux LDOMs to use 64K-1 data packets even
though Solaris vswitch is limited to <16K MTU.

Signed-off-by: David L Stevens <david.stevens@oracle.com>
---
 drivers/net/ethernet/sun/sunvnet.c |   37 +++++++++++++++++++++++++++++++++++-
 1 files changed, 36 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index 5e64e60..3c4ee18 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -17,6 +17,13 @@
 #include <linux/mutex.h>
 #include <linux/if_vlan.h>
 
+#if IS_ENABLED(CONFIG_IPV6)
+#include <linux/icmpv6.h>
+#endif
+
+#include <net/icmp.h>
+#include <net/route.h>
+
 #include <asm/vio.h>
 #include <asm/ldc.h>
 
@@ -791,8 +798,36 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (unlikely(!port))
 		goto out_dropped;
 
-	if (skb->len > port->rmtu)
+	if (skb->len > port->rmtu) {
+		unsigned long localmtu = port->rmtu - ETH_HLEN;
+
+		if (vio_version_after_eq(&port->vio, 1, 3))
+			localmtu -= VLAN_HLEN;
+
+		if (skb->protocol == htons(ETH_P_IP)) {
+			struct flowi4 fl4;
+			struct rtable *rt = NULL;
+
+			memset(&fl4, 0, sizeof(fl4));
+			fl4.flowi4_oif = dev->ifindex;
+			fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
+			fl4.daddr = ip_hdr(skb)->daddr;
+			fl4.saddr = ip_hdr(skb)->saddr;
+
+			rt = ip_route_output_key(dev_net(dev), &fl4);
+			if (!IS_ERR(rt)) {
+				skb_dst_set(skb, &rt->dst);
+				icmp_send(skb, ICMP_DEST_UNREACH,
+					  ICMP_FRAG_NEEDED,
+					  htonl(localmtu));
+			}
+		}
+#if IS_ENABLED(CONFIG_IPV6)
+		else if (skb->protocol == htons(ETH_P_IPV6))
+			icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, localmtu);
+#endif
 		goto out_dropped;
+	}
 
 	spin_lock_irqsave(&port->vio.lock, flags);
 
-- 
1.7.1

^ permalink raw reply related

* [PATCHv5 net-next 0/3] sunvnet: add jumbo frames support
From: David L Stevens @ 2014-09-17 20:49 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

This patch set updates the sunvnet driver to version 1.6 of the VIO protocol
to support per-port exchange of MTU information and allow non-standard MTU
sizes, including jumbo frames.

Using large MTUs shows a > 4X throughput improvement Linux-Solaris
and > 8X throughput improvement Linux-Linux.

Changes from v4:
	- changed VNET_MAXPACKET per David Laight <David.Laight@ACULAB.COM>
	- added cookies to support non-contiguous buffers of max size
Changes from v3:
	- added version functions per Dave Miller <davem@davemloft.net>
	- moved rmtu to vnet_port per Dave Miller <davem@davemloft.net>
	- explicitly set options bits and capability flags to 0 per
		Raghuram Kothakota <Raghuram.Kothakota@oracle.com>
Changes from v2:
	- make checkpatch clean
Changes from v1:
	- fix brace formatting per Dave Miller <davem@davemloft.net>

David L Stevens (3):
  sunvnet: upgrade to VIO protocol version 1.6
  sunvnet: allow admin to set sunvnet MTU
  sunvnet: generate ICMP PTMUD messages for smaller port MTUs

 arch/sparc/include/asm/vio.h       |   44 ++++++++++-
 arch/sparc/kernel/ldc.c            |    2 +-
 arch/sparc/kernel/viohs.c          |   14 +++-
 drivers/net/ethernet/sun/sunvnet.c |  146 +++++++++++++++++++++++++++++++-----
 drivers/net/ethernet/sun/sunvnet.h |    7 ++-
 5 files changed, 187 insertions(+), 26 deletions(-)

^ permalink raw reply

* Re: Cannot move macvlan interface on top of bonding device
From: Cong Wang @ 2014-09-17 20:46 UTC (permalink / raw)
  To: Vlad Yasevich
  Cc: Florian Westphal, Francesco Ruggeri, netdev, David S. Miller,
	Weilong Chen
In-Reply-To: <5419F17D.2090409@gmail.com>

On Wed, Sep 17, 2014 at 1:39 PM, Vlad Yasevich <vyasevich@gmail.com> wrote:
> On 09/17/2014 03:06 PM, Florian Westphal wrote:
>> Cong Wang <cwang@twopensource.com> wrote:
>>> On Wed, Sep 17, 2014 at 8:56 AM, Francesco Ruggeri <fruggeri@arista.com> wrote:
>>>> This used to work in older releases.
>>>> The problem seems to be that commit f939981492 sets NETIF_F_NETNS_LOCAL
>>>> on bonding interfaces, and commit 797f87f83 causes macvlan interfaces
>>>> to inherit its features from the lower device.
>>>>
>>>> Is there a reason why NETIF_F_NETNS_LOCAL should be inherited from the
>>>> lower device
>>>> by macvlan interfaces?
>>>
>>> commit 797f87f83 looks wrong, it should not inherit NETIF_F_NETNS_LOCAL,
>>> so just clear this flag. Please submit a patch.
>>
>> Under which conditions would NETIF_F_NETNS_LOCAL have to be inherited?
>> (i.e., why is it inheritable in the first place?)
>
> macvlan code calls
>         features = netdev_increment_features(vlan->lowerdev->features,
>                                              features,
>                                              mask);
>
> where lowerdev->features contains the NETIF_F_NETNS_LOCAL bit.  That
> bit is not set in features or in mask.  It is also not one of the ALL_FOR_ALL
> bits so it's not turned off.
>
> As an example, here are the values from a quit test I ran:
>
> bond features = 0x400f3888
> features = 0x3b5a09  (mask is the same).
> incremented features = 0x41bf389
>
> NETIF_F_NETNS_LOCAL is still on.

I think the comment on netdev_increment_features() is clear:

 *      Computes a new feature set after adding a device with feature set
 *      @one to the master device with current feature set @all.  Will not
 *      enable anything that is off in @mask. Returns the new feature set.

And NETIF_F_NETNS_LOCAL is on in mask.

>
> May be a better solution is:
>
>         features = netdev_increment_features(vlan->lowerdev->features & MACVLAN_FEATURS,
>                                              features,
>                                              mask);
>
> This way we start with only the feature MACVLAN is interested in.
>

Or clear it in mask?

^ permalink raw reply

* Re: Cannot move macvlan interface on top of bonding device
From: Vlad Yasevich @ 2014-09-17 20:39 UTC (permalink / raw)
  To: Florian Westphal, Cong Wang
  Cc: Francesco Ruggeri, netdev, David S. Miller, Weilong Chen
In-Reply-To: <20140917190626.GA11354@breakpoint.cc>

On 09/17/2014 03:06 PM, Florian Westphal wrote:
> Cong Wang <cwang@twopensource.com> wrote:
>> On Wed, Sep 17, 2014 at 8:56 AM, Francesco Ruggeri <fruggeri@arista.com> wrote:
>>> This used to work in older releases.
>>> The problem seems to be that commit f939981492 sets NETIF_F_NETNS_LOCAL
>>> on bonding interfaces, and commit 797f87f83 causes macvlan interfaces
>>> to inherit its features from the lower device.
>>>
>>> Is there a reason why NETIF_F_NETNS_LOCAL should be inherited from the
>>> lower device
>>> by macvlan interfaces?
>>
>> commit 797f87f83 looks wrong, it should not inherit NETIF_F_NETNS_LOCAL,
>> so just clear this flag. Please submit a patch.
> 
> Under which conditions would NETIF_F_NETNS_LOCAL have to be inherited?
> (i.e., why is it inheritable in the first place?)

macvlan code calls
        features = netdev_increment_features(vlan->lowerdev->features,
                                             features,
                                             mask);

where lowerdev->features contains the NETIF_F_NETNS_LOCAL bit.  That
bit is not set in features or in mask.  It is also not one of the ALL_FOR_ALL
bits so it's not turned off.

As an example, here are the values from a quit test I ran:

bond features = 0x400f3888
features = 0x3b5a09  (mask is the same).
incremented features = 0x41bf389

NETIF_F_NETNS_LOCAL is still on.

May be a better solution is:

        features = netdev_increment_features(vlan->lowerdev->features & MACVLAN_FEATURS,
                                             features,
                                             mask);

This way we start with only the feature MACVLAN is interested in.

-vlad

> --
> 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: Cannot move macvlan interface on top of bonding device
From: Cong Wang @ 2014-09-17 20:25 UTC (permalink / raw)
  To: Florian Westphal; +Cc: Francesco Ruggeri, netdev, David S. Miller, Weilong Chen
In-Reply-To: <20140917190626.GA11354@breakpoint.cc>

On Wed, Sep 17, 2014 at 12:06 PM, Florian Westphal <fw@strlen.de> wrote:
> Cong Wang <cwang@twopensource.com> wrote:
>> On Wed, Sep 17, 2014 at 8:56 AM, Francesco Ruggeri <fruggeri@arista.com> wrote:
>> > This used to work in older releases.
>> > The problem seems to be that commit f939981492 sets NETIF_F_NETNS_LOCAL
>> > on bonding interfaces, and commit 797f87f83 causes macvlan interfaces
>> > to inherit its features from the lower device.
>> >
>> > Is there a reason why NETIF_F_NETNS_LOCAL should be inherited from the
>> > lower device
>> > by macvlan interfaces?
>>
>> commit 797f87f83 looks wrong, it should not inherit NETIF_F_NETNS_LOCAL,
>> so just clear this flag. Please submit a patch.
>
> Under which conditions would NETIF_F_NETNS_LOCAL have to be inherited?
> (i.e., why is it inheritable in the first place?)

Huh? Kidding me?
Isn't the question for yourself the author of commit 797f87f83?

^ permalink raw reply

* Re: [PATCH v13 net-next 07/11] bpf: verifier (add ability to receive verification log)
From: Alexei Starovoitov @ 2014-09-17 19:37 UTC (permalink / raw)
  To: Daniel Borkmann
  Cc: David S. Miller, Ingo Molnar, Linus Torvalds, Andy Lutomirski,
	Hannes Frederic Sowa, Chema Gonzalez, Eric Dumazet,
	Peter Zijlstra, Pablo Neira Ayuso, H. Peter Anvin, Andrew Morton,
	Kees Cook, Linux API, Network Development, LKML
In-Reply-To: <5419DE51.1060904-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

On Wed, Sep 17, 2014 at 12:17 PM, Daniel Borkmann <dborkman-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> On 09/17/2014 07:03 PM, Daniel Borkmann wrote:
>>
>> You built your shiny new binary on that uapi setting, and later on
>> decide to run it on an older kernel. What will happen is that in your
>> bpf syscall handler you will return with -EINVAL on that kernel right
>> away since the size of union bpf_attr is greater.

that's a correct description of the code in this set.
What I mentioned in cover letter during v7 was:
"I've decided not to bother with forward compatiblity for now.
We can address it later the way perf_event_open did."
I was trying not open this can of worms :)

>> That would mean over time when new features will get added, applications
>> that want to make sure to run on _all_ kernels where the bpf syscall is
>> available have to make sure to either use the _initial_ version of
>> union bpf_attr in order to not get an -EINVAL, or worse they have
>> to probe though a syscall different versions of union bpf_attr if they
>> wish to make use of a particular feature until they do not get an -EINVAL
>> anymore.

Correct as well.
I say that would be the least of user space concerns.
If user app is built with newer bpf_attr and relies on it for some
functionality, it would need a lot more than probing.
Depending how big the new bpf_attr feature is, the app might
not have a workaround for older kernels at all.
So seeing EINVAL on older kernel might be a preferred way.

>> in BPF extensions we can ask the kernel up to what extension it
>> supports and accordingly adapt to it up front. I know it's just a
>> /trivial/ example but have you thought about something on that kind for
>> the syscall?

A 2nd option would be to do what perf_copy_attr() does:
when newer struct is coming from user space, kernel checks
that space beyond known last field is all zeros.
We can do the same, but I'm not convinced that it will
help userspace much. Newer user space can only be
_compiled_ with newer bpf_attr. It is still cannot use any new
features and it needs to make sure that all new fields are zero.
I'm not sure how it helps.
perf_event_open() also returns size. In that case it's helpful,
since it's one structure. In ebpf case we have multiple
structures under one union, so returning size of the whole
bpf_attr doesn't help one particular command.

> Hm, thinking out loudly ... perhaps this could be made a library problem.
> Such that the library which wraps the syscall needs to be aware of a
> marker where the initial version ends, and if the application doesn't
> make use of any of the new features, it would just pass in the length up
> to the marker as size attribute into the syscall. Similarly, if new
> features are always added to the end of a structure and the library
> truncates the overall-length after the last used member we might have
> a chance to load something on older kernels, haven't tried that though.

that's a 3rd option. I think it's cleaner than 2nd, since it solves it
completely from user space.
It can even be smarter than that. If this syscall wrapper library
sees that newer features are used and it can workaround them:
it can chop size and pass older fields into the older kernel
and when it returns, do a workaround based on newer fields.

^ permalink raw reply

* [PATCH v4 net-next 7/7] gre: Setup and TX path for gre/UDP foo-over-udp encapsulation
From: Tom Herbert @ 2014-09-17 19:26 UTC (permalink / raw)
  To: davem, netdev
In-Reply-To: <1410981961-15545-1-git-send-email-therbert@google.com>

Added netlink attrs to configure FOU encapsulation for GRE, netlink
handling of these flags, and properly adjust MTU for encapsulation.
ip_tunnel_encap is called from ip_tunnel_xmit to actually perform FOU
encapsulation.

Signed-off-by: Tom Herbert <therbert@google.com>
---
 include/uapi/linux/if_tunnel.h |  4 ++
 net/ipv4/ip_gre.c              | 90 +++++++++++++++++++++++++++++++++++++++---
 2 files changed, 89 insertions(+), 5 deletions(-)

diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h
index 9fedca7..7c832af 100644
--- a/include/uapi/linux/if_tunnel.h
+++ b/include/uapi/linux/if_tunnel.h
@@ -106,6 +106,10 @@ enum {
 	IFLA_GRE_ENCAP_LIMIT,
 	IFLA_GRE_FLOWINFO,
 	IFLA_GRE_FLAGS,
+	IFLA_GRE_ENCAP_TYPE,
+	IFLA_GRE_ENCAP_FLAGS,
+	IFLA_GRE_ENCAP_SPORT,
+	IFLA_GRE_ENCAP_DPORT,
 	__IFLA_GRE_MAX,
 };
 
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 9b84254..829aff8b 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -239,7 +239,7 @@ static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,
 	tpi.seq = htonl(tunnel->o_seqno);
 
 	/* Push GRE header. */
-	gre_build_header(skb, &tpi, tunnel->hlen);
+	gre_build_header(skb, &tpi, tunnel->tun_hlen);
 
 	ip_tunnel_xmit(skb, dev, tnl_params, tnl_params->protocol);
 }
@@ -310,7 +310,7 @@ out:
 static int ipgre_tunnel_ioctl(struct net_device *dev,
 			      struct ifreq *ifr, int cmd)
 {
-	int err = 0;
+	int err;
 	struct ip_tunnel_parm p;
 
 	if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
@@ -470,13 +470,18 @@ static void ipgre_tunnel_setup(struct net_device *dev)
 static void __gre_tunnel_init(struct net_device *dev)
 {
 	struct ip_tunnel *tunnel;
+	int t_hlen;
 
 	tunnel = netdev_priv(dev);
-	tunnel->hlen = ip_gre_calc_hlen(tunnel->parms.o_flags);
+	tunnel->tun_hlen = ip_gre_calc_hlen(tunnel->parms.o_flags);
 	tunnel->parms.iph.protocol = IPPROTO_GRE;
 
-	dev->needed_headroom	= LL_MAX_HEADER + sizeof(struct iphdr) + 4;
-	dev->mtu		= ETH_DATA_LEN - sizeof(struct iphdr) - 4;
+	tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen;
+
+	t_hlen = tunnel->hlen + sizeof(struct iphdr);
+
+	dev->needed_headroom	= LL_MAX_HEADER + t_hlen + 4;
+	dev->mtu		= ETH_DATA_LEN - t_hlen - 4;
 
 	dev->features		|= GRE_FEATURES;
 	dev->hw_features	|= GRE_FEATURES;
@@ -628,6 +633,40 @@ static void ipgre_netlink_parms(struct nlattr *data[], struct nlattr *tb[],
 		parms->iph.frag_off = htons(IP_DF);
 }
 
+/* This function returns true when ENCAP attributes are present in the nl msg */
+static bool ipgre_netlink_encap_parms(struct nlattr *data[],
+				      struct ip_tunnel_encap *ipencap)
+{
+	bool ret = false;
+
+	memset(ipencap, 0, sizeof(*ipencap));
+
+	if (!data)
+		return ret;
+
+	if (data[IFLA_GRE_ENCAP_TYPE]) {
+		ret = true;
+		ipencap->type = nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]);
+	}
+
+	if (data[IFLA_GRE_ENCAP_FLAGS]) {
+		ret = true;
+		ipencap->flags = nla_get_u16(data[IFLA_GRE_ENCAP_FLAGS]);
+	}
+
+	if (data[IFLA_GRE_ENCAP_SPORT]) {
+		ret = true;
+		ipencap->sport = nla_get_u16(data[IFLA_GRE_ENCAP_SPORT]);
+	}
+
+	if (data[IFLA_GRE_ENCAP_DPORT]) {
+		ret = true;
+		ipencap->dport = nla_get_u16(data[IFLA_GRE_ENCAP_DPORT]);
+	}
+
+	return ret;
+}
+
 static int gre_tap_init(struct net_device *dev)
 {
 	__gre_tunnel_init(dev);
@@ -657,6 +696,15 @@ static int ipgre_newlink(struct net *src_net, struct net_device *dev,
 			 struct nlattr *tb[], struct nlattr *data[])
 {
 	struct ip_tunnel_parm p;
+	struct ip_tunnel_encap ipencap;
+
+	if (ipgre_netlink_encap_parms(data, &ipencap)) {
+		struct ip_tunnel *t = netdev_priv(dev);
+		int err = ip_tunnel_encap_setup(t, &ipencap);
+
+		if (err < 0)
+			return err;
+	}
 
 	ipgre_netlink_parms(data, tb, &p);
 	return ip_tunnel_newlink(dev, tb, &p);
@@ -666,6 +714,15 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
 			    struct nlattr *data[])
 {
 	struct ip_tunnel_parm p;
+	struct ip_tunnel_encap ipencap;
+
+	if (ipgre_netlink_encap_parms(data, &ipencap)) {
+		struct ip_tunnel *t = netdev_priv(dev);
+		int err = ip_tunnel_encap_setup(t, &ipencap);
+
+		if (err < 0)
+			return err;
+	}
 
 	ipgre_netlink_parms(data, tb, &p);
 	return ip_tunnel_changelink(dev, tb, &p);
@@ -694,6 +751,14 @@ static size_t ipgre_get_size(const struct net_device *dev)
 		nla_total_size(1) +
 		/* IFLA_GRE_PMTUDISC */
 		nla_total_size(1) +
+		/* IFLA_GRE_ENCAP_TYPE */
+		nla_total_size(2) +
+		/* IFLA_GRE_ENCAP_FLAGS */
+		nla_total_size(2) +
+		/* IFLA_GRE_ENCAP_SPORT */
+		nla_total_size(2) +
+		/* IFLA_GRE_ENCAP_DPORT */
+		nla_total_size(2) +
 		0;
 }
 
@@ -714,6 +779,17 @@ static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
 	    nla_put_u8(skb, IFLA_GRE_PMTUDISC,
 		       !!(p->iph.frag_off & htons(IP_DF))))
 		goto nla_put_failure;
+
+	if (nla_put_u16(skb, IFLA_GRE_ENCAP_TYPE,
+			t->encap.type) ||
+	    nla_put_u16(skb, IFLA_GRE_ENCAP_SPORT,
+			t->encap.sport) ||
+	    nla_put_u16(skb, IFLA_GRE_ENCAP_DPORT,
+			t->encap.dport) ||
+	    nla_put_u16(skb, IFLA_GRE_ENCAP_FLAGS,
+			t->encap.dport))
+		goto nla_put_failure;
+
 	return 0;
 
 nla_put_failure:
@@ -731,6 +807,10 @@ static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
 	[IFLA_GRE_TTL]		= { .type = NLA_U8 },
 	[IFLA_GRE_TOS]		= { .type = NLA_U8 },
 	[IFLA_GRE_PMTUDISC]	= { .type = NLA_U8 },
+	[IFLA_GRE_ENCAP_TYPE]	= { .type = NLA_U16 },
+	[IFLA_GRE_ENCAP_FLAGS]	= { .type = NLA_U16 },
+	[IFLA_GRE_ENCAP_SPORT]	= { .type = NLA_U16 },
+	[IFLA_GRE_ENCAP_DPORT]	= { .type = NLA_U16 },
 };
 
 static struct rtnl_link_ops ipgre_link_ops __read_mostly = {
-- 
2.1.0.rc2.206.gedb03e5

^ permalink raw reply related

* [PATCH v4 net-next 6/7] ipip: Setup and TX path for ipip/UDP foo-over-udp encapsulation
From: Tom Herbert @ 2014-09-17 19:26 UTC (permalink / raw)
  To: davem, netdev
In-Reply-To: <1410981961-15545-1-git-send-email-therbert@google.com>

Add netlink handling for IP tunnel encapsulation parameters and
and adjustment of MTU for encapsulation.  ip_tunnel_encap is called
from ip_tunnel_xmit to actually perform FOU encapsulation.

Signed-off-by: Tom Herbert <therbert@google.com>
---
 net/ipv4/ipip.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 77 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 62eaa00..bfec31d 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -301,7 +301,8 @@ static int ipip_tunnel_init(struct net_device *dev)
 	memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
 	memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
 
-	tunnel->hlen = 0;
+	tunnel->tun_hlen = 0;
+	tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen;
 	tunnel->parms.iph.protocol = IPPROTO_IPIP;
 	return ip_tunnel_init(dev);
 }
@@ -340,10 +341,53 @@ static void ipip_netlink_parms(struct nlattr *data[],
 		parms->iph.frag_off = htons(IP_DF);
 }
 
+/* This function returns true when ENCAP attributes are present in the nl msg */
+static bool ipip_netlink_encap_parms(struct nlattr *data[],
+				     struct ip_tunnel_encap *ipencap)
+{
+	bool ret = false;
+
+	memset(ipencap, 0, sizeof(*ipencap));
+
+	if (!data)
+		return ret;
+
+	if (data[IFLA_IPTUN_ENCAP_TYPE]) {
+		ret = true;
+		ipencap->type = nla_get_u16(data[IFLA_IPTUN_ENCAP_TYPE]);
+	}
+
+	if (data[IFLA_IPTUN_ENCAP_FLAGS]) {
+		ret = true;
+		ipencap->flags = nla_get_u16(data[IFLA_IPTUN_ENCAP_FLAGS]);
+	}
+
+	if (data[IFLA_IPTUN_ENCAP_SPORT]) {
+		ret = true;
+		ipencap->sport = nla_get_u16(data[IFLA_IPTUN_ENCAP_SPORT]);
+	}
+
+	if (data[IFLA_IPTUN_ENCAP_DPORT]) {
+		ret = true;
+		ipencap->dport = nla_get_u16(data[IFLA_IPTUN_ENCAP_DPORT]);
+	}
+
+	return ret;
+}
+
 static int ipip_newlink(struct net *src_net, struct net_device *dev,
 			struct nlattr *tb[], struct nlattr *data[])
 {
 	struct ip_tunnel_parm p;
+	struct ip_tunnel_encap ipencap;
+
+	if (ipip_netlink_encap_parms(data, &ipencap)) {
+		struct ip_tunnel *t = netdev_priv(dev);
+		int err = ip_tunnel_encap_setup(t, &ipencap);
+
+		if (err < 0)
+			return err;
+	}
 
 	ipip_netlink_parms(data, &p);
 	return ip_tunnel_newlink(dev, tb, &p);
@@ -353,6 +397,15 @@ static int ipip_changelink(struct net_device *dev, struct nlattr *tb[],
 			   struct nlattr *data[])
 {
 	struct ip_tunnel_parm p;
+	struct ip_tunnel_encap ipencap;
+
+	if (ipip_netlink_encap_parms(data, &ipencap)) {
+		struct ip_tunnel *t = netdev_priv(dev);
+		int err = ip_tunnel_encap_setup(t, &ipencap);
+
+		if (err < 0)
+			return err;
+	}
 
 	ipip_netlink_parms(data, &p);
 
@@ -378,6 +431,14 @@ static size_t ipip_get_size(const struct net_device *dev)
 		nla_total_size(1) +
 		/* IFLA_IPTUN_PMTUDISC */
 		nla_total_size(1) +
+		/* IFLA_IPTUN_ENCAP_TYPE */
+		nla_total_size(2) +
+		/* IFLA_IPTUN_ENCAP_FLAGS */
+		nla_total_size(2) +
+		/* IFLA_IPTUN_ENCAP_SPORT */
+		nla_total_size(2) +
+		/* IFLA_IPTUN_ENCAP_DPORT */
+		nla_total_size(2) +
 		0;
 }
 
@@ -394,6 +455,17 @@ static int ipip_fill_info(struct sk_buff *skb, const struct net_device *dev)
 	    nla_put_u8(skb, IFLA_IPTUN_PMTUDISC,
 		       !!(parm->iph.frag_off & htons(IP_DF))))
 		goto nla_put_failure;
+
+	if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE,
+			tunnel->encap.type) ||
+	    nla_put_u16(skb, IFLA_IPTUN_ENCAP_SPORT,
+			tunnel->encap.sport) ||
+	    nla_put_u16(skb, IFLA_IPTUN_ENCAP_DPORT,
+			tunnel->encap.dport) ||
+	    nla_put_u16(skb, IFLA_IPTUN_ENCAP_FLAGS,
+			tunnel->encap.dport))
+		goto nla_put_failure;
+
 	return 0;
 
 nla_put_failure:
@@ -407,6 +479,10 @@ static const struct nla_policy ipip_policy[IFLA_IPTUN_MAX + 1] = {
 	[IFLA_IPTUN_TTL]		= { .type = NLA_U8 },
 	[IFLA_IPTUN_TOS]		= { .type = NLA_U8 },
 	[IFLA_IPTUN_PMTUDISC]		= { .type = NLA_U8 },
+	[IFLA_IPTUN_ENCAP_TYPE]		= { .type = NLA_U16 },
+	[IFLA_IPTUN_ENCAP_FLAGS]	= { .type = NLA_U16 },
+	[IFLA_IPTUN_ENCAP_SPORT]	= { .type = NLA_U16 },
+	[IFLA_IPTUN_ENCAP_DPORT]	= { .type = NLA_U16 },
 };
 
 static struct rtnl_link_ops ipip_link_ops __read_mostly = {
-- 
2.1.0.rc2.206.gedb03e5

^ 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