Netdev List
 help / color / mirror / Atom feed
* [net-next PATCH v2 4/4] net: sched: cls_fw: add missing tcf_exts_init call in fw_change()
From: John Fastabend @ 2014-09-16  6:31 UTC (permalink / raw)
  To: xiyou.wangcong, davem, eric.dumazet; +Cc: netdev, jhs
In-Reply-To: <20140916063024.2905.55403.stgit@nitbit.x32>

When allocating a new structure we also need to call tcf_exts_init
to initialize exts.

A follow up patch might be in order to remove some of this code
and do tcf_exts_assign(). With this we could remove the
tcf_exts_init/tcf_exts_change pattern for some of the classifiers.
As part of the future tcf_actions RCU series this will need to be
done. For now fix the call here.

Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
 net/sched/cls_fw.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 006b45a..2650285 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -264,6 +264,8 @@ static int fw_change(struct net *net, struct sk_buff *in_skb,
 #endif /* CONFIG_NET_CLS_IND */
 		fnew->tp = f->tp;
 
+		tcf_exts_init(&fnew->exts, TCA_FW_ACT, TCA_FW_POLICE);
+
 		err = fw_change_attrs(net, tp, fnew, tb, tca, base, ovr);
 		if (err < 0) {
 			kfree(fnew);

^ permalink raw reply related

* [net-next PATCH v2 3/4] net: sched: cls_cgroup fix possible memory leak of 'new'
From: John Fastabend @ 2014-09-16  6:31 UTC (permalink / raw)
  To: xiyou.wangcong, davem, eric.dumazet; +Cc: netdev, jhs
In-Reply-To: <20140916063024.2905.55403.stgit@nitbit.x32>

tree:   git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git master
head:   54996b529ab70ca1d6f40677cd2698c4f7127e87
commit: c7953ef23042b7c4fc2be5ecdd216aacff6df5eb [625/646] net: sched: cls_cgroup use RCU

net/sched/cls_cgroup.c:130 cls_cgroup_change() warn: possible memory leak of 'new'
net/sched/cls_cgroup.c:135 cls_cgroup_change() warn: possible memory leak of 'new'
net/sched/cls_cgroup.c:139 cls_cgroup_change() warn: possible memory leak of 'new'

Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
 net/sched/cls_cgroup.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 3b75487..10c7ffd 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -127,16 +127,18 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
 	err = nla_parse_nested(tb, TCA_CGROUP_MAX, tca[TCA_OPTIONS],
 			       cgroup_policy);
 	if (err < 0)
-		return err;
+		goto errout;
 
 	tcf_exts_init(&e, TCA_CGROUP_ACT, TCA_CGROUP_POLICE);
 	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
 	if (err < 0)
-		return err;
+		goto errout;
 
 	err = tcf_em_tree_validate(tp, tb[TCA_CGROUP_EMATCHES], &t);
-	if (err < 0)
-		return err;
+	if (err < 0) {
+		tcf_exts_destroy(tp, &e);
+		goto errout;
+	}
 
 	tcf_exts_change(tp, &new->exts, &e);
 	tcf_em_tree_change(tp, &new->ematches, &t);
@@ -145,6 +147,9 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
 	if (head)
 		call_rcu(&head->rcu, cls_cgroup_destroy_rcu);
 	return 0;
+errout:
+	kfree(new);
+	return err;
 }
 
 static void cls_cgroup_destroy(struct tcf_proto *tp)

^ permalink raw reply related

* [net-next PATCH v2 2/4] net: sched: cls_u32 add missing rcu_assign_pointer and annotation
From: John Fastabend @ 2014-09-16  6:30 UTC (permalink / raw)
  To: xiyou.wangcong, davem, eric.dumazet; +Cc: netdev, jhs
In-Reply-To: <20140916063024.2905.55403.stgit@nitbit.x32>

Add missing rcu_assign_pointer and missing  annotation for ht_up
in cls_u32.c

Caught by kbuild bot,

>> net/sched/cls_u32.c:378:36: sparse: incorrect type in initializer (different address spaces)
   net/sched/cls_u32.c:378:36:    expected struct tc_u_hnode *ht
   net/sched/cls_u32.c:378:36:    got struct tc_u_hnode [noderef] <asn:4>*ht_up
>> net/sched/cls_u32.c:610:54: sparse: incorrect type in argument 4 (different address spaces)
   net/sched/cls_u32.c:610:54:    expected struct tc_u_hnode *ht
   net/sched/cls_u32.c:610:54:    got struct tc_u_hnode [noderef] <asn:4>*ht_up
>> net/sched/cls_u32.c:684:18: sparse: incorrect type in assignment (different address spaces)
   net/sched/cls_u32.c:684:18:    expected struct tc_u_hnode [noderef] <asn:4>*ht_up
   net/sched/cls_u32.c:684:18:    got struct tc_u_hnode *[assigned] ht
>> net/sched/cls_u32.c:359:18: sparse: dereference of noderef expression

Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
 net/sched/cls_u32.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 8cffe5a..eceeb04 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -375,7 +375,7 @@ static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key)
 {
 	struct tc_u_knode __rcu **kp;
 	struct tc_u_knode *pkp;
-	struct tc_u_hnode *ht = key->ht_up;
+	struct tc_u_hnode *ht = rtnl_dereference(key->ht_up);
 
 	if (ht) {
 		kp = &ht->ht[TC_U32_HASH(key->handle)];
@@ -607,7 +607,8 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
 		if (TC_U32_KEY(n->handle) == 0)
 			return -EINVAL;
 
-		return u32_set_parms(net, tp, base, n->ht_up, n, tb,
+		return u32_set_parms(net, tp, base,
+				     rtnl_dereference(n->ht_up), n, tb,
 				     tca[TCA_RATE], ovr);
 	}
 
@@ -681,7 +682,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
 #endif
 
 	memcpy(&n->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key));
-	n->ht_up = ht;
+	RCU_INIT_POINTER(n->ht_up, ht);
 	n->handle = handle;
 	n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0;
 	tcf_exts_init(&n->exts, TCA_U32_ACT, TCA_U32_POLICE);

^ permalink raw reply related

* RE: curent state of GSO over IPv6 tunnel
From: Yuval Mintz @ 2014-09-16  6:30 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1410776995.7106.143.camel@edumazet-glaptop2.roam.corp.google.com>

 > > > Hi,
> > > >
> > > > Tried running simple scenarios using ipv6/ipv6 via gre-tunnel [ip6_gre].
> > > >
> > > > When I've tried sniffing Tx traffic [tcpdump] I've noticed there
> > > > were no aggregations being set, i.e., only MTU-sized packets reached NIC.
> > > >
> > > > Looking at output of `ethtool -k', I can see `tx_gre_segmentation' is on.
> > > >
> > > > What's the current state of the feature? Is it feasible and I'm
> > > > missing some configuration, or is it yet an unsupported feature?
> > >
> > > As far as I know, only bnx2x driver currently supports
> > > NETIF_F_GSO_GRE
> > >
> >
> > Hi Eric,
> >
> > Might be true, but should this flag hold any sway over IPv6?
> > [Both at the moment and in general, i.e., if it does not would we need
> > an additional feature or simply extend the functionality so that it
> > would effect IPv6 as well?]
> 
> Both ipv4 and ipv6 are supported under this single flag.
> 
> Really, in 2014 all NIC supporting TSO for GRE should support IPv6 as well.
> 

O.k. - I can see that natively ip6_gre device doesn't show any features.
If I would like to modify its code in order for it to support GSO/TSO,
what would that entail?

[I assume it would require a deep-dive otherwise someone would have done
it already; But still, I'd like to get a pointer if possible].

Thanks,
Yuval

^ permalink raw reply

* Re: Qdisc: Measuring Head-of-Line blocking with netperf-wrapper
From: Jesper Dangaard Brouer @ 2014-09-16  6:30 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Tom Herbert, netdev@vger.kernel.org, Stephen Hemminger,
	David Miller, Hannes Frederic Sowa, Daniel Borkmann,
	Florian Westphal, Toke Høiland-Jørgensen, Dave Taht,
	brouer
In-Reply-To: <1410801863.7106.169.camel@edumazet-glaptop2.roam.corp.google.com>

On Mon, 15 Sep 2014 10:24:23 -0700
Eric Dumazet <eric.dumazet@gmail.com> wrote:

> On Mon, 2014-09-15 at 10:10 -0700, Tom Herbert wrote:
> > On Mon, Sep 15, 2014 at 9:45 AM, Jesper Dangaard Brouer
> > <brouer@redhat.com> wrote:
> > >
> > > Hi Eric,
> > >
> > > I've constructed a "netperf-wrapper" test for measuring Head-of-Line
> > > blocking, called "tcp_upload_prio", that I hope you will approve of?
> > >
> > >  https://github.com/tohojo/netperf-wrapper/commit/1e6b755e8051b6
> > >
> > > The basic idea is to have ping packets with TOS bit 0x10, which end-up
> > > in the high-prio band of pfifo_fast.  While two TCP uploads utilize
> > > all the bandwidth.
> > >
> > > These high-prio ping packet should then demonstrate the Head-of-Line
> > > blocking occurring due to 1) packets in the HW TX ring buffer, or
> > > 2) in the qdisc layers requeue mechanism.  Disgusting these two case
> > > might be a little difficult.
> > >
> > >
> > >
> > > Special care need to be take for using this on the default
> > > qdisc MQ which have pfifo_fast assigned for every HW queue.
> > >
> > > Setup requirements:
> > >  1. IRQ align CPUs to NIC HW queues
> > >  2. Force netperf-wrapper subcommands to run the same CPU
> > >   E.g: taskset -c 2 ./netperf-wrapper -H IP tcp_upload_prio
> > >
> > > This will force all measurements to go through the same qdisc.  This
> > > is needed so the ping/latency tests measures the real property of
> > > the qdisc and Head-of-Line blocking effect.
> > >
> > >
> > > Basically the same as:
> > >  sudo taskset -c 2 ping -Q 0x10 192.168.8.2
> > >  sudo taskset -c 2 ping         192.168.8.2
> > >  sudo taskset -c 2 netperf   -H 192.168.8.2 -t TCP_STREAM -l 120
> > >  sudo taskset -c 2 netperf   -H 192.168.8.2 -t TCP_STREAM -l 120
> > > --
> > ping is a very coarse way to measure latency and in network devices it
> > doesn't follow same path as TCP/UDP (no 4-tuple for RSS, ECMP) so it's
> > biased and not a very realistic workload. You might want to try using
> > netperf TCP_RR at higher priority for a fairer comparison (this is
> > what I used to verify BQL benefits). 

I worry about starvation, when putting too much/heavy traffic in the
high prio queue.

I've played with UDP_RR (in high prio queue) to measure the latency, it
worked well (much less fluctuations than ping) for GSO and TSO , but
for the none-GSO case it disturbed the two TCP uploads so much, that
they could not utilize the link.

For TCP_RR I worry what happens if a packet loss and RTO happens, but I
guess putting this in the high prio queue should make drops (a lot)
less likely.

> > Also, you probably want to make
> > sure to have enough antagonist flows to saturate all links when using
> > MQ.

For the none-GSO case, I guess adding more TCP uploads might help, but
they might just get starvated.  I'll give it a try.


> Jesper, relevant netperf option is :
> 
>     -y local,remote   Set the socket priority

Check, netperf-wrapper already supports setting these.


-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Sr. Network Kernel Developer at Red Hat
  Author of http://www.iptv-analyzer.org
  LinkedIn: http://www.linkedin.com/in/brouer

^ permalink raw reply

* Re: [net-next PATCH 2/3] net: sched: cls_u32 add missing rcu_assign_pointer and annotation
From: John Fastabend @ 2014-09-16  6:25 UTC (permalink / raw)
  To: John Fastabend, xiyou.wangcong, davem, eric.dumazet; +Cc: netdev, jhs
In-Reply-To: <20140916024759.3010.24175.stgit@nitbit.x32>

On 09/15/2014 07:48 PM, John Fastabend wrote:
> Add missing rcu_assign_pointer and missing  annotation for ht_up
> in cls_u32.c
> 
> Caught by kbuild bot,
> 
>>> net/sched/cls_u32.c:378:36: sparse: incorrect type in initializer (different address spaces)
>    net/sched/cls_u32.c:378:36:    expected struct tc_u_hnode *ht
>    net/sched/cls_u32.c:378:36:    got struct tc_u_hnode [noderef] <asn:4>*ht_up
>>> net/sched/cls_u32.c:610:54: sparse: incorrect type in argument 4 (different address spaces)
>    net/sched/cls_u32.c:610:54:    expected struct tc_u_hnode *ht
>    net/sched/cls_u32.c:610:54:    got struct tc_u_hnode [noderef] <asn:4>*ht_up
>>> net/sched/cls_u32.c:684:18: sparse: incorrect type in assignment (different address spaces)
>    net/sched/cls_u32.c:684:18:    expected struct tc_u_hnode [noderef] <asn:4>*ht_up
>    net/sched/cls_u32.c:684:18:    got struct tc_u_hnode *[assigned] ht
>>> net/sched/cls_u32.c:359:18: sparse: dereference of noderef expression
> 
> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> ---
>  net/sched/cls_u32.c |    7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
> index 8cffe5a..19b2808 100644
> --- a/net/sched/cls_u32.c
> +++ b/net/sched/cls_u32.c
> @@ -375,7 +375,7 @@ static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key)
>  {
>  	struct tc_u_knode __rcu **kp;
>  	struct tc_u_knode *pkp;
> -	struct tc_u_hnode *ht = key->ht_up;
> +	struct tc_u_hnode *ht = rtnl_dereference(key->ht_up);
>  
>  	if (ht) {
>  		kp = &ht->ht[TC_U32_HASH(key->handle)];
> @@ -607,7 +607,8 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
>  		if (TC_U32_KEY(n->handle) == 0)
>  			return -EINVAL;
>  
> -		return u32_set_parms(net, tp, base, n->ht_up, n, tb,
> +		return u32_set_parms(net, tp, base,
> +				     rtnl_dereference(n->ht_up), n, tb,
>  				     tca[TCA_RATE], ovr);
>  	}
>  
> @@ -681,7 +682,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
>  #endif
>  
>  	memcpy(&n->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key));
> -	n->ht_up = ht;
> +	rcu_assign_pointer(n->ht_up, ht);

also believe this should be RCU_INIT_POINTER() the rcu_assign_pointer() to attach
n to the hash table happens below so there are no concurrent readers until after
the assign.

however while reviewing this I realize there is a 'copy'/'update' pattern I
missed in the u32_set_parms case when the classid and ifindex is changed. So
a fix coming for that shortly.

>  	n->handle = handle;
>  	n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0;
>  	tcf_exts_init(&n->exts, TCA_U32_ACT, TCA_U32_POLICE);
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* RE: [PATCH 3] scsi: fix build errors, SCSI_FC_ATTRS needs to depend on SCSI && NET
From: Anish Bhatt @ 2014-09-16  4:11 UTC (permalink / raw)
  To: Randy Dunlap, netdev@vger.kernel.org, JBottomley@parallels.com,
	David Miller
  Cc: linux-scsi@vger.kernel.org, mchan@broadcom.com,
	eddie.wai@broadcom.com, jim.epost@gmail.com
In-Reply-To: <5417ABD7.3020005@infradead.org>


________________________________________
From: Randy Dunlap [rdunlap@infradead.org]
Sent: Monday, September 15, 2014 8:17 PM
To: Anish Bhatt; netdev@vger.kernel.org; JBottomley@parallels.com; David Miller
Cc: linux-scsi@vger.kernel.org; mchan@broadcom.com; eddie.wai@broadcom.com; jim.epost@gmail.com
Subject: Re: [PATCH 3] scsi: fix build errors, SCSI_FC_ATTRS needs to depend on SCSI && NET

On 09/15/14 20:00, Anish Bhatt wrote:
>>
>> Doesn't fix make warnings, but SCSI_FC_ATTRS can no longer be selected without
>> NET. Though both ia64 and powerpc emit a lot of unmet dependency warnings as is
>> on defconfig


> You mean these kconfig warnings?
[....]
> I'll look into those.
>--
>~Randy

Yes, thanks
-Anish

^ permalink raw reply

* Re: [PATCH 3] scsi: fix build errors, SCSI_FC_ATTRS needs to depend on SCSI && NET
From: David Miller @ 2014-09-16  4:07 UTC (permalink / raw)
  To: rdunlap; +Cc: anish, netdev, JBottomley, linux-scsi, mchan, eddie.wai,
	jim.epost
In-Reply-To: <5417825A.4050902@infradead.org>

From: Randy Dunlap <rdunlap@infradead.org>
Date: Mon, 15 Sep 2014 17:20:42 -0700

> From: Randy Dunlap <rdunlap@infradead.org>
> 
> Fix build errors when CONFIG_SCSI_NETLINK is enabled but
> CONFIG_NET is not enabled:
 ...
> Signed-off-by: Randy Dunlap <rdunlap@infradead.org>

Applied, thanks a lot Randy.

^ permalink raw reply

* [PATCH firmware RESEND] rtl_nic: add firmware for RTL8168H and RTL8107E
From: Hayes Wang @ 2014-09-16  3:46 UTC (permalink / raw)
  To: linux-firmware; +Cc: netdev, linux-kernel, hau, ivecera, Hayes Wang
In-Reply-To: <1394712342-15778-41-Taiwan-albertk@realtek.com>

File: rtl_nic/rtl8168h-1.fw
Version: 0.0.1

File: rtl_nic/rtl8168h-2.fw
Version: 0.0.1

File: rtl_nic/rtl8107e-1.fw
Version: 0.0.1

File: rtl_nic/rtl8107e-2.fw
Version: 0.0.1

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 WHENCE                |  12 ++++++++++++
 rtl_nic/rtl8107e-1.fw | Bin 0 -> 2496 bytes
 rtl_nic/rtl8107e-2.fw | Bin 0 -> 2464 bytes
 rtl_nic/rtl8168h-1.fw | Bin 0 -> 2496 bytes
 rtl_nic/rtl8168h-2.fw | Bin 0 -> 2464 bytes
 5 files changed, 12 insertions(+)
 create mode 100644 rtl_nic/rtl8107e-1.fw
 create mode 100644 rtl_nic/rtl8107e-2.fw
 create mode 100644 rtl_nic/rtl8168h-1.fw
 create mode 100644 rtl_nic/rtl8168h-2.fw

diff --git a/WHENCE b/WHENCE
index 26cabf4..3ffc68e 100644
--- a/WHENCE
+++ b/WHENCE
@@ -2149,6 +2149,18 @@ Version: 0.0.1
 File: rtl_nic/rtl8168g-3.fw
 Version: 0.0.1
 
+File: rtl_nic/rtl8168h-1.fw
+Version: 0.0.1
+
+File: rtl_nic/rtl8168h-2.fw
+Version: 0.0.1
+
+File: rtl_nic/rtl8107e-1.fw
+Version: 0.0.1
+
+File: rtl_nic/rtl8107e-2.fw
+Version: 0.0.1
+
 Licence:
  * Copyright © 2011-2013, Realtek Semiconductor Corporation
  *
diff --git a/rtl_nic/rtl8107e-1.fw b/rtl_nic/rtl8107e-1.fw
new file mode 100644
index 0000000000000000000000000000000000000000..5ac3d62bcd6adb9a28bc84dcccbccd99a0dab290
GIT binary patch
literal 2496
zcmY+`aY$8J9tZH#8`lw6?5({q$7vb~2?^JE&%|{l<k3V(NQ6j4L^+P@NJxlCL_~YW
ziHK+%iHL{@S0o~$iHMMB#F5sG2x%iCB;p|w5z$0MM1;E^o!MpPzW3qxJ?Fl2&b{~i
z@ooqq^!4{NWYT~6+n+PL(lzOtOhx*ypJ!@6&(t}$aJ18w2;uLcwWWS-eeJH^FZ;jh
z-c_5<)TNE9`Ks&dicDSO+Dv0+ZTN1qa$(G`WoStV*~z7!#SjW8q=;gYl#rq{eh@+~
z`dvXT#HG1J{8KJ3F3aV|k8%ZZd9E;ioGXf-<ci~m|1$2=k~sTaD*n`58WaC4i{Z!e
zI2TsLiQG!<3hh;~G*Kz9maELaMy{4?<aA6-)y6PhC)djja-+OXZj!U|dU=DqQEp}v
zEo^2Bt+cU~ZER-;J87qbPP*u3H$Cj3mp=O0%RcsVfP+K^IK*L&aFk;VGQ@FCaFSD;
z<_u>UW`t4Bah?lY<Pw*;!d0#@#&vEm&IFU(WQtqd<_^=`<sSEWz(Zzu#A9;IGRG61
z@{H%a;3cnk%^TkGj`z$Hz6l{g9{ChdND;*(DIrBEWt6jml~k~bN>)?F8mg%wO)YiQ
z(?BEZXd=scHn5RqHqpXnw$Mr&TiM2TcCeFnI_RW}Zg$hd9(w7cpS|p3KL<ESWPn2)
z<_JeQ#vnr+=L9D?#c9rPmSIL1<s9d^z(p=`nJZl78e?4N2IEXH$xWuX#cl2|&0X$s
zp9ef-hDSUm$1HO^;VI8}&I?}hir2j1E$?{GJYm58lSe)U6jDSnNlHjjN*U#>U?ml-
zqLS5Av4(1DNK;E4^)%4PI-1C`o(*iInN75?nJu)^##XkmogM6?oenzbqMP0Hu!mmy
z=w~nc*v|nD5*gqShdIJgjxop($2q}CPH~zuoMo61MmfiME^v`cT;>W_xyBgRxxqLS
zOmdScZgHDCOmmle+~)xgnc)$S$uY|uPk72Rp7Vm2yy7))c*{H9Gf()|{*y;O1r$<5
zF-b~DQA!!*tY9S-tfG?DRI!F?YDiN{9rZNO$U2(HvYriWq?t{$u$e8i(#BS{v7H_4
zq@4~r>7tw6^st9s`simb``FI`4iXvQ5QjO!QI0Xl5XU*eNltN^Gn{3Z5k@)3c`k5~
zOI+p(SGmR**SWzs6HIcGDQ<C_J4|zzd)(&%51HW+kI6C198Y-4GoJH;m%QRNZ+Oc)
z-ZTI0;=4l3kF(wvl8M6jK`2}JPsk4Zap4^z>9hEqh>PveyTpPEU0EBS4T<4S4=98`
zq`xTqELO#3F?6J2&DgTIB&6a(UxhrBNX3$2=k%r2yy{d;{?<q;F8PPP=~V2^rDAre
z_78lYicMwu2jy?nfmEESO2zVD=gL=?n=?=SNKL5A)S&*`xP`To)?T=d5Pn(zm-|{C
e=Km8aLRdcW|LZpHfA{?J;<@BRc5z(z-SJ;Ub$cHG

literal 0
HcmV?d00001

diff --git a/rtl_nic/rtl8107e-2.fw b/rtl_nic/rtl8107e-2.fw
new file mode 100644
index 0000000000000000000000000000000000000000..949ca670fa31242940caa9f2222c0e268274ae0c
GIT binary patch
literal 2464
zcmYk;aY$8J9tZH#8^>`RF~{DR>$HtD5)!UGO&nJu-nb@ixDgT(5$QUPE3Jr#L`1|H
zCnBN=iHL{@35kd{A|fPOainn~A|fIpA|4_U5p6_7MA&|GnxXsNhu`<yd(S!d-Sfvg
zA%rk6*jrbX`sVw;RJW%pQ<YVvslTqQs$N-D<J#QO!9Nlqd>dL@YFE`(H?%jl{=IE&
zYkU7c2fyoSZ|eJguzl^?wUys>|EsjBrhZjbebqPNr_r*xz6(M~PcHl_hLA%pdE`?-
zAxVnjM<HaQ`*JcNF3cq2=b5ayD3cw($mGPuncVoNOkVsllOI3%Rlh$M#_6Au@#p5E
znE0hQhX0ntnXn{IWR_}|YA=gLi86V)TyFdoa)n$er($BNI)?EYxmK=|>*dw*8aXXD
z$c=K7+{`*!SkDGp*+?6k*vuBT(m^L(bkoB&dg-H|0S4L54tBDO-9(1i!(R5Wp936Z
zm_r=q2uC@_aZWJ8Nk%!vY0hw#bDZY_7rDe3m$||?6HIcIDXwvy8{Fg;x4FYz?s1<7
zJS4+3Gd$ukPk72Rp7Vm2yy7))c*`u|hY%8EkxdS{<dIJSg(NAWm=cz-lv0*a#&XJ8
zK?RkhsHTQm>ZoTmYe>^TBTY23juzIlfmSxs#wIqig{^eZNf+Jpu#H~&=x2aIwzGqs
z>|!^OA@;DBeeCA|2N~uNhdIJgj&Yn5jBt`sPH~zuoaG$nxxhs(F~()CFwO*%TxE)D
zT;~Qixy5bnaF=`B=K&ANFwG2)c+3-?@{H%a;3cnk%^Th_OBk~LWRXn{x#W>g0fi(f
zqL>nvu#{4kQO0u0SwRJrq^PEbTI#50HET%IKqE~wvyK+lvw>DN(#9q>vxTj6&`B5F
z^stRy`sinXLAJAlo$O*aks<c5mwoK#00$Z75QjO!QI2t(6O3?@QBHB1Go0ld=efW|
zE-}Vst}xC7lU!wrYh33BH@U@a?r@iT+~)xg$uP|fk9f=zp7M<6yx=9Tc+DH$GE4Z;
z`jbUAIpmT@J_Qt#q=;flSi(|DSw<PlDQ5*0RFa~a8fvMdp4F@&O#_WI(abtpSkDGp
z*+?6k*vuBT(m^L(bkoB&dg-H|0S4L54tBDO-9(1i!(R5Wp936Zm_r=q2uC@_aZWJ8
zNk%!vY0hw#bDZY_7rDe3m$||?6HIcIDXwvy8{Fg;x4FYz?s1<7JS4+3Gd$ukPk72R
zp7Vm2yy7))c+2dM^LvGu9jEOV3KF^Tqfk8epO7B<Y;F%x;4}Z7i1Y2xzrciZr_vTa
z9TFp5UQh@hr~a1vRV<H-;)2d(tQ=EAGR~bVm4_3_SU9rCc*&SlvnrDD(+@28PcnX}
z_v>UVd4GSl`fgz|X1%Y8_cf^hUX+|4zrgr&bA|BR9KSvL;xPLzl!mZ);`e8poB#LU
Q^}qRR1rzD{e&LVf|B-EW9{>OV

literal 0
HcmV?d00001

diff --git a/rtl_nic/rtl8168h-1.fw b/rtl_nic/rtl8168h-1.fw
new file mode 100644
index 0000000000000000000000000000000000000000..4bdd3825e3bdc9a15ddd87c199636bda4afb4169
GIT binary patch
literal 2496
zcmY+`aY$8J9tZH#8^;k>?2Wz5b=pQkLc+19<2tT{JlY5ei4cj1D8~^;LPSI&BI1k_
z5z)935fKrtNJK;%5h2ltBaIUg(nLf^#6u(^qK$}%2zNhPyX@ZgKK#Dt+;`5o_ntrA
z4IzZS{_gtfy85oKs&}WW(pA-E>A$S2u31-I>)gW8Mr$I3p3u@<_jO&(?%r?vzw6pv
zldi5!SEs+J`mXc)vg+D~uhR{G{wDl1TD~ymV;Nc!LS}O5mobDq@+qK@Bt@hsj-P~(
zjeeJx4RL8U5kJr7#AVssxICK|S7h_!AF~DVi)>;1>^I~7R1{}_O2uEAieuu}k{Et2
zjdNjToXD=yF4JBeixcJY8o9#!YvoG0N>0bbR80)ywQ`+YFE_~R<wiLpZ;&_2o8%@o
z)65pO(n2fS*v<}ivWqs_>7bJ?_Rviaz4Xz~UiPt{0~{nWz#$HEgrgi|kRgt9f|H!$
zG-o)=Fe8j|j`LjLBA2+#6|QoPF|KoiaVD7LCR5zvHg}ljF88?410FKNBOa4wmN}mA
zlxIBW1uuEUYu@mdcf4nw@Iwd*a>yl*d<rNeNf9ZEDWQ~=tfGw7l(U8k)>26oX=<pY
zj(QqcPa_#Nu#rtPv6*JJu$2~C*~WHuu#;W1(M|`Qbg_qSdg!H(e)h7D{T$#RkpT{I
zm?IqJ7=sLPoD-bn6sI}ES%w*5lyjWt0vEZ&Wv+0QYm9N78;mo-BsZDj7Pq;>G<Uhj
zeID?T86NSNEVIn<gr_{?IWKt0D_--4x4h#$^MnEWPY$`{kxv1IBq<_AF(s6;l2w$k
znsU}q!CES*B25jo)KO0Z>uDsz1~#&ZCN|T|7PittE8E!44tBDOHrnZ+lP>nqO%J{F
z(a&D?v7ZARBr?Du4s(Q~9Al6nj&p*OoZ>WRILk02jB<|iT;L*?xXcx<a*Z*rbAxdv
znB*o?+~PKOnC33`xX%L~GQ%StlVz4Up74}sJm&>3dBtnq@RoPHXP)q*{U?W9^2n!v
zLXs4bqL>m&S;;EOSWP)=s9-IXRFS5JTI#5$f%P<!VFMf4L=&57W(!+sp_OfHX9qjk
zMH}sO&`B42=%$BW`simb``FI`4iXvQ5QjO!QI0Xl5XU*eNltN^Gn{3Z5k@)3c`k5~
zOI+p(SGmR**SWzs6HIcGDQ<C_J4|zzd)(&%51HW+kI6F298Y-4GoJH;m%QRNZ+Oc)
z-ZTH>;=4l3jkDetl8OBINhn$PPsj}XVc{Jj>9hEqh>PveyTpPET^Spn35nqj4=99B
z(|^tXGFHT8F|?;*)!4GQB&6a(Uzt3VNX4RI=k%r2oXS*8{;!c#T=I8))2Y~-O~uSo
z?SJsMRBSBKKPdm84y58tMJkqloGVvdVa^<NxtdUysX_hSxP`To)?T=d5I(H`;l5Uc
e`G1A75LQh5_qvVy&prQh@mz8uvp6pN-|=rm*n1xU

literal 0
HcmV?d00001

diff --git a/rtl_nic/rtl8168h-2.fw b/rtl_nic/rtl8168h-2.fw
new file mode 100644
index 0000000000000000000000000000000000000000..949bacc1614d6e1014736611bd371ef30a3e8daf
GIT binary patch
literal 2464
zcmYk;aY&Wt9tZHJGp}<_%-NYaZ)?&dB)oQXB2HQyoQVq;At4cw&N;6%5fO=qi08V9
zh!zqN5fKs+5iKGjB)a02<{}~@A|fIVA`uZSA|fJeA6>ibJ?F#k`@HY_JkNXH=a2J*
z5W>J<Z(UVwUC+O&+f$XP%Bs@Tmn*BPS60=yHg|OJZ6buPLTgLy7q!(5?TxM9w5@4v
z@BeP_`=0iuz8?nL*Q{An`F;1lORH+?zo@EDRfnHP%jWtn2q8VW@Us{~4!Pu!PXUD_
zDT?ofkcsZg$%MEtlZYQ>vf`plcKkS#6BlQ4<0qNC_|Hs!eE&E7J}r#XKPTh=nu}uM
z*WwudTM}o&k~ooBs$HtREEXlo<mGa?@mI(da;2P#iK*%s#%ttSxlXQ^SIMj8wA>&!
z%1v@JYiVH}>uF^JZER!{o7qAKopjMn4_oP_kA4OiWE<Pr!A^D&8Dckk*vmflbAVwE
za)`qm;V8#A&Il(M<s_##%^A*ej`LjLB4b?QGUH4z$rYx!$~CTYgPYvqHg~woJ?`^>
z4Aac;kVib`2~T;(b6)V0SG?v8vxNVIkRXd}a>yl*d<rNeNfE`Au!N<QvWzm8Q_c!1
zs3b)-HPli^J*!wvng$waqM5a{u#WY#vVk@>vWd-Xp@UAk=%$CQ^wLK^0}Qf_?d)JD
zyNC?2n?3AhANx7LFb6rrVUBQ=V;pCM6O3|_Q=H}uXF11tE^v`CE^(Q0CYa<3Q(Wa5
z*SWz>ZgHDC+~pqkc|e9~W_ZXW9`l5!JmWbpc*!eX^M+Z%ko6~vY;wpYk9-O!BuNp)
zl(2-Ql(LL6mQ&6ODySqyH8s>yM?I@pO_~N8X`-36w6Ko#w6cLVHnNG$Y@vfry6C2d
zt@P4IKLZT1jqU7UC%cFYv70^YWgq)Fz%U0n#9@wblw%xcgcFQ%l2e@K3}-pVc`k5~
zF)neLaVD7L3R7I=8rQkOO>S|UJKW_S_jy2uX=ZrHBOddFr#$01FL=o-Uh{@o!cW$p
zEV9WVmpt+*ppYa*6jQ<ymQu<x%2-Z0E2yB76xGyFOC9yBVl`<RXrzf|*3!Z{*3-%c
z+Ste@HnW8eI_aXD9=6g;AN>q4$TqgKgPrUmGQ@87u$O)8=K#YT<Pe8B!cmTKoDohi
z%1KUfnlqf`9Ot>fMaH<qWyYCck}FJcm1|t*1~<9IZSHWFd)(&%8K#-xA&+>>6Q1&n
z=e*!0uXxQHW`COBE5z(LZNE^E$c^uX;<^8X^w5WMdx!#``R_!WZ-@Q`CY(E!w(#kY
z80qqYLik7O>)g*`d0Z41bS7ivm>QCC?p&!noJhvPkwwN!#-y56k&GYw&4OQ&@$Y&+
zPsWmW_h+kb7bauYyP9}cgZks5<ox&r#-E!jgg@u_^Vt`N*|(uIgvAqoJ=@&;fBmlC
P=dTq^r04sE{~vz<lf`x)

literal 0
HcmV?d00001

-- 
1.9.3

^ permalink raw reply related

* Re: [net-next PATCH 3/3] net: sched: cls_cgroup fix possible memory leak of 'new'
From: John Fastabend @ 2014-09-16  3:29 UTC (permalink / raw)
  To: Cong Wang, John Fastabend
  Cc: Cong Wang, David Miller, Eric Dumazet, netdev, Jamal Hadi Salim
In-Reply-To: <CAHA+R7Pz2sCRC7BYAtd2P48gy2oxb=YfJqmx4=+8gKEyLwvMBA@mail.gmail.com>

On 09/15/2014 08:04 PM, Cong Wang wrote:
> On Mon, Sep 15, 2014 at 7:48 PM, John Fastabend
> <john.fastabend@gmail.com> wrote:
>> diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
>> index 3b75487..52b7900 100644
>> --- a/net/sched/cls_cgroup.c
>> +++ b/net/sched/cls_cgroup.c
>> @@ -127,16 +127,16 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
>>         err = nla_parse_nested(tb, TCA_CGROUP_MAX, tca[TCA_OPTIONS],
>>                                cgroup_policy);
>>         if (err < 0)
>> -               return err;
>> +               goto errout;
>>
>>         tcf_exts_init(&e, TCA_CGROUP_ACT, TCA_CGROUP_POLICE);
>>         err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
>>         if (err < 0)
>> -               return err;
>> +               goto errout;
>>
>>         err = tcf_em_tree_validate(tp, tb[TCA_CGROUP_EMATCHES], &t);
>>         if (err < 0)
>> -               return err;
>> +               goto errout;
>>
> 
> I think you need to call tcf_exts_destroy() too after tcf_exts_validate(),
> while you are on it. :)

Yep, and did a quick audit looks like its handled correctly in the other
classifiers.

Also there is a needed fix for cls_fw I'll include with the update for this patch.

.John

> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* [PATCH net] r8169: adjust __rtl8169_set_features
From: Hayes Wang @ 2014-09-16  3:40 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, Hayes Wang, Francois Romieu
In-Reply-To: <20140916000321.GA19564@electric-eye.fr.zoreil.com>

Remove the "changed" test in __rtl8169_set_features(). Instead, do
simple test in rtl8169_set_features().

Set the RxChkSum and RxVlan through __rtl8169_set_features() in
rtl_open().

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 74 +++++++++++++++++-------------------
 1 file changed, 34 insertions(+), 40 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 7a7860a..ef2cee5 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -1783,33 +1783,31 @@ static void __rtl8169_set_features(struct net_device *dev,
 				   netdev_features_t features)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	netdev_features_t changed = features ^ dev->features;
 	void __iomem *ioaddr = tp->mmio_addr;
+	u32 rx_config;
 
-	if (!(changed & (NETIF_F_RXALL | NETIF_F_RXCSUM |
-			 NETIF_F_HW_VLAN_CTAG_RX)))
-		return;
+	rx_config = RTL_R32(RxConfig);
+	if (features & NETIF_F_RXALL)
+		rx_config |= (AcceptErr | AcceptRunt);
+	else
+		rx_config &= ~(AcceptErr | AcceptRunt);
 
-	if (changed & (NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_RX)) {
-		if (features & NETIF_F_RXCSUM)
-			tp->cp_cmd |= RxChkSum;
-		else
-			tp->cp_cmd &= ~RxChkSum;
+	RTL_W32(RxConfig, rx_config);
 
-		if (features & NETIF_F_HW_VLAN_CTAG_RX)
-			tp->cp_cmd |= RxVlan;
-		else
-			tp->cp_cmd &= ~RxVlan;
+	if (features & NETIF_F_RXCSUM)
+		tp->cp_cmd |= RxChkSum;
+	else
+		tp->cp_cmd &= ~RxChkSum;
 
-		RTL_W16(CPlusCmd, tp->cp_cmd);
-		RTL_R16(CPlusCmd);
-	}
-	if (changed & NETIF_F_RXALL) {
-		int tmp = (RTL_R32(RxConfig) & ~(AcceptErr | AcceptRunt));
-		if (features & NETIF_F_RXALL)
-			tmp |= (AcceptErr | AcceptRunt);
-		RTL_W32(RxConfig, tmp);
-	}
+	if (features & NETIF_F_HW_VLAN_CTAG_RX)
+		tp->cp_cmd |= RxVlan;
+	else
+		tp->cp_cmd &= ~RxVlan;
+
+	tp->cp_cmd |= RTL_R16(CPlusCmd) & ~(RxVlan | RxChkSum);
+
+	RTL_W16(CPlusCmd, tp->cp_cmd);
+	RTL_R16(CPlusCmd);
 }
 
 static int rtl8169_set_features(struct net_device *dev,
@@ -1817,8 +1815,11 @@ static int rtl8169_set_features(struct net_device *dev,
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 
+	features &= NETIF_F_RXALL | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_RX;
+
 	rtl_lock_work(tp);
-	__rtl8169_set_features(dev, features);
+	if (features ^ dev->features);
+		__rtl8169_set_features(dev, features);
 	rtl_unlock_work(tp);
 
 	return 0;
@@ -6707,12 +6708,7 @@ static int rtl_open(struct net_device *dev)
 
 	rtl8169_init_phy(dev, tp);
 
-	if (dev->features & NETIF_F_HW_VLAN_CTAG_RX)
-		tp->cp_cmd |= RxVlan;
-	else
-		tp->cp_cmd &= ~RxVlan;
-
-	RTL_W16(CPlusCmd, tp->cp_cmd);
+	__rtl8169_set_features(dev, dev->features);
 
 	rtl_pll_power_up(tp);
 
@@ -7123,8 +7119,7 @@ static void rtl_hw_initialize(struct rtl8169_private *tp)
 	}
 }
 
-static int
-rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
 	const unsigned int region = cfg->region;
@@ -7199,7 +7194,7 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_out_mwi_2;
 	}
 
-	tp->cp_cmd = RxChkSum;
+	tp->cp_cmd = 0;
 
 	if ((sizeof(dma_addr_t) > 4) &&
 	    !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) {
@@ -7240,13 +7235,6 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	pci_set_master(pdev);
 
-	/*
-	 * Pretend we are using VLANs; This bypasses a nasty bug where
-	 * Interrupts stop flowing on high load on 8110SCd controllers.
-	 */
-	if (tp->mac_version == RTL_GIGA_MAC_VER_05)
-		tp->cp_cmd |= RxVlan;
-
 	rtl_init_mdio_ops(tp);
 	rtl_init_pll_power_ops(tp);
 	rtl_init_jumbo_ops(tp);
@@ -7307,8 +7295,14 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
 		NETIF_F_HIGHDMA;
 
+	tp->cp_cmd |= RxChkSum | RxVlan;
+
+	/*
+	 * Pretend we are using VLANs; This bypasses a nasty bug where
+	 * Interrupts stop flowing on high load on 8110SCd controllers.
+	 */
 	if (tp->mac_version == RTL_GIGA_MAC_VER_05)
-		/* 8110SCd requires hardware Rx VLAN - disallow toggling */
+		/* Disallow toggling */
 		dev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_RX;
 
 	if (tp->txd_version == RTL_TD_0)
-- 
1.9.3

^ permalink raw reply related

* [PATCH v3 net-next 7/7] gre: Setup and TX path for gre/UDP foo-over-udp encapsulation
From: Tom Herbert @ 2014-09-16  3:30 UTC (permalink / raw)
  To: davem, netdev
In-Reply-To: <1410838224-19777-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              | 98 +++++++++++++++++++++++++++++++++++++++---
 2 files changed, 95 insertions(+), 7 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..5681344 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,18 +696,40 @@ 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 *nt = netdev_priv(dev);
+	struct ip_tunnel_encap ipencap;
+	int err;
+
+	if (ipgre_netlink_encap_parms(data, &ipencap)) {
+		err = ip_tunnel_encap_setup(nt, &ipencap);
+		if (err < 0)
+			return err;
+	}
 
 	ipgre_netlink_parms(data, tb, &p);
-	return ip_tunnel_newlink(dev, tb, &p);
+	err = ip_tunnel_newlink(dev, tb, &p);
+
+	return err;
 }
 
 static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
 			    struct nlattr *data[])
 {
+	struct ip_tunnel *t = netdev_priv(dev);
 	struct ip_tunnel_parm p;
+	struct ip_tunnel_encap ipencap;
+	int err;
+
+	if (ipgre_netlink_encap_parms(data, &ipencap)) {
+		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);
+	err = ip_tunnel_changelink(dev, tb, &p);
+
+	return err;
 }
 
 static size_t ipgre_get_size(const struct net_device *dev)
@@ -694,6 +755,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 +783,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 +811,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 v3 net-next 6/7] ipip: Setup and TX path for ipip/UDP foo-over-udp encapsulation
From: Tom Herbert @ 2014-09-16  3:30 UTC (permalink / raw)
  To: davem, netdev
In-Reply-To: <1410838224-19777-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 | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 83 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 62eaa00..2985551 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,19 +341,73 @@ 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 *t = netdev_priv(dev);
+	struct ip_tunnel_encap ipencap;
+	int err;
+
+	if (ipip_netlink_encap_parms(data, &ipencap)) {
+		err = ip_tunnel_encap_setup(t, &ipencap);
+		if (err < 0)
+			return err;
+	}
 
 	ipip_netlink_parms(data, &p);
-	return ip_tunnel_newlink(dev, tb, &p);
+	err = ip_tunnel_newlink(dev, tb, &p);
+
+	return err;
 }
 
 static int ipip_changelink(struct net_device *dev, struct nlattr *tb[],
 			   struct nlattr *data[])
 {
+	struct ip_tunnel *t = netdev_priv(dev);
 	struct ip_tunnel_parm p;
+	struct ip_tunnel_encap ipencap;
+	int err;
+
+	if (ipip_netlink_encap_parms(data, &ipencap)) {
+		err = ip_tunnel_encap_setup(t, &ipencap);
+		if (err < 0)
+			return err;
+	}
 
 	ipip_netlink_parms(data, &p);
 
@@ -360,7 +415,9 @@ static int ipip_changelink(struct net_device *dev, struct nlattr *tb[],
 	    (!(dev->flags & IFF_POINTOPOINT) && p.iph.daddr))
 		return -EINVAL;
 
-	return ip_tunnel_changelink(dev, tb, &p);
+	err = ip_tunnel_changelink(dev, tb, &p);
+
+	return err;
 }
 
 static size_t ipip_get_size(const struct net_device *dev)
@@ -378,6 +435,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 +459,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 +483,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

* [PATCH v3 net-next 5/7] sit: Setup and TX path for sit/UDP foo-over-udp encapsulation
From: Tom Herbert @ 2014-09-16  3:30 UTC (permalink / raw)
  To: davem, netdev
In-Reply-To: <1410838224-19777-1-git-send-email-therbert@google.com>

Added netlink handling of IP tunnel encapulation paramters, properly
adjust MTU for encapsulation. Added ip_tunnel_encap call to
ipip6_tunnel_xmit to actually perform FOU encapsulation.

Signed-off-by: Tom Herbert <therbert@google.com>
---
 net/ipv6/sit.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 97 insertions(+), 10 deletions(-)

diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 86e3fa8..db75809 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -822,6 +822,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
 	int addr_type;
 	u8 ttl;
 	int err;
+	u8 protocol = IPPROTO_IPV6;
+	int t_hlen = tunnel->hlen + sizeof(struct iphdr);
 
 	if (skb->protocol != htons(ETH_P_IPV6))
 		goto tx_error;
@@ -911,8 +913,14 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
 		goto tx_error;
 	}
 
+	skb = iptunnel_handle_offloads(skb, false, SKB_GSO_SIT);
+	if (IS_ERR(skb)) {
+		ip_rt_put(rt);
+		goto out;
+	}
+
 	if (df) {
-		mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr);
+		mtu = dst_mtu(&rt->dst) - t_hlen;
 
 		if (mtu < 68) {
 			dev->stats.collisions++;
@@ -947,7 +955,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
 	/*
 	 * Okay, now see if we can stuff it in the buffer as-is.
 	 */
-	max_headroom = LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr);
+	max_headroom = LL_RESERVED_SPACE(tdev) + t_hlen;
 
 	if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
 	    (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
@@ -969,14 +977,13 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
 		ttl = iph6->hop_limit;
 	tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6));
 
-	skb = iptunnel_handle_offloads(skb, false, SKB_GSO_SIT);
-	if (IS_ERR(skb)) {
+	if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0) {
 		ip_rt_put(rt);
-		goto out;
+		goto tx_error;
 	}
 
 	err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr,
-			    IPPROTO_IPV6, tos, ttl, df,
+			    protocol, tos, ttl, df,
 			    !net_eq(tunnel->net, dev_net(dev)));
 	iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
 	return NETDEV_TX_OK;
@@ -1059,8 +1066,10 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
 		tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
 
 	if (tdev) {
+		int t_hlen = tunnel->hlen + sizeof(struct iphdr);
+
 		dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
-		dev->mtu = tdev->mtu - sizeof(struct iphdr);
+		dev->mtu = tdev->mtu - t_hlen;
 		if (dev->mtu < IPV6_MIN_MTU)
 			dev->mtu = IPV6_MIN_MTU;
 	}
@@ -1307,7 +1316,10 @@ done:
 
 static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu)
 {
-	if (new_mtu < IPV6_MIN_MTU || new_mtu > 0xFFF8 - sizeof(struct iphdr))
+	struct ip_tunnel *tunnel = netdev_priv(dev);
+	int t_hlen = tunnel->hlen + sizeof(struct iphdr);
+
+	if (new_mtu < IPV6_MIN_MTU || new_mtu > 0xFFF8 - t_hlen)
 		return -EINVAL;
 	dev->mtu = new_mtu;
 	return 0;
@@ -1338,12 +1350,15 @@ static void ipip6_dev_free(struct net_device *dev)
 
 static void ipip6_tunnel_setup(struct net_device *dev)
 {
+	struct ip_tunnel *tunnel = netdev_priv(dev);
+	int t_hlen = tunnel->hlen + sizeof(struct iphdr);
+
 	dev->netdev_ops		= &ipip6_netdev_ops;
 	dev->destructor		= ipip6_dev_free;
 
 	dev->type		= ARPHRD_SIT;
-	dev->hard_header_len	= LL_MAX_HEADER + sizeof(struct iphdr);
-	dev->mtu		= ETH_DATA_LEN - sizeof(struct iphdr);
+	dev->hard_header_len	= LL_MAX_HEADER + t_hlen;
+	dev->mtu		= ETH_DATA_LEN - t_hlen;
 	dev->flags		= IFF_NOARP;
 	dev->priv_flags	       &= ~IFF_XMIT_DST_RELEASE;
 	dev->iflink		= 0;
@@ -1466,6 +1481,40 @@ static void ipip6_netlink_parms(struct nlattr *data[],
 
 }
 
+/* This function returns true when ENCAP attributes are present in the nl msg */
+static bool ipip6_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;
+}
+
 #ifdef CONFIG_IPV6_SIT_6RD
 /* This function returns true when 6RD attributes are present in the nl msg */
 static bool ipip6_netlink_6rd_parms(struct nlattr *data[],
@@ -1509,12 +1558,20 @@ static int ipip6_newlink(struct net *src_net, struct net_device *dev,
 {
 	struct net *net = dev_net(dev);
 	struct ip_tunnel *nt;
+	struct ip_tunnel_encap ipencap;
 #ifdef CONFIG_IPV6_SIT_6RD
 	struct ip_tunnel_6rd ip6rd;
 #endif
 	int err;
 
 	nt = netdev_priv(dev);
+
+	if (ipip6_netlink_encap_parms(data, &ipencap)) {
+		err = ip_tunnel_encap_setup(nt, &ipencap);
+		if (err < 0)
+			return err;
+	}
+
 	ipip6_netlink_parms(data, &nt->parms);
 
 	if (ipip6_tunnel_locate(net, &nt->parms, 0))
@@ -1537,15 +1594,23 @@ static int ipip6_changelink(struct net_device *dev, struct nlattr *tb[],
 {
 	struct ip_tunnel *t = netdev_priv(dev);
 	struct ip_tunnel_parm p;
+	struct ip_tunnel_encap ipencap;
 	struct net *net = t->net;
 	struct sit_net *sitn = net_generic(net, sit_net_id);
 #ifdef CONFIG_IPV6_SIT_6RD
 	struct ip_tunnel_6rd ip6rd;
 #endif
+	int err;
 
 	if (dev == sitn->fb_tunnel_dev)
 		return -EINVAL;
 
+	if (ipip6_netlink_encap_parms(data, &ipencap)) {
+		err = ip_tunnel_encap_setup(t, &ipencap);
+		if (err < 0)
+			return err;
+	}
+
 	ipip6_netlink_parms(data, &p);
 
 	if (((dev->flags & IFF_POINTOPOINT) && !p.iph.daddr) ||
@@ -1599,6 +1664,14 @@ static size_t ipip6_get_size(const struct net_device *dev)
 		/* IFLA_IPTUN_6RD_RELAY_PREFIXLEN */
 		nla_total_size(2) +
 #endif
+		/* 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;
 }
 
@@ -1630,6 +1703,16 @@ static int ipip6_fill_info(struct sk_buff *skb, const struct net_device *dev)
 		goto nla_put_failure;
 #endif
 
+	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:
@@ -1651,6 +1734,10 @@ static const struct nla_policy ipip6_policy[IFLA_IPTUN_MAX + 1] = {
 	[IFLA_IPTUN_6RD_PREFIXLEN]	= { .type = NLA_U16 },
 	[IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NLA_U16 },
 #endif
+	[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 void ipip6_dellink(struct net_device *dev, struct list_head *head)
-- 
2.1.0.rc2.206.gedb03e5

^ permalink raw reply related

* [PATCH v3 net-next 4/7] net: Changes to ip_tunnel to support foo-over-udp encapsulation
From: Tom Herbert @ 2014-09-16  3:30 UTC (permalink / raw)
  To: davem, netdev
In-Reply-To: <1410838224-19777-1-git-send-email-therbert@google.com>

This patch changes IP tunnel to support (secondary) encapsulation,
Foo-over-UDP. Changes include:

1) Adding tun_hlen as the tunnel header length, encap_hlen as the
   encapsulation header length, and hlen becomes the grand total
   of these.
2) Added common netlink define to support FOU encapsulation.
3) Routines to perform FOU encapsulation.

Signed-off-by: Tom Herbert <therbert@google.com>
---
 include/net/ip_tunnels.h       | 19 ++++++++-
 include/uapi/linux/if_tunnel.h | 12 ++++++
 net/ipv4/ip_tunnel.c           | 91 +++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 120 insertions(+), 2 deletions(-)

diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 8dd8cab..7f538ba 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -10,6 +10,7 @@
 #include <net/gro_cells.h>
 #include <net/inet_ecn.h>
 #include <net/ip.h>
+#include <net/netns/generic.h>
 #include <net/rtnetlink.h>
 
 #if IS_ENABLED(CONFIG_IPV6)
@@ -31,6 +32,13 @@ struct ip_tunnel_6rd_parm {
 };
 #endif
 
+struct ip_tunnel_encap {
+	__u16			type;
+	__u16			flags;
+	__be16			sport;
+	__be16			dport;
+};
+
 struct ip_tunnel_prl_entry {
 	struct ip_tunnel_prl_entry __rcu *next;
 	__be32				addr;
@@ -56,13 +64,18 @@ struct ip_tunnel {
 	/* These four fields used only by GRE */
 	__u32		i_seqno;	/* The last seen seqno	*/
 	__u32		o_seqno;	/* The last output seqno */
-	int		hlen;		/* Precalculated header length */
+	int		tun_hlen;	/* Precalculated header length */
 	int		mlink;
 
 	struct ip_tunnel_dst __percpu *dst_cache;
 
 	struct ip_tunnel_parm parms;
 
+	int		encap_hlen;	/* Encap header length (FOU,GUE) */
+	struct ip_tunnel_encap encap;
+
+	int		hlen;		/* tun_hlen + encap_hlen */
+
 	/* for SIT */
 #ifdef CONFIG_IPV6_SIT_6RD
 	struct ip_tunnel_6rd_parm ip6rd;
@@ -114,6 +127,8 @@ void ip_tunnel_delete_net(struct ip_tunnel_net *itn, struct rtnl_link_ops *ops);
 void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
 		    const struct iphdr *tnl_params, const u8 protocol);
 int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd);
+int ip_tunnel_encap(struct sk_buff *skb, struct ip_tunnel *t,
+		    u8 *protocol, struct flowi4 *fl4);
 int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu);
 
 struct rtnl_link_stats64 *ip_tunnel_get_stats64(struct net_device *dev,
@@ -131,6 +146,8 @@ int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
 		      struct ip_tunnel_parm *p);
 void ip_tunnel_setup(struct net_device *dev, int net_id);
 void ip_tunnel_dst_reset_all(struct ip_tunnel *t);
+int ip_tunnel_encap_setup(struct ip_tunnel *t,
+			  struct ip_tunnel_encap *ipencap);
 
 /* Extract dsfield from inner protocol */
 static inline u8 ip_tunnel_get_dsfield(const struct iphdr *iph,
diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h
index 3bce9e9..9fedca7 100644
--- a/include/uapi/linux/if_tunnel.h
+++ b/include/uapi/linux/if_tunnel.h
@@ -53,10 +53,22 @@ enum {
 	IFLA_IPTUN_6RD_RELAY_PREFIX,
 	IFLA_IPTUN_6RD_PREFIXLEN,
 	IFLA_IPTUN_6RD_RELAY_PREFIXLEN,
+	IFLA_IPTUN_ENCAP_TYPE,
+	IFLA_IPTUN_ENCAP_FLAGS,
+	IFLA_IPTUN_ENCAP_SPORT,
+	IFLA_IPTUN_ENCAP_DPORT,
 	__IFLA_IPTUN_MAX,
 };
 #define IFLA_IPTUN_MAX	(__IFLA_IPTUN_MAX - 1)
 
+enum tunnel_encap_types {
+	TUNNEL_ENCAP_NONE,
+	TUNNEL_ENCAP_FOU,
+};
+
+#define TUNNEL_ENCAP_FLAG_CSUM		(1<<0)
+#define TUNNEL_ENCAP_FLAG_CSUM6		(1<<1)
+
 /* SIT-mode i_flags */
 #define	SIT_ISATAP	0x0001
 
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index afed1aa..e3a3dc9 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -55,6 +55,7 @@
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 #include <net/rtnetlink.h>
+#include <net/udp.h>
 
 #if IS_ENABLED(CONFIG_IPV6)
 #include <net/ipv6.h>
@@ -487,6 +488,91 @@ drop:
 }
 EXPORT_SYMBOL_GPL(ip_tunnel_rcv);
 
+static int ip_encap_hlen(struct ip_tunnel_encap *e)
+{
+	switch (e->type) {
+	case TUNNEL_ENCAP_NONE:
+		return 0;
+	case TUNNEL_ENCAP_FOU:
+		return sizeof(struct udphdr);
+	default:
+		return -EINVAL;
+	}
+}
+
+int ip_tunnel_encap_setup(struct ip_tunnel *t,
+			  struct ip_tunnel_encap *ipencap)
+{
+	int hlen;
+
+	memset(&t->encap, 0, sizeof(t->encap));
+
+	hlen = ip_encap_hlen(ipencap);
+	if (hlen < 0)
+		return hlen;
+
+	t->encap.type = ipencap->type;
+	t->encap.sport = ipencap->sport;
+	t->encap.dport = ipencap->dport;
+	t->encap.flags = ipencap->flags;
+
+	t->encap_hlen = hlen;
+	t->hlen = t->encap_hlen + t->tun_hlen;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ip_tunnel_encap_setup);
+
+static int fou_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
+			    size_t hdr_len, u8 *protocol, struct flowi4 *fl4)
+{
+	struct udphdr *uh;
+	__be16 sport;
+	bool csum = !!(e->flags & TUNNEL_ENCAP_FLAG_CSUM);
+	int type = csum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
+
+	skb = iptunnel_handle_offloads(skb, csum, type);
+
+	if (IS_ERR(skb))
+		return PTR_ERR(skb);
+
+	/* Get length and hash before making space in skb */
+
+	sport = e->sport ? : udp_flow_src_port(dev_net(skb->dev),
+					       skb, 0, 0, false);
+
+	skb_push(skb, hdr_len);
+
+	skb_reset_transport_header(skb);
+	uh = udp_hdr(skb);
+
+	uh->dest = e->dport;
+	uh->source = sport;
+	uh->len = htons(skb->len);
+	uh->check = 0;
+	udp_set_csum(!(e->flags & TUNNEL_ENCAP_FLAG_CSUM), skb,
+		     fl4->saddr, fl4->daddr, skb->len);
+
+	*protocol = IPPROTO_UDP;
+
+	return 0;
+}
+
+int ip_tunnel_encap(struct sk_buff *skb, struct ip_tunnel *t,
+		    u8 *protocol, struct flowi4 *fl4)
+{
+	switch (t->encap.type) {
+	case TUNNEL_ENCAP_NONE:
+		return 0;
+	case TUNNEL_ENCAP_FOU:
+		return fou_build_header(skb, &t->encap, t->encap_hlen,
+					protocol, fl4);
+	default:
+		return -EINVAL;
+	}
+}
+EXPORT_SYMBOL(ip_tunnel_encap);
+
 static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
 			    struct rtable *rt, __be16 df)
 {
@@ -536,7 +622,7 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
 }
 
 void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
-		    const struct iphdr *tnl_params, const u8 protocol)
+		    const struct iphdr *tnl_params, u8 protocol)
 {
 	struct ip_tunnel *tunnel = netdev_priv(dev);
 	const struct iphdr *inner_iph;
@@ -617,6 +703,9 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
 	init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr,
 			 tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link);
 
+	if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0)
+		goto tx_error;
+
 	rt = connected ? tunnel_rtable_get(tunnel, 0, &fl4.saddr) : NULL;
 
 	if (!rt) {
-- 
2.1.0.rc2.206.gedb03e5

^ permalink raw reply related

* [PATCH v3 net-next 3/7] fou: Add GRO support
From: Tom Herbert @ 2014-09-16  3:30 UTC (permalink / raw)
  To: davem, netdev
In-Reply-To: <1410838224-19777-1-git-send-email-therbert@google.com>

Implement fou_gro_receive and fou_gro_complete, and populate these
in the correponsing udp_offloads for the socket. Added ipproto to
udp_offloads and pass this from UDP to the fou GRO routine in proto
field of napi_gro_cb structure.

Signed-off-by: Tom Herbert <therbert@google.com>
---
 include/linux/netdevice.h |  3 +-
 net/ipv4/fou.c            | 89 +++++++++++++++++++++++++++++++++++++++++++++++
 net/ipv4/udp_offload.c    |  5 ++-
 3 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index f9e81d1..d380574 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1874,7 +1874,7 @@ struct napi_gro_cb {
 	/* jiffies when first packet was created/queued */
 	unsigned long age;
 
-	/* Used in ipv6_gro_receive() */
+	/* Used in ipv6_gro_receive() and foo-over-udp */
 	u16	proto;
 
 	/* Used in udp_gro_receive */
@@ -1925,6 +1925,7 @@ struct packet_offload {
 
 struct udp_offload {
 	__be16			 port;
+	u8			 ipproto;
 	struct offload_callbacks callbacks;
 };
 
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
index de2af74..ac430d1 100644
--- a/net/ipv4/fou.c
+++ b/net/ipv4/fou.c
@@ -8,6 +8,7 @@
 #include <linux/kernel.h>
 #include <net/genetlink.h>
 #include <net/ip.h>
+#include <net/protocol.h>
 #include <net/udp.h>
 #include <net/udp_tunnel.h>
 #include <net/xfrm.h>
@@ -21,6 +22,7 @@ struct fou {
 	struct socket *sock;
 	u8 protocol;
 	u16 port;
+	struct udp_offload udp_offloads;
 	struct list_head list;
 };
 
@@ -62,6 +64,69 @@ static int fou_udp_recv(struct sock *sk, struct sk_buff *skb)
 					  sizeof(struct udphdr));
 }
 
+static struct sk_buff **fou_gro_receive(struct sk_buff **head,
+					struct sk_buff *skb,
+					const struct net_offload **offloads)
+{
+	const struct net_offload *ops;
+	struct sk_buff **pp = NULL;
+	u8 proto = NAPI_GRO_CB(skb)->proto;
+
+	rcu_read_lock();
+	ops = rcu_dereference(offloads[proto]);
+	if (!ops || !ops->callbacks.gro_receive)
+		goto out_unlock;
+
+	pp = ops->callbacks.gro_receive(head, skb);
+
+out_unlock:
+	rcu_read_unlock();
+
+	return pp;
+}
+
+static int fou_gro_complete(struct sk_buff *skb, int nhoff,
+			    const struct net_offload **offloads)
+{
+	const struct net_offload *ops;
+	u8 proto = NAPI_GRO_CB(skb)->proto;
+	int err = -ENOSYS;
+
+	rcu_read_lock();
+	ops = rcu_dereference(offloads[proto]);
+	if (WARN_ON(!ops || !ops->callbacks.gro_complete))
+		goto out_unlock;
+
+	err = ops->callbacks.gro_complete(skb, nhoff);
+
+out_unlock:
+	rcu_read_unlock();
+
+	return err;
+}
+
+static struct sk_buff **fou4_gro_receive(struct sk_buff **head,
+					 struct sk_buff *skb)
+{
+	return fou_gro_receive(head, skb, inet_offloads);
+}
+
+static int fou4_gro_complete(struct sk_buff *skb, int nhoff)
+{
+	return fou_gro_complete(skb, nhoff, inet_offloads);
+}
+
+static struct sk_buff **fou6_gro_receive(struct sk_buff **head,
+					 struct sk_buff *skb)
+{
+	return fou_gro_receive(head, skb, inet6_offloads);
+}
+
+static int fou6_gro_complete(struct sk_buff *skb, int nhoff)
+{
+	return fou_gro_complete(skb, nhoff, inet6_offloads);
+}
+
 static int fou_add_to_port_list(struct fou *fou)
 {
 	struct fou *fout;
@@ -134,6 +199,29 @@ static int fou_create(struct net *net, struct fou_cfg *cfg,
 
 	sk->sk_allocation = GFP_ATOMIC;
 
+	switch (cfg->udp_config.family) {
+	case AF_INET:
+		fou->udp_offloads.callbacks.gro_receive = fou4_gro_receive;
+		fou->udp_offloads.callbacks.gro_complete = fou4_gro_complete;
+		break;
+	case AF_INET6:
+		fou->udp_offloads.callbacks.gro_receive = fou6_gro_receive;
+		fou->udp_offloads.callbacks.gro_complete = fou6_gro_complete;
+		break;
+	default:
+		err = -EPFNOSUPPORT;
+		goto error;
+	}
+
+	fou->udp_offloads.port = cfg->udp_config.local_udp_port;
+	fou->udp_offloads.ipproto = cfg->protocol;
+
+	if (cfg->udp_config.family == AF_INET) {
+		err = udp_add_offload(&fou->udp_offloads);
+		if (err)
+			goto error;
+	}
+
 	err = fou_add_to_port_list(fou);
 	if (err)
 		goto error;
@@ -160,6 +248,7 @@ static int fou_destroy(struct net *net, struct fou_cfg *cfg)
 	spin_lock(&fou_lock);
 	list_for_each_entry(fou, &fou_list, list) {
 		if (fou->port == port) {
+			udp_del_offload(&fou->udp_offloads);
 			fou_release(fou);
 			err = 0;
 			break;
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index adab393..d7c43f7 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -276,6 +276,7 @@ unflush:
 
 	skb_gro_pull(skb, sizeof(struct udphdr)); /* pull encapsulating udp header */
 	skb_gro_postpull_rcsum(skb, uh, sizeof(struct udphdr));
+	NAPI_GRO_CB(skb)->proto = uo_priv->offload->ipproto;
 	pp = uo_priv->offload->callbacks.gro_receive(head, skb);
 
 out_unlock:
@@ -329,8 +330,10 @@ int udp_gro_complete(struct sk_buff *skb, int nhoff)
 			break;
 	}
 
-	if (uo_priv != NULL)
+	if (uo_priv != NULL) {
+		NAPI_GRO_CB(skb)->proto = uo_priv->offload->ipproto;
 		err = uo_priv->offload->callbacks.gro_complete(skb, nhoff + sizeof(struct udphdr));
+	}
 
 	rcu_read_unlock();
 	return err;
-- 
2.1.0.rc2.206.gedb03e5

^ permalink raw reply related

* [PATCH v3 net-next 2/7] fou: Support for foo-over-udp RX path
From: Tom Herbert @ 2014-09-16  3:30 UTC (permalink / raw)
  To: davem, netdev
In-Reply-To: <1410838224-19777-1-git-send-email-therbert@google.com>

This patch provides a receive path for foo-over-udp. This allows
direct encapsulation of IP protocols over UDP. The bound destination
port is used to map to an IP protocol, and the XFRM framework
(udp_encap_rcv) is used to receive encapsulated packets. Upon
reception, the encapsulation header is logically removed (pointer
to transport header is advanced) and the packet is reinjected into
the receive path with the IP protocol indicated by the mapping.

Netlink is used to configure FOU ports. The configuration information
includes the port number to bind to and the IP protocol corresponding
to that port.

This should support GRE/UDP
(http://tools.ietf.org/html/draft-yong-tsvwg-gre-in-udp-encap-02),
as will as the other IP tunneling protocols (IPIP, SIT).

Signed-off-by: Tom Herbert <therbert@google.com>
---
 include/uapi/linux/fou.h |  32 ++++++
 net/ipv4/Kconfig         |  10 ++
 net/ipv4/Makefile        |   1 +
 net/ipv4/fou.c           | 279 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 322 insertions(+)
 create mode 100644 include/uapi/linux/fou.h
 create mode 100644 net/ipv4/fou.c

diff --git a/include/uapi/linux/fou.h b/include/uapi/linux/fou.h
new file mode 100644
index 0000000..e03376d
--- /dev/null
+++ b/include/uapi/linux/fou.h
@@ -0,0 +1,32 @@
+/* fou.h - FOU Interface */
+
+#ifndef _UAPI_LINUX_FOU_H
+#define _UAPI_LINUX_FOU_H
+
+/* NETLINK_GENERIC related info
+ */
+#define FOU_GENL_NAME		"fou"
+#define FOU_GENL_VERSION	0x1
+
+enum {
+	FOU_ATTR_UNSPEC,
+	FOU_ATTR_PORT,				/* u16 */
+	FOU_ATTR_AF,				/* u8 */
+	FOU_ATTR_IPPROTO,			/* u8 */
+
+	__FOU_ATTR_MAX,
+};
+
+#define FOU_ATTR_MAX		(__FOU_ATTR_MAX - 1)
+
+enum {
+	FOU_CMD_UNSPEC,
+	FOU_CMD_ADD,
+	FOU_CMD_DEL,
+
+	__FOU_CMD_MAX,
+};
+
+#define FOU_CMD_MAX	(__FOU_CMD_MAX - 1)
+
+#endif /* _UAPI_LINUX_FOU_H */
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index dbc10d8..84f710b 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -311,6 +311,16 @@ config NET_UDP_TUNNEL
 	tristate
 	default n
 
+config NET_FOU
+	tristate "IP: Foo (IP protocols) over UDP"
+	select XFRM
+	select NET_UDP_TUNNEL
+	---help---
+	  Foo over UDP allows any IP protocol to be directly encapsulated
+	  over UDP include tunnels (IPIP, GRE, SIT). By encapsulating in UDP
+	  network mechanisms and optimizations for UDP (such as ECMP
+	  and RSS) can be leveraged to provide better service.
+
 config INET_AH
 	tristate "IP: AH transformation"
 	select XFRM_ALGO
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 8ee1cd4..d78d404 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o
 obj-$(CONFIG_IP_MROUTE) += ipmr.o
 obj-$(CONFIG_NET_IPIP) += ipip.o
 gre-y := gre_demux.o
+obj-$(CONFIG_NET_FOU) += fou.o
 obj-$(CONFIG_NET_IPGRE_DEMUX) += gre.o
 obj-$(CONFIG_NET_IPGRE) += ip_gre.o
 obj-$(CONFIG_NET_UDP_TUNNEL) += udp_tunnel.o
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
new file mode 100644
index 0000000..de2af74
--- /dev/null
+++ b/net/ipv4/fou.c
@@ -0,0 +1,279 @@
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <net/genetlink.h>
+#include <net/ip.h>
+#include <net/udp.h>
+#include <net/udp_tunnel.h>
+#include <net/xfrm.h>
+#include <uapi/linux/fou.h>
+#include <uapi/linux/genetlink.h>
+
+static DEFINE_SPINLOCK(fou_lock);
+static LIST_HEAD(fou_list);
+
+struct fou {
+	struct socket *sock;
+	u8 protocol;
+	u16 port;
+	struct list_head list;
+};
+
+struct fou_cfg {
+	u8 protocol;
+	struct udp_port_cfg udp_config;
+};
+
+static inline struct fou *fou_from_sock(struct sock *sk)
+{
+	return (struct fou *)sk->sk_user_data;
+}
+
+static int fou_udp_encap_recv_deliver(struct sk_buff *skb,
+				      u8 protocol, size_t len)
+{
+	struct iphdr *iph = ip_hdr(skb);
+
+	/* Remove 'len' bytes from the packet (UDP header and
+	 * FOU header if present), modify the protocol to the one
+	 * we found, and then call rcv_encap.
+	 */
+	iph->tot_len = htons(ntohs(iph->tot_len) - len);
+	__skb_pull(skb, len);
+	skb_postpull_rcsum(skb, udp_hdr(skb), len);
+	skb_reset_transport_header(skb);
+
+	return -protocol;
+}
+
+static int fou_udp_recv(struct sock *sk, struct sk_buff *skb)
+{
+	struct fou *fou = fou_from_sock(sk);
+
+	if (!fou)
+		return 1;
+
+	return fou_udp_encap_recv_deliver(skb, fou->protocol,
+					  sizeof(struct udphdr));
+}
+
+static int fou_add_to_port_list(struct fou *fou)
+{
+	struct fou *fout;
+
+	spin_lock(&fou_lock);
+	list_for_each_entry(fout, &fou_list, list) {
+		if (fou->port == fout->port) {
+			spin_unlock(&fou_lock);
+			return -EALREADY;
+		}
+	}
+
+	list_add(&fou->list, &fou_list);
+	spin_unlock(&fou_lock);
+
+	return 0;
+}
+
+static void fou_release(struct fou *fou)
+{
+	struct socket *sock = fou->sock;
+	struct sock *sk = sock->sk;
+
+	udp_del_offload(&fou->udp_offloads);
+
+	list_del(&fou->list);
+
+	/* Remove hooks into tunnel socket */
+	sk->sk_user_data = NULL;
+
+	sock_release(sock);
+
+	kfree(fou);
+}
+
+static int fou_create(struct net *net, struct fou_cfg *cfg,
+		      struct socket **sockp)
+{
+	struct fou *fou = NULL;
+	int err;
+	struct socket *sock = NULL;
+	struct sock *sk;
+
+	/* Open UDP socket */
+	err = udp_sock_create(net, &cfg->udp_config, &sock);
+	if (err < 0)
+		goto error;
+
+	sk = sock->sk;
+
+	/* Allocate FOU port structure */
+	fou = kzalloc(sizeof(*fou), GFP_KERNEL);
+	if (!fou) {
+		err = -ENOMEM;
+		goto error;
+	}
+
+	/* Mark socket as an encapsulation socket. See net/ipv4/udp.c */
+	fou->protocol = cfg->protocol;
+	fou->port =  cfg->udp_config.local_udp_port;
+	udp_sk(sk)->encap_rcv = fou_udp_recv;
+
+	udp_sk(sk)->encap_type = 1;
+	udp_encap_enable();
+
+	sk->sk_user_data = fou;
+	fou->sock = sock;
+
+	udp_set_convert_csum(sock->sk, true);
+
+	sk->sk_allocation = GFP_ATOMIC;
+
+	err = fou_add_to_port_list(fou);
+	if (err)
+		goto error;
+
+	if (sockp)
+		*sockp = sock;
+
+	return 0;
+
+error:
+	kfree(fou);
+	if (sock)
+		sock_release(sock);
+
+	return err;
+}
+
+static int fou_destroy(struct net *net, struct fou_cfg *cfg)
+{
+	struct fou *fou;
+	u16 port = htons(cfg->udp_config.local_udp_port);
+	int err = -EINVAL;
+
+	spin_lock(&fou_lock);
+	list_for_each_entry(fou, &fou_list, list) {
+		if (fou->port == port) {
+			fou_release(fou);
+			err = 0;
+			break;
+		}
+	}
+	spin_unlock(&fou_lock);
+
+	return err;
+}
+
+static struct genl_family fou_nl_family = {
+	.id		= GENL_ID_GENERATE,
+	.hdrsize	= 0,
+	.name		= FOU_GENL_NAME,
+	.version	= FOU_GENL_VERSION,
+	.maxattr	= FOU_ATTR_MAX,
+	.netnsok	= true,
+};
+
+static struct nla_policy fou_nl_policy[FOU_ATTR_MAX + 1] = {
+	[FOU_ATTR_PORT] = { .type = NLA_U16, },
+	[FOU_ATTR_AF] = { .type = NLA_U8, },
+	[FOU_ATTR_IPPROTO] = { .type = NLA_U8, },
+};
+
+static int parse_nl_config(struct genl_info *info,
+			   struct fou_cfg *cfg)
+{
+	memset(cfg, 0, sizeof(*cfg));
+
+	cfg->udp_config.family = AF_INET;
+
+	if (info->attrs[FOU_ATTR_AF]) {
+		u8 family = nla_get_u8(info->attrs[FOU_ATTR_AF]);
+
+		if (family != AF_INET && family != AF_INET6)
+			return -EINVAL;
+
+		cfg->udp_config.family = family;
+	}
+
+	if (info->attrs[FOU_ATTR_PORT]) {
+		u16 port = nla_get_u16(info->attrs[FOU_ATTR_PORT]);
+
+		cfg->udp_config.local_udp_port = port;
+	}
+
+	if (info->attrs[FOU_ATTR_IPPROTO])
+		cfg->protocol = nla_get_u8(info->attrs[FOU_ATTR_IPPROTO]);
+
+	return 0;
+}
+
+static int fou_nl_cmd_add_port(struct sk_buff *skb, struct genl_info *info)
+{
+	struct fou_cfg cfg;
+	int err;
+
+	err = parse_nl_config(info, &cfg);
+	if (err)
+		return err;
+
+	return fou_create(&init_net, &cfg, NULL);
+}
+
+static int fou_nl_cmd_rm_port(struct sk_buff *skb, struct genl_info *info)
+{
+	struct fou_cfg cfg;
+
+	parse_nl_config(info, &cfg);
+
+	return fou_destroy(&init_net, &cfg);
+}
+
+static const struct genl_ops fou_nl_ops[] = {
+	{
+		.cmd = FOU_CMD_ADD,
+		.doit = fou_nl_cmd_add_port,
+		.policy = fou_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = FOU_CMD_DEL,
+		.doit = fou_nl_cmd_rm_port,
+		.policy = fou_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+};
+
+static int __init fou_init(void)
+{
+	int ret;
+
+	ret = genl_register_family_with_ops(&fou_nl_family,
+					    fou_nl_ops);
+
+	return ret;
+}
+
+static void __exit fou_fini(void)
+{
+	struct fou *fou, *next;
+
+	genl_unregister_family(&fou_nl_family);
+
+	/* Close all the FOU sockets */
+
+	spin_lock(&fou_lock);
+	list_for_each_entry_safe(fou, next, &fou_list, list)
+		fou_release(fou);
+	spin_unlock(&fou_lock);
+}
+
+module_init(fou_init);
+module_exit(fou_fini);
+MODULE_AUTHOR("Tom Herbert <therbert@google.com>");
+MODULE_LICENSE("GPL");
-- 
2.1.0.rc2.206.gedb03e5

^ permalink raw reply related

* [PATCH v3 net-next 1/7] net: Export inet_offloads and inet6_offloads
From: Tom Herbert @ 2014-09-16  3:30 UTC (permalink / raw)
  To: davem, netdev
In-Reply-To: <1410838224-19777-1-git-send-email-therbert@google.com>

Want to be able to use these in foo-over-udp offloads, etc.

Signed-off-by: Tom Herbert <therbert@google.com>
---
 net/ipv4/protocol.c | 1 +
 net/ipv6/protocol.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c
index 46d6a1c..4b7c0ec 100644
--- a/net/ipv4/protocol.c
+++ b/net/ipv4/protocol.c
@@ -30,6 +30,7 @@
 
 const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS] __read_mostly;
 const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS] __read_mostly;
+EXPORT_SYMBOL(inet_offloads);
 
 int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol)
 {
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c
index e048cf1..e3770ab 100644
--- a/net/ipv6/protocol.c
+++ b/net/ipv6/protocol.c
@@ -51,6 +51,7 @@ EXPORT_SYMBOL(inet6_del_protocol);
 #endif
 
 const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS] __read_mostly;
+EXPORT_SYMBOL(inet6_offloads);
 
 int inet6_add_offload(const struct net_offload *prot, unsigned char protocol)
 {
-- 
2.1.0.rc2.206.gedb03e5

^ permalink raw reply related

* [PATCH v3 net-next 0/7] net: foo-over-udp (fou)
From: Tom Herbert @ 2014-09-16  3:30 UTC (permalink / raw)
  To: davem, netdev

This patch series implements foo-over-udp. The idea is that we can
encapsulate different IP protocols in UDP packets. The rationale for
this is that networking devices such as NICs and switches are usually
implemented with UDP (and TCP) specific mechanims for processing. For
instance, many switches and routers will implement a 5-tuple hash
for UDP packets to perform Equal Cost Multipath Routing (ECMP) or
RSS (on NICs). Many NICs also only provide rudimentary checksum
offload (basic TCP and UDP packet), with foo-over-udp we may be
able to leverage these NICs to offload checksums of tunneled packets
(using checksum unnecessary conversion and eventually remote checksum
offload)
 
An example encapsulation of IPIP over FOU is diagrammed below. As
illustrated, the packet overhead for FOU is the 8 byte UDP header.

+------------------+
|    IPv4 hdr      |
+------------------+
|     UDP hdr      |
+------------------+
|    IPv4 hdr      |
+------------------+
|     TCP hdr      |
+------------------+
|   TCP payload    |
+------------------+

Conceptually, FOU should be able to encapsulate any IP protocol.
The FOU header (UDP hdr.) is essentially an inserted header between the
IP header and transport, so in the case of TCP or UDP encapsulation
the pseudo header would be based on the outer IP header and its length
field must not include the UDP header.

* Receive

In this patch set the RX path for FOU is implemented in a new fou
module. To enable FOU for a particular protocol, a UDP-FOU socket is
opened to the port to receive FOU packets. The socket is mapped to the
IP protocol for the packets. The XFRM mechanism used to receive
encapsulated packets (udp_encap_rcv) for the port. Upon reception, the
UDP is removed and packet is reinjected in the stack for the
corresponding protocol associated with the socket (return -protocol
from udp_encap_rcv function).

GRO is provided with the appropriate fou_gro_receive and
fou_gro_complete. These routines need to know the encapsulation
protocol so we save that in udp_offloads structure with the port
and pass it in the napi_gro_cb structure.

* TX

This patch series implements FOU transmit encapsulation for IPIP, GRE, and
SIT. This done by some common infrastructure in ip_tunnel including an
ip_tunnel_encap to perform FOU encapsulation and common configuration
to enable FOU on IP tunnels. FOU is configured on existing tunnels and
does not create any new interfaces. The transmit and receive paths are
independent, so use of FOU may be assymetric between tunnel endpoints.

* Configuration

The fou module using netlink to configure FOU receive ports. The ip
command can be augmented with a fou subcommand to support this. e.g. to
configure FOU for IPIP on port 5555:

  ip fou add port 5555 ipproto 4

GRE, IPIP, and SIT have been modified with netlink commands to
configure use of FOU on transmit. The "ip link" command will be
augmented with an encap subcommand (for supporting various forms of
secondary encapsulation). For instance, to configure an ipip tunnel
with FOU on port 5555:

  ip link add name tun1 type ipip \
    remote 192.168.1.1 local 192.168.1.2 ttl 225 \
    encap fou encap-sport auto encap-dport 5555

* Notes
  - This patch set does not implement GSO for FOU. The UDP encapsulation
    code assumes TEB, so that will need to be reimplemented.
  - When a packet is received through FOU, the UDP header is not
    actually removed for the skbuf, pointers to transport header
    and length in the IP header are updated (like in ESP/UDP RX). A
    side effect is the IP header will now appear to have an incorrect
    checksum by an external observer (e.g. tcpdump), it will be off
    by sizeof UDP header. If necessary we could adjust the checksum 
    to compensate.
  - Performance results are below. My expectation is that FOU should
    entail little overhead (clearly there is some work to do :-) ).
    Optimizing UDP socket lookup for encapsulation ports should help
    significantly.
  - I really don't expect/want devices to have special support for any
    of this. Generic checksum offload mechanisms (NETIF_HW_CSUM
    and use of CHECKSUM_COMPLETE) should be sufficient. RSS and flow
    steering is provided by commonly implemented UDP hashing. GRO/GSO
    seem fairly comparable with LRO/TSO already.

* Performance

Ran netperf TCP_RR and TCP_STREAM tests across various configurations.
This was performed on bnx2x and I disabled TSO/GSO on sender to get
fair comparison for FOU versus non-FOU. CPU utilization is reported
for receive in TCP_STREAM.

  GRE
    IPv4, FOU, UDP checksum enabled
      TCP_STREAM
        24.85% CPU utilization
        9310.6 Mbps
      TCP_RR
        94.2% CPU utilization
        155/249/460 90/95/99% latencies
        1.17018e+06 tps
    IPv4, FOU, UDP checksum disabled
      TCP_STREAM
        31.04% CPU utilization
        9302.22 Mbps
      TCP_RR
        94.13% CPU utilization
        154/239/419 90/95/99% latencies
        1.17555e+06 tps
    IPv4, no FOU
      TCP_STREAM
        23.13% CPU utilization
        9354.58 Mbps
      TCP_RR
        90.24% CPU utilization
        156/228/360 90/95/99% latencies
        1.18169e+06 tps

  IPIP
    FOU, UDP checksum enabled
      TCP_STREAM
        24.13% CPU utilization
        9328 Mbps
      TCP_RR
        94.23
        149/237/429 90/95/99% latencies
        1.19553e+06 tps
    FOU, UDP checksum disabled
      TCP_STREAM
        29.13% CPU utilization
        9370.25 Mbps
      TCP_RR
        94.13% CPU utilization
        149/232/398 90/95/99% latencies
        1.19225e+06 tps
    No FOU
      TCP_STREAM
        10.43% CPU utilization
        5302.03 Mbps
      TCP_RR
        51.53% CPU utilization
        215/324/475 90/95/99% latencies
        864998 tps

  SIT
    FOU, UDP checksum enabled
      TCP_STREAM
        30.38% CPU utilization
        9176.76 Mbps
      TCP_RR
        96.9% CPU utilization
        170/281/581 90/95/99% latencies
        1.03372e+06 tps
    FOU, UDP checksum disabled
      TCP_STREAM
        39.6% CPU utilization
        9176.57 Mbps
      TCP_RR
        97.14% CPU utilization
        167/272/548 90/95/99% latencies
        1.03203e+06 tps
    No FOU
      TCP_STREAM
        11.2% CPU utilization
        4636.05 Mbps
      TCP_RR
        59.51% CPU utilization
        232/346/489 90/95/99% latencies
        813199 tps

v2:
  - Removed encap IP tunnel ioctls, configuration is done by netlink
    only.
  - Don't export fou_create and fou_destroy, they are currently
    intended to be called within fou module only.
  - Filled on tunnel netlink structures and functions for new values.

v3:
  - Fixed change logs for some of the patches.
  - Remove inline from fou_gro_receive and fou_gro_complete, let
    compiler decide on these.


Tom Herbert (7):
  net: Export inet_offloads and inet6_offloads
  fou: Support for foo-over-udp RX path
  fou: Add GRO support
  net: Changes to ip_tunnel to support foo-over-udp encapsulation
  sit: Setup and TX path for sit/UDP foo-over-udp encapsulation
  ipip: Setup and TX path for ipip/UDP foo-over-udp encapsulation
  gre: Setup and TX path for gre/UDP foo-over-udp encapsulation

 include/linux/netdevice.h      |   3 +-
 include/net/ip_tunnels.h       |  19 ++-
 include/uapi/linux/fou.h       |  32 ++++
 include/uapi/linux/if_tunnel.h |  16 ++
 net/ipv4/Kconfig               |  10 ++
 net/ipv4/Makefile              |   1 +
 net/ipv4/fou.c                 | 368 +++++++++++++++++++++++++++++++++++++++++
 net/ipv4/ip_gre.c              |  98 ++++++++++-
 net/ipv4/ip_tunnel.c           |  91 +++++++++-
 net/ipv4/ipip.c                |  86 +++++++++-
 net/ipv4/protocol.c            |   1 +
 net/ipv4/udp_offload.c         |   5 +-
 net/ipv6/protocol.c            |   1 +
 net/ipv6/sit.c                 | 107 ++++++++++--
 14 files changed, 814 insertions(+), 24 deletions(-)
 create mode 100644 include/uapi/linux/fou.h
 create mode 100644 net/ipv4/fou.c

-- 
2.1.0.rc2.206.gedb03e5

^ permalink raw reply

* RE: [PATCH net 1/2] r8169: fix the default setting of rx vlan
From: Hayes Wang @ 2014-09-16  3:23 UTC (permalink / raw)
  To: Francois Romieu
  Cc: netdev@vger.kernel.org, nic_swsd, linux-kernel@vger.kernel.org
In-Reply-To: <20140916000321.GA19564@electric-eye.fr.zoreil.com>

 From: Francois Romieu [mailto:romieu@fr.zoreil.com] 
> Sent: Tuesday, September 16, 2014 8:03 AM
[...]
> However it's getting messy and the code stomps CPlusCmd in 
> rtl_open right
> before it's given a chance to be read in hw_start. Something like the
> untested patch below should avoid it and keep related things together.

You are right. Your patch is more reasonable. I would sent the patch.
Thanks.
 
Best Regards,
Hayes

^ permalink raw reply

* Re: [PATCH 3] scsi: fix build errors, SCSI_FC_ATTRS needs to depend on SCSI && NET
From: Randy Dunlap @ 2014-09-16  3:17 UTC (permalink / raw)
  To: Anish Bhatt, netdev@vger.kernel.org, JBottomley@parallels.com,
	David Miller
  Cc: linux-scsi@vger.kernel.org, mchan@broadcom.com,
	eddie.wai@broadcom.com, jim.epost@gmail.com
In-Reply-To: <525DB349B3FB5444AE057A887CB2A8D88EBB11@nice.asicdesigners.com>

On 09/15/14 20:00, Anish Bhatt wrote:
> 
> Doesn't fix make warnings, but SCSI_FC_ATTRS can no longer be selected without
> NET. Though both ia64 and powerpc emit a lot of unmet dependency warnings as is 
> on defconfig


You mean these kconfig warnings?

<quote>

After merging the net tree, today's linux-next build
(powerpc ppc64_defconfig) failed like this:

warning: (PPC_CELL_NATIVE && BLUESTONE && CANYONLANDS && GLACIER && EIGER && 440EPX && 440GRX && 440GX && 460SX && 405EX) selects IBM_EMAC_RGMII which has unmet direct dependencies (NETDEVICES && ETHERNET && NET_VENDOR_IBM)
warning: (PPC_CELL_NATIVE && CANYONLANDS && GLACIER && 440EP && 440EPX && 440GRX && 440GP && 440GX && 460SX && 405GP) selects IBM_EMAC_ZMII which has unmet direct dependencies (NETDEVICES && ETHERNET && NET_VENDOR_IBM)
warning: (PPC_CELL_NATIVE && 440GX && 460EX && 460SX && APM821xx) selects IBM_EMAC_TAH which has unmet direct dependencies (NETDEVICES && ETHERNET && NET_VENDOR_IBM)
warning: (PPC_CELL_NATIVE && AKEBONO && 440EPX && 440GRX && 440GX && 440SPe && 460EX && 460SX && APM821xx && 405EX) selects IBM_EMAC_EMAC4 which has unmet direct dependencies (NETDEVICES && ETHERNET && NET_VENDOR_IBM)
warning: (PPC_CELL_NATIVE && CANYONLANDS && GLACIER && 440EP && 440EPX && 440GRX && 440GP && 440GX && 460SX && 405GP) selects IBM_EMAC_ZMII which has unmet direct dependencies (NETDEVICES && ETHERNET && NET_VENDOR_IBM)
warning: (PPC_CELL_NATIVE && BLUESTONE && CANYONLANDS && GLACIER && EIGER && 440EPX && 440GRX && 440GX && 460SX && 405EX) selects IBM_EMAC_RGMII which has unmet direct dependencies (NETDEVICES && ETHERNET && NET_VENDOR_IBM)
warning: (PPC_CELL_NATIVE && 440GX && 460EX && 460SX && APM821xx) selects IBM_EMAC_TAH which has unmet direct dependencies (NETDEVICES && ETHERNET && NET_VENDOR_IBM)
warning: (PPC_CELL_NATIVE && AKEBONO && 440EPX && 440GRX && 440GX && 440SPe && 460EX && 460SX && APM821xx && 405EX) selects IBM_EMAC_EMAC4 which has unmet direct dependencies (NETDEVICES && ETHERNET && NET_VENDOR_IBM)

</quote>

I'll look into those.
-- 
~Randy

^ permalink raw reply

* RE: [Patch net-next 4/4] net: fec: Workaround for imx6sx enet tx hang when enable three queues
From: fugang.duan @ 2014-09-16  3:09 UTC (permalink / raw)
  To: Shawn Guo, Frank.Li@freescale.com
  Cc: lznuaa@gmail.com, netdev@vger.kernel.org, davem@davemloft.net,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <20140916005204.GA23482@dragon>

From: Shawn Guo <shawn.guo@linaro.org> Sent: Tuesday, September 16, 2014 8:52 AM
>To: Li Frank-B20596
>Cc: Duan Fugang-B38611; davem@davemloft.net; netdev@vger.kernel.org;
>lznuaa@gmail.com; linux-arm-kernel@lists.infradead.org
>Subject: Re: [Patch net-next 4/4] net: fec: Workaround for imx6sx enet tx
>hang when enable three queues
>
>On Tue, Sep 16, 2014 at 01:12:57AM +0800, Frank.Li@freescale.com wrote:
>> From: Fugang Duan <B38611@freescale.com>
>>
>> When enable three queues on imx6sx enet, and then do tx performance
>> test with iperf tool, after some time running, tx hang.
>>
>> Found that:
>> 	If uDMA is running, software set TDAR may cause tx hang.
>> 	If uDMA is in idle, software set TDAR don't cause tx hang.
>>
>> There is a TDAR race condition for mutliQ when the software sets TDAR
>> and the UDMA clears TDAR simultaneously or in a small window (2-4
>cycles).
>> This will cause the udma_tx and udma_tx_arbiter state machines to hang.
>> The issue exist at i.MX6SX enet IP.
>>
>> So, the Workaround is checking TDAR status four time, if TDAR cleared
>> by hardware and then write TDAR, otherwise don't set TDAR.
>>
>> The patch is only one Workaround for the issue TKT210582.
>>
>> Signed-off-by: Fugang Duan <B38611@freescale.com>
>> Signed-off-by: Frank Li <Frank.Li@freescale.com>
>> ---
>>  drivers/net/ethernet/freescale/fec_main.c | 18 ++++++++++++++++--
>>  1 file changed, 16 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/freescale/fec_main.c
>> b/drivers/net/ethernet/freescale/fec_main.c
>> index 524ddbe..452e576 100644
>> --- a/drivers/net/ethernet/freescale/fec_main.c
>> +++ b/drivers/net/ethernet/freescale/fec_main.c
>> @@ -111,6 +111,13 @@ static void fec_enet_itr_coal_init(struct
>net_device *ndev);
>>   *   independent rings
>>   */
>>  #define FEC_QUIRK_HAS_AVB		(1 << 8)
>> +/*
>> + * There is a TDAR race condition for mutliQ when the software sets
>> +TDAR
>> + * and the UDMA clears TDAR simultaneously or in a small window (2-4
>cycles).
>> + * This will cause the udma_tx and udma_tx_arbiter state machines to
>hang.
>> + * The issue exist at i.MX6SX enet IP.
>> + */
>> +#define FEC_QUIRK_TKT210582		(1 << 9)
>
>I think TKTxxx number is used by Freescale design team to track issues
>internally, and there should be a corresponding errata number like ERRxxx
>which should be accessible by external people in errata document?
>
>Shawn
The issue ticket is: TDAR race condition for mutliQ - Errata: ERR007885

>
>>
>>  static struct platform_device_id fec_devtype[] = {
>>  	{
>> @@ -139,7 +146,7 @@ static struct platform_device_id fec_devtype[] = {
>>  		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
>>  				FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
>>  				FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 |
>> -				FEC_QUIRK_HAS_AVB,
>> +				FEC_QUIRK_HAS_AVB | FEC_QUIRK_TKT210582,
>>  	}, {
>>  		/* sentinel */
>>  	}
>> @@ -709,6 +716,8 @@ static int fec_enet_txq_submit_tso(struct
>fec_enet_priv_tx_q *txq,
>>  	struct tso_t tso;
>>  	unsigned int index = 0;
>>  	int ret;
>> +	const struct platform_device_id *id_entry =
>> +				platform_get_device_id(fep->pdev);
>>
>>  	if (tso_count_descs(skb) >= fec_enet_get_free_txdesc_num(fep, txq))
>{
>>  		dev_kfree_skb_any(skb);
>> @@ -770,7 +779,12 @@ static int fec_enet_txq_submit_tso(struct
>fec_enet_priv_tx_q *txq,
>>  	txq->cur_tx = bdp;
>>
>>  	/* Trigger transmission start */
>> -	writel(0, fep->hwp + FEC_X_DES_ACTIVE(queue));
>> +	if (!(id_entry->driver_data & FEC_QUIRK_TKT210582) ||
>> +		!readl(fep->hwp + FEC_X_DES_ACTIVE(queue)) ||
>> +		!readl(fep->hwp + FEC_X_DES_ACTIVE(queue)) ||
>> +		!readl(fep->hwp + FEC_X_DES_ACTIVE(queue)) ||
>> +		!readl(fep->hwp + FEC_X_DES_ACTIVE(queue)))
>> +		writel(0, fep->hwp + FEC_X_DES_ACTIVE(queue));
>>
>>  	return 0;
>>
>> --
>> 1.9.1
>>

^ permalink raw reply

* Re: [net-next PATCH 3/3] net: sched: cls_cgroup fix possible memory leak of 'new'
From: Cong Wang @ 2014-09-16  3:04 UTC (permalink / raw)
  To: John Fastabend
  Cc: Cong Wang, David Miller, Eric Dumazet, netdev, Jamal Hadi Salim
In-Reply-To: <20140916024831.3010.64477.stgit@nitbit.x32>

On Mon, Sep 15, 2014 at 7:48 PM, John Fastabend
<john.fastabend@gmail.com> wrote:
> diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
> index 3b75487..52b7900 100644
> --- a/net/sched/cls_cgroup.c
> +++ b/net/sched/cls_cgroup.c
> @@ -127,16 +127,16 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
>         err = nla_parse_nested(tb, TCA_CGROUP_MAX, tca[TCA_OPTIONS],
>                                cgroup_policy);
>         if (err < 0)
> -               return err;
> +               goto errout;
>
>         tcf_exts_init(&e, TCA_CGROUP_ACT, TCA_CGROUP_POLICE);
>         err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
>         if (err < 0)
> -               return err;
> +               goto errout;
>
>         err = tcf_em_tree_validate(tp, tb[TCA_CGROUP_EMATCHES], &t);
>         if (err < 0)
> -               return err;
> +               goto errout;
>

I think you need to call tcf_exts_destroy() too after tcf_exts_validate(),
while you are on it. :)

^ permalink raw reply

* RE: [PATCH 3] scsi: fix build errors, SCSI_FC_ATTRS needs to depend on SCSI && NET
From: Anish Bhatt @ 2014-09-16  3:00 UTC (permalink / raw)
  To: Randy Dunlap, netdev@vger.kernel.org, JBottomley@parallels.com,
	David Miller
  Cc: linux-scsi@vger.kernel.org, mchan@broadcom.com,
	eddie.wai@broadcom.com, jim.epost@gmail.com
In-Reply-To: <5417825A.4050902@infradead.org>

> From : Randy Dunlap [rdunlap@infradead.org]
> Sent: Monday, September 15, 2014 5:20 PM
> To: Anish Bhatt; netdev@vger.kernel.org; JBottomley@parallels.com; David Miller
> Cc: linux-scsi@vger.kernel.org; mchan@broadcom.com; eddie.wai@broadcom.com; jim.epost@gmail.com
> Subject: [PATCH 3] scsi: fix build errors, SCSI_FC_ATTRS needs to depend on SCSI && NET
>
> From: Randy Dunlap <rdunlap@infradead.org>
>
> Fix build errors when CONFIG_SCSI_NETLINK is enabled but
> CONFIG_NET is not enabled:
>
> drivers/built-in.o: In function `scsi_nl_rcv_msg':
> scsi_netlink.c:(.text+0x1850fa): undefined reference to `netlink_ack'
> scsi_netlink.c:(.text+0x185105): undefined reference to `skb_pull'
> scsi_netlink.c:(.text+0x18515d): undefined reference to `netlink_capable'
> drivers/built-in.o: In function `scsi_netlink_init':
> (.text+0x185244): undefined reference to `init_net'
> drivers/built-in.o: In function `scsi_netlink_init':
> (.text+0x185258): undefined reference to `__netlink_kernel_create'
> drivers/built-in.o: In function `scsi_netlink_exit':
> (.text+0x185291): undefined reference to `netlink_kernel_release'
>
> Signed-off-by: Randy Dunlap <rdunlap@infradead.org>

Doesn't fix make warnings, but SCSI_FC_ATTRS can no longer be selected without
NET. Though both ia64 and powerpc emit a lot of unmet dependency warnings as is 
on defconfig

Tested-by: Anish Bhatt <anish@chelsio.com>
> ---
>  drivers/scsi/Kconfig |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> Based on Anish's previous SCSI_NETLINK patch.
> Sorry about missing this one.
>
> --- lnx-317-rc5.orig/drivers/scsi/Kconfig
> +++ lnx-317-rc5/drivers/scsi/Kconfig
> @@ -257,7 +257,7 @@ config SCSI_SPI_ATTRS
>
>  config SCSI_FC_ATTRS
>         tristate "FiberChannel Transport Attributes"
> -       depends on SCSI
> +       depends on SCSI && NET
>         select SCSI_NETLINK
>         help
>           If you wish to export transport-specific information about

^ permalink raw reply

* [net-next PATCH 3/3] net: sched: cls_cgroup fix possible memory leak of 'new'
From: John Fastabend @ 2014-09-16  2:48 UTC (permalink / raw)
  To: xiyou.wangcong, davem, eric.dumazet; +Cc: netdev, jhs
In-Reply-To: <20140916024729.3010.47421.stgit@nitbit.x32>

tree:   git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git master
head:   54996b529ab70ca1d6f40677cd2698c4f7127e87
commit: c7953ef23042b7c4fc2be5ecdd216aacff6df5eb [625/646] net: sched: cls_cgroup use RCU

net/sched/cls_cgroup.c:130 cls_cgroup_change() warn: possible memory leak of 'new'
net/sched/cls_cgroup.c:135 cls_cgroup_change() warn: possible memory leak of 'new'
net/sched/cls_cgroup.c:139 cls_cgroup_change() warn: possible memory leak of 'new'

Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
 net/sched/cls_cgroup.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 3b75487..52b7900 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -127,16 +127,16 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
 	err = nla_parse_nested(tb, TCA_CGROUP_MAX, tca[TCA_OPTIONS],
 			       cgroup_policy);
 	if (err < 0)
-		return err;
+		goto errout;
 
 	tcf_exts_init(&e, TCA_CGROUP_ACT, TCA_CGROUP_POLICE);
 	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
 	if (err < 0)
-		return err;
+		goto errout;
 
 	err = tcf_em_tree_validate(tp, tb[TCA_CGROUP_EMATCHES], &t);
 	if (err < 0)
-		return err;
+		goto errout;
 
 	tcf_exts_change(tp, &new->exts, &e);
 	tcf_em_tree_change(tp, &new->ematches, &t);
@@ -145,6 +145,9 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
 	if (head)
 		call_rcu(&head->rcu, cls_cgroup_destroy_rcu);
 	return 0;
+errout:
+	kfree(new);
+	return err;
 }
 
 static void cls_cgroup_destroy(struct tcf_proto *tp)

^ 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