* Re: [PATCH net-next v3 06/13] net: dsa: Add support for querying supported bridge flags
From: Florian Fainelli @ 2017-08-07 18:01 UTC (permalink / raw)
To: Arkadi Sharshevsky, netdev
Cc: davem, jiri, ivecera, andrew, vivien.didelot, Woojung.Huh, mlxsw
In-Reply-To: <1502025351-41261-7-git-send-email-arkadis@mellanox.com>
On 08/06/2017 06:15 AM, Arkadi Sharshevsky wrote:
> The DSA drivers do not support bridge flags offload. Yet, this attribute
> should be added in order for the bridge to fail when one tries set a
> flag on the port, as explained in commit dc0ecabd6231 ("net: switchdev:
> Add support for querying supported bridge flags by hardware").
>
> Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com>
> Reviewed-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
^ permalink raw reply
* Re: [PATCH] of_mdio: use of_property_read_u32_array()
From: Florian Fainelli @ 2017-08-07 18:01 UTC (permalink / raw)
To: Sergei Shtylyov, Rob Herring
Cc: Andrew Lunn, Frank Rowand, netdev, devicetree@vger.kernel.org
In-Reply-To: <080ebcb6-b5aa-63db-176b-83477c2540e5@cogentembedded.com>
On 08/07/2017 09:18 AM, Sergei Shtylyov wrote:
> Hello!
>
> On 08/07/2017 05:18 PM, Rob Herring wrote:
>
>>> The "fixed-link" prop support predated of_property_read_u32_array(), so
>>> basically had to open-code it. Using the modern API saves 24 bytes of
>>> the
>>> object code (ARM gcc 4.8.5); the only behavior change would be that the
>>> prop length check is now less strict (however the strict pre-check done
>>> in of_phy_is_fixed_link() is left intact anyway)...
>>>
>>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>>>
>>> ---
>>> The patch is against the 'dt/next' branch of Rob Herring's
>>> 'linux-git' repo
>>> plus the previously posted patch killing the useless local variable in
>>> of_phy_register_fixed_link().
>>
>> It shouldn't depend on anything in my tree and David normally takes
>> of_mdio.c changes.
>
> MAINTAINERS still only point at the DT repo, perhaps it should be
> updated?
More or less done with this (minus the repo part):
http://patchwork.ozlabs.org/patch/795887/
--
Florian
^ permalink raw reply
* [PATCH] TCP_USER_TIMEOUT and tcp_keepalive should conform to RFC5482
From: Rao Shoaib @ 2017-08-07 17:51 UTC (permalink / raw)
To: davem, kuznet; +Cc: netdev
Signed-off-by: Rao Shoaib <rao.shoaib@oracle.com>
---
net/ipv4/tcp.c | 10 ++++++++--
net/ipv4/tcp_timer.c | 9 +--------
2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 71ce33d..f2af44d 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2628,7 +2628,9 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
break;
case TCP_KEEPIDLE:
- if (val < 1 || val > MAX_TCP_KEEPIDLE)
+ /* Per RFC5482 keepalive_time must be > user_timeout */
+ if (val < 1 || val > MAX_TCP_KEEPIDLE ||
+ ((val * HZ) <= icsk->icsk_user_timeout))
err = -EINVAL;
else {
tp->keepalive_time = val * HZ;
@@ -2724,8 +2726,12 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
case TCP_USER_TIMEOUT:
/* Cap the max time in ms TCP will retry or probe the window
* before giving up and aborting (ETIMEDOUT) a connection.
+ * Per RFC5482 TCP user timeout must be < keepalive_time.
+ * If the default value changes later -- all bets are off.
*/
- if (val < 0)
+ if (val < 0 || (tp->keepalive_time &&
+ tp->keepalive_time <= msecs_to_jiffies(val)) ||
+ net->ipv4.sysctl_tcp_keepalive_time <= msecs_to_jiffies(val))
err = -EINVAL;
else
icsk->icsk_user_timeout = msecs_to_jiffies(val);
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index c0feeee..d39fe60 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -664,14 +664,7 @@ static void tcp_keepalive_timer (unsigned long data)
elapsed = keepalive_time_elapsed(tp);
if (elapsed >= keepalive_time_when(tp)) {
- /* If the TCP_USER_TIMEOUT option is enabled, use that
- * to determine when to timeout instead.
- */
- if ((icsk->icsk_user_timeout != 0 &&
- elapsed >= icsk->icsk_user_timeout &&
- icsk->icsk_probes_out > 0) ||
- (icsk->icsk_user_timeout == 0 &&
- icsk->icsk_probes_out >= keepalive_probes(tp))) {
+ if (icsk->icsk_probes_out >= keepalive_probes(tp)) {
tcp_send_active_reset(sk, GFP_ATOMIC);
tcp_write_err(sk);
goto out;
--
2.7.4
^ permalink raw reply related
* Re: [Patch net-next 1/2] net_sched: refactor notification code for RTM_DELTFILTER
From: Cong Wang @ 2017-08-07 17:50 UTC (permalink / raw)
To: Jamal Hadi Salim; +Cc: Linux Kernel Network Developers, Jiri Pirko
In-Reply-To: <7b8c926f-8c28-b403-e380-c6ae521c9cc0@mojatatu.com>
On Sun, Aug 6, 2017 at 4:42 AM, Jamal Hadi Salim <jhs@mojatatu.com> wrote:
> On 17-08-05 12:31 AM, Cong Wang wrote:
>> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
>> index e655221c654e..afd099727aea 100644
>> --- a/net/sched/cls_api.c
>> +++ b/net/sched/cls_api.c
>> @@ -104,6 +104,10 @@ static int tfilter_notify(struct net *net, struct
>> sk_buff *oskb,
>> struct nlmsghdr *n, struct tcf_proto *tp,
>> unsigned long fh, int event, bool unicast);
>> +static int tfilter_del_notify(struct net *net, struct sk_buff *oskb,
>> + struct nlmsghdr *n, struct tcf_proto *tp,
>> + unsigned long fh, bool unicast, bool *last);
>> +
>
>
> Any reason not to move the functin up here and getting rid of this
> forward declaration?
It calls tcf_fill_node() which is defined at line 643,
it is called at line 602. Moving it requires moves the
rest, this makes this patch unnecessarily bigger.
Why not make it a separate patch?
^ permalink raw reply
* Re: Qdisc->u32_node - licence to kill
From: John Fastabend @ 2017-08-07 17:47 UTC (permalink / raw)
To: Jiri Pirko, jhs, xiyou.wangcong, davem; +Cc: netdev, mlxsw
In-Reply-To: <20170807164100.GK2085@nanopsycho.orion>
On 08/07/2017 09:41 AM, Jiri Pirko wrote:
> Hi Jamal/Cong/David/all.
>
> Digging in the u32 code deeper now. I need to get rid of tp->q for shared
> blocks, but I found out about this:
>
> struct Qdisc {
> ......
> void *u32_node;
> ......
> };
>
> Yeah, ugly. u32 uses it to store some shared data, tp_c. It actually
> stores a linked list of all hashtables added to one qdiscs.
>
> So basically what you have is, you have 1 root ht per prio/pref. Then
> you can have multiple hts, linked from any other ht, does not matter in
> which prio/pref they are.
>
We can create arbitrary hash tables here independent of prio/pref via
TCA_U32_DIVISOR. Then these can be linked to other hash tables via
TCA_U32_LINK commands.
prio/pref does not really play any part here from my reading, except as
a further specifier in the walk callbacks. Making it a useful filter on
dump operations.
> Do I understand that correctly that prio/pref only has meaning if
> linking does not take place, because if there is linking, the prio/pref
> of inserted rule is simply ignored?
I think even then the prio/pref meaning is dubious, from u32_change,
for (pins = rtnl_dereference(*ins); pins;
ins = &pins->next, pins = rtnl_dereference(*ins))
if (TC_U32_NODE(handle) < TC_U32_NODE(pins->handle))
break;
I think the list insert is done via handle not via prio/pref.
>
> That is the most confusing thing I saw in net/sched/ so far.
> Is this a bug? Sounds like one.
>
I don't think this is a bug at very least I don't see how we can
change it without breaking users. I know people depend on the hash map
capabilities and linking logic.
> Did someone introduce *u32_node (formerly static struct tc_u_common
> *u32_list;) just to allow this weirdness?
>
> Can I just remove this shared tp_c and make the linking to other
> hashtables only possible within the same prio/pref? That would make
> sense to me.
>
The idea to make linking hash tables only possible within the same
prio/pref will break existing programs. We can't do this its part of
UAPI now and people depend on it.
> Thanks.
>
> Jiri
>
^ permalink raw reply
* [PATCH net-next] liquidio: fix wrong info about vf rx/tx ring parameters reported to ethtool
From: Felix Manlunas @ 2017-08-07 17:39 UTC (permalink / raw)
To: davem
Cc: netdev, raghu.vatsavayi, derek.chickles, satananda.burla,
intiyaz.basha
From: Intiyaz Basha <intiyaz.basha@cavium.com>
Information reported to ethtool about vf rx/tx ring parameters is wrong.
Fix it by adding the missing initializations.
Signed-off-by: Intiyaz Basha <intiyaz.basha@cavium.com>
Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com>
---
drivers/net/ethernet/cavium/liquidio/lio_ethtool.c | 30 +++++++---------------
1 file changed, 9 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c b/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c
index 09e2875..b78e296 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c
@@ -649,33 +649,21 @@ lio_ethtool_get_ringparam(struct net_device *netdev,
rx_max_pending = CN6XXX_MAX_OQ_DESCRIPTORS;
rx_pending = CFG_GET_NUM_RX_DESCS_NIC_IF(conf6x, lio->ifidx);
tx_pending = CFG_GET_NUM_TX_DESCS_NIC_IF(conf6x, lio->ifidx);
- } else if (OCTEON_CN23XX_PF(oct)) {
- struct octeon_config *conf23 = CHIP_CONF(oct, cn23xx_pf);
-
+ } else if (OCTEON_CN23XX_PF(oct) || OCTEON_CN23XX_VF(oct)) {
tx_max_pending = CN23XX_MAX_IQ_DESCRIPTORS;
rx_max_pending = CN23XX_MAX_OQ_DESCRIPTORS;
- rx_pending = CFG_GET_NUM_RX_DESCS_NIC_IF(conf23, lio->ifidx);
- tx_pending = CFG_GET_NUM_TX_DESCS_NIC_IF(conf23, lio->ifidx);
- }
-
- if (lio->mtu > OCTNET_DEFAULT_FRM_SIZE - OCTNET_FRM_HEADER_SIZE) {
- ering->rx_pending = 0;
- ering->rx_max_pending = 0;
- ering->rx_mini_pending = 0;
- ering->rx_jumbo_pending = rx_pending;
- ering->rx_mini_max_pending = 0;
- ering->rx_jumbo_max_pending = rx_max_pending;
- } else {
- ering->rx_pending = rx_pending;
- ering->rx_max_pending = rx_max_pending;
- ering->rx_mini_pending = 0;
- ering->rx_jumbo_pending = 0;
- ering->rx_mini_max_pending = 0;
- ering->rx_jumbo_max_pending = 0;
+ rx_pending = oct->droq[0]->max_count;
+ tx_pending = oct->instr_queue[0]->max_count;
}
ering->tx_pending = tx_pending;
ering->tx_max_pending = tx_max_pending;
+ ering->rx_pending = rx_pending;
+ ering->rx_max_pending = rx_max_pending;
+ ering->rx_mini_pending = 0;
+ ering->rx_jumbo_pending = 0;
+ ering->rx_mini_max_pending = 0;
+ ering->rx_jumbo_max_pending = 0;
}
static u32 lio_get_msglevel(struct net_device *netdev)
^ permalink raw reply related
* Re: [PATCH 0/6] In-kernel QMI handling
From: Bjorn Andersson @ 2017-08-07 17:38 UTC (permalink / raw)
To: Dan Williams
Cc: David S. Miller, Andy Gross, David Brown, linux-arm-msm,
linux-soc, netdev, linux-kernel
In-Reply-To: <1501860967.939.6.camel@redhat.com>
On Fri 04 Aug 08:36 PDT 2017, Dan Williams wrote:
> On Fri, 2017-08-04 at 07:59 -0700, Bjorn Andersson wrote:
> > This series starts by moving the common definitions of the QMUX
> > protocol to the
> > uapi header, as they are shared with clients - both in kernel and
> > userspace.
> >
> > This series then introduces in-kernel helper functions for aiding the
> > handling
> > of QMI encoded messages in the kernel. QMI encoding is a wire-format
> > used in
> > exchanging messages between the majority of QRTR clients and
> > services.
>
> This raises a few red-flags for me.
I'm glad it does. In discussions with the responsible team within
Qualcomm I've highlighted a number of concerns about enabling this
support in the kernel. Together we're continuously looking into what
should be pushed out to user space, and trying to not introduce
unnecessary new users.
> So far, we've kept almost everything QMI related in userspace and
> handled all QMI control-channel messages from libraries like libqmi or
> uqmi via the cdc-wdm driver and the "rmnet" interface via the qmi_wwan
> driver. The kernel drivers just serve as the transport.
>
The path that was taken to support the MSM-style devices was to
implement net/qrtr, which exposes a socket interface to abstract the
physical transports (QMUX or IPCROUTER in Qualcomm terminology).
As I share you view on letting the kernel handle the transportation only
the task of keeping track of registered services (service id -> node and
port mapping) was done in a user space process and so far we've only
ever have to deal with QMI encoded messages in various user space tools.
> Can you describe what kinds of in-kernel drivers need to actually parse
> QMI messages as part of their operation?
>
= "sysmon"
sysmon is a mechanism in Qualcomm devices to notify remote processors
when other remote processors goes away. This is required for such things
as letting the modem firmware know that the audio path is gone in the
case that the adsp abruptly disappears - i.e. when the adsp hits a
watchdog bite and doesn't have a chance to close the modem<->audio
communication channels.
In previous platforms the sysmon messages was just handled by packed
structs, but this was changed to being done using QMI and IPCROUTER
recently.
These messages needs to be sent before we attempt to restart the remote
processor and doing this from user space causes synchronization issues.
= Qualcomm slimbus implementation
The slimbus implementation in Qualcomm MSM devices expects a few QMI
encoded control messages to be sent for configuration and power
management purposes. So in order to get audio from the audio blocks to
the codec we need to send a few QMI encoded messages in the Qualcomm
slimbus driver.
As this is used to communicate power management states from the kernel
driver I see it infeasible to do this from user space.
= IPQ8074 WiFi driver
In many Qualcomm SoC the WiFi solution is split between an in-SoC core
that does protocol handling and an off-chip RF module. The communication
of control messages with the protocol core is done over shared memory
transports (SMD or GLINK) and has in the past (WCN3620, 3660 and 3680)
been done with packed structs. In the latest incarnation this is
replaced by QMI-encoded messages.
Qualcomm is trying to move forward in upstreaming a driver for this, as
part of their push to get IPQ8074 support upstream. I have not reviewed
the new version of this driver, but the driver for the previous
generation dealt with a mixture of control messages, dealing with DMA
channels and direct hardware control - so this does indeed look to
require in-kernel QMI messaging.
Regards,
Bjorn
> Dan
>
> > It then adds an abstractions to reduce the duplication of common code
> > in
> > drivers that needs to query the name server and send and receive
> > encoded
> > messages to a remote service.
> >
> > Finally it introduces a sample implementation for showing QRTR and
> > the QMI
> > helpers in action. The sample device instantiates in response to
> > finding the
> > "test service" and implements the "test protocol".
> >
> > Bjorn Andersson (6):
> > net: qrtr: Invoke sk_error_report() after setting sk_err
> > net: qrtr: Move constants to header file
> > net: qrtr: Add control packet definition to uapi
> > soc: qcom: Introduce QMI encoder/decoder
> > soc: qcom: Introduce QMI helpers
> > samples: Introduce Qualcomm QRTR sample client
> >
> > drivers/soc/qcom/Kconfig | 8 +
> > drivers/soc/qcom/Makefile | 3 +
> > drivers/soc/qcom/qmi_encdec.c | 812
> > ++++++++++++++++++++++++++++++++++++++
> > drivers/soc/qcom/qmi_interface.c | 540 +++++++++++++++++++++++++
> > include/linux/soc/qcom/qmi.h | 249 ++++++++++++
> > include/uapi/linux/qrtr.h | 35 ++
> > net/qrtr/qrtr.c | 16 +-
> > samples/Kconfig | 8 +
> > samples/Makefile | 2 +-
> > samples/qrtr/Makefile | 1 +
> > samples/qrtr/qrtr_sample_client.c | 603 ++++++++++++++++++++++++++++
> > 11 files changed, 2261 insertions(+), 16 deletions(-)
> > create mode 100644 drivers/soc/qcom/qmi_encdec.c
> > create mode 100644 drivers/soc/qcom/qmi_interface.c
> > create mode 100644 include/linux/soc/qcom/qmi.h
> > create mode 100644 samples/qrtr/Makefile
> > create mode 100644 samples/qrtr/qrtr_sample_client.c
> >
^ permalink raw reply
* Re: Re: [PATCH net] ppp: Fix a scheduling-while-atomic bug in del_chan
From: Cong Wang @ 2017-08-07 17:34 UTC (permalink / raw)
To: Gao Feng; +Cc: xeb, David Miller, Linux Kernel Network Developers
In-Reply-To: <CAM_iQpWmJmk=_yoV8=krOWonE_0orTC5Z4GaCnPg8Jv3GX6dmw@mail.gmail.com>
On Mon, Aug 7, 2017 at 10:17 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> Unless I miss any other code path, pptp_exit_module() is
> problematic too, I don't think it can just vfree() the whole thing.
>
This path should be fine, because:
1. sock holds a refcnt to module via proto->owner
2. gre_del_protocol() already waits for readers
^ permalink raw reply
* [PATCH v3 net-next 5/5] ulp: Documention for ULP infrastructure
From: Tom Herbert @ 2017-08-07 17:28 UTC (permalink / raw)
To: netdev; +Cc: rohit, davejwatson, john.fastabend, Tom Herbert
In-Reply-To: <20170807172818.31855-1-tom@quantonium.net>
Add a doc in Documentation/networking
Signed-off-by: Tom Herbert <tom@quantonium.net>
---
Documentation/networking/ulp.txt | 82 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 82 insertions(+)
create mode 100644 Documentation/networking/ulp.txt
diff --git a/Documentation/networking/ulp.txt b/Documentation/networking/ulp.txt
new file mode 100644
index 000000000000..5f6ae2153e69
--- /dev/null
+++ b/Documentation/networking/ulp.txt
@@ -0,0 +1,82 @@
+Upper Layer Protocol (ULP) Infrastructure
+=========================================
+
+The ULP kernel infrastructure provides a means to hook upper layer
+protocol support on a socket. A module may register a ULP hook
+in the kernel. ULP processing is enabled by a setsockopt on a socket
+that specifies the name of the registered ULP to invoked. An
+initialization function is defined for each ULP that can change the
+function entry points of the socket (sendmsg, rcvmsg, etc.) or change
+the socket in other fundamental ways.
+
+Note, no synchronization is enforced between the setsockopt to enable
+a ULP and ongoing asynchronous operations on the socket (such as a
+blocked read). If synchronization is required this must be handled by
+the ULP and caller.
+
+User interface
+==============
+
+The structure for the socket SOL_ULP options is defined in socket.h.
+
+Example to enable "my_ulp" ULP on a socket:
+
+struct ulp_config ulpc = {
+ .ulp_name = "my_ulp",
+};
+
+setsockopt(sock, SOL_SOCKET, SO_ULP, &ulpc, sizeof(ulpc))
+
+The ulp_config struct includes a "__u8 ulp_params[0]" field that may be
+used to refer ULP specific parameters being set.
+
+Kernel interface
+================
+
+The interface for ULP infrastructure is defined in net/ulp_sock.h.
+
+ULP registration functions
+--------------------------
+
+int ulp_register(struct ulp_ops *type)
+
+ Called to register a ULP. The ulp_ops structure is described below.
+
+void ulp_unregister(struct ulp_ops *type);
+
+ Called to unregister a ULP.
+
+ulp_ops structure
+-----------------
+
+int (*init)(struct sock *sk, char __user *optval, int len)
+
+ Initialization function for the ULP. This is called from setsockopt
+ when the ULP name in the ulp_config argument matches the registered
+ ULP. optval is a userspace pointer to the ULP specific parameters.
+ len is the length of the ULP specific parameters.
+
+void (*release)(struct sock *sk)
+
+ Called when socket is being destroyed. The ULP implementation
+ should cancel any asynchronous operations (such as timers) and
+ release any acquired resources.
+
+int (*get_params)(struct sock *sk, char __user *optval, int *optlen)
+
+ Get the ULP specific parameters previous set in the init function
+ for the ULP. Note that optlen is a pointer to kernel memory.
+
+char name[ULP_NAME_MAX]
+
+ Name of the ULP. Must be NULL terminated.
+
+struct module *owner
+
+ Corresponding owner for ref count.
+
+Author
+======
+
+Tom Herbert (tom@quantonium.net)
+
--
2.11.0
^ permalink raw reply related
* [PATCH v3 net-next 4/5] tcp: Adjust TCP ULP to defer to sockets ULP
From: Tom Herbert @ 2017-08-07 17:28 UTC (permalink / raw)
To: netdev; +Cc: rohit, davejwatson, john.fastabend, Tom Herbert
In-Reply-To: <20170807172818.31855-1-tom@quantonium.net>
Fix TCP and TLS to use the newer ULP infrastructure in sockets.
Signed-off-by: Tom Herbert <tom@quantonium.net>
---
Documentation/networking/tls.txt | 6 +-
include/net/inet_connection_sock.h | 4 --
include/net/tcp.h | 25 -------
include/net/tls.h | 4 +-
net/ipv4/Makefile | 2 +-
net/ipv4/sysctl_net_ipv4.c | 9 ++-
net/ipv4/tcp.c | 42 +++++++-----
net/ipv4/tcp_ipv4.c | 2 -
net/ipv4/tcp_ulp.c | 135 -------------------------------------
net/tls/Kconfig | 1 +
net/tls/tls_main.c | 24 ++++---
11 files changed, 53 insertions(+), 201 deletions(-)
delete mode 100644 net/ipv4/tcp_ulp.c
diff --git a/Documentation/networking/tls.txt b/Documentation/networking/tls.txt
index 77ed00631c12..b70309df4709 100644
--- a/Documentation/networking/tls.txt
+++ b/Documentation/networking/tls.txt
@@ -12,8 +12,12 @@ Creating a TLS connection
First create a new TCP socket and set the TLS ULP.
+ struct ulp_config ulpc = {
+ .ulp_name = "tls",
+ };
+
sock = socket(AF_INET, SOCK_STREAM, 0);
- setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls"));
+ setsockopt(sock, SOL_SOCKET, SO_ULP, &ulpc, sizeof(ulpc))
Setting the TLS ULP allows us to set/get TLS socket options. Currently
only the symmetric encryption is handled in the kernel. After the TLS
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index 13e4c89a8231..c7a577976bec 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -75,8 +75,6 @@ struct inet_connection_sock_af_ops {
* @icsk_pmtu_cookie Last pmtu seen by socket
* @icsk_ca_ops Pluggable congestion control hook
* @icsk_af_ops Operations which are AF_INET{4,6} specific
- * @icsk_ulp_ops Pluggable ULP control hook
- * @icsk_ulp_data ULP private data
* @icsk_ca_state: Congestion control state
* @icsk_retransmits: Number of unrecovered [RTO] timeouts
* @icsk_pending: Scheduled timer event
@@ -99,8 +97,6 @@ struct inet_connection_sock {
__u32 icsk_pmtu_cookie;
const struct tcp_congestion_ops *icsk_ca_ops;
const struct inet_connection_sock_af_ops *icsk_af_ops;
- const struct tcp_ulp_ops *icsk_ulp_ops;
- void *icsk_ulp_data;
unsigned int (*icsk_sync_mss)(struct sock *sk, u32 pmtu);
__u8 icsk_ca_state:6,
icsk_ca_setsockopt:1,
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 5173fecde495..84adac23d324 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1969,31 +1969,6 @@ static inline void tcp_listendrop(const struct sock *sk)
enum hrtimer_restart tcp_pace_kick(struct hrtimer *timer);
-/*
- * Interface for adding Upper Level Protocols over TCP
- */
-
-#define TCP_ULP_NAME_MAX 16
-#define TCP_ULP_MAX 128
-#define TCP_ULP_BUF_MAX (TCP_ULP_NAME_MAX*TCP_ULP_MAX)
-
-struct tcp_ulp_ops {
- struct list_head list;
-
- /* initialize ulp */
- int (*init)(struct sock *sk);
- /* cleanup ulp */
- void (*release)(struct sock *sk);
-
- char name[TCP_ULP_NAME_MAX];
- struct module *owner;
-};
-int tcp_register_ulp(struct tcp_ulp_ops *type);
-void tcp_unregister_ulp(struct tcp_ulp_ops *type);
-int tcp_set_ulp(struct sock *sk, const char *name);
-void tcp_get_available_ulp(char *buf, size_t len);
-void tcp_cleanup_ulp(struct sock *sk);
-
/* Call BPF_SOCK_OPS program that returns an int. If the return value
* is < 0, then the BPF op failed (for example if the loaded BPF
* program does not support the chosen operation or there is no BPF
diff --git a/include/net/tls.h b/include/net/tls.h
index b89d397dd62f..7d88a6e2f5a7 100644
--- a/include/net/tls.h
+++ b/include/net/tls.h
@@ -214,9 +214,7 @@ static inline void tls_fill_prepend(struct tls_context *ctx,
static inline struct tls_context *tls_get_ctx(const struct sock *sk)
{
- struct inet_connection_sock *icsk = inet_csk(sk);
-
- return icsk->icsk_ulp_data;
+ return sk->sk_ulp_data;
}
static inline struct tls_sw_context *tls_sw_ctx(
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index afcb435adfbe..f83de23a30e7 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -8,7 +8,7 @@ obj-y := route.o inetpeer.o protocol.o \
inet_timewait_sock.o inet_connection_sock.o \
tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \
tcp_minisocks.o tcp_cong.o tcp_metrics.o tcp_fastopen.o \
- tcp_rate.o tcp_recovery.o tcp_ulp.o \
+ tcp_rate.o tcp_recovery.o \
tcp_offload.o datagram.o raw.o udp.o udplite.o \
udp_offload.o arp.o icmp.o devinet.o af_inet.o igmp.o \
fib_frontend.o fib_semantics.o fib_trie.o fib_notifier.o \
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 0d3c038d7b04..9ab0c278b7ba 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -21,6 +21,7 @@
#include <net/route.h>
#include <net/tcp.h>
#include <net/udp.h>
+#include <net/ulp_sock.h>
#include <net/cipso_ipv4.h>
#include <net/inet_frag.h>
#include <net/ping.h>
@@ -372,13 +373,15 @@ static int proc_tcp_available_ulp(struct ctl_table *ctl,
void __user *buffer, size_t *lenp,
loff_t *ppos)
{
- struct ctl_table tbl = { .maxlen = TCP_ULP_BUF_MAX, };
+ struct ctl_table tbl = { .maxlen = ULP_BUF_MAX, };
int ret;
tbl.data = kmalloc(tbl.maxlen, GFP_USER);
if (!tbl.data)
return -ENOMEM;
- tcp_get_available_ulp(tbl.data, TCP_ULP_BUF_MAX);
+
+ /* Just return all ULPs for compatibility */
+ ulp_get_available(tbl.data, ULP_BUF_MAX);
ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
kfree(tbl.data);
@@ -709,7 +712,7 @@ static struct ctl_table ipv4_table[] = {
},
{
.procname = "tcp_available_ulp",
- .maxlen = TCP_ULP_BUF_MAX,
+ .maxlen = ULP_BUF_MAX,
.mode = 0444,
.proc_handler = proc_tcp_available_ulp,
},
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 71b25567e787..b1ca6b4c605c 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2434,24 +2434,25 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
release_sock(sk);
return err;
}
+
case TCP_ULP: {
- char name[TCP_ULP_NAME_MAX];
+ struct ulp_config ulpc;
if (optlen < 1)
return -EINVAL;
- val = strncpy_from_user(name, optval,
- min_t(long, TCP_ULP_NAME_MAX - 1,
+ val = strncpy_from_user(ulpc.ulp_name, optval,
+ min_t(long, ULP_NAME_MAX - 1,
optlen));
if (val < 0)
return -EFAULT;
- name[val] = 0;
- lock_sock(sk);
- err = tcp_set_ulp(sk, name);
- release_sock(sk);
- return err;
+ ulpc.ulp_name[val] = 0;
+
+ return kernel_setsockopt(sk->sk_socket, SOL_SOCKET, SO_ULP,
+ (char *)&ulpc, sizeof(ulpc));
}
+
default:
/* fallthru */
break;
@@ -3023,20 +3024,29 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
return -EFAULT;
return 0;
- case TCP_ULP:
+ case TCP_ULP: {
+ struct ulp_config ulpc;
+ int ulen, ret;
+
if (get_user(len, optlen))
return -EFAULT;
- len = min_t(unsigned int, len, TCP_ULP_NAME_MAX);
- if (!icsk->icsk_ulp_ops) {
- if (put_user(0, optlen))
- return -EFAULT;
- return 0;
- }
+
+ len = min_t(unsigned int, len, ULP_NAME_MAX);
+
+ ulen = sizeof(ulpc);
+
+ /* Backwards compatbility */
+ ret = kernel_getsockopt(sk->sk_socket, SOL_SOCKET, SO_ULP,
+ (char *)&ulpc, &ulen);
+ if (ret)
+ return ret;
+
if (put_user(len, optlen))
return -EFAULT;
- if (copy_to_user(optval, icsk->icsk_ulp_ops->name, len))
+ if (copy_to_user(optval, ulpc.ulp_name, len))
return -EFAULT;
return 0;
+ }
case TCP_THIN_LINEAR_TIMEOUTS:
val = tp->thin_lto;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 5f708c85110e..95e47c641f17 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1858,8 +1858,6 @@ void tcp_v4_destroy_sock(struct sock *sk)
tcp_cleanup_congestion_control(sk);
- tcp_cleanup_ulp(sk);
-
/* Cleanup up the write buffer. */
tcp_write_queue_purge(sk);
diff --git a/net/ipv4/tcp_ulp.c b/net/ipv4/tcp_ulp.c
deleted file mode 100644
index 2417f55374c5..000000000000
--- a/net/ipv4/tcp_ulp.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Pluggable TCP upper layer protocol support.
- *
- * Copyright (c) 2016-2017, Mellanox Technologies. All rights reserved.
- * Copyright (c) 2016-2017, Dave Watson <davejwatson@fb.com>. All rights reserved.
- *
- */
-
-#include<linux/module.h>
-#include <linux/mm.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/gfp.h>
-#include <net/tcp.h>
-
-static DEFINE_SPINLOCK(tcp_ulp_list_lock);
-static LIST_HEAD(tcp_ulp_list);
-
-/* Simple linear search, don't expect many entries! */
-static struct tcp_ulp_ops *tcp_ulp_find(const char *name)
-{
- struct tcp_ulp_ops *e;
-
- list_for_each_entry_rcu(e, &tcp_ulp_list, list) {
- if (strcmp(e->name, name) == 0)
- return e;
- }
-
- return NULL;
-}
-
-static const struct tcp_ulp_ops *__tcp_ulp_find_autoload(const char *name)
-{
- const struct tcp_ulp_ops *ulp = NULL;
-
- rcu_read_lock();
- ulp = tcp_ulp_find(name);
-
-#ifdef CONFIG_MODULES
- if (!ulp && capable(CAP_NET_ADMIN)) {
- rcu_read_unlock();
- request_module("%s", name);
- rcu_read_lock();
- ulp = tcp_ulp_find(name);
- }
-#endif
- if (!ulp || !try_module_get(ulp->owner))
- ulp = NULL;
-
- rcu_read_unlock();
- return ulp;
-}
-
-/* Attach new upper layer protocol to the list
- * of available protocols.
- */
-int tcp_register_ulp(struct tcp_ulp_ops *ulp)
-{
- int ret = 0;
-
- spin_lock(&tcp_ulp_list_lock);
- if (tcp_ulp_find(ulp->name)) {
- pr_notice("%s already registered or non-unique name\n",
- ulp->name);
- ret = -EEXIST;
- } else {
- list_add_tail_rcu(&ulp->list, &tcp_ulp_list);
- }
- spin_unlock(&tcp_ulp_list_lock);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(tcp_register_ulp);
-
-void tcp_unregister_ulp(struct tcp_ulp_ops *ulp)
-{
- spin_lock(&tcp_ulp_list_lock);
- list_del_rcu(&ulp->list);
- spin_unlock(&tcp_ulp_list_lock);
-
- synchronize_rcu();
-}
-EXPORT_SYMBOL_GPL(tcp_unregister_ulp);
-
-/* Build string with list of available upper layer protocl values */
-void tcp_get_available_ulp(char *buf, size_t maxlen)
-{
- struct tcp_ulp_ops *ulp_ops;
- size_t offs = 0;
-
- *buf = '\0';
- rcu_read_lock();
- list_for_each_entry_rcu(ulp_ops, &tcp_ulp_list, list) {
- offs += snprintf(buf + offs, maxlen - offs,
- "%s%s",
- offs == 0 ? "" : " ", ulp_ops->name);
- }
- rcu_read_unlock();
-}
-
-void tcp_cleanup_ulp(struct sock *sk)
-{
- struct inet_connection_sock *icsk = inet_csk(sk);
-
- if (!icsk->icsk_ulp_ops)
- return;
-
- if (icsk->icsk_ulp_ops->release)
- icsk->icsk_ulp_ops->release(sk);
- module_put(icsk->icsk_ulp_ops->owner);
-}
-
-/* Change upper layer protocol for socket */
-int tcp_set_ulp(struct sock *sk, const char *name)
-{
- struct inet_connection_sock *icsk = inet_csk(sk);
- const struct tcp_ulp_ops *ulp_ops;
- int err = 0;
-
- if (icsk->icsk_ulp_ops)
- return -EEXIST;
-
- ulp_ops = __tcp_ulp_find_autoload(name);
- if (!ulp_ops)
- err = -ENOENT;
- else
- err = ulp_ops->init(sk);
-
- if (err)
- goto out;
-
- icsk->icsk_ulp_ops = ulp_ops;
- out:
- return err;
-}
diff --git a/net/tls/Kconfig b/net/tls/Kconfig
index eb583038c67e..60ae4e9b257e 100644
--- a/net/tls/Kconfig
+++ b/net/tls/Kconfig
@@ -7,6 +7,7 @@ config TLS
select CRYPTO
select CRYPTO_AES
select CRYPTO_GCM
+ select ULP_SOCK
default n
---help---
Enable kernel support for TLS protocol. This allows symmetric
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index 60aff60e30ad..f5c90efec8b4 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -31,15 +31,15 @@
* SOFTWARE.
*/
-#include <linux/module.h>
-
-#include <net/tcp.h>
-#include <net/inet_common.h>
#include <linux/highmem.h>
+#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/sched/signal.h>
-
+#include <net/inet_common.h>
+#include <net/sock.h>
+#include <net/tcp.h>
#include <net/tls.h>
+#include <net/ulp_sock.h>
MODULE_AUTHOR("Mellanox Technologies");
MODULE_DESCRIPTION("Transport Layer Security Support");
@@ -438,19 +438,21 @@ static int tls_setsockopt(struct sock *sk, int level, int optname,
return do_tls_setsockopt(sk, optname, optval, optlen);
}
-static int tls_init(struct sock *sk)
+static int tls_init(struct sock *sk, char __user *optval, int len)
{
- struct inet_connection_sock *icsk = inet_csk(sk);
struct tls_context *ctx;
int rc = 0;
+ if (sk->sk_protocol != IPPROTO_TCP)
+ return -EPROTONOSUPPORT;
+
/* allocate tls context */
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx) {
rc = -ENOMEM;
goto out;
}
- icsk->icsk_ulp_data = ctx;
+ sk->sk_ulp_data = ctx;
ctx->setsockopt = sk->sk_prot->setsockopt;
ctx->getsockopt = sk->sk_prot->getsockopt;
sk->sk_prot = &tls_base_prot;
@@ -458,7 +460,7 @@ static int tls_init(struct sock *sk)
return rc;
}
-static struct tcp_ulp_ops tcp_tls_ulp_ops __read_mostly = {
+static struct ulp_ops ulp_tls_ops __read_mostly = {
.name = "tls",
.owner = THIS_MODULE,
.init = tls_init,
@@ -475,14 +477,14 @@ static int __init tls_register(void)
tls_sw_prot.sendpage = tls_sw_sendpage;
tls_sw_prot.close = tls_sk_proto_close;
- tcp_register_ulp(&tcp_tls_ulp_ops);
+ ulp_register(&ulp_tls_ops);
return 0;
}
static void __exit tls_unregister(void)
{
- tcp_unregister_ulp(&tcp_tls_ulp_ops);
+ ulp_unregister(&ulp_tls_ops);
}
module_init(tls_register);
--
2.11.0
^ permalink raw reply related
* [PATCH v3 net-next 3/5] sock: ULP infrastructure
From: Tom Herbert @ 2017-08-07 17:28 UTC (permalink / raw)
To: netdev; +Cc: rohit, davejwatson, john.fastabend, Tom Herbert
In-Reply-To: <20170807172818.31855-1-tom@quantonium.net>
Generalize the TCP ULP infrastructure recently introduced to support
kTLS. This adds a SO_ULP socket option and creates new fields in
sock structure for ULP ops and ULP data. Also, the interface allows
additional per ULP parameters to be set so that a ULP can be pushed
and operations started in one shot.
Signed-off-by: Tom Herbert <tom@quantonium.net>
---
arch/alpha/include/uapi/asm/socket.h | 2 +
arch/frv/include/uapi/asm/socket.h | 2 +
arch/ia64/include/uapi/asm/socket.h | 2 +
arch/m32r/include/uapi/asm/socket.h | 2 +
arch/mips/include/uapi/asm/socket.h | 2 +
arch/mn10300/include/uapi/asm/socket.h | 2 +
arch/parisc/include/uapi/asm/socket.h | 2 +
arch/s390/include/uapi/asm/socket.h | 2 +
arch/sparc/include/uapi/asm/socket.h | 2 +
arch/xtensa/include/uapi/asm/socket.h | 2 +
include/linux/socket.h | 9 ++
include/net/sock.h | 6 +
include/net/ulp_sock.h | 76 +++++++++++++
include/uapi/asm-generic/socket.h | 2 +
net/Kconfig | 4 +
net/core/Makefile | 1 +
net/core/sock.c | 12 ++
net/core/sysctl_net_core.c | 25 +++++
net/core/ulp_sock.c | 196 +++++++++++++++++++++++++++++++++
net/ipv4/inet_connection_sock.c | 5 +
20 files changed, 356 insertions(+)
create mode 100644 include/net/ulp_sock.h
create mode 100644 net/core/ulp_sock.c
diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h
index c6133a045352..810e0dc8f394 100644
--- a/arch/alpha/include/uapi/asm/socket.h
+++ b/arch/alpha/include/uapi/asm/socket.h
@@ -111,4 +111,6 @@
#define SO_ZEROCOPY 60
+#define SO_ULP 61
+
#endif /* _UAPI_ASM_SOCKET_H */
diff --git a/arch/frv/include/uapi/asm/socket.h b/arch/frv/include/uapi/asm/socket.h
index 9abf02d6855a..c7bb41ae784b 100644
--- a/arch/frv/include/uapi/asm/socket.h
+++ b/arch/frv/include/uapi/asm/socket.h
@@ -104,5 +104,7 @@
#define SO_ZEROCOPY 60
+#define SO_ULP 61
+
#endif /* _ASM_SOCKET_H */
diff --git a/arch/ia64/include/uapi/asm/socket.h b/arch/ia64/include/uapi/asm/socket.h
index 002eb85a6941..c4e94563c4ce 100644
--- a/arch/ia64/include/uapi/asm/socket.h
+++ b/arch/ia64/include/uapi/asm/socket.h
@@ -113,4 +113,6 @@
#define SO_ZEROCOPY 60
+#define SO_ULP 61
+
#endif /* _ASM_IA64_SOCKET_H */
diff --git a/arch/m32r/include/uapi/asm/socket.h b/arch/m32r/include/uapi/asm/socket.h
index e268e51a38d1..4359388a541d 100644
--- a/arch/m32r/include/uapi/asm/socket.h
+++ b/arch/m32r/include/uapi/asm/socket.h
@@ -104,4 +104,6 @@
#define SO_ZEROCOPY 60
+#define SO_ULP 61
+
#endif /* _ASM_M32R_SOCKET_H */
diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h
index 6c755bc07975..300eb1074611 100644
--- a/arch/mips/include/uapi/asm/socket.h
+++ b/arch/mips/include/uapi/asm/socket.h
@@ -122,4 +122,6 @@
#define SO_ZEROCOPY 60
+#define SO_ULP 61
+
#endif /* _UAPI_ASM_SOCKET_H */
diff --git a/arch/mn10300/include/uapi/asm/socket.h b/arch/mn10300/include/uapi/asm/socket.h
index ac82a3f26dbf..c458c614afa6 100644
--- a/arch/mn10300/include/uapi/asm/socket.h
+++ b/arch/mn10300/include/uapi/asm/socket.h
@@ -104,4 +104,6 @@
#define SO_ZEROCOPY 60
+#define SO_ULP 61
+
#endif /* _ASM_SOCKET_H */
diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h
index 3b2bf7ae703b..fa25c1105faf 100644
--- a/arch/parisc/include/uapi/asm/socket.h
+++ b/arch/parisc/include/uapi/asm/socket.h
@@ -103,4 +103,6 @@
#define SO_ZEROCOPY 0x4035
+#define SO_ULP 0x4036
+
#endif /* _UAPI_ASM_SOCKET_H */
diff --git a/arch/s390/include/uapi/asm/socket.h b/arch/s390/include/uapi/asm/socket.h
index a56916c83565..d0bee5a5ac17 100644
--- a/arch/s390/include/uapi/asm/socket.h
+++ b/arch/s390/include/uapi/asm/socket.h
@@ -110,4 +110,6 @@
#define SO_ZEROCOPY 60
+#define SO_ULP 61
+
#endif /* _ASM_SOCKET_H */
diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h
index b2f5c50d0947..46f5d04426e8 100644
--- a/arch/sparc/include/uapi/asm/socket.h
+++ b/arch/sparc/include/uapi/asm/socket.h
@@ -100,6 +100,8 @@
#define SO_ZEROCOPY 0x003e
+#define SO_ULP 0x003f
+
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x5001
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
diff --git a/arch/xtensa/include/uapi/asm/socket.h b/arch/xtensa/include/uapi/asm/socket.h
index 220059999e74..f654e2507726 100644
--- a/arch/xtensa/include/uapi/asm/socket.h
+++ b/arch/xtensa/include/uapi/asm/socket.h
@@ -115,4 +115,6 @@
#define SO_ZEROCOPY 60
+#define SO_ULP 61
+
#endif /* _XTENSA_SOCKET_H */
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 8ad963cdc88c..9ff7b1b2256f 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -156,6 +156,15 @@ struct ucred {
__u32 gid;
};
+/* ULP configuration for socket */
+
+#define ULP_NAME_MAX 16
+
+struct ulp_config {
+ char ulp_name[ULP_NAME_MAX];
+ __u8 ulp_params[0];
+};
+
/* Supported address families. */
#define AF_UNSPEC 0
#define AF_UNIX 1 /* Unix domain sockets */
diff --git a/include/net/sock.h b/include/net/sock.h
index fe1a0bc25cd3..ea67ea91db87 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -72,6 +72,7 @@
#include <net/tcp_states.h>
#include <linux/net_tstamp.h>
#include <net/smc.h>
+#include <net/ulp_sock.h>
/*
* This structure really needs to be cleaned up.
@@ -313,6 +314,8 @@ struct sock_common {
* @sk_destruct: called at sock freeing time, i.e. when all refcnt == 0
* @sk_reuseport_cb: reuseport group container
* @sk_rcu: used during RCU grace period
+ * @sk_ulp_ops: pluggable ULP control hook
+ * @sk_ulp_data: ULP private data
*/
struct sock {
/*
@@ -480,6 +483,9 @@ struct sock {
void (*sk_destruct)(struct sock *sk);
struct sock_reuseport __rcu *sk_reuseport_cb;
struct rcu_head sk_rcu;
+
+ const struct ulp_ops *sk_ulp_ops;
+ void *sk_ulp_data;
};
enum sk_pacing {
diff --git a/include/net/ulp_sock.h b/include/net/ulp_sock.h
new file mode 100644
index 000000000000..b292831a5d75
--- /dev/null
+++ b/include/net/ulp_sock.h
@@ -0,0 +1,76 @@
+/*
+ * Pluggable upper layer protocol support in sockets.
+ *
+ * Copyright (c) 2016-2017, Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2016-2017, Dave Watson <davejwatson@fb.com>. All rights reserved.
+ * Copyright (c) 2017, Tom Herbert <tom@quantonium.net>. All rights reserved.
+ *
+ */
+
+#ifndef __NET_ULP_SOCK_H
+#define __NET_ULP_SOCK_H
+
+#include <linux/socket.h>
+
+#define ULP_MAX 128
+#define ULP_BUF_MAX (ULP_NAME_MAX * ULP_MAX)
+
+struct ulp_ops {
+ struct list_head list;
+
+ /* initialize ulp */
+ int (*init)(struct sock *sk, char __user *optval, int len);
+
+ /* cleanup ulp */
+ void (*release)(struct sock *sk);
+
+ /* Get ULP specific parameters in getsockopt */
+ int (*get_params)(struct sock *sk, char __user *optval, int *optlen);
+
+ char name[ULP_NAME_MAX];
+ struct module *owner;
+};
+
+#ifdef CONFIG_ULP_SOCK
+
+int ulp_register(struct ulp_ops *type);
+void ulp_unregister(struct ulp_ops *type);
+int ulp_set(struct sock *sk, char __user *optval, int len);
+int ulp_get_config(struct sock *sk, char __user *optval, int *optlen);
+void ulp_get_available(char *buf, size_t len);
+void ulp_cleanup(struct sock *sk);
+
+#else
+
+static inline int ulp_register(struct ulp_ops *type)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline void ulp_unregister(struct ulp_ops *type)
+{
+}
+
+static inline int ulp_set(struct sock *sk, char __user *optval, int len)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int ulp_get_config(struct sock *sk, char __user *optval,
+ int *optlen)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline void ulp_get_available(char *buf, size_t len)
+{
+ *buf = '\0';
+}
+
+static inline void ulp_cleanup(struct sock *sk)
+{
+}
+
+#endif
+
+#endif /* __NET_ULP_SOCK_H */
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
index e47c9e436221..41abbf7f6b66 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -106,4 +106,6 @@
#define SO_ZEROCOPY 60
+#define SO_ULP 61
+
#endif /* __ASM_GENERIC_SOCKET_H */
diff --git a/net/Kconfig b/net/Kconfig
index 7d57ef34b79c..2b8d2d88bc2b 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -419,6 +419,10 @@ config GRO_CELLS
bool
default n
+config ULP_SOCK
+ bool
+ default n
+
config NET_DEVLINK
tristate "Network physical/parent device Netlink interface"
help
diff --git a/net/core/Makefile b/net/core/Makefile
index 56d771a887b6..0d90c0ade1c8 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_DST_CACHE) += dst_cache.o
obj-$(CONFIG_HWBM) += hwbm.o
obj-$(CONFIG_NET_DEVLINK) += devlink.o
obj-$(CONFIG_GRO_CELLS) += gro_cells.o
+obj-$(CONFIG_ULP_SOCK) += ulp_sock.o
diff --git a/net/core/sock.c b/net/core/sock.c
index 9ea988d25b0a..b2a6162cca9d 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1069,6 +1069,10 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
sock_valbool_flag(sk, SOCK_ZEROCOPY, valbool);
break;
+ case SO_ULP:
+ ret = ulp_set(sk, optval, optlen);
+ break;
+
default:
ret = -ENOPROTOOPT;
break;
@@ -1401,6 +1405,9 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
v.val = sock_flag(sk, SOCK_ZEROCOPY);
break;
+ case SO_ULP:
+ return ulp_get_config(sk, optval, optlen);
+
default:
/* We implement the SO_SNDLOWAT etc to not be settable
* (1003.1g 7).
@@ -2990,6 +2997,11 @@ EXPORT_SYMBOL(compat_sock_common_setsockopt);
void sk_common_release(struct sock *sk)
{
+ /* Clean up ULP before destroying protocol socket since ULP might
+ * be dependent on transport (and not the other way around).
+ */
+ ulp_cleanup(sk);
+
if (sk->sk_prot->destroy)
sk->sk_prot->destroy(sk);
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index b7cd9aafe99e..9e14f91b57eb 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -21,6 +21,7 @@
#include <net/net_ratelimit.h>
#include <net/busy_poll.h>
#include <net/pkt_sched.h>
+#include <net/ulp_sock.h>
static int zero = 0;
static int one = 1;
@@ -249,6 +250,24 @@ static int proc_do_rss_key(struct ctl_table *table, int write,
return proc_dostring(&fake_table, write, buffer, lenp, ppos);
}
+static int proc_ulp_available(struct ctl_table *ctl,
+ int write,
+ void __user *buffer, size_t *lenp,
+ loff_t *ppos)
+{
+ struct ctl_table tbl = { .maxlen = ULP_BUF_MAX, };
+ int ret;
+
+ tbl.data = kmalloc(tbl.maxlen, GFP_USER);
+ if (!tbl.data)
+ return -ENOMEM;
+ ulp_get_available(tbl.data, ULP_BUF_MAX);
+ ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
+ kfree(tbl.data);
+
+ return ret;
+}
+
static struct ctl_table net_core_table[] = {
#ifdef CONFIG_NET
{
@@ -460,6 +479,12 @@ static struct ctl_table net_core_table[] = {
.proc_handler = proc_dointvec_minmax,
.extra1 = &zero,
},
+ {
+ .procname = "ulp_available",
+ .maxlen = ULP_BUF_MAX,
+ .mode = 0444,
+ .proc_handler = proc_ulp_available,
+ },
{ }
};
diff --git a/net/core/ulp_sock.c b/net/core/ulp_sock.c
new file mode 100644
index 000000000000..0bd9e8af18a4
--- /dev/null
+++ b/net/core/ulp_sock.c
@@ -0,0 +1,196 @@
+/*
+ * Pluggable upper layer protocol support in sockets.
+ *
+ * Copyright (c) 2016-2017, Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2016-2017, Dave Watson <davejwatson@fb.com>. All rights reserved.
+ * Copyright (c) 2017, Tom Herbert <tom@quantonium.net>. All rights reserved.
+ *
+ */
+
+#include <linux/gfp.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <net/sock.h>
+#include <net/ulp_sock.h>
+
+static DEFINE_SPINLOCK(ulp_list_lock);
+static LIST_HEAD(ulp_list);
+
+/* Simple linear search, don't expect many entries! */
+static struct ulp_ops *ulp_find(const char *name)
+{
+ struct ulp_ops *e;
+
+ list_for_each_entry_rcu(e, &ulp_list, list) {
+ if (strcmp(e->name, name) == 0)
+ return e;
+ }
+
+ return NULL;
+}
+
+static const struct ulp_ops *__ulp_find_autoload(const char *name)
+{
+ const struct ulp_ops *ulp = NULL;
+
+ rcu_read_lock();
+ ulp = ulp_find(name);
+
+#ifdef CONFIG_MODULES
+ if (!ulp && capable(CAP_NET_ADMIN)) {
+ rcu_read_unlock();
+ request_module("%s", name);
+ rcu_read_lock();
+ ulp = ulp_find(name);
+ }
+#endif
+ if (!ulp || !try_module_get(ulp->owner))
+ ulp = NULL;
+
+ rcu_read_unlock();
+ return ulp;
+}
+
+/* Attach new upper layer protocol to the list
+ * of available protocols.
+ */
+int ulp_register(struct ulp_ops *ulp)
+{
+ int ret = 0;
+
+ spin_lock(&ulp_list_lock);
+ if (ulp_find(ulp->name)) {
+ pr_notice("%s already registered or non-unique name\n",
+ ulp->name);
+ ret = -EEXIST;
+ } else {
+ list_add_tail_rcu(&ulp->list, &ulp_list);
+ }
+ spin_unlock(&ulp_list_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(ulp_register);
+
+void ulp_unregister(struct ulp_ops *ulp)
+{
+ spin_lock(&ulp_list_lock);
+ list_del_rcu(&ulp->list);
+ spin_unlock(&ulp_list_lock);
+
+ synchronize_rcu();
+}
+EXPORT_SYMBOL_GPL(ulp_unregister);
+
+/* Build string with list of available upper layer protocl values */
+void ulp_get_available(char *buf, size_t maxlen)
+{
+ struct ulp_ops *ulp_ops;
+ size_t offs = 0;
+
+ *buf = '\0';
+ rcu_read_lock();
+ list_for_each_entry_rcu(ulp_ops, &ulp_list, list) {
+ offs += snprintf(buf + offs, maxlen - offs,
+ "%s%s",
+ offs == 0 ? "" : " ", ulp_ops->name);
+ }
+ rcu_read_unlock();
+}
+EXPORT_SYMBOL_GPL(ulp_get_available);
+
+void ulp_cleanup(struct sock *sk)
+{
+ if (!sk->sk_ulp_ops)
+ return;
+
+ if (sk->sk_ulp_ops->release)
+ sk->sk_ulp_ops->release(sk);
+
+ module_put(sk->sk_ulp_ops->owner);
+
+ sk->sk_ulp_ops = NULL;
+}
+EXPORT_SYMBOL_GPL(ulp_cleanup);
+
+/* Change upper layer protocol for socket, Called from setsockopt. */
+int ulp_set(struct sock *sk, char __user *optval, int len)
+{
+ const struct ulp_ops *ulp_ops;
+ struct ulp_config ulpc;
+ int err = 0;
+
+ if (len < sizeof(ulpc))
+ return -EINVAL;
+
+ if (copy_from_user(&ulpc, optval, sizeof(ulpc)))
+ return -EFAULT;
+
+ if (sk->sk_ulp_ops)
+ return -EEXIST;
+
+ ulp_ops = __ulp_find_autoload(ulpc.ulp_name);
+ if (!ulp_ops)
+ return -ENOENT;
+
+ optval += sizeof(ulpc);
+ len -= sizeof(ulpc);
+
+ err = ulp_ops->init(sk, optval, len);
+ if (err)
+ return err;
+
+ sk->sk_ulp_ops = ulp_ops;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ulp_set);
+
+/* Get upper layer protocol for socket. Called from getsockopt. */
+int ulp_get_config(struct sock *sk, char __user *optval, int *optlen)
+{
+ struct ulp_config ulpc;
+ int len = *optlen;
+ int used_len;
+ int ret;
+
+ if (get_user(len, optlen))
+ return -EFAULT;
+
+ if (len < sizeof(ulpc))
+ return -EINVAL;
+
+ if (!sk->sk_ulp_ops) {
+ if (put_user(0, optlen))
+ return -EFAULT;
+ return 0;
+ }
+
+ memcpy(ulpc.ulp_name, sk->sk_ulp_ops->name,
+ sizeof(ulpc.ulp_name));
+
+ if (copy_to_user(optval, &ulpc, sizeof(ulpc)))
+ return -EFAULT;
+
+ used_len = sizeof(ulpc);
+
+ if (sk->sk_ulp_ops->get_params) {
+ len -= sizeof(ulpc);
+ optval += sizeof(ulpc);
+
+ ret = sk->sk_ulp_ops->get_params(sk, optval, &len);
+ if (ret)
+ return ret;
+
+ used_len += len;
+ }
+
+ if (put_user(used_len, optlen))
+ return -EFAULT;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ulp_get_config);
+
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 4089c013cb03..4e9e60f738a9 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -830,6 +830,11 @@ void inet_csk_destroy_sock(struct sock *sk)
/* If it has not 0 inet_sk(sk)->inet_num, it must be bound */
WARN_ON(inet_sk(sk)->inet_num && !inet_csk(sk)->icsk_bind_hash);
+ /* Clean up ULP before destroying protocol socket since ULP might
+ * be dependent on transport (and not the other way around).
+ */
+ ulp_cleanup(sk);
+
sk->sk_prot->destroy(sk);
sk_stream_kill_queues(sk);
--
2.11.0
^ permalink raw reply related
* [PATCH v3 net-next 2/5] inet: include net/sock.h in inet_common.h
From: Tom Herbert @ 2017-08-07 17:28 UTC (permalink / raw)
To: netdev; +Cc: rohit, davejwatson, john.fastabend, Tom Herbert
In-Reply-To: <20170807172818.31855-1-tom@quantonium.net>
inet_common.h has a dependency on sock.h so it should include that.
Signed-off-by: Tom Herbert <tom@quantonium.net>
---
include/net/inet_common.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/net/inet_common.h b/include/net/inet_common.h
index f39ae697347f..df0119a317aa 100644
--- a/include/net/inet_common.h
+++ b/include/net/inet_common.h
@@ -1,6 +1,8 @@
#ifndef _INET_COMMON_H
#define _INET_COMMON_H
+#include <net/sock.h>
+
extern const struct proto_ops inet_stream_ops;
extern const struct proto_ops inet_dgram_ops;
--
2.11.0
^ permalink raw reply related
* [PATCH v3 net-next 1/5] proto_ops: Fixes to adding locked version of sendmsg/page
From: Tom Herbert @ 2017-08-07 17:28 UTC (permalink / raw)
To: netdev; +Cc: rohit, davejwatson, john.fastabend, Tom Herbert
In-Reply-To: <20170807172818.31855-1-tom@quantonium.net>
Fixes for two issues pointed out by John Fastabend.
Fixes: 306b13eb3cf9515a ("proto_ops: Add locked held versions of sendmsg and sendpage")
Reported-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: Tom Herbert <tom@quantonium.net>
---
net/core/skbuff.c | 2 +-
net/socket.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 42b62c716a33..e3bac9f74789 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2285,7 +2285,7 @@ int skb_send_sock_locked(struct sock *sk, struct sk_buff *skb, int offset,
slen = min_t(int, len, skb_headlen(skb) - offset);
kv.iov_base = skb->data + offset;
- kv.iov_len = len;
+ kv.iov_len = slen;
memset(&msg, 0, sizeof(msg));
ret = kernel_sendmsg_locked(sk, &msg, &kv, 1, slen);
diff --git a/net/socket.c b/net/socket.c
index b332d1e8e4e4..c729625eb5d3 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -658,7 +658,7 @@ int kernel_sendmsg_locked(struct sock *sk, struct msghdr *msg,
struct socket *sock = sk->sk_socket;
if (!sock->ops->sendmsg_locked)
- sock_no_sendmsg_locked(sk, msg, size);
+ return sock_no_sendmsg_locked(sk, msg, size);
iov_iter_kvec(&msg->msg_iter, WRITE | ITER_KVEC, vec, num, size);
--
2.11.0
^ permalink raw reply related
* [PATCH v3 net-next 0/5] ulp: Generalize ULP infrastructure
From: Tom Herbert @ 2017-08-07 17:28 UTC (permalink / raw)
To: netdev; +Cc: rohit, davejwatson, john.fastabend, Tom Herbert
Generalize the ULP infrastructure that was recently introduced to
support kTLS. This adds a SO_ULP socket option and creates new fields in
sock structure for ULP ops and ULP data. Also, the interface allows
additional per ULP parameters to be set so that a ULP can be pushed
and operations started in one shot.
In this patch set:
- Minor dependency fix in inet_common.h
- Implement ULP infrastructure as a socket mechanism
- Fixes TCP and TLS to use the new method (maintaining backwards
API compatibility)
- Adds a ulp.txt document
Tested: Ran simple ULP. Dave Watson verified kTLS works.
-v2: Fix compilation errors when CONFIG_ULP_SOCK not set.
-v3: Fix one more build issue, check that sk_protocol is IPPROTO_TCP
in tsl_init. Also, fix a couple of minor issues related to
introducing locked versions of sendmsg, send page. Thanks to
Dave Watson, John Fastabend, and Mat Martineau for testing and
providing fixes.
Tom Herbert (5):
proto_ops: Fixes to adding locked version of sendmsg/page
inet: include net/sock.h in inet_common.h
sock: ULP infrastructure
tcp: Adjust TCP ULP to defer to sockets ULP
ulp: Documention for ULP infrastructure
Documentation/networking/tls.txt | 6 +-
Documentation/networking/ulp.txt | 82 ++++++++++++++
arch/alpha/include/uapi/asm/socket.h | 2 +
arch/frv/include/uapi/asm/socket.h | 2 +
arch/ia64/include/uapi/asm/socket.h | 2 +
arch/m32r/include/uapi/asm/socket.h | 2 +
arch/mips/include/uapi/asm/socket.h | 2 +
arch/mn10300/include/uapi/asm/socket.h | 2 +
arch/parisc/include/uapi/asm/socket.h | 2 +
arch/s390/include/uapi/asm/socket.h | 2 +
arch/sparc/include/uapi/asm/socket.h | 2 +
arch/xtensa/include/uapi/asm/socket.h | 2 +
include/linux/socket.h | 9 ++
include/net/inet_common.h | 2 +
include/net/inet_connection_sock.h | 4 -
include/net/sock.h | 6 +
include/net/tcp.h | 25 -----
include/net/tls.h | 4 +-
include/net/ulp_sock.h | 76 +++++++++++++
include/uapi/asm-generic/socket.h | 2 +
net/Kconfig | 4 +
net/core/Makefile | 1 +
net/core/skbuff.c | 2 +-
net/core/sock.c | 12 ++
net/core/sysctl_net_core.c | 25 +++++
net/core/ulp_sock.c | 196 +++++++++++++++++++++++++++++++++
net/ipv4/Makefile | 2 +-
net/ipv4/inet_connection_sock.c | 5 +
net/ipv4/sysctl_net_ipv4.c | 9 +-
net/ipv4/tcp.c | 42 ++++---
net/ipv4/tcp_ipv4.c | 2 -
net/ipv4/tcp_ulp.c | 135 -----------------------
net/socket.c | 2 +-
net/tls/Kconfig | 1 +
net/tls/tls_main.c | 24 ++--
35 files changed, 495 insertions(+), 203 deletions(-)
create mode 100644 Documentation/networking/ulp.txt
create mode 100644 include/net/ulp_sock.h
create mode 100644 net/core/ulp_sock.c
delete mode 100644 net/ipv4/tcp_ulp.c
--
2.11.0
^ permalink raw reply
* Re: Re: [PATCH net] ppp: Fix a scheduling-while-atomic bug in del_chan
From: Cong Wang @ 2017-08-07 17:17 UTC (permalink / raw)
To: Gao Feng; +Cc: xeb, David Miller, Linux Kernel Network Developers
In-Reply-To: <31c9755c.ff6.15dba5238fc.Coremail.gfree.wind@vip.163.com>
On Sun, Aug 6, 2017 at 6:32 PM, Gao Feng <gfree.wind@vip.163.com> wrote:
> I think the RCU should be supposed to avoid the race between del_chan and lookup_chan.
More precisely, it is callid_sock which is protected by RCU.
Unless I miss any other code path, pptp_exit_module() is
problematic too, I don't think it can just vfree() the whole thing.
> The synchronize_rcu could make sure if there was one which calls lookup_chan in this period, it would be finished and the sock refcnt is increased if necessary.
>
> So I think it is ok to invoke sock_put directly without SOCK_RCU_FREE, because the lookup_chan caller has already hold the sock refcnt,
>
If you mean the sock_hold() inside lookup_chan(), no,
it doesn't help because we already dereference the sock
before it.
Also, lookup_chan_dst() does not have a refcnt, I don't
find any code preventing it deref'ing other sock in callid_sock
than the calling one.
^ permalink raw reply
* Re: [PATCH V1 0/3] asix: Improve robustness
From: David Miller @ 2017-08-07 17:11 UTC (permalink / raw)
To: Dean_Jenkins; +Cc: netdev, linux-usb
In-Reply-To: <1502095816-3255-1-git-send-email-Dean_Jenkins@mentor.com>
From: Dean Jenkins <Dean_Jenkins@mentor.com>
Date: Mon, 7 Aug 2017 09:50:13 +0100
> Please consider taking these patches to improve the robustness of the ASIX USB
> to Ethernet driver.
I applied these to 'net' since they are bug fixes.
Please target bug fixes to 'net' instead of 'net-next' in the
future, unless they are fixing problems which only exist in
'net-next'.
Thanks.
^ permalink raw reply
* [PATCH net-next] net: vrf: Add extack messages for newlink failures
From: David Ahern @ 2017-08-07 17:08 UTC (permalink / raw)
To: netdev; +Cc: David Ahern
Add extack error messages for failure paths creating vrf devices. Once
extack support is added to iproute2, we go from the unhelpful:
$ ip li add foobar type vrf
RTNETLINK answers: Invalid argument
to:
$ ip li add foobar type vrf
Error: VRF table id is missing
Signed-off-by: David Ahern <dsahern@gmail.com>
---
drivers/net/vrf.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 8a1eaf3c302a..abd2010c48ae 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -1371,10 +1371,14 @@ static int vrf_validate(struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{
if (tb[IFLA_ADDRESS]) {
- if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
+ if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) {
+ NL_SET_ERR_MSG(extack, "Invalid hardware address");
return -EINVAL;
- if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
+ }
+ if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) {
+ NL_SET_ERR_MSG(extack, "Invalid hardware address");
return -EADDRNOTAVAIL;
+ }
}
return 0;
}
@@ -1399,12 +1403,17 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev,
struct net *net;
int err;
- if (!data || !data[IFLA_VRF_TABLE])
+ if (!data || !data[IFLA_VRF_TABLE]) {
+ NL_SET_ERR_MSG(extack, "VRF table id is missing");
return -EINVAL;
+ }
vrf->tb_id = nla_get_u32(data[IFLA_VRF_TABLE]);
- if (vrf->tb_id == RT_TABLE_UNSPEC)
+ if (vrf->tb_id == RT_TABLE_UNSPEC) {
+ NL_SET_ERR_MSG_ATTR(extack, data[IFLA_VRF_TABLE],
+ "Invalid VRF table id");
return -EINVAL;
+ }
dev->priv_flags |= IFF_L3MDEV_MASTER;
--
2.1.4
^ permalink raw reply related
* Re: [PATCHv2] bpf: fix selftest/bpf/test_pkt_md_access on s390x
From: David Miller @ 2017-08-07 17:06 UTC (permalink / raw)
To: tmricht; +Cc: ast, daniel, netdev, heiko.carstens, schwidefsky, brueckner
In-Reply-To: <20170807081636.65099-1-tmricht@linux.vnet.ibm.com>
From: Thomas Richter <tmricht@linux.vnet.ibm.com>
Date: Mon, 7 Aug 2017 10:16:36 +0200
> Commit 18f3d6be6be1 ("selftests/bpf: Add test cases to test narrower ctx field loads")
> introduced new eBPF test cases. One of them (test_pkt_md_access.c)
> fails on s390x. The BPF verifier error message is:
>
> [root@s8360046 bpf]# ./test_progs
> test_pkt_access:PASS:ipv4 349 nsec
> test_pkt_access:PASS:ipv6 212 nsec
> [....]
> libbpf: load bpf program failed: Permission denied
> libbpf: -- BEGIN DUMP LOG ---
> libbpf:
> 0: (71) r2 = *(u8 *)(r1 +0)
> invalid bpf_context access off=0 size=1
>
> libbpf: -- END LOG --
> libbpf: failed to load program 'test1'
> libbpf: failed to load object './test_pkt_md_access.o'
> Summary: 29 PASSED, 1 FAILED
> [root@s8360046 bpf]#
>
> This is caused by a byte endianness issue. S390x is a big endian
> architecture. Pointer access to the lowest byte or halfword of a
> four byte value need to add an offset.
> On little endian architectures this offset is not needed.
>
> Fix this and use the same approach as the originator used for other files
> (for example test_verifier.c) in his original commit.
>
> With this fix the test program test_progs succeeds on s390x:
...
> Signed-off-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
> Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Applied, thanks.
^ permalink raw reply
* Re: [RFC] iproute: Add support for extended ack to rtnl_talk
From: David Ahern @ 2017-08-07 16:48 UTC (permalink / raw)
To: Stephen Hemminger, Simon Horman
Cc: Daniel Borkmann, Phil Sutter, David Miller, netdev
In-Reply-To: <20170804094729.00548085@xeon-e3>
On 8/4/17 10:47 AM, Stephen Hemminger wrote:
> I will put in the libmnl version. If it doesn't work because no one sent
> me test cases, then fine. send a patch for that.
This commit:
commit b6432e68ac2f1f6b4ea50aa0d6d47e72c445c71c
Author: Stephen Hemminger <stephen@networkplumber.org>
Date: Fri Aug 4 09:52:15 2017 -0700
iproute: Add support for extended ack to rtnl_talk
Does not work. Seems like you pushed the RFC commit which was known to
be incomplete.
First, the Config is HAVE_MNL not HAVE_LIBMNL which is in lib/libnetlink.c.
Second, changing that to HAVE_MNL does not work -- something is not
getting passed in correctly. Just remove the semicolon on the else path:
+#else
+/* No extended error ack without libmnl */
+static int nl_dump_ext_err(const struct nlmsghdr *nlh, nl_ext_ack_fn_t
errfn)
+{
+ return 0;
+}
+#endif
and you will see that HAVE_MNL is never defined.
Third, force that path to build and you get:
ip
LINK ip
../lib/libnetlink.a(libnetlink.o): In function `err_attr_cb':
libnetlink.c:(.text+0x10): undefined reference to `mnl_attr_type_valid'
libnetlink.c:(.text+0x1c): undefined reference to `mnl_attr_get_type'
libnetlink.c:(.text+0x34): undefined reference to `mnl_attr_validate'
../lib/libnetlink.a(libnetlink.o): In function `__rtnl_talk':
libnetlink.c:(.text+0x408): undefined reference to `mnl_nlmsg_get_payload'
libnetlink.c:(.text+0x42c): undefined reference to
`mnl_nlmsg_get_payload_len'
libnetlink.c:(.text+0x445): undefined reference to `mnl_attr_parse'
libnetlink.c:(.text+0x454): undefined reference to `mnl_attr_get_str'
libnetlink.c:(.text+0x46a): undefined reference to `mnl_attr_get_u32'
collect2: error: ld returned 1 exit status
Makefile:29: recipe for target 'ip' failed
make[1]: *** [ip] Error 1
Makefile:66: recipe for target 'all' failed
make: *** [all] Error 2
as I mentioned in a past response the libmnl dependency can not be
placed on libutil.a -- because it is an archive. That means each and
every command that uses libutil.a needs to inherit the libmnl dependency.
^ permalink raw reply
* Re: [patch net-next v2 00/16] net: sched: summer cleanup part 2, ndo_setup_tc
From: David Miller @ 2017-08-07 16:43 UTC (permalink / raw)
To: jiri
Cc: netdev, jhs, xiyou.wangcong, daniel, mlxsw, andrew,
vivien.didelot, f.fainelli, simon.horman, pieter.jansenvanvuuren,
dirk.vandermerwe, alexander.h.duyck, amritha.nambiar, oss-drivers,
yisen.zhuang, salil.mehta
In-Reply-To: <20170807081532.32760-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@resnulli.us>
Date: Mon, 7 Aug 2017 10:15:16 +0200
> From: Jiri Pirko <jiri@mellanox.com>
>
> This patchset focuses on ndo_setup_tc and its args.
> Currently there are couple of things that do not make much sense.
> The type is passed in struct tc_to_netdev, but as it is always
> required, should be arg of the ndo. Other things are passed as args
> but they are only relevant for cls offloads and not mqprio. Therefore,
> they should be pushed to struct. As the tc_to_netdev struct in the end
> is just a container of single pointer, we get rid of it and pass the
> struct according to type. So in the end, we have:
> ndo_setup_tc(dev, type, type_data_struct)
>
> There are couple of cosmetics done on the way to make things smooth.
> Also, reported error is consolidated to eopnotsupp in case the
> asked offload is not supported.
>
> v1->v2:
> - added forgotten hns3pf bits
Series applied, thanks.
^ permalink raw reply
* Re: latest kselftest with stable tree: bpf failures
From: Sumit Semwal @ 2017-08-07 16:41 UTC (permalink / raw)
To: Daniel Borkmann
Cc: ast, netdev, # 3.4.x,
open list:KERNEL SELFTEST FRAMEWORK <linux-kselftest@vger.kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Shuah Khan
In-Reply-To: <5984BE63.7040608@iogearbox.net>
Hello Daniel,
On 5 August 2017 at 00:05, Daniel Borkmann <daniel@iogearbox.net> wrote:
> On 08/03/2017 05:34 PM, Sumit Semwal wrote:
>>
>> On 3 August 2017 at 20:49, Daniel Borkmann <daniel@iogearbox.net> wrote:
>>>
>>> On 08/03/2017 05:09 PM, Sumit Semwal wrote:
>>>>
>>>>
>>>> Hello Alexei, Daniel, and the bpf community,
>>>>
>>>> As part of trying to improve stable kernels' testing, we're running
>>>> ~current kselftests with stable kernels (4.4 and 4.9 for now), and
>>>> reporting issues.
>>>
>>>
>>> Thanks for the report, I haven't been tracking the BPF testsuite
>>> with stable kernels much so far. I will take a look! Just to clarify,
>>> with '~current kselftests' you mean the one in current Linus' tree
>>> or the ones corresponding to the 4.4 and 4.9 -stable kernels?
>>
>> I meant current Linus's release (4.12) atm.
>
>
> Thanks for clarifying that, hmm. Why not running the
> selftests that are tied to the actual -stable kernel,
> meaning those that the corresponding kernel ships? Is
> the assumption that potentially you might have more
> coverage on Linus' tree directly, or that test cases
> are not updated via -stable along with fixes?
Thanks so much for your reply!
[1] has details of this discussion, but in summary, yes, it's
primarily the former - test cases have shown more coverage when tested
with Linus' tree in most cases.
>
> I looked at some of the SKIP cases, and how to tie that
> to the BPF tests (the suite runs probably over 1k tests
> on verifier, interpreter, jit, etc combinations currently).
> E.g. in some cases the verifier gets smarter and tests that
> are rejected on older kernels get accepted on newer ones.
> But then, we also wouldn't want to exclude these tests
> (e.g. based on kernel version number or such) for older
> kernels for the sake of making sure that in case stable
> updates are applied that they don't introduce regressions
> we'd otherwise could miss.
No, certainly not - but would there be some way to denote this
'smartness' as a feature, so we could test against the feature itself,
and not rely on kernel version?
>
> Then, mostly for testing JITs there's the test_bpf.c kernel
> module, which is a moving target as well, f.e. cleanups
> like de77b966ce8a ("net: introduce __skb_put_[zero, data,
> u8]") [unintentionally] tie this to a specific kernel version
> again. But then again, skipping test_bpf we'd potentially
> miss to run important test cases. For the mainline git tree
> it's fairly easy as the test suite is directly coupled to
> it. Hm, I don't have a good, reliably idea for the time
> being to not make this a maintenance/testing mess long
> term, so my recommendation for the time being would be
> to test with 4.4 and 4.9 test suites, but I'm definitely
> open for ideas to brainstorm.
>
Would it be possible to have test_bpf differentiate between SKIP (for
missing feature) and actual FAIL for the features it is testing? And
in case there are 0 FAILS, perhaps it could return success? There are
a few examples in selftests which are quite robust that ways.
I understand completely that it could feel like wasted effort, but
IMHO, tying tests to kernel versions rather than features can get into
a bigger maintenance issue.
> Thanks,
> Daniel
Best,
Sumit.
[1]: https://lkml.org/lkml/2017/6/16/691
^ permalink raw reply
* Qdisc->u32_node - licence to kill
From: Jiri Pirko @ 2017-08-07 16:41 UTC (permalink / raw)
To: jhs, xiyou.wangcong, davem; +Cc: netdev, mlxsw
Hi Jamal/Cong/David/all.
Digging in the u32 code deeper now. I need to get rid of tp->q for shared
blocks, but I found out about this:
struct Qdisc {
......
void *u32_node;
......
};
Yeah, ugly. u32 uses it to store some shared data, tp_c. It actually
stores a linked list of all hashtables added to one qdiscs.
So basically what you have is, you have 1 root ht per prio/pref. Then
you can have multiple hts, linked from any other ht, does not matter in
which prio/pref they are.
Do I understand that correctly that prio/pref only has meaning if
linking does not take place, because if there is linking, the prio/pref
of inserted rule is simply ignored?
That is the most confusing thing I saw in net/sched/ so far.
Is this a bug? Sounds like one.
Did someone introduce *u32_node (formerly static struct tc_u_common
*u32_list;) just to allow this weirdness?
Can I just remove this shared tp_c and make the linking to other
hashtables only possible within the same prio/pref? That would make
sense to me.
Thanks.
Jiri
^ permalink raw reply
* [PATCH net-next v1 2/2] bpf: Extend check_uarg_tail_zero() checks
From: Mickaël Salaün @ 2017-08-07 16:36 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Alexei Starovoitov, Daniel Borkmann,
David S . Miller, Kees Cook, Martin KaFai Lau, netdev,
Alexei Starovoitov
In-Reply-To: <20170807163605.14194-1-mic@digikod.net>
The function check_uarg_tail_zero() was created from bpf(2) for
BPF_OBJ_GET_INFO_BY_FD without taking the access_ok() nor the PAGE_SIZE
checks. Make this checks more generally available while unlikely to be
triggered, extend the memory range check and add an explanation
including why the ToCToU should not be a security concern.
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: David S. Miller <davem@davemloft.net>
Cc: Kees Cook <keescook@chromium.org>
Cc: Martin KaFai Lau <kafai@fb.com>
Link: https://lkml.kernel.org/r/CAGXu5j+vRGFvJZmjtAcT8Hi8B+Wz0e1b6VKYZHfQP_=DXzC4CQ@mail.gmail.com
---
kernel/bpf/syscall.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index c653ee0bd162..b884fdc371e0 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -48,6 +48,15 @@ static const struct bpf_map_ops * const bpf_map_types[] = {
#undef BPF_MAP_TYPE
};
+/*
+ * If we're handed a bigger struct than we know of, ensure all the unknown bits
+ * are 0 - i.e. new user-space does not rely on any kernel feature extensions
+ * we dont know about yet.
+ *
+ * There is a ToCToU between this function call and the following
+ * copy_from_user() call. However, this should not be a concern since this
+ * function is meant to be a future-proofing of bits.
+ */
static int check_uarg_tail_zero(void __user *uaddr,
size_t expected_size,
size_t actual_size)
@@ -57,6 +66,12 @@ static int check_uarg_tail_zero(void __user *uaddr,
unsigned char val;
int err;
+ if (unlikely(!access_ok(VERIFY_READ, uaddr, actual_size)))
+ return -EFAULT;
+
+ if (unlikely(actual_size > PAGE_SIZE)) /* silly large */
+ return -E2BIG;
+
if (actual_size <= expected_size)
return 0;
@@ -1393,17 +1408,6 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz
if (!capable(CAP_SYS_ADMIN) && sysctl_unprivileged_bpf_disabled)
return -EPERM;
- if (!access_ok(VERIFY_READ, uattr, 1))
- return -EFAULT;
-
- if (size > PAGE_SIZE) /* silly large */
- return -E2BIG;
-
- /* If we're handed a bigger struct than we know of,
- * ensure all the unknown bits are 0 - i.e. new
- * user-space does not rely on any kernel feature
- * extensions we dont know about yet.
- */
err = check_uarg_tail_zero(uattr, sizeof(attr), size);
if (err)
return err;
--
2.13.3
^ permalink raw reply related
* [PATCH net-next v1 1/2] bpf: Move check_uarg_tail_zero() upward
From: Mickaël Salaün @ 2017-08-07 16:36 UTC (permalink / raw)
To: linux-kernel
Cc: Mickaël Salaün, Alexei Starovoitov, Daniel Borkmann,
David S . Miller, Kees Cook, Martin KaFai Lau, netdev,
Alexei Starovoitov
The function check_uarg_tail_zero() may be useful for other part of the
code in the syscall.c file. Move this function at the beginning of the
file.
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: David S. Miller <davem@davemloft.net>
Cc: Kees Cook <keescook@chromium.org>
Cc: Martin KaFai Lau <kafai@fb.com>
---
This is needed for the Landlock patch series. :)
---
kernel/bpf/syscall.c | 52 ++++++++++++++++++++++++++--------------------------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 6c772adabad2..c653ee0bd162 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -48,6 +48,32 @@ static const struct bpf_map_ops * const bpf_map_types[] = {
#undef BPF_MAP_TYPE
};
+static int check_uarg_tail_zero(void __user *uaddr,
+ size_t expected_size,
+ size_t actual_size)
+{
+ unsigned char __user *addr;
+ unsigned char __user *end;
+ unsigned char val;
+ int err;
+
+ if (actual_size <= expected_size)
+ return 0;
+
+ addr = uaddr + expected_size;
+ end = uaddr + actual_size;
+
+ for (; addr < end; addr++) {
+ err = get_user(val, addr);
+ if (err)
+ return err;
+ if (val)
+ return -E2BIG;
+ }
+
+ return 0;
+}
+
static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
{
struct bpf_map *map;
@@ -1246,32 +1272,6 @@ static int bpf_map_get_fd_by_id(const union bpf_attr *attr)
return fd;
}
-static int check_uarg_tail_zero(void __user *uaddr,
- size_t expected_size,
- size_t actual_size)
-{
- unsigned char __user *addr;
- unsigned char __user *end;
- unsigned char val;
- int err;
-
- if (actual_size <= expected_size)
- return 0;
-
- addr = uaddr + expected_size;
- end = uaddr + actual_size;
-
- for (; addr < end; addr++) {
- err = get_user(val, addr);
- if (err)
- return err;
- if (val)
- return -E2BIG;
- }
-
- return 0;
-}
-
static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
const union bpf_attr *attr,
union bpf_attr __user *uattr)
--
2.13.3
^ permalink raw reply related
* Re: [PATCH] of_mdio: use of_property_read_u32_array()
From: Sergei Shtylyov @ 2017-08-07 16:18 UTC (permalink / raw)
To: Rob Herring
Cc: Andrew Lunn, Florian Fainelli, Frank Rowand, netdev,
devicetree@vger.kernel.org
In-Reply-To: <CAL_JsqKDXAbAVpgMSU39+9mF7MZWQotLUNkjePy9eUsnBs99Vw@mail.gmail.com>
Hello!
On 08/07/2017 05:18 PM, Rob Herring wrote:
>> The "fixed-link" prop support predated of_property_read_u32_array(), so
>> basically had to open-code it. Using the modern API saves 24 bytes of the
>> object code (ARM gcc 4.8.5); the only behavior change would be that the
>> prop length check is now less strict (however the strict pre-check done
>> in of_phy_is_fixed_link() is left intact anyway)...
>>
>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>>
>> ---
>> The patch is against the 'dt/next' branch of Rob Herring's 'linux-git' repo
>> plus the previously posted patch killing the useless local variable in
>> of_phy_register_fixed_link().
>
> It shouldn't depend on anything in my tree and David normally takes
> of_mdio.c changes.
MAINTAINERS still only point at the DT repo, perhaps it should be updated?
> Reviewed-by: Rob Herring <robh@kernel.org>
Thank you.
>> drivers/of/of_mdio.c | 16 ++++++++--------
>> 1 file changed, 8 insertions(+), 8 deletions(-)
MBR, Sergei
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox