Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] tcp: TCP_USER_TIMEOUT can not work in tcp_probe_timer()
From: Eric Dumazet @ 2017-09-12 15:38 UTC (permalink / raw)
  To: liujian
  Cc: davem, kuznet, yoshfuji, edumazet, ycheng, hkchu, netdev,
	weiyongjun1, wangkefeng 00227729
In-Reply-To: <1505228700.15310.138.camel@edumazet-glaptop3.roam.corp.google.com>

On Tue, 2017-09-12 at 08:05 -0700, Eric Dumazet wrote:
> On Tue, 2017-09-12 at 14:08 +0800, liujian wrote:
> > Hi,
> > 
> > In the scenario, tcp server side IP changed, and at that memont,
> > userspace application still send data continuously;
> > tcp_send_head(sk)'s timestamp always be refreshed.
> > 
> > Here is the packetdrill script:
> > 
> >    0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
> >    +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
> >    +0 bind(3, ..., ...) = 0
> >    +0 listen(3, 1) = 0
> > 
> >    +0 < S 0:0(0) win 0 <mss 1460,sackOK,nop,nop,nop,wscale 7>
> >    +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 7>
> > 
> >   +.1 < . 1:1(0) ack 1 win 65530
> >    +0 accept(3, ..., ...) = 4
> > 
> >    +0 setsockopt(4, SOL_TCP, TCP_USER_TIMEOUT, [3000], 4) = 0
> >    +0 write(4, ..., 24) = 24
> >    +0 > P. 1:25(24) ack 1 win 229
> >    +.1 < . 1:1(0) ack 25 win 65530
> > 
> > //change the ipaddress
> >    +1 `ifconfig tun0 192.168.0.10/16`
> > 
> >    +1 write(4, ..., 24) = 24
> >    +1 write(4, ..., 24) = 24
> >    +1 write(4, ..., 24) = 24
> >    +1 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> >    +3 write(4, ..., 24) = 24
> > 
> >    +0 `ifconfig tun0 192.168.0.1/16`
> >    +0 < . 1:1(0) ack 1 win 1000
> >    +0 write(4, ..., 24) = -1
> > 
> > 
> 
> This has nothing to do with the code patch you have changed.
> 
> How have you tested your patch exactly ?
> 


lpaa23:~# ss -toenmi src :8080
State      Recv-Q Send-Q Local Address:Port               Peer
Address:Port              
ESTAB      0      144    192.168.134.161:8080
192.0.2.1:51165               timer:(persist,8.262ms,5) ino:1
82083 sk:3 <->
	 skmem:(r0,rb359040,t0,tb46080,f1792,w2304,o0,bl0,d0) sack cubic
wscale:7,8 rto:301 backoff:5 rtt:100.127/37.576 
mss:1460 rcvmss:536 advmss:1460 cwnd:10 bytes_acked:24 segs_out:12
segs_in:3 data_segs_out:12 send 1.2Mbps lastsnd:1370 l
astrcv:13348 lastack:13248 pacing_rate 2.3Mbps delivery_rate 116.7Kbps
app_limited busy:11346ms rcv_space:29200 notsent:1
44 minrtt:100.043

This is the typical RTO timer, not zero window probe.

^ permalink raw reply

* Re: [PATCH] tcp: TCP_USER_TIMEOUT can not work in tcp_probe_timer()
From: Eric Dumazet @ 2017-09-12 15:05 UTC (permalink / raw)
  To: liujian
  Cc: davem, kuznet, yoshfuji, edumazet, ycheng, hkchu, netdev,
	weiyongjun1, wangkefeng 00227729
In-Reply-To: <e7e09201-40c2-933a-1e8e-a31eddcc75ab@huawei.com>

On Tue, 2017-09-12 at 14:08 +0800, liujian wrote:
> Hi,
> 
> In the scenario, tcp server side IP changed, and at that memont,
> userspace application still send data continuously;
> tcp_send_head(sk)'s timestamp always be refreshed.
> 
> Here is the packetdrill script:
> 
>    0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
>    +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
>    +0 bind(3, ..., ...) = 0
>    +0 listen(3, 1) = 0
> 
>    +0 < S 0:0(0) win 0 <mss 1460,sackOK,nop,nop,nop,wscale 7>
>    +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 7>
> 
>   +.1 < . 1:1(0) ack 1 win 65530
>    +0 accept(3, ..., ...) = 4
> 
>    +0 setsockopt(4, SOL_TCP, TCP_USER_TIMEOUT, [3000], 4) = 0
>    +0 write(4, ..., 24) = 24
>    +0 > P. 1:25(24) ack 1 win 229
>    +.1 < . 1:1(0) ack 25 win 65530
> 
> //change the ipaddress
>    +1 `ifconfig tun0 192.168.0.10/16`
> 
>    +1 write(4, ..., 24) = 24
>    +1 write(4, ..., 24) = 24
>    +1 write(4, ..., 24) = 24
>    +1 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
>    +3 write(4, ..., 24) = 24
> 
>    +0 `ifconfig tun0 192.168.0.1/16`
>    +0 < . 1:1(0) ack 1 win 1000
>    +0 write(4, ..., 24) = -1
> 
> 

This has nothing to do with the code patch you have changed.

How have you tested your patch exactly ?


> [root@localhost ~]# time ./gtests/net/packetdrill/packetdrill test.pkt
> test.pkt:50: runtime error in write call: Expected result -1 but got 24 with errno 2 (No such file or directory)
> 
> real	1m11.364s
> user	0m0.028s
> sys	0m0.106s
> 
> [root@localhost ~]# netstat -toen
> Active Internet connections (w/o servers)
> Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode      Timer
> tcp        0    504 192.168.0.1:8080        192.0.2.1:33993         ESTABLISHED 0          45453      probe (22.38/0/7)
> 
> since the script didn't wait for enough time, here only got 7 probes.
> 
> 在 2017/9/11 23:22, Eric Dumazet 写道:
> > On Mon, 2017-09-11 at 08:13 -0700, Eric Dumazet wrote:
> > 
> >> You can see we got only 3 probes, not 4.
> > 
> > Here is complete packetdrill test showing that code behaves as expected.
> > 
> >     0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
> >    +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
> >    +0 bind(3, ..., ...) = 0
> >    +0 listen(3, 1) = 0
> > 
> >    +0 < S 0:0(0) win 0 <mss 1460,sackOK,nop,nop,nop,wscale 7>
> >    +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8>
> > 
> > // Client advertises a zero receive window, so we can't send.
> >   +.1 < . 1:1(0) ack 1 win 0
> >    +0 accept(3, ..., ...) = 4
> > 
> >    +0 setsockopt(4, SOL_TCP, TCP_USER_TIMEOUT, [3000], 4) = 0
> >    +0 write(4, ..., 2920) = 2920
> > 
> > // Window probes are scheduled just like RTOs.
> >   +.3~+.31 > . 0:0(0) ack 1
> >   +.6~+.62 > . 0:0(0) ack 1
> >  +1.2~+1.24 > . 0:0(0) ack 1
> > 
> > // Peer opens its window too late !
> >    +3 < . 1:1(0) ack 1 win 1000
> >    +0 > R 1:1(0)
> > 
> > 
> > 
> > .
> > 
> 

^ permalink raw reply

* [iproute PATCH] ipaddress: Fix segfault in 'addr showdump'
From: Phil Sutter @ 2017-09-12 14:58 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Hangbin Liu

Obviously, 'addr showdump' feature wasn't adjusted to json output
support. As a consequence, calls to print_string() in print_addrinfo()
tried to dereference a NULL FILE pointer.

Fixes: d0e720111aad2 ("ip: ipaddress.c: add support for json output")
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 ip/ipaddress.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 9797145023966..ee6c9f588e7ba 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -1801,17 +1801,31 @@ static int show_handler(const struct sockaddr_nl *nl,
 {
 	struct ifaddrmsg *ifa = NLMSG_DATA(n);
 
-	printf("if%d:\n", ifa->ifa_index);
+	open_json_object(NULL);
+	print_int(PRINT_ANY, "index", "if%d:\n", ifa->ifa_index);
 	print_addrinfo(NULL, n, stdout);
+	close_json_object();
 	return 0;
 }
 
 static int ipaddr_showdump(void)
 {
+	int err;
+
 	if (ipadd_dump_check_magic())
 		exit(-1);
 
-	exit(rtnl_from_file(stdin, &show_handler, NULL));
+	new_json_obj(json, stdout);
+	open_json_object(NULL);
+	open_json_array(PRINT_JSON, "addr_info");
+
+	err = rtnl_from_file(stdin, &show_handler, NULL);
+
+	close_json_array(PRINT_JSON, NULL);
+	close_json_object();
+	delete_json_obj();
+
+	exit(err);
 }
 
 static int restore_handler(const struct sockaddr_nl *nl,
-- 
2.13.1

^ permalink raw reply related

* Re: [PATCH] ieee802154: fix gcc-4.9 warnings
From: Marcel Holtmann @ 2017-09-12 14:22 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Harry Morris, linuxdev, Alexander Aring, Stefan Schmidt,
	David S. Miller, Markus Elfring, Gustavo A. R. Silva,
	Florian Westphal, Johannes Berg, Christophe JAILLET,
	Colin Ian King, linux-wpan, Network Development, linux-kernel
In-Reply-To: <20170912101636.3811626-1-arnd@arndb.de>

Hi Arnd,

> All older compiler versions up to gcc-4.9 produce these
> harmless warnings:
> 
> drivers/net/ieee802154/ca8210.c: In function 'ca8210_skb_tx':
> drivers/net/ieee802154/ca8210.c:1947:9: warning: missing braces around initializer [-Wmissing-braces]
> 
> This changes the syntax to something that works on all versions
> without warnings.
> 
> Fixes: ded845a781a5 ("ieee802154: Add CA8210 IEEE 802.15.4 device driver")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> drivers/net/ieee802154/ca8210.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)

patch has been applied to bluetooth-next tree.

Regards

Marcel

^ permalink raw reply

* [PATCH/RFC net-next 2/2] net/sched: allow flower to match tunnel options
From: Simon Horman @ 2017-09-12 14:20 UTC (permalink / raw)
  To: Jiri Pirko, Jamal Hadi Salim, Cong Wang; +Cc: netdev, oss-drivers, Simon Horman
In-Reply-To: <1505226037-2758-1-git-send-email-simon.horman@netronome.com>

Allow matching on options in tunnel headers.
This makes use of existing tunnel metadata support.

Options are a bytestring of up to 256 bytes.
Tunnel implementations may support less or more options,
or no options at all.

 # ip link add name geneve0 type geneve dstport 0 external
 # tc qdisc add dev eth0 ingress
 # tc qdisc del dev eth0 ingress; tc qdisc add dev eth0 ingress
 # tc filter add dev eth0 protocol ip parent ffff: \
     flower indev eth0 \
        ip_proto udp \
        action tunnel_key \
            set src_ip 10.0.99.192 \
            dst_ip 10.0.99.193 \
            dst_port 4789 \
            id 11 \
            opts 0102800100800022 \
    action mirred egress redirect dev geneve0

Signed-off-by: Simon Horman <simon.horman@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 include/net/flow_dissector.h | 13 +++++++++++++
 include/uapi/linux/pkt_cls.h |  3 +++
 net/sched/cls_flower.c       | 35 ++++++++++++++++++++++++++++++++++-
 3 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
index fc3dce730a6b..43f98bf0b349 100644
--- a/include/net/flow_dissector.h
+++ b/include/net/flow_dissector.h
@@ -183,6 +183,18 @@ struct flow_dissector_key_ip {
 	__u8	ttl;
 };
 
+/**
+ * struct flow_dissector_key_enc_opts:
+ * @data: data
+ * @len: len
+ */
+struct flow_dissector_key_enc_opts {
+	u8 data[256];	/* Using IP_TUNNEL_OPTS_MAX is desired here
+			 * but seems difficult to #include
+			 */
+	u8 len;
+};
+
 enum flow_dissector_key_id {
 	FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
 	FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
@@ -205,6 +217,7 @@ enum flow_dissector_key_id {
 	FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
 	FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
 	FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
+	FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
 
 	FLOW_DISSECTOR_KEY_MAX,
 };
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index d5e2bf68d0d4..7a09a28f21e0 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -467,6 +467,9 @@ enum {
 	TCA_FLOWER_KEY_IP_TTL,		/* u8 */
 	TCA_FLOWER_KEY_IP_TTL_MASK,	/* u8 */
 
+	TCA_FLOWER_KEY_ENC_OPTS,
+	TCA_FLOWER_KEY_ENC_OPTS_MASK,
+
 	__TCA_FLOWER_MAX,
 };
 
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 1a267e77c6de..2a8364ef4fd5 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -51,6 +51,7 @@ struct fl_flow_key {
 	struct flow_dissector_key_mpls mpls;
 	struct flow_dissector_key_tcp tcp;
 	struct flow_dissector_key_ip ip;
+	struct flow_dissector_key_enc_opts enc_opts;
 } __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */
 
 struct fl_flow_mask_range {
@@ -181,6 +182,11 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 		skb_key.enc_key_id.keyid = tunnel_id_to_key32(key->tun_id);
 		skb_key.enc_tp.src = key->tp_src;
 		skb_key.enc_tp.dst = key->tp_dst;
+
+		if (info->options_len) {
+			skb_key.enc_opts.len = info->options_len;
+			ip_tunnel_info_opts_get(skb_key.enc_opts.data, info);
+		}
 	}
 
 	skb_key.indev_ifindex = skb->skb_iif;
@@ -421,6 +427,8 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = {
 	[TCA_FLOWER_KEY_IP_TOS_MASK]	= { .type = NLA_U8 },
 	[TCA_FLOWER_KEY_IP_TTL]		= { .type = NLA_U8 },
 	[TCA_FLOWER_KEY_IP_TTL_MASK]	= { .type = NLA_U8 },
+	[TCA_FLOWER_KEY_ENC_OPTS]	= { .type = NLA_BINARY },
+	[TCA_FLOWER_KEY_ENC_OPTS_MASK]	= { .type = NLA_BINARY },
 };
 
 static void fl_set_key_val(struct nlattr **tb,
@@ -712,6 +720,26 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
 		       &mask->enc_tp.dst, TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK,
 		       sizeof(key->enc_tp.dst));
 
+	if (tb[TCA_FLOWER_KEY_ENC_OPTS]) {
+		key->enc_opts.len = nla_len(tb[TCA_FLOWER_KEY_ENC_OPTS]);
+
+		if (key->enc_opts.len > sizeof(key->enc_opts.data))
+			return -EINVAL;
+
+		/* enc_opts is variable length.
+		 * If present ensure the value and mask are the same length.
+		 */
+		if (tb[TCA_FLOWER_KEY_ENC_OPTS_MASK] &&
+		    nla_len(tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]) != key->enc_opts.len)
+			return -EINVAL;
+
+		mask->enc_opts.len = key->enc_opts.len;
+		fl_set_key_val(tb, key->enc_opts.data, TCA_FLOWER_KEY_ENC_OPTS,
+			       mask->enc_opts.data,
+			       TCA_FLOWER_KEY_ENC_OPTS_MASK,
+			       key->enc_opts.len);
+	}
+
 	if (tb[TCA_FLOWER_KEY_FLAGS])
 		ret = fl_set_key_flags(tb, &key->control.flags, &mask->control.flags);
 
@@ -804,6 +832,8 @@ static void fl_init_dissector(struct cls_fl_head *head,
 			   enc_control);
 	FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
 			     FLOW_DISSECTOR_KEY_ENC_PORTS, enc_tp);
+	FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
+			     FLOW_DISSECTOR_KEY_ENC_OPTS, enc_opts);
 
 	skb_flow_dissector_init(&head->dissector, keys, cnt);
 }
@@ -1327,7 +1357,10 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, void *fh,
 			    TCA_FLOWER_KEY_ENC_UDP_DST_PORT,
 			    &mask->enc_tp.dst,
 			    TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK,
-			    sizeof(key->enc_tp.dst)))
+			    sizeof(key->enc_tp.dst)) ||
+	    fl_dump_key_val(skb, key->enc_opts.data, TCA_FLOWER_KEY_ENC_OPTS,
+			    mask->enc_opts.data, TCA_FLOWER_KEY_ENC_OPTS_MASK,
+			    key->enc_opts.len))
 		goto nla_put_failure;
 
 	if (fl_dump_key_flags(skb, key->control.flags, mask->control.flags))
-- 
2.1.4

^ permalink raw reply related

* [PATCH/RFC net-next 1/2] net/sched: add tunnel option support to act_tunnel_key
From: Simon Horman @ 2017-09-12 14:20 UTC (permalink / raw)
  To: Jiri Pirko, Jamal Hadi Salim, Cong Wang; +Cc: netdev, oss-drivers, Simon Horman
In-Reply-To: <1505226037-2758-1-git-send-email-simon.horman@netronome.com>

Allow setting tunnel options using the act_tunnel_key action.

Options are a bitwise maskable bytestring of up to 256 bytes.
Tunnel implementations may support less or more options,
or no options at all.

e.g.
 # ip link add name geneve0 type geneve dstport 0 external
 # tc qdisc del dev geneve0 ingress
 # tc filter add dev geneve0 protocol ip parent ffff: \
     flower \
       enc_src_ip 10.0.99.192 \
       enc_dst_ip 10.0.99.193 \
       enc_key_id 11 \
       enc_opts 0102800100800020/fffffffffffffff0 \
       ip_proto udp \
       action mirred egress redirect dev eth1

Signed-off-by: Simon Horman <simon.horman@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 include/uapi/linux/tc_act/tc_tunnel_key.h |  1 +
 net/sched/act_tunnel_key.c                | 26 +++++++++++++++++++++-----
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/include/uapi/linux/tc_act/tc_tunnel_key.h b/include/uapi/linux/tc_act/tc_tunnel_key.h
index afcd4be953e2..e0cb1121d132 100644
--- a/include/uapi/linux/tc_act/tc_tunnel_key.h
+++ b/include/uapi/linux/tc_act/tc_tunnel_key.h
@@ -35,6 +35,7 @@ enum {
 	TCA_TUNNEL_KEY_PAD,
 	TCA_TUNNEL_KEY_ENC_DST_PORT,	/* be16 */
 	TCA_TUNNEL_KEY_NO_CSUM,		/* u8 */
+	TCA_TUNNEL_KEY_ENC_OPTS,
 	__TCA_TUNNEL_KEY_MAX,
 };
 
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
index 30c96274c638..77b5890a48b9 100644
--- a/net/sched/act_tunnel_key.c
+++ b/net/sched/act_tunnel_key.c
@@ -66,6 +66,7 @@ static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
 	[TCA_TUNNEL_KEY_ENC_KEY_ID]   = { .type = NLA_U32 },
 	[TCA_TUNNEL_KEY_ENC_DST_PORT] = {.type = NLA_U16},
 	[TCA_TUNNEL_KEY_NO_CSUM]      = { .type = NLA_U8 },
+	[TCA_TUNNEL_KEY_ENC_OPTS]     = { .type = NLA_BINARY },
 };
 
 static int tunnel_key_init(struct net *net, struct nlattr *nla,
@@ -81,9 +82,11 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
 	struct tcf_tunnel_key *t;
 	bool exists = false;
 	__be16 dst_port = 0;
+	int opts_len = 0;
 	__be64 key_id;
 	__be16 flags;
 	int ret = 0;
+	u8 *opts;
 	int err;
 
 	if (!nla)
@@ -121,6 +124,11 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
 		if (tb[TCA_TUNNEL_KEY_ENC_DST_PORT])
 			dst_port = nla_get_be16(tb[TCA_TUNNEL_KEY_ENC_DST_PORT]);
 
+		if (tb[TCA_TUNNEL_KEY_ENC_OPTS]) {
+			opts = nla_data(tb[TCA_TUNNEL_KEY_ENC_OPTS]);
+			opts_len = nla_len(tb[TCA_TUNNEL_KEY_ENC_OPTS]);
+		}
+
 		if (tb[TCA_TUNNEL_KEY_ENC_IPV4_SRC] &&
 		    tb[TCA_TUNNEL_KEY_ENC_IPV4_DST]) {
 			__be32 saddr;
@@ -131,7 +139,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
 
 			metadata = __ip_tun_set_dst(saddr, daddr, 0, 0,
 						    dst_port, flags,
-						    key_id, 0);
+						    key_id, opts_len);
 		} else if (tb[TCA_TUNNEL_KEY_ENC_IPV6_SRC] &&
 			   tb[TCA_TUNNEL_KEY_ENC_IPV6_DST]) {
 			struct in6_addr saddr;
@@ -142,9 +150,13 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
 
 			metadata = __ipv6_tun_set_dst(&saddr, &daddr, 0, 0, dst_port,
 						      0, flags,
-						      key_id, 0);
+						      key_id, opts_len);
 		}
 
+		if (opts_len)
+			ip_tunnel_info_opts_set(&metadata->u.tun_info,
+						opts, opts_len);
+
 		if (!metadata) {
 			ret = -EINVAL;
 			goto err_out;
@@ -264,8 +276,9 @@ static int tunnel_key_dump(struct sk_buff *skb, struct tc_action *a,
 		goto nla_put_failure;
 
 	if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET) {
-		struct ip_tunnel_key *key =
-			&params->tcft_enc_metadata->u.tun_info.key;
+		struct ip_tunnel_info *info =
+			&params->tcft_enc_metadata->u.tun_info;
+		struct ip_tunnel_key *key = &info->key;
 		__be32 key_id = tunnel_id_to_key32(key->tun_id);
 
 		if (nla_put_be32(skb, TCA_TUNNEL_KEY_ENC_KEY_ID, key_id) ||
@@ -273,7 +286,10 @@ static int tunnel_key_dump(struct sk_buff *skb, struct tc_action *a,
 					      &params->tcft_enc_metadata->u.tun_info) ||
 		    nla_put_be16(skb, TCA_TUNNEL_KEY_ENC_DST_PORT, key->tp_dst) ||
 		    nla_put_u8(skb, TCA_TUNNEL_KEY_NO_CSUM,
-			       !(key->tun_flags & TUNNEL_CSUM)))
+			       !(key->tun_flags & TUNNEL_CSUM)) ||
+		    (info->options_len &&
+		     nla_put(skb, TCA_TUNNEL_KEY_ENC_OPTS, info->options_len,
+			     info + 1)))
 			goto nla_put_failure;
 	}
 
-- 
2.1.4

^ permalink raw reply related

* [PATCH/RFC net-next 0/2] net/sched: support tunnel options in cls_flower and act_tunnel_key
From: Simon Horman @ 2017-09-12 14:20 UTC (permalink / raw)
  To: Jiri Pirko, Jamal Hadi Salim, Cong Wang; +Cc: netdev, oss-drivers, Simon Horman

Allow the flower classifier to match on tunnel options and the
tunnel key action to set them.

Tunnel options are a bytestring of up to 256 bytes.
The flower classifier matching with an optional bitwise mask.
Tunnel implementations may support more or less options,
or none at all.

Simon Horman (2):
  net/sched: add tunnel option support to act_tunnel_key
  net/sched: allow flower to match tunnel options

 include/net/flow_dissector.h              | 13 ++++++++++++
 include/uapi/linux/pkt_cls.h              |  3 +++
 include/uapi/linux/tc_act/tc_tunnel_key.h |  1 +
 net/sched/act_tunnel_key.c                | 26 ++++++++++++++++++-----
 net/sched/cls_flower.c                    | 35 ++++++++++++++++++++++++++++++-
 5 files changed, 72 insertions(+), 6 deletions(-)

-- 
2.1.4

^ permalink raw reply

* [PATCH iproute2/net-next] tc: flower: support for matching MPLS labels
From: Simon Horman @ 2017-09-12 14:06 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Jiri Pirko, Jamal Hadi Salim, Cong Wang, netdev, oss-drivers

From: Benjamin LaHaise <benjamin.lahaise@netronome.com>

This patch adds support to the iproute2 tc filter command for matching MPLS
labels in the flower classifier.  The ability to match the Time To Live,
Bottom Of Stack, Traffic Control and Label fields are added as options to
the flower filter.

e.g.:
  tc filter add dev eth0 protocol 0x8847 parent ffff: \
    flower mpls_label 1 mpls_tc 2 mpls_ttl 3 mpls_bos 0 \
    action drop

Signed-off-by: Benjamin LaHaise <benjamin.lahaise@netronome.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
v1 [Simon Horman]
- added flower_print_opt portion to code
- added example to changelog
- revised manpage changes

v0 [Benjamin LaHaise]
---
 man/man8/tc-flower.8 | 37 +++++++++++++++++++--
 tc/f_flower.c        | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 127 insertions(+), 2 deletions(-)

diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8
index be46f0278b4f..88a23f544133 100644
--- a/man/man8/tc-flower.8
+++ b/man/man8/tc-flower.8
@@ -29,6 +29,14 @@ flower \- flow based traffic control filter
 .IR PRIORITY " | "
 .BR vlan_ethtype " { " ipv4 " | " ipv6 " | "
 .IR ETH_TYPE " } | "
+.B mpls_label
+.IR LABEL " | "
+.B mpls_tc
+.IR TC " | "
+.B mpls_bos
+.IR BOS " | "
+.B mpls_ttl
+.IR TTL " | "
 .BR ip_proto " { " tcp " | " udp " | " sctp " | " icmp " | " icmpv6 " | "
 .IR IP_PROTO " } | "
 .B ip_tos
@@ -119,6 +127,29 @@ may be either
 .BR ipv4 ", " ipv6
 or an unsigned 16bit value in hexadecimal format.
 .TP
+.BI mpls_label " LABEL"
+Match the label id in the outermost MPLS label stack entry.
+.I LABEL
+is an unsigned 20 bit value in decimal format.
+.TP
+.BI mpls_tc " TC"
+Match on the MPLS TC field, which is typically used for packet priority,
+in the outermost MPLS label stack entry.
+.I TC
+is an unsigned 3 bit value in decimal format.
+.TP
+.BI mpls_bos " BOS"
+Match on the MPLS Bottom Of Stack field in the outermost MPLS label stack
+entry.
+.I BOS
+is a 1 bit value in decimal format.
+.TP
+.BI mpls_ttl " TTL"
+Match on the MPLS Time To Live field in the outermost MPLS label stack
+entry.
+.I TTL
+is an unsigned 8 bit value in decimal format.
+.TP
 .BI ip_proto " IP_PROTO"
 Match on layer four protocol.
 .I IP_PROTO
@@ -226,8 +257,10 @@ to match on fragmented packets or not respectively.
 As stated above where applicable, matches of a certain layer implicitly depend
 on the matches of the next lower layer. Precisely, layer one and two matches
 (\fBindev\fR,  \fBdst_mac\fR and \fBsrc_mac\fR)
-have no dependency, layer three matches
-(\fBip_proto\fR, \fBdst_ip\fR, \fBsrc_ip\fR, \fBarp_tip\fR, \fBarp_sip\fR,
+have no dependency,
+MPLS and layer three matches
+(\fBmpls_label\fR, \fBmpls_tc\fR, \fBmpls_bos\fR, \fBmpls_ttl\fR,
+\fBip_proto\fR, \fBdst_ip\fR, \fBsrc_ip\fR, \fBarp_tip\fR, \fBarp_sip\fR,
 \fBarp_op\fR, \fBarp_tha\fR, \fBarp_sha\fR and \fBip_flags\fR)
 depend on the
 .B protocol
diff --git a/tc/f_flower.c b/tc/f_flower.c
index 934832e2bbe9..8c4bfb0d339e 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -19,6 +19,7 @@
 #include <linux/if_ether.h>
 #include <linux/ip.h>
 #include <linux/tc_act/tc_vlan.h>
+#include <linux/mpls.h>
 
 #include "utils.h"
 #include "tc_util.h"
@@ -55,6 +56,10 @@ static void explain(void)
 		"                       ip_proto [tcp | udp | sctp | icmp | icmpv6 | IP-PROTO ] |\n"
 		"                       ip_tos MASKED-IP_TOS |\n"
 		"                       ip_ttl MASKED-IP_TTL |\n"
+		"                       mpls_label LABEL |\n"
+		"                       mpls_tc TC |\n"
+		"                       mpls_bos BOS |\n"
+		"                       mpls_ttl TTL |\n"
 		"                       dst_ip PREFIX |\n"
 		"                       src_ip PREFIX |\n"
 		"                       dst_port PORT-NUMBER |\n"
@@ -672,6 +677,70 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
 						 &vlan_ethtype, n);
 			if (ret < 0)
 				return -1;
+		} else if (matches(*argv, "mpls_label") == 0) {
+			__u32 label;
+
+			NEXT_ARG();
+			if (eth_type != htons(ETH_P_MPLS_UC) &&
+			    eth_type != htons(ETH_P_MPLS_MC)) {
+				fprintf(stderr,
+					"Can't set \"mpls_label\" if ethertype isn't MPLS\n");
+				return -1;
+			}
+			ret = get_u32(&label, *argv, 10);
+			if (ret < 0 || label & ~(MPLS_LS_LABEL_MASK >> MPLS_LS_LABEL_SHIFT)) {
+				fprintf(stderr, "Illegal \"mpls_label\"\n");
+				return -1;
+			}
+			addattr32(n, MAX_MSG, TCA_FLOWER_KEY_MPLS_LABEL, label);
+		} else if (matches(*argv, "mpls_tc") == 0) {
+			__u8 tc;
+
+			NEXT_ARG();
+			if (eth_type != htons(ETH_P_MPLS_UC) &&
+			    eth_type != htons(ETH_P_MPLS_MC)) {
+				fprintf(stderr,
+					"Can't set \"mpls_tc\" if ethertype isn't MPLS\n");
+				return -1;
+			}
+			ret = get_u8(&tc, *argv, 10);
+			if (ret < 0 || tc & ~(MPLS_LS_TC_MASK >> MPLS_LS_TC_SHIFT)) {
+				fprintf(stderr, "Illegal \"mpls_tc\"\n");
+				return -1;
+			}
+			addattr8(n, MAX_MSG, TCA_FLOWER_KEY_MPLS_TC, tc);
+		} else if (matches(*argv, "mpls_bos") == 0) {
+			__u8 bos;
+
+			NEXT_ARG();
+			if (eth_type != htons(ETH_P_MPLS_UC) &&
+			    eth_type != htons(ETH_P_MPLS_MC)) {
+				fprintf(stderr,
+					"Can't set \"mpls_bos\" if ethertype isn't MPLS\n");
+				return -1;
+			}
+			ret = get_u8(&bos, *argv, 10);
+			if (ret < 0 || bos & ~(MPLS_LS_S_MASK >> MPLS_LS_S_SHIFT)) {
+				fprintf(stderr, "Illegal \"mpls_bos\"\n");
+				return -1;
+			}
+			addattr8(n, MAX_MSG, TCA_FLOWER_KEY_MPLS_BOS, bos);
+		} else if (matches(*argv, "mpls_ttl") == 0) {
+			__u8 ttl;
+
+			NEXT_ARG();
+			if (eth_type != htons(ETH_P_MPLS_UC) &&
+			    eth_type != htons(ETH_P_MPLS_MC)) {
+				fprintf(stderr,
+					"Can't set \"mpls_ttl\" if ethertype isn't MPLS\n");
+				return -1;
+			}
+			ret = get_u8(&ttl, *argv, 10);
+			if (ret < 0 || ttl & ~(MPLS_LS_TTL_MASK >> MPLS_LS_TTL_SHIFT)) {
+				fprintf(stderr, "Illegal \"mpls_ttl\"\n");
+				return -1;
+			}
+			addattr8(n, MAX_MSG, TCA_FLOWER_KEY_MPLS_TTL, ttl);
 		} else if (matches(*argv, "dst_mac") == 0) {
 			NEXT_ARG();
 			ret = flower_parse_eth_addr(*argv,
@@ -1163,6 +1232,24 @@ static void flower_print_masked_u8(FILE *f, const char *name,
 		fprintf(f, "/%d", mask);
 }
 
+static void flower_print_u8(FILE *f, const char *name, struct rtattr *attr)
+{
+	flower_print_masked_u8(f, name, attr, NULL, NULL);
+}
+
+static void flower_print_u32(FILE *f, const char *name, struct rtattr *attr)
+{
+	const char *value_str = NULL;
+	__u32 value;
+
+	if (!attr)
+		return;
+
+	value = rta_getattr_u32(attr);
+
+	fprintf(f, "\n  %s %d", name, value);
+}
+
 static void flower_print_arp_op(FILE *f, const char *name,
 				struct rtattr *op_attr,
 				struct rtattr *mask_attr)
@@ -1225,6 +1312,11 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
 	flower_print_ip_attr(f, "ip_ttl", tb[TCA_FLOWER_KEY_IP_TTL],
 			    tb[TCA_FLOWER_KEY_IP_TTL_MASK]);
 
+	flower_print_u32(f, "mpls_label", tb[TCA_FLOWER_KEY_MPLS_LABEL]);
+	flower_print_u8(f, "mpls_tc", tb[TCA_FLOWER_KEY_MPLS_TC]);
+	flower_print_u8(f, "mpls_bos", tb[TCA_FLOWER_KEY_MPLS_BOS]);
+	flower_print_u8(f, "mpls_ttl", tb[TCA_FLOWER_KEY_MPLS_TTL]);
+
 	flower_print_ip_addr(f, "dst_ip", eth_type,
 			     tb[TCA_FLOWER_KEY_IPV4_DST],
 			     tb[TCA_FLOWER_KEY_IPV4_DST_MASK],
-- 
2.1.4

^ permalink raw reply related

* Re: [patch net] mlxsw: spectrum: Prevent mirred-related crash on removal
From: Andrew Lunn @ 2017-09-12 13:34 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: netdev, davem, yuvalm, idosch, flokli, mlxsw
In-Reply-To: <20170912131550.GK2036@nanopsycho>

On Tue, Sep 12, 2017 at 03:15:50PM +0200, Jiri Pirko wrote:
> Tue, Sep 12, 2017 at 03:05:06PM CEST, andrew@lunn.ch wrote:
> >On Tue, Sep 12, 2017 at 08:50:53AM +0200, Jiri Pirko wrote:
> >> From: Yuval Mintz <yuvalm@mellanox.com>
> >
> >Hi Jiri, Yuval
> >
> >s/mirred/mirrored/g
> 
> Actually, the name of the tc action is indeed "mirred".

:-(

	Andrew

^ permalink raw reply

* Re: [patch net] mlxsw: spectrum: Prevent mirred-related crash on removal
From: Jiri Pirko @ 2017-09-12 13:15 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, davem, yuvalm, idosch, flokli, mlxsw
In-Reply-To: <20170912130506.GB32598@lunn.ch>

Tue, Sep 12, 2017 at 03:05:06PM CEST, andrew@lunn.ch wrote:
>On Tue, Sep 12, 2017 at 08:50:53AM +0200, Jiri Pirko wrote:
>> From: Yuval Mintz <yuvalm@mellanox.com>
>
>Hi Jiri, Yuval
>
>s/mirred/mirrored/g

Actually, the name of the tc action is indeed "mirred".
See net/sched/act_mirred.c

^ permalink raw reply

* Re: [patch net] mlxsw: spectrum: Prevent mirred-related crash on removal
From: Andrew Lunn @ 2017-09-12 13:05 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: netdev, davem, yuvalm, idosch, flokli, mlxsw
In-Reply-To: <20170912065053.1392-1-jiri@resnulli.us>

On Tue, Sep 12, 2017 at 08:50:53AM +0200, Jiri Pirko wrote:
> From: Yuval Mintz <yuvalm@mellanox.com>

Hi Jiri, Yuval

s/mirred/mirrored/g

	Andrew

^ permalink raw reply

* [PATCH/RFC net-next] ravb: RX checksum offload
From: Simon Horman @ 2017-09-12 13:04 UTC (permalink / raw)
  To: David Miller, Sergei Shtylyov
  Cc: Magnus Damm, netdev, linux-renesas-soc, Simon Horman

Add support for RX checksum offload. This is enabled by default and
may be disabled and re-enabled using ethtool:

 # ethtool -K eth0 rx off
 # ethtool -K eth0 rx on

The RAVB provides a simple checksumming scheme which appears to be
completely compatible with CHECKSUM_COMPLETE: a 1's complement sum of
all packet data after the L2 header is appended to packet data; this may
be trivially read by the driver and used to update the skb accordingly.

In terms of performance throughput is close to gigabit line-rate both with
and without RX checksum offload enabled. Perf output, however, appears to
indicate that significantly less time is spent in do_csum(). This is as
expected.

Test results with RX checksum offload enabled:
 # /usr/bin/perf_3.16 record -o /run/perf.data -a netperf -t TCP_MAERTS -H 10.4.3.162
 MIGRATED TCP MAERTS TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.4.3.162 () port 0 AF_INET : demo
 enable_enobufs failed: getprotobyname
 Recv   Send    Send
 Socket Socket  Message  Elapsed
 Size   Size    Size     Time     Throughput
 bytes  bytes   bytes    secs.    10^6bits/sec

  87380  16384  16384    10.00     938.78
 [ perf record: Woken up 14 times to write data ]
 [ perf record: Captured and wrote 3.524 MB /run/perf.data (~153957 samples) ]

 Summary of output of perf report:
    19.49%      ksoftirqd/0  [kernel.kallsyms]  [k] _raw_spin_unlock_irqrestore
     9.88%      ksoftirqd/0  [kernel.kallsyms]  [k] __pi_memcpy
     7.33%      ksoftirqd/0  [kernel.kallsyms]  [k] skb_put
     7.00%      ksoftirqd/0  [kernel.kallsyms]  [k] ravb_poll
     3.89%      ksoftirqd/0  [kernel.kallsyms]  [k] dev_gro_receive
     3.65%          netperf  [kernel.kallsyms]  [k] __arch_copy_to_user
     3.43%          swapper  [kernel.kallsyms]  [k] arch_cpu_idle
     2.77%          swapper  [kernel.kallsyms]  [k] tick_nohz_idle_enter
     1.85%      ksoftirqd/0  [kernel.kallsyms]  [k] __netdev_alloc_skb
     1.80%          swapper  [kernel.kallsyms]  [k] _raw_spin_unlock_irq
     1.64%      ksoftirqd/0  [kernel.kallsyms]  [k] __slab_alloc.isra.79
     1.62%      ksoftirqd/0  [kernel.kallsyms]  [k] __pi___inval_cache_range

Test results without RX checksum offload enabled:
 # /usr/bin/perf_3.16 record -o /run/perf.data -a netperf -t TCP_MAERTS -H 10.4.3.162
 MIGRATED TCP MAERTS TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.4.3.162 () port 0 AF_INET : demo
 enable_enobufs failed: getprotobyname
 Recv   Send    Send
 Socket Socket  Message  Elapsed
 Size   Size    Size     Time     Throughput
 bytes  bytes   bytes    secs.    10^6bits/sec

  87380  16384  16384    10.00     941.09
 [ perf record: Woken up 14 times to write data ]
 [ perf record: Captured and wrote 3.411 MB /run/perf.data (~149040 samples) ]

 Summary of output of perf report:
   17.50%    ksoftirqd/0  [kernel.kallsyms]  [k] _raw_spin_unlock_irqrestore
    10.60%    ksoftirqd/0  [kernel.kallsyms]  [k] __pi_memcpy
     7.91%    ksoftirqd/0  [kernel.kallsyms]  [k] skb_put
     6.95%    ksoftirqd/0  [kernel.kallsyms]  [k] do_csum
     6.22%    ksoftirqd/0  [kernel.kallsyms]  [k] ravb_poll
     3.84%    ksoftirqd/0  [kernel.kallsyms]  [k] dev_gro_receive
     2.53%        netperf  [kernel.kallsyms]  [k] __arch_copy_to_user
     2.53%        swapper  [kernel.kallsyms]  [k] arch_cpu_idle
     2.27%        swapper  [kernel.kallsyms]  [k] tick_nohz_idle_enter
     1.90%    ksoftirqd/0  [kernel.kallsyms]  [k] __pi___inval_cache_range
     1.90%    ksoftirqd/0  [kernel.kallsyms]  [k] __netdev_alloc_skb
     1.52%    ksoftirqd/0  [kernel.kallsyms]  [k] __slab_alloc.isra.79

Above results collected on an R-Car Gen 3 Salvator-X/r8a7796 ES1.0.
Also tested on a R-Car Gen 3 Salvator-X/r8a7795 ES1.0.

By inspection this also appears to be compatible with the ravb found
on R-Car Gen 2 SoCs, however, this patch is currently untested on such
hardware.

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 drivers/net/ethernet/renesas/ravb_main.c | 58 +++++++++++++++++++++++++++++++-
 1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index fdf30bfa403b..7c6438cd7de7 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -403,8 +403,9 @@ static void ravb_emac_init(struct net_device *ndev)
 	/* Receive frame limit set register */
 	ravb_write(ndev, ndev->mtu + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN, RFLR);
 
-	/* PAUSE prohibition */
+	/* EMAC Mode: PAUSE prohibition; Duplex; RX Checksum; TX; RX */
 	ravb_write(ndev, ECMR_ZPF | (priv->duplex ? ECMR_DM : 0) |
+		   (ndev->features & NETIF_F_RXCSUM ? ECMR_RCSC : 0) |
 		   ECMR_TE | ECMR_RE, ECMR);
 
 	ravb_set_rate(ndev);
@@ -520,6 +521,19 @@ static void ravb_get_tx_tstamp(struct net_device *ndev)
 	}
 }
 
+static void ravb_rx_csum(struct sk_buff *skb)
+{
+	u8 *hw_csum;
+
+	/* The hardware checksum is 2 bytes appended to packet data */
+	if (unlikely(skb->len < 2))
+		return;
+	hw_csum = skb_tail_pointer(skb) - 2;
+	skb->csum = csum_unfold((__force __sum16)get_unaligned_le16(hw_csum));
+	skb->ip_summed = CHECKSUM_COMPLETE;
+	skb_trim(skb, skb->len - 2);
+}
+
 /* Packet receive function for Ethernet AVB */
 static bool ravb_rx(struct net_device *ndev, int *quota, int q)
 {
@@ -587,8 +601,11 @@ static bool ravb_rx(struct net_device *ndev, int *quota, int q)
 				ts.tv_nsec = le32_to_cpu(desc->ts_n);
 				shhwtstamps->hwtstamp = timespec64_to_ktime(ts);
 			}
+
 			skb_put(skb, pkt_len);
 			skb->protocol = eth_type_trans(skb, ndev);
+			if (ndev->features & NETIF_F_RXCSUM)
+				ravb_rx_csum(skb);
 			napi_gro_receive(&priv->napi[q], skb);
 			stats->rx_packets++;
 			stats->rx_bytes += pkt_len;
@@ -1842,6 +1859,41 @@ static int ravb_do_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
 	return phy_mii_ioctl(phydev, req, cmd);
 }
 
+static void ravb_set_rx_csum(struct net_device *ndev, bool enable)
+{
+	struct ravb_private *priv = netdev_priv(ndev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	/* Disable TX and RX */
+	ravb_rcv_snd_disable(ndev);
+
+	/* Modify RX Checksum setting */
+	if (enable)
+		ravb_modify(ndev, ECMR, 0, ECMR_RCSC);
+	else
+		ravb_modify(ndev, ECMR, ECMR_RCSC, 0);
+
+	/* Enable TX and RX */
+	ravb_rcv_snd_enable(ndev);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int ravb_set_features(struct net_device *ndev,
+			     netdev_features_t features)
+{
+	netdev_features_t changed = ndev->features ^ features;
+
+	if (changed & NETIF_F_RXCSUM)
+		ravb_set_rx_csum(ndev, features & NETIF_F_RXCSUM);
+
+	ndev->features = features;
+
+	return 0;
+}
+
 static const struct net_device_ops ravb_netdev_ops = {
 	.ndo_open		= ravb_open,
 	.ndo_stop		= ravb_close,
@@ -1853,6 +1905,7 @@ static const struct net_device_ops ravb_netdev_ops = {
 	.ndo_do_ioctl		= ravb_do_ioctl,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_set_features	= ravb_set_features,
 };
 
 /* MDIO bus init function */
@@ -2004,6 +2057,9 @@ static int ravb_probe(struct platform_device *pdev)
 	if (!ndev)
 		return -ENOMEM;
 
+	ndev->features |= NETIF_F_RXCSUM;
+	ndev->hw_features |= ndev->features;
+
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_get_sync(&pdev->dev);
 
-- 
2.1.4

^ permalink raw reply related

* RE: [PATCH v2 net 1/3] lan78xx: Fix for eeprom read/write when device auto suspend
From: Nisar.Sayed @ 2017-09-12 13:01 UTC (permalink / raw)
  To: andrew; +Cc: davem, UNGLinuxDriver, netdev
In-Reply-To: <20170911202428.GB5983@lunn.ch>

> > From: Nisar Sayed <Nisar.Sayed@microchip.com>
> >
> > Fix for eeprom read/write when device auto suspend
> >
> > Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to
> > 10/100/1000 Ethernet device driver")
> > Signed-off-by: Nisar Sayed <Nisar.Sayed@microchip.com>
> > ---
> >  drivers/net/usb/lan78xx.c | 22 ++++++++++++++++++----
> >  1 file changed, 18 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
> > index b99a7fb..baf91c7 100644
> > --- a/drivers/net/usb/lan78xx.c
> > +++ b/drivers/net/usb/lan78xx.c
> > @@ -1265,30 +1265,44 @@ static int lan78xx_ethtool_get_eeprom(struct
> net_device *netdev,
> >  				      struct ethtool_eeprom *ee, u8 *data)  {
> >  	struct lan78xx_net *dev = netdev_priv(netdev);
> > +	int ret = -EINVAL;
> > +
> > +	if (usb_autopm_get_interface(dev->intf) < 0)
> > +		return ret;
> 
> Hi Nisar
> 
> It is better to do
> 
>    ret = usb_autopm_get_interface(dev->intf;
>    if (ret)
>         return ret;
> 
> i.e. use the error code usb_autopm_get_interface() gives you.
> 
> >  	ee->magic = LAN78XX_EEPROM_MAGIC;
> >
> > -	return lan78xx_read_raw_eeprom(dev, ee->offset, ee->len, data);
> > +	ret = lan78xx_read_raw_eeprom(dev, ee->offset, ee->len, data);
> > +
> > +	usb_autopm_put_interface(dev->intf);
> > +
> > +	return ret;
> >  }
> >
> >  static int lan78xx_ethtool_set_eeprom(struct net_device *netdev,
> >  				      struct ethtool_eeprom *ee, u8 *data)  {
> >  	struct lan78xx_net *dev = netdev_priv(netdev);
> > +	int ret = -EINVAL;
> > +
> > +	if (usb_autopm_get_interface(dev->intf) < 0)
> > +		return ret;
> 
> Same here.
> 
>      Andrew

Thanks Andrew, will update it.

- Nisar

^ permalink raw reply

* Re: [PATCH net-next v2 1/2] net: phy: realtek: rename RTL8211F_PAGE_SELECT to RTL821x_PAGE_SELECT
From: Andrew Lunn @ 2017-09-12 12:57 UTC (permalink / raw)
  To: Kunihiko Hayashi; +Cc: Florian Fainelli, netdev, Jassi Brar
In-Reply-To: <1505210076-32311-1-git-send-email-hayashi.kunihiko@socionext.com>

On Tue, Sep 12, 2017 at 06:54:35PM +0900, Kunihiko Hayashi wrote:
> This renames the definition of page select register from
> RTL8211F_PAGE_SELECT to RTL821x_PAGE_SELECT to use it across models.
> 
> Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply

* [PATCH] w90p910_ether: include linux/interrupt.h
From: Arnd Bergmann @ 2017-09-12 12:31 UTC (permalink / raw)
  To: Wan ZongShun
  Cc: linux-arm-kernel, netdev, David S. Miller, Arnd Bergmann,
	linux-kernel

A randconfig build caused a compile failure:

drivers/net/ethernet/nuvoton/w90p910_ether.c: In function 'w90p910_ether_close':
drivers/net/ethernet/nuvoton/w90p910_ether.c:580:2: error: implicit declaration of function 'free_irq'; did you mean 'free_uid'? [-Werror=implicit-function-declaration]

Adding the correct include fixes the problem.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/net/ethernet/nuvoton/w90p910_ether.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/nuvoton/w90p910_ether.c b/drivers/net/ethernet/nuvoton/w90p910_ether.c
index 89ab786da25f..4a67c55aa9f1 100644
--- a/drivers/net/ethernet/nuvoton/w90p910_ether.c
+++ b/drivers/net/ethernet/nuvoton/w90p910_ether.c
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/mii.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
-- 
2.9.0

^ permalink raw reply related

* [PATCH net] net: bonding: fix tlb_dynamic_lb default value
From: Nikolay Aleksandrov @ 2017-09-12 12:10 UTC (permalink / raw)
  To: netdev; +Cc: j.vosburgh, vfalico, andy, maheshb, Nikolay Aleksandrov

Commit 8b426dc54cf4 ("bonding: remove hardcoded value") changed the
default value for tlb_dynamic_lb which lead to either broken ALB mode
(since tlb_dynamic_lb can be changed only in TLB) or setting TLB mode
with tlb_dynamic_lb equal to 0.
The first issue was recently fixed by setting tlb_dynamic_lb to 1 always
when switching to ALB mode, but the default value is still wrong and
we'll enter TLB mode with tlb_dynamic_lb equal to 0 if the mode is
changed via netlink or sysfs. In order to restore the previous behaviour
and default value simply remove the mode check around the default param
initialization for tlb_dynamic_lb which will always set it to 1 as
before.

Fixes: 8b426dc54cf4 ("bonding: remove hardcoded value")
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
 drivers/net/bonding/bond_main.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index fc63992ab0e0..c99dc59d729b 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4289,7 +4289,7 @@ static int bond_check_params(struct bond_params *params)
 	int bond_mode	= BOND_MODE_ROUNDROBIN;
 	int xmit_hashtype = BOND_XMIT_POLICY_LAYER2;
 	int lacp_fast = 0;
-	int tlb_dynamic_lb = 0;
+	int tlb_dynamic_lb;
 
 	/* Convert string parameters. */
 	if (mode) {
@@ -4601,16 +4601,13 @@ static int bond_check_params(struct bond_params *params)
 	}
 	ad_user_port_key = valptr->value;
 
-	if ((bond_mode == BOND_MODE_TLB) || (bond_mode == BOND_MODE_ALB)) {
-		bond_opt_initstr(&newval, "default");
-		valptr = bond_opt_parse(bond_opt_get(BOND_OPT_TLB_DYNAMIC_LB),
-					&newval);
-		if (!valptr) {
-			pr_err("Error: No tlb_dynamic_lb default value");
-			return -EINVAL;
-		}
-		tlb_dynamic_lb = valptr->value;
+	bond_opt_initstr(&newval, "default");
+	valptr = bond_opt_parse(bond_opt_get(BOND_OPT_TLB_DYNAMIC_LB), &newval);
+	if (!valptr) {
+		pr_err("Error: No tlb_dynamic_lb default value");
+		return -EINVAL;
 	}
+	tlb_dynamic_lb = valptr->value;
 
 	if (lp_interval == 0) {
 		pr_warn("Warning: ip_interval must be between 1 and %d, so it was reset to %d\n",
-- 
2.1.4

^ permalink raw reply related

* Re: ipset losing entries on its own
From: Akshat Kakkar @ 2017-09-12 11:54 UTC (permalink / raw)
  To: Denys Fedoryshchenko; +Cc: netdev, netdev-owner
In-Reply-To: <CAA5aLPgM9=VU4Cysy-LtN-uXPqvG00X2v8MP9EM5RtPVB6tGvw@mail.gmail.com>

can somebody throw more light on this? How it is possible (without a
bug) that for exactly same set of IPs, at time IPSET HASHSIZE remains
at 1024 and at times it increases to 2048?

As a workaround I am running the show setting HASHSIZE as 16384 at
times of IPSET creation itself, and till now (its more than 4 days)
the issue has not repeated.

But this need to be addressed, right?

^ permalink raw reply

* Re: Subject: [PATCH] vxlan: only reduce known arp boardcast request to support, virtual IP
From: Jiri Benc @ 2017-09-12 11:51 UTC (permalink / raw)
  To: oc; +Cc: davem, Linux Kernel Network Developers
In-Reply-To: <2c1bfd7d-5fe7-d492-2396-71deaeb14244@yunify.com>

On Tue, 12 Sep 2017 11:26:49 +0800, oc wrote:
> The purpose of vxlan arp reduce feature is to reply the boardcast
> arp request in vtep instead of sending it out to save traffic.
> The current implemention drops arp packet, if the ip cannot be
> found in neigh table. In the case of virtual IP address, user
> defines IP address without management from SDN controller. The IP
> address does not exist in neigh table, so the arp boardcast request
> from a client can not be sent to the server who owns the virtual IP
> address.
> 
> This patch allow the arp request to be sent out if:
> 1. not arp boardcast request
> 2. cannot be found in neigh table
> 3. arp record status is not NUD_CONNECTED
> 
> The user defined of virtual IP address works while arp reduce still
> suppress the arp boardcast for IP address managed by SDN controller
> with this patch.

Your patch is whitespace damaged, does not conform to the kernel coding
style and the email does not have your full name in the From header.

As for the patch itself, you're changing existing functionality that
people may depend on and thus a new config option is needed to enable
the behavior.

 Jiri

^ permalink raw reply

* [PATCH] vti: fix NULL dereference in xfrm_input()
From: Alexey Kodanev @ 2017-09-12 11:53 UTC (permalink / raw)
  To: netdev; +Cc: Steffen Klassert, Herbert Xu, David Miller, Alexey Kodanev

Can be reproduced with LTP tests:
  # icmp-uni-vti.sh -p ah -a sha256 -m tunnel -S fffffffe -k 1 -s 10

IPv4:
  RIP: 0010:xfrm_input+0x7f9/0x870
  ...
  Call Trace:
  <IRQ>
  vti_input+0xaa/0x110 [ip_vti]
  ? skb_free_head+0x21/0x40
  vti_rcv+0x33/0x40 [ip_vti]
  xfrm4_ah_rcv+0x33/0x60
  ip_local_deliver_finish+0x94/0x1e0
  ip_local_deliver+0x6f/0xe0
  ? ip_route_input_noref+0x28/0x50
  ...

  # icmp-uni-vti.sh -6 -p ah -a sha256 -m tunnel -S fffffffe -k 1 -s 10
IPv6:
  RIP: 0010:xfrm_input+0x7f9/0x870
  ...
  Call Trace:
  <IRQ>
  xfrm6_rcv_tnl+0x3c/0x40
  vti6_rcv+0xd5/0xe0 [ip6_vti]
  xfrm6_ah_rcv+0x33/0x60
  ip6_input_finish+0xee/0x460
  ip6_input+0x3f/0xb0
  ip6_rcv_finish+0x45/0xa0
  ipv6_rcv+0x34b/0x540

xfrm_input() invokes xfrm_rcv_cb() -> vti_rcv_cb(), the last callback
might call skb_scrub_packet(), which in turn can reset secpath.

Fix it by adding a check that skb->sp is not NULL.

Fixes: 7e9e9202bccc ("xfrm: Clear RX SKB secpath xfrm_offload")
Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
 net/xfrm/xfrm_input.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 2515cd2..8ac9d32 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -429,7 +429,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 	nf_reset(skb);
 
 	if (decaps) {
-		skb->sp->olen = 0;
+		if (skb->sp)
+			skb->sp->olen = 0;
 		skb_dst_drop(skb);
 		gro_cells_receive(&gro_cells, skb);
 		return 0;
@@ -440,7 +441,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 
 		err = x->inner_mode->afinfo->transport_finish(skb, xfrm_gro || async);
 		if (xfrm_gro) {
-			skb->sp->olen = 0;
+			if (skb->sp)
+				skb->sp->olen = 0;
 			skb_dst_drop(skb);
 			gro_cells_receive(&gro_cells, skb);
 			return err;
-- 
1.7.1

^ permalink raw reply related

* [PATCH] qed: remove unnecessary call to memset
From: Himanshu Jha @ 2017-09-12 11:19 UTC (permalink / raw)
  To: Yuval.Mintz
  Cc: Ariel.Elior, everest-linux-l2, netdev, linux-kernel, Himanshu Jha

call to memset to assign 0 value immediately after allocating
memory with kzalloc is unnecesaary as kzalloc allocates the memory
filled with 0 value.

Semantic patch used to resolve this issue:

@@
expression e,e2; constant c;
statement S;
@@

  e = kzalloc(e2, c);
  if(e == NULL) S
- memset(e, 0, e2);

Signed-off-by: Himanshu Jha <himanshujha199640@gmail.com>
---
 drivers/net/ethernet/qlogic/qed/qed_dcbx.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
index eaca457..8f6ccc0 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
@@ -1244,7 +1244,6 @@ int qed_dcbx_get_config_params(struct qed_hwfn *p_hwfn,
 	if (!dcbx_info)
 		return -ENOMEM;
 
-	memset(dcbx_info, 0, sizeof(*dcbx_info));
 	rc = qed_dcbx_query_params(p_hwfn, dcbx_info, QED_DCBX_OPERATIONAL_MIB);
 	if (rc) {
 		kfree(dcbx_info);
-- 
2.7.4

^ permalink raw reply related

* Re: broken vlan support on Realtek RTL8111/8168/8411 rev 9
From: Benoit Panizzon @ 2017-09-12 11:07 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev
In-Reply-To: <20170911222325.GA23162@electric-eye.fr.zoreil.com>

Hi Francois

> ethtool -K eth0 rxvlan off

Thank you, that did the trick, vlan tags are not correctly passed on
and not set to vlan 0 with rxvlan turned off.
 
> For my reward, please send a complete dmesg where the messages from
> the vanilla r8169 module appear for the rev 09 card (r81..f ?). I
> won't dig it right now.

Yes, the 'f' variant:

[    1.035203] r8169 Gigabit Ethernet driver 2.3LK-NAPI loaded
[    1.035262] r8169 0000:03:00.0: setting latency timer to 64
[    1.035348] r8169 0000:03:00.0: irq 41 for MSI/MSI-X
[    1.035634] r8169 0000:03:00.0: eth0: RTL8168f/8111f at 0xffffc90000c28000, c8:60:00:dd:f8:6c, XID 08000800 IRQ 41
[    1.035637] r8169 0000:03:00.0: eth0: jumbo features [frames: 9200 bytes, tx checksumming: ko]
[   10.403921] r8169 0000:03:00.0: firmware: agent loaded rtl_nic/rtl8168f-1.fw into memory

Linux pulsar 4.9.0-3-amd64 #1 SMP Debian 4.9.30-2+deb9u2 (2017-06-26) x86_64 GNU/Linux

624831688e25aa47fa84c30c045fcae3  /lib/firmware/rtl_nic/rtl8168f-1.fw

Firmware Bug or Hardware Problem?

-Benoît Panizzon-
-- 
I m p r o W a r e   A G    -    Leiter Commerce Kunden
______________________________________________________

Zurlindenstrasse 29             Tel  +41 61 826 93 00
CH-4133 Pratteln                Fax  +41 61 826 93 01
Schweiz                         Web  http://www.imp.ch
______________________________________________________

^ permalink raw reply

* Re: [Patch net v3 3/3] net_sched: carefully handle tcf_block_put()
From: Jiri Pirko @ 2017-09-12 10:43 UTC (permalink / raw)
  To: Cong Wang; +Cc: netdev, jiri, jakub.kicinski, jhs
In-Reply-To: <20170911233332.7594-4-xiyou.wangcong@gmail.com>

Tue, Sep 12, 2017 at 01:33:32AM CEST, xiyou.wangcong@gmail.com wrote:
>As pointed out by Jiri, there is still a race condition between
>tcf_block_put() and tcf_chain_destroy() in a RCU callback. There
>is no way to make it correct without proper locking or synchronization,
>because both operate on a shared list.
>
>Locking is hard, because the only lock we can pick here is a spinlock,
>however, in tc_dump_tfilter() we iterate this list with a sleeping
>function called (tcf_chain_dump()), which makes using a lock to protect
>chain_list almost impossible.
>
>Jiri suggested the idea of holding a refcnt before flushing, this works
>because it guarantees us there would be no parallel tcf_chain_destroy()
>during the loop, therefore the race condition is gone. But we have to
>be very careful with proper synchronization with RCU callbacks.
>
>Suggested-by: Jiri Pirko <jiri@mellanox.com>
>Cc: Jamal Hadi Salim <jhs@mojatatu.com>
>Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>

Acked-by: Jiri Pirko <jiri@mellanox.com>

Thanks!

^ permalink raw reply

* Re: [Patch net v3 2/3] net_sched: fix reference counting of tc filter chain
From: Jiri Pirko @ 2017-09-12 10:43 UTC (permalink / raw)
  To: Cong Wang; +Cc: netdev, jiri, jakub.kicinski, jhs
In-Reply-To: <20170911233332.7594-3-xiyou.wangcong@gmail.com>

Tue, Sep 12, 2017 at 01:33:31AM CEST, xiyou.wangcong@gmail.com wrote:
>This patch fixes the following ugliness of tc filter chain refcnt:
>
>a) tp proto should hold a refcnt to the chain too. This significantly
>   simplifies the logic.
>
>b) Chain 0 is no longer special, it is created with refcnt=1 like any
>   other chains. All the ugliness in tcf_chain_put() can be gone!
>
>c) No need to handle the flushing oddly, because block still holds
>   chain 0, it can not be released, this guarantees block is the last
>   user.
>
>d) The race condition with RCU callbacks is easier to handle with just
>   a rcu_barrier(). Much easier to understand, nothing to hide. Thanks
>   to the previous patch. Please see also the comments in code.
>
>e) Make the code understandable by humans, much less error-prone.
>
>Fixes: 744a4cf63e52 ("net: sched: fix use after free when tcf_chain_destroy is called multiple times")
>Fixes: 5bc1701881e3 ("net: sched: introduce multichain support for filters")
>Cc: Jiri Pirko <jiri@mellanox.com>
>Cc: Jamal Hadi Salim <jhs@mojatatu.com>
>Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>

Looking good to me. Thanks!

Acked-by: Jiri Pirko <jiri@mellanox.com>

^ permalink raw reply

* Re: [Patch net v3 1/3] net_sched: get rid of tcfa_rcu
From: Jiri Pirko @ 2017-09-12 10:40 UTC (permalink / raw)
  To: Cong Wang; +Cc: netdev, jiri, jakub.kicinski, jhs, Eric Dumazet
In-Reply-To: <20170912094215.GB2036@nanopsycho>

Tue, Sep 12, 2017 at 11:42:15AM CEST, jiri@resnulli.us wrote:
>Tue, Sep 12, 2017 at 01:33:30AM CEST, xiyou.wangcong@gmail.com wrote:
>>gen estimator has been rewritten in commit 1c0d32fde5bd
>>("net_sched: gen_estimator: complete rewrite of rate estimators"),
>>the caller is no longer needed to wait for a grace period.
>>So this patch gets rid of it.
>>
>>This also completely closes a race condition between action free
>>path and filter chain add/remove path for the following patch.
>>Because otherwise the nested RCU callback can't be caught by
>>rcu_barrier().
>>
>>Please see also the comments in code.
>
>Looks like this is causing a null pointer dereference bug for me, 100%
>of the time. Just add and remove any rule with action and you get:
>

[...]

>
>Looks like you need to save owner of the module before you call
>__tcf_idr_release so you can later on use it for module_put

This patch helps:

diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index fcd7dc7..de73e71 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -514,13 +514,15 @@ EXPORT_SYMBOL(tcf_action_exec);
 
 int tcf_action_destroy(struct list_head *actions, int bind)
 {
+	const struct tc_action_ops *ops;
 	struct tc_action *a, *tmp;
 	int ret = 0;
 
 	list_for_each_entry_safe(a, tmp, actions, list) {
+		ops = a->ops;
 		ret = __tcf_idr_release(a, bind, true);
 		if (ret == ACT_P_DELETED)
-			module_put(a->ops->owner);
+			module_put(ops->owner);
 		else if (ret < 0)
 			return ret;
 	}

^ permalink raw reply related

* [PATCH] ipv4: Namespaceify tcp_fastopen knob
From: Haishuang Yan @ 2017-09-12 10:30 UTC (permalink / raw)
  To: David S. Miller, Alexey Kuznetsov, Eric Dumazet
  Cc: netdev, linux-kernel, Haishuang Yan

Different namespace application might require enable TCP Fast Open
feature independently of the host.

Reported-by: Luca BRUNO <lucab@debian.org>
Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
---
 include/net/netns/ipv4.h   |  2 ++
 include/net/tcp.h          |  1 -
 net/ipv4/af_inet.c         |  7 ++++---
 net/ipv4/sysctl_net_ipv4.c | 42 +++++++++++++++++++++---------------------
 net/ipv4/tcp.c             |  4 ++--
 net/ipv4/tcp_fastopen.c    | 13 ++++++-------
 net/ipv4/tcp_ipv4.c        |  2 ++
 samples/bpf/test_ipip.sh   |  2 ++
 8 files changed, 39 insertions(+), 34 deletions(-)

diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 305e031..ea0953b 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -128,6 +128,8 @@ struct netns_ipv4 {
 	struct inet_timewait_death_row tcp_death_row;
 	int sysctl_max_syn_backlog;
 	int sysctl_tcp_max_orphans;
+	int sysctl_tcp_fastopen;
+	unsigned int sysctl_tcp_fastopen_blackhole_timeout;
 
 #ifdef CONFIG_NET_L3_MASTER_DEV
 	int sysctl_udp_l3mdev_accept;
diff --git a/include/net/tcp.h b/include/net/tcp.h
index ac2d998..e4cc0dd 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -240,7 +240,6 @@
 
 
 /* sysctl variables for tcp */
-extern int sysctl_tcp_fastopen;
 extern int sysctl_tcp_retrans_collapse;
 extern int sysctl_tcp_stdurg;
 extern int sysctl_tcp_rfc1337;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index e31108e..309b849 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -195,7 +195,7 @@ int inet_listen(struct socket *sock, int backlog)
 {
 	struct sock *sk = sock->sk;
 	unsigned char old_state;
-	int err;
+	int err, tcp_fastopen;
 
 	lock_sock(sk);
 
@@ -217,8 +217,9 @@ int inet_listen(struct socket *sock, int backlog)
 		 * because the socket was in TCP_LISTEN state previously but
 		 * was shutdown() rather than close().
 		 */
-		if ((sysctl_tcp_fastopen & TFO_SERVER_WO_SOCKOPT1) &&
-		    (sysctl_tcp_fastopen & TFO_SERVER_ENABLE) &&
+		tcp_fastopen =  sock_net(sk)->ipv4.sysctl_tcp_fastopen;
+		if ((tcp_fastopen & TFO_SERVER_WO_SOCKOPT1) &&
+		    (tcp_fastopen & TFO_SERVER_ENABLE) &&
 		    !inet_csk(sk)->icsk_accept_queue.fastopenq.max_qlen) {
 			fastopen_queue_tune(sk, backlog);
 			tcp_fastopen_init_key_once(true);
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 4f26c8d3..30ebeb9 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -394,27 +394,6 @@ static int proc_tcp_available_ulp(struct ctl_table *ctl,
 		.proc_handler	= proc_dointvec
 	},
 	{
-		.procname	= "tcp_fastopen",
-		.data		= &sysctl_tcp_fastopen,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
-	},
-	{
-		.procname	= "tcp_fastopen_key",
-		.mode		= 0600,
-		.maxlen		= ((TCP_FASTOPEN_KEY_LENGTH * 2) + 10),
-		.proc_handler	= proc_tcp_fastopen_key,
-	},
-	{
-		.procname	= "tcp_fastopen_blackhole_timeout_sec",
-		.data		= &sysctl_tcp_fastopen_blackhole_timeout,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_tfo_blackhole_detect_timeout,
-		.extra1		= &zero,
-	},
-	{
 		.procname	= "tcp_abort_on_overflow",
 		.data		= &sysctl_tcp_abort_on_overflow,
 		.maxlen		= sizeof(int),
@@ -1085,6 +1064,27 @@ static int proc_tcp_available_ulp(struct ctl_table *ctl,
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec
 	},
+	{
+		.procname	= "tcp_fastopen",
+		.data		= &init_net.ipv4.sysctl_tcp_fastopen,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec,
+	},
+	{
+		.procname	= "tcp_fastopen_key",
+		.mode		= 0600,
+		.maxlen		= ((TCP_FASTOPEN_KEY_LENGTH * 2) + 10),
+		.proc_handler	= proc_tcp_fastopen_key,
+	},
+	{
+		.procname	= "tcp_fastopen_blackhole_timeout_sec",
+		.data		= &init_net.ipv4.sysctl_tcp_fastopen_blackhole_timeout,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_tfo_blackhole_detect_timeout,
+		.extra1		= &zero,
+	},
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
 	{
 		.procname	= "fib_multipath_use_neigh",
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 39187ac..b3a2ffc 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1126,7 +1126,7 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
 	struct sockaddr *uaddr = msg->msg_name;
 	int err, flags;
 
-	if (!(sysctl_tcp_fastopen & TFO_CLIENT_ENABLE) ||
+	if (!(sock_net(sk)->ipv4.sysctl_tcp_fastopen & TFO_CLIENT_ENABLE) ||
 	    (uaddr && msg->msg_namelen >= sizeof(uaddr->sa_family) &&
 	     uaddr->sa_family == AF_UNSPEC))
 		return -EOPNOTSUPP;
@@ -2759,7 +2759,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
 	case TCP_FASTOPEN_CONNECT:
 		if (val > 1 || val < 0) {
 			err = -EINVAL;
-		} else if (sysctl_tcp_fastopen & TFO_CLIENT_ENABLE) {
+		} else if (net->ipv4.sysctl_tcp_fastopen & TFO_CLIENT_ENABLE) {
 			if (sk->sk_state == TCP_CLOSE)
 				tp->fastopen_connect = val;
 			else
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index e3c3322..1bf57e8 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -9,8 +9,6 @@
 #include <net/inetpeer.h>
 #include <net/tcp.h>
 
-int sysctl_tcp_fastopen __read_mostly = TFO_CLIENT_ENABLE;
-
 struct tcp_fastopen_context __rcu *tcp_fastopen_ctx;
 
 static DEFINE_SPINLOCK(tcp_fastopen_ctx_lock);
@@ -282,18 +280,19 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
 	struct tcp_fastopen_cookie valid_foc = { .len = -1 };
 	bool syn_data = TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq + 1;
 	struct sock *child;
+	int tcp_fastopen = sock_net(sk)->ipv4.sysctl_tcp_fastopen;
 
 	if (foc->len == 0) /* Client requests a cookie */
 		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPFASTOPENCOOKIEREQD);
 
-	if (!((sysctl_tcp_fastopen & TFO_SERVER_ENABLE) &&
+	if (!((tcp_fastopen & TFO_SERVER_ENABLE) &&
 	      (syn_data || foc->len >= 0) &&
 	      tcp_fastopen_queue_check(sk))) {
 		foc->len = -1;
 		return NULL;
 	}
 
-	if (syn_data && (sysctl_tcp_fastopen & TFO_SERVER_COOKIE_NOT_REQD))
+	if (syn_data && (tcp_fastopen & TFO_SERVER_COOKIE_NOT_REQD))
 		goto fastopen;
 
 	if (foc->len >= 0 &&  /* Client presents or requests a cookie */
@@ -347,7 +346,7 @@ bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss,
 		return false;
 	}
 
-	if (sysctl_tcp_fastopen & TFO_CLIENT_NO_COOKIE) {
+	if (sock_net(sk)->ipv4.sysctl_tcp_fastopen & TFO_CLIENT_NO_COOKIE) {
 		cookie->len = -1;
 		return true;
 	}
@@ -402,7 +401,6 @@ bool tcp_fastopen_defer_connect(struct sock *sk, int *err)
  */
 
 /* Default to 1hr */
-unsigned int sysctl_tcp_fastopen_blackhole_timeout __read_mostly = 60 * 60;
 static atomic_t tfo_active_disable_times __read_mostly = ATOMIC_INIT(0);
 static unsigned long tfo_active_disable_stamp __read_mostly;
 
@@ -431,13 +429,14 @@ bool tcp_fastopen_active_should_disable(struct sock *sk)
 	int tfo_da_times = atomic_read(&tfo_active_disable_times);
 	int multiplier;
 	unsigned long timeout;
+	unsigned int tfo_bh_timeout = sock_net(sk)->ipv4.sysctl_tcp_fastopen_blackhole_timeout;
 
 	if (!tfo_da_times)
 		return false;
 
 	/* Limit timout to max: 2^6 * initial timeout */
 	multiplier = 1 << min(tfo_da_times - 1, 6);
-	timeout = multiplier * sysctl_tcp_fastopen_blackhole_timeout * HZ;
+	timeout = multiplier * tfo_bh_timeout * HZ;
 	if (time_before(jiffies, tfo_active_disable_stamp + timeout))
 		return true;
 
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 4b17a91..38d30ea 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2473,6 +2473,8 @@ static int __net_init tcp_sk_init(struct net *net)
 	net->ipv4.sysctl_tcp_window_scaling = 1;
 	net->ipv4.sysctl_tcp_timestamps = 1;
 
+	net->ipv4.sysctl_tcp_fastopen = TFO_CLIENT_ENABLE;
+	net->ipv4.sysctl_tcp_fastopen_blackhole_timeout = 60 * 60;
 	return 0;
 fail:
 	tcp_sk_exit(net);
diff --git a/samples/bpf/test_ipip.sh b/samples/bpf/test_ipip.sh
index 1969254..7bbc521 100755
--- a/samples/bpf/test_ipip.sh
+++ b/samples/bpf/test_ipip.sh
@@ -173,6 +173,8 @@ function cleanup {
 cleanup
 echo "Testing IP tunnels..."
 test_ipip
+sleep 1
 test_ipip6
+sleep 1
 test_ip6ip6
 echo "*** PASS ***"
-- 
1.8.3.1

^ permalink raw reply related


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