Netdev List
 help / color / mirror / Atom feed
* [PATCH v2 4/4] samples/bpf: add .gitignore file
From: Taeung Song @ 2018-07-04 13:36 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann; +Cc: netdev, linux-kernel, Taeung Song
In-Reply-To: <20180704133639.11855-1-treeze.taeung@gmail.com>

For untracked executables of samples/bpf, add this.

  Untracked files:
    (use "git add <file>..." to include in what will be committed)

  	samples/bpf/cpustat
  	samples/bpf/fds_example
  	samples/bpf/lathist
  	samples/bpf/load_sock_ops
	...

Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
 samples/bpf/.gitignore | 49 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 samples/bpf/.gitignore

diff --git a/samples/bpf/.gitignore b/samples/bpf/.gitignore
new file mode 100644
index 000000000000..8ae4940025f8
--- /dev/null
+++ b/samples/bpf/.gitignore
@@ -0,0 +1,49 @@
+cpustat
+fds_example
+lathist
+load_sock_ops
+lwt_len_hist
+map_perf_test
+offwaketime
+per_socket_stats_example
+sampleip
+sock_example
+sockex1
+sockex2
+sockex3
+spintest
+syscall_nrs.h
+syscall_tp
+task_fd_query
+tc_l2_redirect
+test_cgrp2_array_pin
+test_cgrp2_attach
+test_cgrp2_attach2
+test_cgrp2_sock
+test_cgrp2_sock2
+test_current_task_under_cgroup
+test_lru_dist
+test_map_in_map
+test_overhead
+test_probe_write_user
+trace_event
+trace_output
+tracex1
+tracex2
+tracex3
+tracex4
+tracex5
+tracex6
+tracex7
+xdp1
+xdp2
+xdp_adjust_tail
+xdp_fwd
+xdp_monitor
+xdp_redirect
+xdp_redirect_cpu
+xdp_redirect_map
+xdp_router_ipv4
+xdp_rxq_info
+xdp_tx_iptunnel
+xdpsock
-- 
2.17.1

^ permalink raw reply related

* Re: [PATCH v2 net-next 00/14] Scheduled packet Transmission: ETF
From: David Miller @ 2018-07-04 13:37 UTC (permalink / raw)
  To: jesus.sanchez-palencia
  Cc: netdev, tglx, jan.altenberg, vinicius.gomes, kurt.kanzenbach,
	henrik, richardcochran, ilias.apalodimas, ivan.khoronzhuk,
	mlichvar, willemb, jhs, xiyou.wangcong, jiri, eric.dumazet,
	jeffrey.t.kirsher
In-Reply-To: <20180703224300.25300-1-jesus.sanchez-palencia@intel.com>

From: Jesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>
Date: Tue,  3 Jul 2018 15:42:46 -0700

> Overview
> ========
> 
> This work consists of a set of kernel interfaces that can be used by
> applications that require (time-based) Scheduled Tx of packets.
> It is comprised by 3 new components to the kernel:
> 
>   - SO_TXTIME: socket option + cmsg programming interfaces.
> 
>   - etf: the "earliest txtime first" qdisc, that provides per-queue
> 	 TxTime-based scheduling. This has been renamed from 'tbs' to
> 	 'etf' to better describe its functionality.
> 
>   - taprio: the "time-aware priority scheduler" qdisc, that provides
> 	    per-port Time-Aware scheduling;
> 
> This patchset is providing the first 2 components, which have been
> developed for longer. The taprio qdisc will be shared as an RFC separately
> (shortly).
 ...

I don't have any problems with this, series applied, thanks.

^ permalink raw reply

* Re: [PATCH] net: dsa: bcm_sf2: remove redundant variable off
From: David Miller @ 2018-07-04 13:40 UTC (permalink / raw)
  To: colin.king
  Cc: andrew, vivien.didelot, f.fainelli, netdev, kernel-janitors,
	linux-kernel
In-Reply-To: <20180704065436.13719-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Wed,  4 Jul 2018 07:54:36 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> Variable 'off' is being assigned but is never used hence it is
> redundant and can be removed.
> 
> Cleans up clang warning:
> warning: variable 'off' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* Re: [PATCH] net: alteon: acenic: remove redundant pointer rxdesc
From: David Miller @ 2018-07-04 13:40 UTC (permalink / raw)
  To: colin.king; +Cc: jes, linux-acenic, netdev, kernel-janitors, linux-kernel
In-Reply-To: <20180704070135.13938-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Wed,  4 Jul 2018 08:01:35 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> Pointer rxdesc is being assigned but is never used hence it is
> redundant and can be removed.
> 
> Cleans up clang warning:
> warning: variable 'rxdesc' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* Re: [PATCH] net: alx: remove redundant variable old_duplex
From: David Miller @ 2018-07-04 13:40 UTC (permalink / raw)
  To: colin.king
  Cc: jcliburn, chris.snook, sd, netdev, kernel-janitors, linux-kernel
In-Reply-To: <20180704071530.14431-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Wed,  4 Jul 2018 08:15:30 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> Variable old_duplex is being assigned but is never used hence it is
> redundant and can be removed.
> 
> Cleans up clang warning:
> warning: variable 'old_duplex' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* Re: [PATCH] net: ethernet: nb8800: remove redundant pointer rxd
From: David Miller @ 2018-07-04 13:40 UTC (permalink / raw)
  To: colin.king; +Cc: marc_gonzalez, netdev, kernel-janitors, linux-kernel
In-Reply-To: <20180704072020.14785-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Wed,  4 Jul 2018 08:20:20 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> Pointer rxd is being assigned but is never used hence it is
> redundant and can be removed.
> 
> Cleans up clang warning:
> warning: variable 'rxb' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* Re: [PATCH] net: bgmac: remove redundant variable 'freed'
From: David Miller @ 2018-07-04 13:40 UTC (permalink / raw)
  To: colin.king
  Cc: f.fainelli, scott.branden, abhishek.shah, netdev, kernel-janitors,
	linux-kernel
In-Reply-To: <20180704073043.15286-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Wed,  4 Jul 2018 08:30:43 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> Variable 'freed' is being assigned but is never used hence it is
> redundant and can be removed.
> 
> Cleans up clang warning:
> warning: variable 'freed' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* Re: [PATCH] cnic: remove redundant pointer req and variable func
From: David Miller @ 2018-07-04 13:40 UTC (permalink / raw)
  To: colin.king; +Cc: christophe.jaillet, netdev, kernel-janitors, linux-kernel
In-Reply-To: <20180704073912.15598-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Wed,  4 Jul 2018 08:39:12 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> Pointer req and variable func are being assigned but are never used
> hence they are redundant and can be removed.
> 
> Cleans up clang warnings:
> warning: variable 'req' set but not used [-Wunused-but-set-variable]
> warning: variable 'func' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* Re: [PATCH] net: fec: remove redundant variable 'inc'
From: David Miller @ 2018-07-04 13:40 UTC (permalink / raw)
  To: colin.king; +Cc: fugang.duan, netdev, kernel-janitors, linux-kernel
In-Reply-To: <20180704074943.15820-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Wed,  4 Jul 2018 08:49:43 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> Variable 'inc' is being assigned but is never used hence it is
> redundant and can be removed.
> 
> Cleans up clang warning:
> warning: variable 'inc' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* Re: [PATCH] net: ethernet: gianfar_ethtool: remove redundant variable last_rule_idx
From: David Miller @ 2018-07-04 13:40 UTC (permalink / raw)
  To: colin.king; +Cc: claudiu.manoil, netdev, kernel-janitors, linux-kernel
In-Reply-To: <20180704075455.16010-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Wed,  4 Jul 2018 08:54:55 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> Variable last_rule_idx is being assigned but is never used hence it is
> redundant and can be removed.
> 
> Cleans up clang warning:
> warning: variable 'last_rule_idx' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* Re: [PATCH] net: hns3: remove redundant variable 'protocol'
From: David Miller @ 2018-07-04 13:40 UTC (permalink / raw)
  To: colin.king
  Cc: yisen.zhuang, salil.mehta, netdev, kernel-janitors, linux-kernel
In-Reply-To: <20180704075925.16163-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Wed,  4 Jul 2018 08:59:25 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> Variable 'protocol' is being assigned but is never used hence it is
> redundant and can be removed.
> 
> Cleans up clang warning:
> warning: variable 'protocol' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* Re: [PATCH] net: hinic: remove redundant pointer pfhwdev
From: David Miller @ 2018-07-04 13:41 UTC (permalink / raw)
  To: colin.king; +Cc: aviad.krawczyk, netdev, kernel-janitors, linux-kernel
In-Reply-To: <20180704080627.16393-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Wed,  4 Jul 2018 09:06:27 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> Pointer pfhwdev is being assigned but is never used hence it is
> redundant and can be removed.
> 
> Cleans up clang warning:
> warning: variable 'pfhwdev' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* Re: [PATCH] ethernet: micrel: remove redundant pointer 'info'
From: David Miller @ 2018-07-04 13:41 UTC (permalink / raw)
  To: colin.king; +Cc: netdev, kernel-janitors, linux-kernel
In-Reply-To: <20180704112044.7930-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Wed,  4 Jul 2018 12:20:44 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> Pointer 'info' is being assigned but is never used hence it is
> redundant and can be removed.
> 
> Cleans up clang warning:
> warning: variable 'info' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* Re: [PATCH] qlogic: netxen: remove various redundant variables
From: David Miller @ 2018-07-04 13:41 UTC (permalink / raw)
  To: colin.king
  Cc: manish.chopra, rahul.verma, Dept-GELinuxNICDev, netdev,
	kernel-janitors, linux-kernel
In-Reply-To: <20180704114553.8293-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Wed,  4 Jul 2018 12:45:53 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> Variables consumer, cmd_desc, end_cnt and no_of_desc are being assigned
> but are never used hence they are redundant and can be removed.
> 
> Cleans up clang warnings:
> warning: variable 'consumer' set but not used [-Wunused-but-set-variable]
> warning: variable 'cmd_desc' set but not used [-Wunused-but-set-variable]
> warning: variable 'end_cnt' set but not used [-Wunused-but-set-variable]
> warning: variable 'no_of_desc' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* Re: [PATCH] qed: remove redundant pointer 'name'
From: David Miller @ 2018-07-04 13:41 UTC (permalink / raw)
  To: colin.king
  Cc: Ariel.Elior, everest-linux-l2, netdev, kernel-janitors,
	linux-kernel
In-Reply-To: <20180704120626.8701-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Wed,  4 Jul 2018 13:06:26 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> Pointer 'name' is being assigned but is never used hence it is
> redundant and can be removed.
> 
> Cleans up clang warning:
> warning: variable 'name' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* Re: [PATCH] sfc: remove redundant variable old_vlan
From: David Miller @ 2018-07-04 13:41 UTC (permalink / raw)
  To: colin.king
  Cc: linux-net-drivers, ecree, bkenward, netdev, kernel-janitors,
	linux-kernel
In-Reply-To: <20180704121301.8896-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Wed,  4 Jul 2018 13:13:01 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> Variable old_vlan is being assigned but is never used hence it is
> and can be removed.
> 
> Cleans up clang warning:
> warning: variable 'old_vlan' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* Re: [PATCH] epic100: remove redundant variable 'irq'
From: David Miller @ 2018-07-04 13:41 UTC (permalink / raw)
  To: colin.king; +Cc: allen.lkml, netdev, kernel-janitors, linux-kernel
In-Reply-To: <20180704121929.9113-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Wed,  4 Jul 2018 13:19:29 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> Variable 'irq' is being assigned but is never used hence it is
> and can be removed.
> 
> Cleans up clang warning:
> warning: variable 'irq' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* RE: [RFC net-next 15/15] net: lora: Add Semtech SX1301
From: Ben Whitten @ 2018-07-04 13:41 UTC (permalink / raw)
  To: Mark Brown, Andreas Färber
  Cc: Steve deRosier, Matthias Brugger, Jiri Pirko, Hasnain Virk,
	netdev@vger.kernel.org, Marcel Holtmann, Dollar Chen,
	linux-kernel@vger.kernel.org, Michael Röder, Janus Piwek,
	linux-spi@vger.kernel.org, LoRa_Community_Support@semtech.com,
	Jian-Hong Pan, Ken Yu, David S . Miller,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <20180704114355.GB11693@sirena.org.uk>

> Subject: Re: [RFC net-next 15/15] net: lora: Add Semtech SX1301
> 
> On Tue, Jul 03, 2018 at 06:40:41PM +0200, Andreas Färber wrote:
> 
> > Do you have an alternative solution for abstraction? A regmap would seem
> > to require putting everything into a monolithic SX1301 driver despite
> > those connected chipsets actually being regular, external SPI chips that
> > could also be attached to non-SX1301 SPI masters.
> 
> I'm suggesting a regmap for those external SPI chips.  It doesn't matter
> what the host uses.

Currently in my testing drivers I have used regmap for both the SX1301 and the downstream SX1257.
In my SX1257 driver currently the regmap is backed via SPI with devm_regmap_init_spi, please correct me if I am wrong but if I understand correctly this could be split out to regmap backed by SPI in the case of a direct host connection, and a regmap backed by the SX1301's regmapped strobing register interface, regmap_bus?
Is there a precedent to this I can examine?

^ permalink raw reply

* [RFC PATCH v3] ipv6: make ipv6_renew_options() interrupt/kernel safe
From: Paul Moore @ 2018-07-04 13:58 UTC (permalink / raw)
  To: netdev; +Cc: viro, selinux, linux-security-module

From: Paul Moore <paul@paul-moore.com>

At present the ipv6_renew_options_kern() function ends up calling into
access_ok() which is problematic if done from inside an interrupt as
access_ok() calls WARN_ON_IN_IRQ() on some (all?) architectures
(x86-64 is affected).  Example warning/backtrace is shown below:

 WARNING: CPU: 1 PID: 3144 at lib/usercopy.c:11 _copy_from_user+0x85/0x90
 ...
 Call Trace:
  <IRQ>
  ipv6_renew_option+0xb2/0xf0
  ipv6_renew_options+0x26a/0x340
  ipv6_renew_options_kern+0x2c/0x40
  calipso_req_setattr+0x72/0xe0
  netlbl_req_setattr+0x126/0x1b0
  selinux_netlbl_inet_conn_request+0x80/0x100
  selinux_inet_conn_request+0x6d/0xb0
  security_inet_conn_request+0x32/0x50
  tcp_conn_request+0x35f/0xe00
  ? __lock_acquire+0x250/0x16c0
  ? selinux_socket_sock_rcv_skb+0x1ae/0x210
  ? tcp_rcv_state_process+0x289/0x106b
  tcp_rcv_state_process+0x289/0x106b
  ? tcp_v6_do_rcv+0x1a7/0x3c0
  tcp_v6_do_rcv+0x1a7/0x3c0
  tcp_v6_rcv+0xc82/0xcf0
  ip6_input_finish+0x10d/0x690
  ip6_input+0x45/0x1e0
  ? ip6_rcv_finish+0x1d0/0x1d0
  ipv6_rcv+0x32b/0x880
  ? ip6_make_skb+0x1e0/0x1e0
  __netif_receive_skb_core+0x6f2/0xdf0
  ? process_backlog+0x85/0x250
  ? process_backlog+0x85/0x250
  ? process_backlog+0xec/0x250
  process_backlog+0xec/0x250
  net_rx_action+0x153/0x480
  __do_softirq+0xd9/0x4f7
  do_softirq_own_stack+0x2a/0x40
  </IRQ>
  ...

While not present in the backtrace, ipv6_renew_option() ends up calling
access_ok() via the following chain:

  access_ok()
  _copy_from_user()
  copy_from_user()
  ipv6_renew_option()

The fix presented in this patch is to perform the userspace copy
earlier in the call chain such that it is only called when the option
data is actually coming from userspace; that place is
do_ipv6_setsockopt().  Not only does this solve the problem seen in
the backtrace above, it also allows us to simplify the code quite a
bit by removing ipv6_renew_options_kern() completely.  We also take
this opportunity to cleanup ipv6_renew_options()/ipv6_renew_option()
a small amount as well.

This patch is heavily based on a rough patch by Al Viro.  I've taken
his original patch, converted a kmemdup() call in do_ipv6_setsockopt()
to a memdup_user() call, made better use of the e_inval jump target in
the same function, and cleaned up the use ipv6_renew_option() by
ipv6_renew_options().

CC: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Paul Moore <paul@paul-moore.com>

--
v3:
- fix typo in ipv6_renew_option() spotted by David Miller
v2:
- handle opt == NULL properly in ipv6_renew_options()
---
 include/net/ipv6.h       |    9 ----
 net/ipv6/calipso.c       |    9 +---
 net/ipv6/exthdrs.c       |  111 ++++++++++++----------------------------------
 net/ipv6/ipv6_sockglue.c |   27 ++++++++---
 4 files changed, 53 insertions(+), 103 deletions(-)

diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 16475c269749..d02881e4ad1f 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -355,14 +355,7 @@ struct ipv6_txoptions *ipv6_dup_options(struct sock *sk,
 struct ipv6_txoptions *ipv6_renew_options(struct sock *sk,
 					  struct ipv6_txoptions *opt,
 					  int newtype,
-					  struct ipv6_opt_hdr __user *newopt,
-					  int newoptlen);
-struct ipv6_txoptions *
-ipv6_renew_options_kern(struct sock *sk,
-			struct ipv6_txoptions *opt,
-			int newtype,
-			struct ipv6_opt_hdr *newopt,
-			int newoptlen);
+					  struct ipv6_opt_hdr *newopt);
 struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
 					  struct ipv6_txoptions *opt);
 
diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c
index 1323b9679cf7..1c0bb9fb76e6 100644
--- a/net/ipv6/calipso.c
+++ b/net/ipv6/calipso.c
@@ -799,8 +799,7 @@ static int calipso_opt_update(struct sock *sk, struct ipv6_opt_hdr *hop)
 {
 	struct ipv6_txoptions *old = txopt_get(inet6_sk(sk)), *txopts;
 
-	txopts = ipv6_renew_options_kern(sk, old, IPV6_HOPOPTS,
-					 hop, hop ? ipv6_optlen(hop) : 0);
+	txopts = ipv6_renew_options(sk, old, IPV6_HOPOPTS, hop);
 	txopt_put(old);
 	if (IS_ERR(txopts))
 		return PTR_ERR(txopts);
@@ -1222,8 +1221,7 @@ static int calipso_req_setattr(struct request_sock *req,
 	if (IS_ERR(new))
 		return PTR_ERR(new);
 
-	txopts = ipv6_renew_options_kern(sk, req_inet->ipv6_opt, IPV6_HOPOPTS,
-					 new, new ? ipv6_optlen(new) : 0);
+	txopts = ipv6_renew_options(sk, req_inet->ipv6_opt, IPV6_HOPOPTS, new);
 
 	kfree(new);
 
@@ -1260,8 +1258,7 @@ static void calipso_req_delattr(struct request_sock *req)
 	if (calipso_opt_del(req_inet->ipv6_opt->hopopt, &new))
 		return; /* Nothing to do */
 
-	txopts = ipv6_renew_options_kern(sk, req_inet->ipv6_opt, IPV6_HOPOPTS,
-					 new, new ? ipv6_optlen(new) : 0);
+	txopts = ipv6_renew_options(sk, req_inet->ipv6_opt, IPV6_HOPOPTS, new);
 
 	if (!IS_ERR(txopts)) {
 		txopts = xchg(&req_inet->ipv6_opt, txopts);
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 5bc2bf3733ab..20291c2036fc 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -1015,29 +1015,21 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
 }
 EXPORT_SYMBOL_GPL(ipv6_dup_options);
 
-static int ipv6_renew_option(void *ohdr,
-			     struct ipv6_opt_hdr __user *newopt, int newoptlen,
-			     int inherit,
-			     struct ipv6_opt_hdr **hdr,
-			     char **p)
+static void ipv6_renew_option(int renewtype,
+			      struct ipv6_opt_hdr **dest,
+			      struct ipv6_opt_hdr *old,
+			      struct ipv6_opt_hdr *new,
+			      int newtype, char **p)
 {
-	if (inherit) {
-		if (ohdr) {
-			memcpy(*p, ohdr, ipv6_optlen((struct ipv6_opt_hdr *)ohdr));
-			*hdr = (struct ipv6_opt_hdr *)*p;
-			*p += CMSG_ALIGN(ipv6_optlen(*hdr));
-		}
-	} else {
-		if (newopt) {
-			if (copy_from_user(*p, newopt, newoptlen))
-				return -EFAULT;
-			*hdr = (struct ipv6_opt_hdr *)*p;
-			if (ipv6_optlen(*hdr) > newoptlen)
-				return -EINVAL;
-			*p += CMSG_ALIGN(newoptlen);
-		}
-	}
-	return 0;
+	struct ipv6_opt_hdr *src;
+
+	src = (renewtype == newtype ? new : old);
+	if (!src)
+		return;
+
+	memcpy(*p, src, ipv6_optlen(src));
+	*dest = (struct ipv6_opt_hdr *)*p;
+	*p += CMSG_ALIGN(ipv6_optlen(*dest));
 }
 
 /**
@@ -1063,13 +1055,11 @@ static int ipv6_renew_option(void *ohdr,
  */
 struct ipv6_txoptions *
 ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
-		   int newtype,
-		   struct ipv6_opt_hdr __user *newopt, int newoptlen)
+		   int newtype, struct ipv6_opt_hdr *newopt)
 {
 	int tot_len = 0;
 	char *p;
 	struct ipv6_txoptions *opt2;
-	int err;
 
 	if (opt) {
 		if (newtype != IPV6_HOPOPTS && opt->hopopt)
@@ -1082,8 +1072,8 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
 			tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
 	}
 
-	if (newopt && newoptlen)
-		tot_len += CMSG_ALIGN(newoptlen);
+	if (newopt)
+		tot_len += CMSG_ALIGN(ipv6_optlen(newopt));
 
 	if (!tot_len)
 		return NULL;
@@ -1098,29 +1088,19 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
 	opt2->tot_len = tot_len;
 	p = (char *)(opt2 + 1);
 
-	err = ipv6_renew_option(opt ? opt->hopopt : NULL, newopt, newoptlen,
-				newtype != IPV6_HOPOPTS,
-				&opt2->hopopt, &p);
-	if (err)
-		goto out;
-
-	err = ipv6_renew_option(opt ? opt->dst0opt : NULL, newopt, newoptlen,
-				newtype != IPV6_RTHDRDSTOPTS,
-				&opt2->dst0opt, &p);
-	if (err)
-		goto out;
-
-	err = ipv6_renew_option(opt ? opt->srcrt : NULL, newopt, newoptlen,
-				newtype != IPV6_RTHDR,
-				(struct ipv6_opt_hdr **)&opt2->srcrt, &p);
-	if (err)
-		goto out;
-
-	err = ipv6_renew_option(opt ? opt->dst1opt : NULL, newopt, newoptlen,
-				newtype != IPV6_DSTOPTS,
-				&opt2->dst1opt, &p);
-	if (err)
-		goto out;
+	ipv6_renew_option(IPV6_HOPOPTS, &opt2->hopopt,
+			  (opt ? opt->hopopt : NULL),
+			  newopt, newtype, &p);
+	ipv6_renew_option(IPV6_RTHDRDSTOPTS, &opt2->dst0opt,
+			  (opt ? opt->dst0opt : NULL),
+			  newopt, newtype, &p);
+	ipv6_renew_option(IPV6_RTHDR,
+			  (struct ipv6_opt_hdr **)&opt2->srcrt,
+			  (opt ? (struct ipv6_opt_hdr *)opt->srcrt : NULL),
+			  newopt, newtype, &p);
+	ipv6_renew_option(IPV6_DSTOPTS, &opt2->dst1opt,
+			  (opt ? opt->dst1opt : NULL),
+			  newopt, newtype, &p);
 
 	opt2->opt_nflen = (opt2->hopopt ? ipv6_optlen(opt2->hopopt) : 0) +
 			  (opt2->dst0opt ? ipv6_optlen(opt2->dst0opt) : 0) +
@@ -1128,37 +1108,6 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
 	opt2->opt_flen = (opt2->dst1opt ? ipv6_optlen(opt2->dst1opt) : 0);
 
 	return opt2;
-out:
-	sock_kfree_s(sk, opt2, opt2->tot_len);
-	return ERR_PTR(err);
-}
-
-/**
- * ipv6_renew_options_kern - replace a specific ext hdr with a new one.
- *
- * @sk: sock from which to allocate memory
- * @opt: original options
- * @newtype: option type to replace in @opt
- * @newopt: new option of type @newtype to replace (kernel-mem)
- * @newoptlen: length of @newopt
- *
- * See ipv6_renew_options().  The difference is that @newopt is
- * kernel memory, rather than user memory.
- */
-struct ipv6_txoptions *
-ipv6_renew_options_kern(struct sock *sk, struct ipv6_txoptions *opt,
-			int newtype, struct ipv6_opt_hdr *newopt,
-			int newoptlen)
-{
-	struct ipv6_txoptions *ret_val;
-	const mm_segment_t old_fs = get_fs();
-
-	set_fs(KERNEL_DS);
-	ret_val = ipv6_renew_options(sk, opt, newtype,
-				     (struct ipv6_opt_hdr __user *)newopt,
-				     newoptlen);
-	set_fs(old_fs);
-	return ret_val;
 }
 
 struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 4d780c7f0130..c95c3486d904 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -398,6 +398,12 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
 	case IPV6_DSTOPTS:
 	{
 		struct ipv6_txoptions *opt;
+		struct ipv6_opt_hdr *new = NULL;
+
+		/* hop-by-hop / destination options are privileged option */
+		retv = -EPERM;
+		if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW))
+			break;
 
 		/* remove any sticky options header with a zero option
 		 * length, per RFC3542.
@@ -409,17 +415,22 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
 		else if (optlen < sizeof(struct ipv6_opt_hdr) ||
 			 optlen & 0x7 || optlen > 8 * 255)
 			goto e_inval;
-
-		/* hop-by-hop / destination options are privileged option */
-		retv = -EPERM;
-		if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW))
-			break;
+		else {
+			new = memdup_user(optval, optlen);
+			if (IS_ERR(new)) {
+				retv = PTR_ERR(new);
+				break;
+			}
+			if (unlikely(ipv6_optlen(new) > optlen)) {
+				kfree(new);
+				goto e_inval;
+			}
+		}
 
 		opt = rcu_dereference_protected(np->opt,
 						lockdep_sock_is_held(sk));
-		opt = ipv6_renew_options(sk, opt, optname,
-					 (struct ipv6_opt_hdr __user *)optval,
-					 optlen);
+		opt = ipv6_renew_options(sk, opt, optname, new);
+		kfree(new);
 		if (IS_ERR(opt)) {
 			retv = PTR_ERR(opt);
 			break;

^ permalink raw reply related

* [PATCH net] qed: Fix reading stale configuration information
From: Denis Bolotin @ 2018-07-04 14:06 UTC (permalink / raw)
  To: davem, netdev; +Cc: Denis Bolotin, Ariel Elior

Configuration information read at driver load can become stale after it is
updated. Mark information as not valid and re-populate when this happens.

Signed-off-by: Denis Bolotin <denis.bolotin@cavium.com>
Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
---
 drivers/net/ethernet/qlogic/qed/qed.h     |  1 +
 drivers/net/ethernet/qlogic/qed/qed_mcp.c | 39 +++++++++++++++++++++----------
 2 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
index 00db340..1dfaccd 100644
--- a/drivers/net/ethernet/qlogic/qed/qed.h
+++ b/drivers/net/ethernet/qlogic/qed/qed.h
@@ -502,6 +502,7 @@ enum BAR_ID {
 struct qed_nvm_image_info {
 	u32 num_images;
 	struct bist_nvm_image_att *image_att;
+	bool valid;
 };
 
 #define DRV_MODULE_VERSION		      \
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
index 4e0b443..9d9e533 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -592,6 +592,9 @@ int qed_mcp_nvm_wr_cmd(struct qed_hwfn *p_hwfn,
 	*o_mcp_resp = mb_params.mcp_resp;
 	*o_mcp_param = mb_params.mcp_param;
 
+	/* nvm_info needs to be updated */
+	p_hwfn->nvm_info.valid = false;
+
 	return 0;
 }
 
@@ -2555,11 +2558,14 @@ int qed_mcp_bist_nvm_get_image_att(struct qed_hwfn *p_hwfn,
 
 int qed_mcp_nvm_info_populate(struct qed_hwfn *p_hwfn)
 {
-	struct qed_nvm_image_info *nvm_info = &p_hwfn->nvm_info;
+	struct qed_nvm_image_info nvm_info;
 	struct qed_ptt *p_ptt;
 	int rc;
 	u32 i;
 
+	if (p_hwfn->nvm_info.valid)
+		return 0;
+
 	p_ptt = qed_ptt_acquire(p_hwfn);
 	if (!p_ptt) {
 		DP_ERR(p_hwfn, "failed to acquire ptt\n");
@@ -2567,29 +2573,29 @@ int qed_mcp_nvm_info_populate(struct qed_hwfn *p_hwfn)
 	}
 
 	/* Acquire from MFW the amount of available images */
-	nvm_info->num_images = 0;
+	nvm_info.num_images = 0;
 	rc = qed_mcp_bist_nvm_get_num_images(p_hwfn,
-					     p_ptt, &nvm_info->num_images);
+					     p_ptt, &nvm_info.num_images);
 	if (rc == -EOPNOTSUPP) {
 		DP_INFO(p_hwfn, "DRV_MSG_CODE_BIST_TEST is not supported\n");
 		goto out;
-	} else if (rc || !nvm_info->num_images) {
+	} else if (rc || !nvm_info.num_images) {
 		DP_ERR(p_hwfn, "Failed getting number of images\n");
 		goto err0;
 	}
 
-	nvm_info->image_att = kmalloc_array(nvm_info->num_images,
-					    sizeof(struct bist_nvm_image_att),
-					    GFP_KERNEL);
-	if (!nvm_info->image_att) {
+	nvm_info.image_att = kmalloc_array(nvm_info.num_images,
+					   sizeof(struct bist_nvm_image_att),
+					   GFP_KERNEL);
+	if (!nvm_info.image_att) {
 		rc = -ENOMEM;
 		goto err0;
 	}
 
 	/* Iterate over images and get their attributes */
-	for (i = 0; i < nvm_info->num_images; i++) {
+	for (i = 0; i < nvm_info.num_images; i++) {
 		rc = qed_mcp_bist_nvm_get_image_att(p_hwfn, p_ptt,
-						    &nvm_info->image_att[i], i);
+						    &nvm_info.image_att[i], i);
 		if (rc) {
 			DP_ERR(p_hwfn,
 			       "Failed getting image index %d attributes\n", i);
@@ -2597,14 +2603,22 @@ int qed_mcp_nvm_info_populate(struct qed_hwfn *p_hwfn)
 		}
 
 		DP_VERBOSE(p_hwfn, QED_MSG_SP, "image index %d, size %x\n", i,
-			   nvm_info->image_att[i].len);
+			   nvm_info.image_att[i].len);
 	}
 out:
+	/* Update hwfn's nvm_info */
+	if (nvm_info.num_images) {
+		p_hwfn->nvm_info.num_images = nvm_info.num_images;
+		kfree(p_hwfn->nvm_info.image_att);
+		p_hwfn->nvm_info.image_att = nvm_info.image_att;
+		p_hwfn->nvm_info.valid = true;
+	}
+
 	qed_ptt_release(p_hwfn, p_ptt);
 	return 0;
 
 err1:
-	kfree(nvm_info->image_att);
+	kfree(nvm_info.image_att);
 err0:
 	qed_ptt_release(p_hwfn, p_ptt);
 	return rc;
@@ -2641,6 +2655,7 @@ int qed_mcp_nvm_info_populate(struct qed_hwfn *p_hwfn)
 		return -EINVAL;
 	}
 
+	qed_mcp_nvm_info_populate(p_hwfn);
 	for (i = 0; i < p_hwfn->nvm_info.num_images; i++)
 		if (type == p_hwfn->nvm_info.image_att[i].image_type)
 			break;
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH iproute2/net-next] devlink: Add param command support
From: Moshe Shemesh @ 2018-07-04 14:12 UTC (permalink / raw)
  To: David S. Miller
  Cc: Vasundhara Volam, Jiri Pirko, netdev, linux-kernel, Moshe Shemesh
In-Reply-To: <1530703837-24563-1-git-send-email-moshe@mellanox.com>

Add support for configuration parameters set and show.
Each parameter can be either generic or driver-specific.
The user can retrieve data on these configuration parameters by devlink
param show command and can set new value to a configuration parameter
by devlink param set command.
The configuration parameters can be set in different configuration
modes:
  runtime - set while driver is running, no reset required.
  driverinit - applied while driver initializes, requires restart
               driver by devlink reload command.
  permanent - written to device's non-volatile memory, hard reset
              required to apply.

New commands added:
  devlink dev param show [DEV name PARAMETER]
  devlink dev param set DEV name PARAMETER value VALUE
			    cmode { permanent | driverinit | runtime }

Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 devlink/devlink.c            | 454 +++++++++++++++++++++++++++++++++++++++++++
 include/uapi/linux/devlink.h |  24 +++
 man/man8/devlink-dev.8       |  57 ++++++
 3 files changed, 535 insertions(+)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index df2c66d..42fa716 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -35,6 +35,10 @@
 #define ESWITCH_INLINE_MODE_NETWORK "network"
 #define ESWITCH_INLINE_MODE_TRANSPORT "transport"
 
+#define PARAM_CMODE_RUNTIME_STR "runtime"
+#define PARAM_CMODE_DRIVERINIT_STR "driverinit"
+#define PARAM_CMODE_PERMANENT_STR "permanent"
+
 static int g_new_line_count;
 
 #define pr_err(args...) fprintf(stderr, ##args)
@@ -187,6 +191,9 @@ static void ifname_map_free(struct ifname_map *ifname_map)
 #define DL_OPT_ESWITCH_ENCAP_MODE	BIT(15)
 #define DL_OPT_RESOURCE_PATH	BIT(16)
 #define DL_OPT_RESOURCE_SIZE	BIT(17)
+#define DL_OPT_PARAM_NAME	BIT(18)
+#define DL_OPT_PARAM_VALUE	BIT(19)
+#define DL_OPT_PARAM_CMODE	BIT(20)
 
 struct dl_opts {
 	uint32_t present; /* flags of present items */
@@ -211,6 +218,9 @@ struct dl_opts {
 	uint32_t resource_size;
 	uint32_t resource_id;
 	bool resource_id_valid;
+	const char *param_name;
+	const char *param_value;
+	enum devlink_param_cmode cmode;
 };
 
 struct dl {
@@ -348,6 +358,12 @@ static const enum mnl_attr_data_type devlink_policy[DEVLINK_ATTR_MAX + 1] = {
 	[DEVLINK_ATTR_DPIPE_FIELD_ID] = MNL_TYPE_U32,
 	[DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH] = MNL_TYPE_U32,
 	[DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE] = MNL_TYPE_U32,
+	[DEVLINK_ATTR_PARAM] = MNL_TYPE_NESTED,
+	[DEVLINK_ATTR_PARAM_NAME] = MNL_TYPE_STRING,
+	[DEVLINK_ATTR_PARAM_TYPE] = MNL_TYPE_U8,
+	[DEVLINK_ATTR_PARAM_VALUES_LIST] = MNL_TYPE_NESTED,
+	[DEVLINK_ATTR_PARAM_VALUE] = MNL_TYPE_NESTED,
+	[DEVLINK_ATTR_PARAM_VALUE_CMODE] = MNL_TYPE_U8,
 };
 
 static int attr_cb(const struct nlattr *attr, void *data)
@@ -514,6 +530,34 @@ static int strtouint16_t(const char *str, uint16_t *p_val)
 	return 0;
 }
 
+static int strtouint8_t(const char *str, uint8_t *p_val)
+{
+	char *endptr;
+	unsigned long int val;
+
+	val = strtoul(str, &endptr, 10);
+	if (endptr == str || *endptr != '\0')
+		return -EINVAL;
+	if (val > UCHAR_MAX)
+		return -ERANGE;
+	*p_val = val;
+	return 0;
+}
+
+static int strtobool(const char *str, bool *p_val)
+{
+	bool val;
+
+	if (!strcmp(str, "true") || !strcmp(str, "1"))
+		val = true;
+	else if (!strcmp(str, "false") || !strcmp(str, "0"))
+		val = false;
+	else
+		return -EINVAL;
+	*p_val = val;
+	return 0;
+}
+
 static int __dl_argv_handle(char *str, char **p_bus_name, char **p_dev_name)
 {
 	strslashrsplit(str, p_bus_name, p_dev_name);
@@ -792,6 +836,22 @@ static int eswitch_encap_mode_get(const char *typestr, bool *p_mode)
 	return 0;
 }
 
+static int param_cmode_get(const char *cmodestr,
+			   enum devlink_param_cmode *cmode)
+{
+	if (strcmp(cmodestr, PARAM_CMODE_RUNTIME_STR) == 0) {
+		*cmode = DEVLINK_PARAM_CMODE_RUNTIME;
+	} else if (strcmp(cmodestr, PARAM_CMODE_DRIVERINIT_STR) == 0) {
+		*cmode = DEVLINK_PARAM_CMODE_DRIVERINIT;
+	} else if (strcmp(cmodestr, PARAM_CMODE_PERMANENT_STR) == 0) {
+		*cmode = DEVLINK_PARAM_CMODE_PERMANENT;
+	} else {
+		pr_err("Unknown configuration mode \"%s\"\n", cmodestr);
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static int dl_argv_parse(struct dl *dl, uint32_t o_required,
 			 uint32_t o_optional)
 {
@@ -973,6 +1033,32 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required,
 			if (err)
 				return err;
 			o_found |= DL_OPT_RESOURCE_SIZE;
+		} else if (dl_argv_match(dl, "name") &&
+			   (o_all & DL_OPT_PARAM_NAME)) {
+			dl_arg_inc(dl);
+			err = dl_argv_str(dl, &opts->param_name);
+			if (err)
+				return err;
+			o_found |= DL_OPT_PARAM_NAME;
+		} else if (dl_argv_match(dl, "value") &&
+			   (o_all & DL_OPT_PARAM_VALUE)) {
+			dl_arg_inc(dl);
+			err = dl_argv_str(dl, &opts->param_value);
+			if (err)
+				return err;
+			o_found |= DL_OPT_PARAM_VALUE;
+		} else if (dl_argv_match(dl, "cmode") &&
+			   (o_all & DL_OPT_PARAM_CMODE)) {
+			const char *cmodestr;
+
+			dl_arg_inc(dl);
+			err = dl_argv_str(dl, &cmodestr);
+			if (err)
+				return err;
+			err = param_cmode_get(cmodestr, &opts->cmode);
+			if (err)
+				return err;
+			o_found |= DL_OPT_PARAM_CMODE;
 		} else {
 			pr_err("Unknown option \"%s\"\n", dl_argv(dl));
 			return -EINVAL;
@@ -1057,6 +1143,24 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required,
 		return -EINVAL;
 	}
 
+	if ((o_required & DL_OPT_PARAM_NAME) &&
+	    !(o_found & DL_OPT_PARAM_NAME)) {
+		pr_err("Parameter name expected.\n");
+		return -EINVAL;
+	}
+
+	if ((o_required & DL_OPT_PARAM_VALUE) &&
+	    !(o_found & DL_OPT_PARAM_VALUE)) {
+		pr_err("Value to set expected.\n");
+		return -EINVAL;
+	}
+
+	if ((o_required & DL_OPT_PARAM_CMODE) &&
+	    !(o_found & DL_OPT_PARAM_CMODE)) {
+		pr_err("Configuration mode expected.\n");
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
@@ -1121,6 +1225,12 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl)
 	if (opts->present & DL_OPT_RESOURCE_SIZE)
 		mnl_attr_put_u64(nlh, DEVLINK_ATTR_RESOURCE_SIZE,
 				 opts->resource_size);
+	if (opts->present & DL_OPT_PARAM_NAME)
+		mnl_attr_put_strz(nlh, DEVLINK_ATTR_PARAM_NAME,
+				  opts->param_name);
+	if (opts->present & DL_OPT_PARAM_CMODE)
+		mnl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_VALUE_CMODE,
+				opts->cmode);
 }
 
 static int dl_argv_parse_put(struct nlmsghdr *nlh, struct dl *dl,
@@ -1179,6 +1289,8 @@ static void cmd_dev_help(void)
 	pr_err("                               [ inline-mode { none | link | network | transport } ]\n");
 	pr_err("                               [ encap { disable | enable } ]\n");
 	pr_err("       devlink dev eswitch show DEV\n");
+	pr_err("       devlink dev param set DEV name PARAMETER value VALUE cmode { permanent | driverinit | runtime }\n");
+	pr_err("       devlink dev param show [DEV name PARAMETER]\n");
 	pr_err("       devlink dev reload DEV\n");
 }
 
@@ -1393,6 +1505,14 @@ static void pr_out_str(struct dl *dl, const char *name, const char *val)
 	}
 }
 
+static void pr_out_bool(struct dl *dl, const char *name, bool val)
+{
+	if (val)
+		pr_out_str(dl, name, "true");
+	else
+		pr_out_str(dl, name, "false");
+}
+
 static void pr_out_uint(struct dl *dl, const char *name, unsigned int val)
 {
 	if (dl->json_output) {
@@ -1475,6 +1595,19 @@ static void pr_out_entry_end(struct dl *dl)
 		__pr_out_newline();
 }
 
+static const char *param_cmode_name(uint8_t cmode)
+{
+	switch (cmode) {
+	case DEVLINK_PARAM_CMODE_RUNTIME:
+		return PARAM_CMODE_RUNTIME_STR;
+	case DEVLINK_PARAM_CMODE_DRIVERINIT:
+		return PARAM_CMODE_DRIVERINIT_STR;
+	case DEVLINK_PARAM_CMODE_PERMANENT:
+		return PARAM_CMODE_PERMANENT_STR;
+	default: return "<unknown type>";
+	}
+}
+
 static const char *eswitch_mode_name(uint32_t mode)
 {
 	switch (mode) {
@@ -1593,6 +1726,304 @@ static int cmd_dev_eswitch(struct dl *dl)
 	return -ENOENT;
 }
 
+static void pr_out_param_value(struct dl *dl, int nla_type, struct nlattr *nl)
+{
+	struct nlattr *nla_value[DEVLINK_ATTR_MAX + 1] = {};
+	struct nlattr *val_attr;
+	int err;
+
+	err = mnl_attr_parse_nested(nl, attr_cb, nla_value);
+	if (err != MNL_CB_OK)
+		return;
+
+	if (!nla_value[DEVLINK_ATTR_PARAM_VALUE_CMODE] ||
+	    (nla_type != MNL_TYPE_FLAG &&
+	     !nla_value[DEVLINK_ATTR_PARAM_VALUE_DATA]))
+		return;
+
+	pr_out_str(dl, "cmode",
+		   param_cmode_name(mnl_attr_get_u8(nla_value[DEVLINK_ATTR_PARAM_VALUE_CMODE])));
+	val_attr = nla_value[DEVLINK_ATTR_PARAM_VALUE_DATA];
+
+	switch (nla_type) {
+	case MNL_TYPE_U8:
+		pr_out_uint(dl, "value", mnl_attr_get_u8(val_attr));
+		break;
+	case MNL_TYPE_U16:
+		pr_out_uint(dl, "value", mnl_attr_get_u16(val_attr));
+		break;
+	case MNL_TYPE_U32:
+		pr_out_uint(dl, "value", mnl_attr_get_u32(val_attr));
+		break;
+	case MNL_TYPE_STRING:
+		pr_out_str(dl, "value", mnl_attr_get_str(val_attr));
+		break;
+	case MNL_TYPE_FLAG:
+		pr_out_bool(dl, "value", val_attr ? true : false);
+		break;
+	}
+}
+
+static void pr_out_param(struct dl *dl, struct nlattr **tb, bool array)
+{
+	struct nlattr *nla_param[DEVLINK_ATTR_MAX + 1] = {};
+	struct nlattr *param_value_attr;
+	int nla_type;
+	int err;
+
+	err = mnl_attr_parse_nested(tb[DEVLINK_ATTR_PARAM], attr_cb, nla_param);
+	if (err != MNL_CB_OK)
+		return;
+	if (!nla_param[DEVLINK_ATTR_PARAM_NAME] ||
+	    !nla_param[DEVLINK_ATTR_PARAM_TYPE] ||
+	    !nla_param[DEVLINK_ATTR_PARAM_VALUES_LIST])
+		return;
+
+	if (array)
+		pr_out_handle_start_arr(dl, tb);
+	else
+		__pr_out_handle_start(dl, tb, true, false);
+
+	nla_type = mnl_attr_get_u8(nla_param[DEVLINK_ATTR_PARAM_TYPE]);
+
+	pr_out_str(dl, "name",
+		   mnl_attr_get_str(nla_param[DEVLINK_ATTR_PARAM_NAME]));
+
+	if (!nla_param[DEVLINK_ATTR_PARAM_GENERIC])
+		pr_out_str(dl, "type", "driver-specific");
+	else
+		pr_out_str(dl, "type", "generic");
+
+	pr_out_array_start(dl, "values");
+	mnl_attr_for_each_nested(param_value_attr,
+				 nla_param[DEVLINK_ATTR_PARAM_VALUES_LIST]) {
+		pr_out_entry_start(dl);
+		pr_out_param_value(dl, nla_type, param_value_attr);
+		pr_out_entry_end(dl);
+	}
+	pr_out_array_end(dl);
+	pr_out_handle_end(dl);
+}
+
+static int cmd_dev_param_show_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
+	struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
+	struct dl *dl = data;
+
+	mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
+	if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
+	    !tb[DEVLINK_ATTR_PARAM])
+		return MNL_CB_ERROR;
+	pr_out_param(dl, tb, true);
+	return MNL_CB_OK;
+}
+
+struct param_ctx {
+	struct dl *dl;
+	int nla_type;
+	union {
+		uint8_t vu8;
+		uint16_t vu16;
+		uint32_t vu32;
+		const char *vstr;
+		bool vbool;
+	} value;
+};
+
+static int cmd_dev_param_set_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
+	struct nlattr *nla_param[DEVLINK_ATTR_MAX + 1] = {};
+	struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
+	struct nlattr *param_value_attr;
+	enum devlink_param_cmode cmode;
+	struct param_ctx *ctx = data;
+	struct dl *dl = ctx->dl;
+	int nla_type;
+	int err;
+
+	mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
+	if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
+	    !tb[DEVLINK_ATTR_PARAM])
+		return MNL_CB_ERROR;
+
+	err = mnl_attr_parse_nested(tb[DEVLINK_ATTR_PARAM], attr_cb, nla_param);
+	if (err != MNL_CB_OK)
+		return MNL_CB_ERROR;
+
+	if (!nla_param[DEVLINK_ATTR_PARAM_TYPE] ||
+	    !nla_param[DEVLINK_ATTR_PARAM_VALUES_LIST])
+		return MNL_CB_ERROR;
+
+	nla_type = mnl_attr_get_u8(nla_param[DEVLINK_ATTR_PARAM_TYPE]);
+	mnl_attr_for_each_nested(param_value_attr,
+				 nla_param[DEVLINK_ATTR_PARAM_VALUES_LIST]) {
+		struct nlattr *nla_value[DEVLINK_ATTR_MAX + 1] = {};
+		struct nlattr *val_attr;
+
+		err = mnl_attr_parse_nested(param_value_attr,
+					    attr_cb, nla_value);
+		if (err != MNL_CB_OK)
+			return MNL_CB_ERROR;
+
+		if (!nla_value[DEVLINK_ATTR_PARAM_VALUE_CMODE] ||
+		    (nla_type != MNL_TYPE_FLAG &&
+		     !nla_value[DEVLINK_ATTR_PARAM_VALUE_DATA]))
+			return MNL_CB_ERROR;
+
+		cmode = mnl_attr_get_u8(nla_value[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
+		if (cmode == dl->opts.cmode) {
+			val_attr = nla_value[DEVLINK_ATTR_PARAM_VALUE_DATA];
+			switch (nla_type) {
+			case MNL_TYPE_U8:
+				ctx->value.vu8 = mnl_attr_get_u8(val_attr);
+				break;
+			case MNL_TYPE_U16:
+				ctx->value.vu16 = mnl_attr_get_u16(val_attr);
+				break;
+			case MNL_TYPE_U32:
+				ctx->value.vu32 = mnl_attr_get_u32(val_attr);
+				break;
+			case MNL_TYPE_STRING:
+				ctx->value.vstr = mnl_attr_get_str(val_attr);
+				break;
+			case MNL_TYPE_FLAG:
+				ctx->value.vbool = val_attr ? true : false;
+				break;
+			}
+			break;
+		}
+	}
+	ctx->nla_type = nla_type;
+	return MNL_CB_OK;
+}
+
+static int cmd_dev_param_set(struct dl *dl)
+{
+	struct param_ctx ctx = {};
+	struct nlmsghdr *nlh;
+	uint32_t val_u32;
+	uint16_t val_u16;
+	uint8_t val_u8;
+	bool val_bool;
+	int err;
+
+	err = dl_argv_parse(dl, DL_OPT_HANDLE |
+			    DL_OPT_PARAM_NAME |
+			    DL_OPT_PARAM_VALUE |
+			    DL_OPT_PARAM_CMODE, 0);
+	if (err)
+		return err;
+
+	/* Get value type */
+	nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PARAM_GET,
+			       NLM_F_REQUEST | NLM_F_ACK);
+	dl_opts_put(nlh, dl);
+
+	ctx.dl = dl;
+	err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dev_param_set_cb, &ctx);
+	if (err)
+		return err;
+
+	nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PARAM_SET,
+			       NLM_F_REQUEST | NLM_F_ACK);
+	dl_opts_put(nlh, dl);
+
+	mnl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_TYPE, ctx.nla_type);
+	switch (ctx.nla_type) {
+	case MNL_TYPE_U8:
+		err = strtouint8_t(dl->opts.param_value, &val_u8);
+		if (err)
+			goto err_param_value_parse;
+		if (val_u8 == ctx.value.vu8)
+			return 0;
+		mnl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, val_u8);
+		break;
+	case MNL_TYPE_U16:
+		err = strtouint16_t(dl->opts.param_value, &val_u16);
+		if (err)
+			goto err_param_value_parse;
+		if (val_u16 == ctx.value.vu16)
+			return 0;
+		mnl_attr_put_u16(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, val_u16);
+		break;
+	case MNL_TYPE_U32:
+		err = strtouint32_t(dl->opts.param_value, &val_u32);
+		if (err)
+			goto err_param_value_parse;
+		if (val_u32 == ctx.value.vu32)
+			return 0;
+		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, val_u32);
+		break;
+	case MNL_TYPE_FLAG:
+		err = strtobool(dl->opts.param_value, &val_bool);
+		if (err)
+			goto err_param_value_parse;
+		if (val_bool == ctx.value.vbool)
+			return 0;
+		if (val_bool)
+			mnl_attr_put(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA,
+				     0, NULL);
+		break;
+	case MNL_TYPE_STRING:
+		mnl_attr_put_strz(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA,
+				  dl->opts.param_value);
+		if (!strcmp(dl->opts.param_value, ctx.value.vstr))
+			return 0;
+		break;
+	default:
+		printf("Value type not supported\n");
+		return -ENOTSUP;
+	}
+	return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
+
+err_param_value_parse:
+	pr_err("Value \"%s\" is not a number or not within range\n",
+	       dl->opts.param_value);
+	return err;
+}
+
+static int cmd_dev_param_show(struct dl *dl)
+{
+	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
+	struct nlmsghdr *nlh;
+	int err;
+
+	if (dl_argc(dl) == 0)
+		flags |= NLM_F_DUMP;
+
+	nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PARAM_GET, flags);
+
+	if (dl_argc(dl) > 0) {
+		err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE |
+					DL_OPT_PARAM_NAME, 0);
+		if (err)
+			return err;
+	}
+
+	pr_out_section_start(dl, "param");
+	err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dev_param_show_cb, dl);
+	pr_out_section_end(dl);
+	return err;
+}
+
+static int cmd_dev_param(struct dl *dl)
+{
+	if (dl_argv_match(dl, "help")) {
+		cmd_dev_help();
+		return 0;
+	} else if (dl_argv_match(dl, "show") ||
+		   dl_argv_match(dl, "list") || dl_no_arg(dl)) {
+		dl_arg_inc(dl);
+		return cmd_dev_param_show(dl);
+	} else if (dl_argv_match(dl, "set")) {
+		dl_arg_inc(dl);
+		return cmd_dev_param_set(dl);
+	}
+	pr_err("Command \"%s\" not found\n", dl_argv(dl));
+	return -ENOENT;
+}
 static int cmd_dev_show_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct dl *dl = data;
@@ -1669,6 +2100,9 @@ static int cmd_dev(struct dl *dl)
 	} else if (dl_argv_match(dl, "reload")) {
 		dl_arg_inc(dl);
 		return cmd_dev_reload(dl);
+	} else if (dl_argv_match(dl, "param")) {
+		dl_arg_inc(dl);
+		return cmd_dev_param(dl);
 	}
 	pr_err("Command \"%s\" not found\n", dl_argv(dl));
 	return -ENOENT;
@@ -2632,6 +3066,10 @@ static const char *cmd_name(uint8_t cmd)
 	case DEVLINK_CMD_PORT_SET: return "set";
 	case DEVLINK_CMD_PORT_NEW: return "new";
 	case DEVLINK_CMD_PORT_DEL: return "del";
+	case DEVLINK_CMD_PARAM_GET: return "get";
+	case DEVLINK_CMD_PARAM_SET: return "set";
+	case DEVLINK_CMD_PARAM_NEW: return "new";
+	case DEVLINK_CMD_PARAM_DEL: return "del";
 	default: return "<unknown cmd>";
 	}
 }
@@ -2650,6 +3088,11 @@ static const char *cmd_obj(uint8_t cmd)
 	case DEVLINK_CMD_PORT_NEW:
 	case DEVLINK_CMD_PORT_DEL:
 		return "port";
+	case DEVLINK_CMD_PARAM_GET:
+	case DEVLINK_CMD_PARAM_SET:
+	case DEVLINK_CMD_PARAM_NEW:
+	case DEVLINK_CMD_PARAM_DEL:
+		return "param";
 	default: return "<unknown obj>";
 	}
 }
@@ -2706,6 +3149,17 @@ static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data)
 		pr_out_mon_header(genl->cmd);
 		pr_out_port(dl, tb);
 		break;
+	case DEVLINK_CMD_PARAM_GET: /* fall through */
+	case DEVLINK_CMD_PARAM_SET: /* fall through */
+	case DEVLINK_CMD_PARAM_NEW: /* fall through */
+	case DEVLINK_CMD_PARAM_DEL:
+		mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
+		if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
+		    !tb[DEVLINK_ATTR_PARAM])
+			return MNL_CB_ERROR;
+		pr_out_mon_header(genl->cmd);
+		pr_out_param(dl, tb, false);
+		break;
 	}
 	return MNL_CB_OK;
 }
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 493f71f..f7fadd7 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -78,6 +78,11 @@ enum devlink_command {
 	 */
 	DEVLINK_CMD_RELOAD,
 
+	DEVLINK_CMD_PARAM_GET,		/* can dump */
+	DEVLINK_CMD_PARAM_SET,
+	DEVLINK_CMD_PARAM_NEW,
+	DEVLINK_CMD_PARAM_DEL,
+
 	/* add new commands above here */
 	__DEVLINK_CMD_MAX,
 	DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
@@ -142,6 +147,16 @@ enum devlink_port_flavour {
 				   */
 };
 
+enum devlink_param_cmode {
+	DEVLINK_PARAM_CMODE_RUNTIME,
+	DEVLINK_PARAM_CMODE_DRIVERINIT,
+	DEVLINK_PARAM_CMODE_PERMANENT,
+
+	/* Add new configuration modes above */
+	__DEVLINK_PARAM_CMODE_MAX,
+	DEVLINK_PARAM_CMODE_MAX = __DEVLINK_PARAM_CMODE_MAX - 1
+};
+
 enum devlink_attr {
 	/* don't change the order or add anything between, this is ABI! */
 	DEVLINK_ATTR_UNSPEC,
@@ -238,6 +253,15 @@ enum devlink_attr {
 	DEVLINK_ATTR_PORT_NUMBER,		/* u32 */
 	DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,	/* u32 */
 
+	DEVLINK_ATTR_PARAM,			/* nested */
+	DEVLINK_ATTR_PARAM_NAME,		/* string */
+	DEVLINK_ATTR_PARAM_GENERIC,		/* flag */
+	DEVLINK_ATTR_PARAM_TYPE,		/* u8 */
+	DEVLINK_ATTR_PARAM_VALUES_LIST,		/* nested */
+	DEVLINK_ATTR_PARAM_VALUE,		/* nested */
+	DEVLINK_ATTR_PARAM_VALUE_DATA,		/* dynamic */
+	DEVLINK_ATTR_PARAM_VALUE_CMODE,		/* u8 */
+
 	/* add new attributes above here, update the policy in devlink.c */
 
 	__DEVLINK_ATTR_MAX,
diff --git a/man/man8/devlink-dev.8 b/man/man8/devlink-dev.8
index 7c749dd..d985da1 100644
--- a/man/man8/devlink-dev.8
+++ b/man/man8/devlink-dev.8
@@ -43,6 +43,23 @@ devlink-dev \- devlink device configuration
 .IR DEV
 
 .ti -8
+.BR "devlink dev param set"
+.IR DEV
+.BR name
+.IR PARAMETER
+.BR value
+.IR VALUE
+.BR cmode " { " runtime " | " driverinit " | " permanent " } "
+
+.ti -8
+.BR "devlink dev param show"
+.RI "[ "
+.IR DEV
+.BR name
+.IR PARAMETER
+.RI "]"
+
+.ti -8
 .BR "devlink dev reload"
 .IR DEV
 
@@ -98,6 +115,36 @@ Set eswitch encapsulation support
 .I enable
 - Enable encapsulation support
 
+.SS devlink dev param set  - set new value to devlink device configuration parameter
+
+.TP
+.BI name " PARAMETER"
+Specify parameter name to set.
+
+.TP
+.BI value " VALUE"
+New value to set.
+
+.TP
+.BR cmode " { " runtime " | " driverinit " | " permanent " } "
+Configuration mode in which the new value is set.
+
+.I runtime
+- Set new value while driver is running. This configuration mode doesn't require any reset to apply the new value.
+
+.I driverinit
+- Set new value which will be applied during driver initialization. This configuration mode requires restart driver by devlink reload command to apply the new value.
+
+.I permanent
+- New value is written to device's non-volatile memory. This configuration mode requires hard reset to apply the new value.
+
+.SS devlink dev param show - display devlink device supported configuration parameters attributes
+
+.BR name
+.IR PARAMETER
+Specify parameter name to show.
+If this argument is omitted all parameters supported by devlink devices are listed.
+
 .SS devlink dev reload - perform hot reload of the driver.
 
 .PP
@@ -126,6 +173,16 @@ devlink dev eswitch set pci/0000:01:00.0 mode switchdev
 Sets the eswitch mode of specified devlink device to switchdev.
 .RE
 .PP
+devlink dev param show pci/0000:01:00.0 name max_macs
+.RS 4
+Shows the parameter max_macs attributes.
+.RE
+.PP
+devlink dev param set pci/0000:01:00.0 name internal_error_reset value true cmode runtime
+.RS 4
+Sets the parameter internal_error_reset of specified devlink device to true.
+.RE
+.PP
 devlink dev reload pci/0000:01:00.0
 .RS 4
 Performs hot reload of specified devlink device.
-- 
1.8.3.1

^ permalink raw reply related

* Re: [PATCH net] net: phy: fix flag masking in __set_phy_supported
From: Andrew Lunn @ 2018-07-04 14:13 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: Florian Fainelli, David Miller, netdev@vger.kernel.org
In-Reply-To: <c0ca1da0-2b55-19c0-708a-ccab9a97ec5c@gmail.com>

On Tue, Jul 03, 2018 at 10:34:54PM +0200, Heiner Kallweit wrote:
> Currently also the pause flags are removed from phydev->supported because
> they're not included in PHY_DEFAULT_FEATURES. I don't think this is
> intended, especially when considering that this function can be called
> via phy_set_max_speed() anywhere in a driver. Change the masking to mask
> out only the values we're going to change. In addition remove the
> misleading comment, job of this small function is just to adjust the
> supported and advertised speeds.
> 
> Fixes: f3a6bd393c2c ("phylib: Add phy_set_max_speed helper")
> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>

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

    Andrew

^ permalink raw reply

* Re: [net-next,v2] tcp: Improve setsockopt() TCP_USER_TIMEOUT accuracy
From: Neal Cardwell @ 2018-07-04 14:13 UTC (permalink / raw)
  To: Jonathan Maxwell
  Cc: David Miller, Eric Dumazet, Alexey Kuznetsov, Hideaki YOSHIFUJI,
	Netdev, LKML, jmaxwell
In-Reply-To: <20180704000608.17360-1-jmaxwell37@gmail.com>

On Tue, Jul 3, 2018 at 8:06 PM Jon Maxwell <jmaxwell37@gmail.com> wrote:
>
> Signed-off-by: Jon Maxwell <jmaxwell37@gmail.com>
> ---
>  net/ipv4/tcp_timer.c | 48 +++++++++++++++++++++++++++++++++++++++---------
>  1 file changed, 39 insertions(+), 9 deletions(-)
>
> diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
> index 3b3611729928..d129e670d02a 100644
> --- a/net/ipv4/tcp_timer.c
> +++ b/net/ipv4/tcp_timer.c
> @@ -22,6 +22,39 @@
>  #include <linux/gfp.h>
>  #include <net/tcp.h>
>
> +unsigned int tcp_retransmit_stamp(struct sock *sk)
> +{
> +       unsigned int start_ts = tcp_sk(sk)->retrans_stamp;

Since retrans_stamp and tcp_skb_timestamp() are both u32, I'd suggest
using u32 for the local variable start_ts and the return type of the
function.

> +
> +       if (unlikely(!start_ts)) {
> +               struct sk_buff *head = tcp_rtx_queue_head(sk);
> +
> +               if (!head)
> +                       return false;

Looks like a copy-and-paste holdover: since this function is returning
an integer, I would suggest returning 0 rather than false.

> +               start_ts = tcp_skb_timestamp(head);
> +       }
> +       return start_ts;
> +}
> +
> +static __u32 tcp_clamp_rto_to_user_timeout(struct sock *sk)
> +{
> +       struct inet_connection_sock *icsk = inet_csk(sk);
> +       __u32 rto = icsk->icsk_rto;
> +       __u32 elapsed, user_timeout;
> +       unsigned int start_ts;

I'd suggest u32 here for start_ts (per the rationale above).

> +
> +       start_ts = tcp_retransmit_stamp(sk);
> +       if (!icsk->icsk_user_timeout || !start_ts)
> +               return rto;
> +       elapsed = tcp_time_stamp(tcp_sk(sk)) - start_ts;
> +       user_timeout = jiffies_to_msecs(icsk->icsk_user_timeout);
> +       if (elapsed >= user_timeout)
> +               rto = 1;  /* user timeout has passed; fire ASAP */
> +       else
> +               rto = min(rto, (__u32)msecs_to_jiffies(user_timeout - elapsed));

My sense is that min_t would be preferred here, e.g:

  rto = min_t(__u32, rto, msecs_to_jiffies(user_timeout - elapsed));

> +       return rto;
> +}
> +
>  /**
>   *  tcp_write_err() - close socket and save error info
>   *  @sk:  The socket the error has appeared on.
> @@ -166,14 +199,9 @@ static bool retransmits_timed_out(struct sock *sk,
>         if (!inet_csk(sk)->icsk_retransmits)
>                 return false;
>
> -       start_ts = tcp_sk(sk)->retrans_stamp;
> -       if (unlikely(!start_ts)) {
> -               struct sk_buff *head = tcp_rtx_queue_head(sk);
> -
> -               if (!head)
> -                       return false;
> -               start_ts = tcp_skb_timestamp(head);
> -       }
> +       start_ts = tcp_retransmit_stamp(sk);
> +       if (!start_ts)
> +               return false;
>
>         if (likely(timeout == 0)) {
>                 linear_backoff_thresh = ilog2(TCP_RTO_MAX/rto_base);
> @@ -407,6 +435,7 @@ void tcp_retransmit_timer(struct sock *sk)
>         struct tcp_sock *tp = tcp_sk(sk);
>         struct net *net = sock_net(sk);
>         struct inet_connection_sock *icsk = inet_csk(sk);
> +       __u32 rto;
>
>         if (tp->fastopen_rsk) {
>                 WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV &&
> @@ -535,7 +564,8 @@ void tcp_retransmit_timer(struct sock *sk)
>                 /* Use normal (exponential) backoff */
>                 icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX);
>         }
> -       inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX);
> +       rto = tcp_clamp_rto_to_user_timeout(sk);
> +       inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, rto, TCP_RTO_MAX);
>         if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1 + 1, 0))
>                 __sk_dst_reset(sk);


Thanks!
neal

^ permalink raw reply

* [PATCH 0/2] net: qrtr: Broadcasting control messages
From: Arun Kumar Neelakantam @ 2018-07-04 14:19 UTC (permalink / raw)
  To: davem, bjorn.andersson
  Cc: netdev, linux-kernel, linux-arm-msm, Arun Kumar Neelakantam

Allow messages only from control port to broadcast to avoid unnecessary 
messages and reset the node to local router NODE ID in control messages
otherwise remote routers consider the packets as invalid and Drops it.

Arun Kumar Neelakantam (2):
  net: qrtr: Broadcast messages only from control port
  net: qrtr: Reset the node and port ID of broadcast messages

 net/qrtr/qrtr.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* [PATCH 1/2] net: qrtr: Broadcast messages only from control port
From: Arun Kumar Neelakantam @ 2018-07-04 14:19 UTC (permalink / raw)
  To: davem, bjorn.andersson
  Cc: netdev, linux-kernel, linux-arm-msm, Arun Kumar Neelakantam,
	Florian Westphal, Nicolas Dechesne, Denys Vlasenko
In-Reply-To: <1530713973-26696-1-git-send-email-aneela@codeaurora.org>

The broadcast node id should only be sent with the control port id.

Signed-off-by: Arun Kumar Neelakantam <aneela@codeaurora.org>
---
 net/qrtr/qrtr.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index 2aa07b5..7ffc9a3 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -764,6 +764,10 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
 	node = NULL;
 	if (addr->sq_node == QRTR_NODE_BCAST) {
 		enqueue_fn = qrtr_bcast_enqueue;
+		if (addr->sq_port != QRTR_PORT_CTRL) {
+			release_sock(sk);
+			return -ENOTCONN;
+		}
 	} else if (addr->sq_node == ipc->us.sq_node) {
 		enqueue_fn = qrtr_local_enqueue;
 	} else {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ 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