* [RFC PATCH] net: don't set __LINK_STATE_START until after dev->open() call
From: Jacob Keller @ 2017-08-07 22:24 UTC (permalink / raw)
To: netdev; +Cc: Jacob Keller
Fix an issue with relying on netif_running() which could be true during
when dev->open() handler is being called, even if it would exit with
a failure. This ensures the state does not get set and removed with
a narrow race for other callers to read it as open when infact it never
finished opening.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
I found this as a result of debugging a race condition in the i40evf
driver, in which we assumed that netif_running() would not be true until
after dev->open() had been called and succeeded. Unfortunately we can't
hold the rtnl_lock() while checking netif_running() because it would
cause a deadlock between our reset task and our ndo_open handler.
I am wondering whether the proposed change is acceptable here, or
whether some ndo_open handlers rely on __LINK_STATE_START being true
prior to their being called?
net/core/dev.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 1d75499add72..11953af90427 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1362,8 +1362,6 @@ static int __dev_open(struct net_device *dev)
if (ret)
return ret;
- set_bit(__LINK_STATE_START, &dev->state);
-
if (ops->ndo_validate_addr)
ret = ops->ndo_validate_addr(dev);
@@ -1372,9 +1370,8 @@ static int __dev_open(struct net_device *dev)
netpoll_poll_enable(dev);
- if (ret)
- clear_bit(__LINK_STATE_START, &dev->state);
- else {
+ if (!ret)
+ set_bit(__LINK_STATE_START, &dev->state);
dev->flags |= IFF_UP;
dev_set_rx_mode(dev);
dev_activate(dev);
--
2.14.0.rc1.251.g593d8d6362ce
^ permalink raw reply related
* [PATCH net-next] net: dsa: lan9303: Only allocate 3 ports
From: Egil Hjelmeland @ 2017-08-07 22:22 UTC (permalink / raw)
To: andrew, vivien.didelot, f.fainelli, netdev, linux-kernel; +Cc: Egil Hjelmeland
Save 2628 bytes on arm eabi by allocate only the required 3 ports.
Now that ds->num_ports is correct: In net/dsa/tag_lan9303.c
eliminate duplicate LAN9303_MAX_PORTS, use ds->num_ports.
(Matching the pattern of other net/dsa/tag_xxx.c files.)
Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
---
drivers/net/dsa/lan9303-core.c | 2 +-
net/dsa/tag_lan9303.c | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index 15befd155251..46fc1d5d3c9e 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -811,7 +811,7 @@ static struct dsa_switch_ops lan9303_switch_ops = {
static int lan9303_register_switch(struct lan9303 *chip)
{
- chip->ds = dsa_switch_alloc(chip->dev, DSA_MAX_PORTS);
+ chip->ds = dsa_switch_alloc(chip->dev, LAN9303_NUM_PORTS);
if (!chip->ds)
return -ENOMEM;
diff --git a/net/dsa/tag_lan9303.c b/net/dsa/tag_lan9303.c
index 247774d149f9..e23e7635fa00 100644
--- a/net/dsa/tag_lan9303.c
+++ b/net/dsa/tag_lan9303.c
@@ -39,7 +39,6 @@
*/
#define LAN9303_TAG_LEN 4
-#define LAN9303_MAX_PORTS 3
static struct sk_buff *lan9303_xmit(struct sk_buff *skb, struct net_device *dev)
{
@@ -104,7 +103,7 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev,
source_port = ntohs(lan9303_tag[1]) & 0x3;
- if (source_port >= LAN9303_MAX_PORTS) {
+ if (source_port >= ds->num_ports) {
dev_warn_ratelimited(&dev->dev, "Dropping packet due to invalid source port\n");
return NULL;
}
--
2.11.0
^ permalink raw reply related
* Re: [PATCH net-next] net: vrf: Add extack messages for newlink failures
From: David Miller @ 2017-08-07 22:16 UTC (permalink / raw)
To: dsahern; +Cc: netdev
In-Reply-To: <1502125690-2212-1-git-send-email-dsahern@gmail.com>
From: David Ahern <dsahern@gmail.com>
Date: Mon, 7 Aug 2017 10:08:10 -0700
> 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>
Applied, thanks David.
^ permalink raw reply
* [PATCH RFC 2/2] stap: Socket tap
From: Tom Herbert @ 2017-08-07 22:12 UTC (permalink / raw)
To: netdev; +Cc: rohit, Tom Herbert
In-Reply-To: <20170807221204.15724-1-tom@quantonium.net>
The socket tap uses ULP mechanism to insert funtionality between the
socket system calls and the connection itself. Basically, this is a
means to tap into a socket. To implement the tap the data operations
(sendmsg, recvmsg, sendpage, and read_sock) are intercepted using the
ULP infrastructure. In each direction a strparser instance is used to
deliniate a stream into application messages. A BPF "verdict" program
is run on the output (applicaiton messages) each strparser. The verdict
program can allow the message, drop it, or drop it and also kill the
connection.
The sendmsg path looks something like:
sendmsg (ULP) -> strparser -> verditct -> send_sock_skb
The receive path looks like:
tcp_read_sock -> strparser -> verdict -> recvmsg
Note the socket tap does not introduce any new locks or queuing
(except for messages under construction by strparser). Also,
the buffer limits of the socket are respectd in all operations.
Signed-off-by: Tom Herbert <tom@quantonium.net>
---
include/net/stap.h | 43 +++
include/uapi/linux/stap.h | 21 ++
net/Kconfig | 1 +
net/Makefile | 1 +
net/stap/Kconfig | 8 +
net/stap/Makefile | 3 +
net/stap/stap_main.c | 769 ++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 846 insertions(+)
create mode 100644 include/net/stap.h
create mode 100644 include/uapi/linux/stap.h
create mode 100644 net/stap/Kconfig
create mode 100644 net/stap/Makefile
create mode 100644 net/stap/stap_main.c
diff --git a/include/net/stap.h b/include/net/stap.h
new file mode 100644
index 000000000000..dfc96a116db2
--- /dev/null
+++ b/include/net/stap.h
@@ -0,0 +1,43 @@
+/*
+ * Socket tap
+ *
+ * Copyright (c) 2017 Tom Herbert <tom@quantonium.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+
+#ifndef __NET_STAP_H_
+#define __NET_STAP_H_
+
+#include <linux/skbuff.h>
+#include <net/sock.h>
+#include <net/strparser.h>
+
+struct stap_bops {
+ struct strparser strp;
+ struct bpf_prog *parse_prog;
+ struct bpf_prog *verdict_prog;
+};
+
+struct stap_sock {
+ struct sock *sk; /* Associated socket */
+
+ const struct proto_ops *orig_ops;
+
+ void (*save_data_ready)(struct sock *sk);
+ void (*save_write_space)(struct sock *sk);
+ void (*save_state_change)(struct sock *sk);
+
+ /* Send items */
+ struct stap_bops send_bops;
+ struct sk_buff_head build_list;
+ struct sk_buff_head ready_list;
+
+ /* Receive items */
+ struct stap_bops recv_bops;
+ struct sk_buff *recv_skb;
+};
+
+#endif /* __NET_STAP_H_ */
diff --git a/include/uapi/linux/stap.h b/include/uapi/linux/stap.h
new file mode 100644
index 000000000000..fa8545628fd2
--- /dev/null
+++ b/include/uapi/linux/stap.h
@@ -0,0 +1,21 @@
+/*
+ * Socket tap
+ *
+ * Copyright (c) 2017 Tom Herbert <tom@quantonium.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+
+#ifndef _UAPI_LINUX_STAP_H
+#define _UAPI_LINUX_STAP_H
+
+struct stap_params {
+ int bpf_send_parse_fd;
+ int bpf_send_verdict_fd;
+ int bpf_recv_parse_fd;
+ int bpf_recv_verdict_fd;
+};
+
+#endif /* _UAPI_LINUX_STAP_H */
diff --git a/net/Kconfig b/net/Kconfig
index 2b8d2d88bc2b..8a1bdd269e84 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -368,6 +368,7 @@ source "net/irda/Kconfig"
source "net/bluetooth/Kconfig"
source "net/rxrpc/Kconfig"
source "net/kcm/Kconfig"
+source "net/stap/Kconfig"
source "net/strparser/Kconfig"
config FIB_RULES
diff --git a/net/Makefile b/net/Makefile
index bed80fa398b7..3ef1d8ae8e58 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_BT) += bluetooth/
obj-$(CONFIG_SUNRPC) += sunrpc/
obj-$(CONFIG_AF_RXRPC) += rxrpc/
obj-$(CONFIG_AF_KCM) += kcm/
+obj-$(CONFIG_STAP) += stap/
obj-$(CONFIG_STREAM_PARSER) += strparser/
obj-$(CONFIG_ATM) += atm/
obj-$(CONFIG_L2TP) += l2tp/
diff --git a/net/stap/Kconfig b/net/stap/Kconfig
new file mode 100644
index 000000000000..adb3149ea624
--- /dev/null
+++ b/net/stap/Kconfig
@@ -0,0 +1,8 @@
+config STAP
+ tristate "Socket tap"
+ depends on INET
+ select BPF_SYSCALL
+ select STREAM_PARSER
+ ---help---
+ Socket tap.
+
diff --git a/net/stap/Makefile b/net/stap/Makefile
new file mode 100644
index 000000000000..f5bce0f59da5
--- /dev/null
+++ b/net/stap/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_STAP) += stap.o
+
+stap-y := stap_main.o
diff --git a/net/stap/stap_main.c b/net/stap/stap_main.c
new file mode 100644
index 000000000000..a34dcf19e6cd
--- /dev/null
+++ b/net/stap/stap_main.c
@@ -0,0 +1,769 @@
+/*
+ * Socket tap
+ *
+ * Copyright (c) 2017 Tom Herbert <tom@quantonium.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+
+#include <linux/in.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched/signal.h>
+#include <net/inet_common.h>
+#include <net/inet_connection_sock.h>
+#include <net/sock.h>
+#include <net/tcp.h>
+#include <net/stap.h>
+#include <uapi/linux/stap.h>
+
+static struct proto_ops stap_tcp_stream_ops;
+
+static inline struct stap_sock *tsk_from_socket(struct socket *sock)
+{
+ return (struct stap_sock *)sock->sk->sk_ulp_data;
+}
+
+static void stap_push(struct stap_sock *tsk);
+
+static void stap_write_space(struct sock *sk)
+{
+ struct stap_sock *tsk = (struct stap_sock *)sk->sk_user_data;
+
+ if (unlikely(!tsk))
+ return;
+
+ stap_push(tsk);
+ tsk->save_write_space(sk);
+}
+
+static void stap_data_ready(struct sock *sk)
+{
+ struct stap_sock *tsk = (struct stap_sock *)sk->sk_user_data;
+
+ if (unlikely(!tsk))
+ return;
+
+ strp_data_ready(&tsk->recv_bops.strp);
+}
+
+static void stap_state_change(struct sock *sk)
+{
+ struct stap_sock *tsk = (struct stap_sock *)sk->sk_user_data;
+
+ if (unlikely(!tsk))
+ return;
+
+ tsk->save_state_change(sk);
+}
+
+/* Try to send completed message from construct queue to transport socket. */
+static void stap_push(struct stap_sock *tsk)
+{
+ struct strp_msg *stm;
+ struct sk_buff *skb;
+ int n;
+
+ while ((skb = skb_peek(&tsk->ready_list))) {
+ stm = strp_msg(skb);
+ WARN_ON(skb->len - stm->offset > stm->full_len);
+ n = skb_send_sock_locked(tsk->sk, skb, stm->offset,
+ stm->full_len);
+ if (n <= 0)
+ return;
+
+ stm->full_len -= n;
+ stm->offset += n;
+ tsk->sk->sk_wmem_queued -= n;
+ sk_mem_uncharge(tsk->sk, n);
+
+ if (!stm->full_len) {
+ __skb_unlink(skb, &tsk->ready_list);
+ kfree_skb(skb);
+ }
+ }
+}
+
+/* Process data pending from sendmsg */
+static void stap_run(struct stap_sock *tsk)
+{
+ struct strparser *strp = &tsk->send_bops.strp;
+ int offset, slen, eaten;
+ struct strp_msg *stm;
+ struct sk_buff *skb;
+
+ while ((skb = skb_peek(&tsk->build_list))) {
+ stm = strp_msg(skb);
+ offset = stm->offset;
+ slen = skb->len - offset;
+
+ eaten = strp_process(strp, skb, offset, slen,
+ tsk->sk->sk_sndbuf, tsk->sk->sk_sndtimeo);
+ if (eaten >= slen) {
+ __skb_unlink(skb, &tsk->build_list);
+ kfree_skb(skb);
+ } else {
+ stm->offset += offset;
+ }
+ }
+
+ stap_push(tsk);
+}
+
+static int stap_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
+{
+ struct sock *sk = sock->sk;
+ long timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
+ struct stap_sock *tsk = tsk_from_socket(sock);
+ int flags = msg->msg_flags;
+ struct sk_buff *skb;
+ int copied = 0;
+ int err;
+ int copy;
+
+ lock_sock(sk);
+
+ err = -EPIPE;
+ if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
+ goto do_error;
+
+ sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
+
+ while (msg_data_left(msg)) {
+ struct page_frag *pfrag = sk_page_frag(sk);
+ bool merge = true;
+ int i;
+
+ skb = skb_peek(&tsk->build_list);
+ if (!skb)
+ goto new_skb;
+
+ i = skb_shinfo(skb)->nr_frags;
+
+ if (!sk_page_frag_refill(sk, pfrag))
+ goto wait_for_memory;
+
+ if (!skb_can_coalesce(skb, i, pfrag->page,
+ pfrag->offset)) {
+ if (i == MAX_SKB_FRAGS) {
+new_skb:
+ skb = alloc_skb(0, sk->sk_allocation);
+ if (!skb)
+ goto wait_for_memory;
+
+ __skb_queue_tail(&tsk->build_list, skb);
+
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ continue;
+ }
+ merge = false;
+ }
+
+ copy = min_t(int, msg_data_left(msg),
+ pfrag->size - pfrag->offset);
+
+ if (!sk_wmem_schedule(sk, copy))
+ goto wait_for_memory;
+
+ err = skb_copy_to_page_nocache(sk, &msg->msg_iter, skb,
+ pfrag->page,
+ pfrag->offset,
+ copy);
+ if (err)
+ goto do_error;
+
+ /* Update the skb. */
+ if (merge) {
+ skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy);
+ } else {
+ skb_fill_page_desc(skb, i, pfrag->page,
+ pfrag->offset, copy);
+ get_page(pfrag->page);
+ }
+
+ pfrag->offset += copy;
+ copied += copy;
+
+ continue;
+
+wait_for_memory:
+ if (copied)
+ stap_run(tsk);
+
+ err = sk_stream_wait_memory(sk, &timeo);
+ if (err != 0)
+ goto do_error;
+ }
+
+out:
+ if (copied)
+ stap_run(tsk);
+
+ release_sock(sk);
+ return copied;
+
+do_error:
+ if (copied)
+ goto out;
+
+ err = sk_stream_error(sk, flags, err);
+
+ release_sock(sk);
+ return err;
+}
+
+static ssize_t stap_sendpage(struct socket *sock, struct page *page,
+ int offset, size_t size, int flags)
+{
+ struct sock *sk = sock->sk;
+ long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
+ struct stap_sock *tsk = tsk_from_socket(sock);
+ size_t copied = 0;
+ int err;
+
+ if (unlikely(!tsk))
+ return 0;
+
+ lock_sock(sk);
+
+ err = -EPIPE;
+ if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
+ goto do_error;
+
+ sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
+
+ while (size) {
+ struct sk_buff *skb;
+ int copy, i;
+ bool can_coalesce;
+
+ copy = size;
+
+ skb = skb_peek(&tsk->build_list);
+ if (!skb) {
+new_skb:
+ skb = alloc_skb(0, sk->sk_allocation);
+ if (!skb)
+ goto wait_for_memory;
+
+ __skb_queue_tail(&tsk->build_list, skb);
+
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ continue;
+ }
+
+ i = skb_shinfo(skb)->nr_frags;
+ can_coalesce = skb_can_coalesce(skb, i, page, offset);
+
+ if (!can_coalesce && i >= sysctl_max_skb_frags)
+ goto new_skb;
+
+ if (!sk_wmem_schedule(sk, copy))
+ goto wait_for_memory;
+
+ if (can_coalesce) {
+ skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1],
+ copy);
+ } else {
+ get_page(page);
+ skb_fill_page_desc(skb, i, page, offset, copy);
+ }
+
+ skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
+
+ skb->len += copy;
+ skb->data_len += copy;
+ skb->truesize += copy;
+ sk->sk_wmem_queued += copy;
+ sk_mem_charge(sk, copy);
+ copied += copy;
+ offset += copy;
+ size -= copy;
+
+ continue;
+
+wait_for_memory:
+ if (copied)
+ stap_run(tsk);
+
+ err = sk_stream_wait_memory(sk, &timeo);
+ if (err != 0)
+ goto do_error;
+ }
+
+out:
+ if (copied)
+ stap_run(tsk);
+
+ release_sock(sk);
+ return copied;
+
+do_error:
+ if (copied)
+ goto out;
+
+ err = sk_stream_error(sk, flags, err);
+
+ release_sock(sk);
+ return err;
+}
+
+static int stap_parse_send_strparser(struct strparser *strp,
+ struct sk_buff *skb)
+{
+ struct stap_sock *tsk = container_of(strp, struct stap_sock,
+ send_bops.strp);
+ struct bpf_prog *prog = tsk->send_bops.parse_prog;
+
+ return (*prog->bpf_func)(skb, prog->insnsi);
+}
+
+static void stap_input_send_strparser(struct strparser *strp,
+ struct sk_buff *skb)
+{
+ struct stap_sock *tsk = container_of(strp, struct stap_sock,
+ send_bops.strp);
+ struct bpf_prog *prog = tsk->send_bops.verdict_prog;
+
+ int rc;
+
+ WARN_ON(tsk->recv_skb);
+
+ /* Run the verdict program to get dispostion of the message */
+ rc = (*prog->bpf_func)(skb, prog->insnsi);
+
+ switch (rc) {
+ case BPF_OK:
+ /* Will push at run queue at end of sendmsg. */
+ __skb_queue_tail(&tsk->ready_list, skb);
+
+ break;
+
+ case BPF_DROP:
+ kfree_skb(skb);
+ return;
+
+ case BPF_REDIRECT:
+ /* Not supported yet. */
+ case BPF_DISCONNECT:
+ /* Kill connection */
+ default:
+ kfree_skb(skb);
+ strp_stop(&tsk->send_bops.strp);
+ tsk->sk->sk_err = ECONNABORTED;
+ tsk->sk->sk_error_report(tsk->sk);
+ }
+}
+
+void stap_send_lock(struct strparser *strp)
+{
+ struct stap_sock *tsk = container_of(strp, struct stap_sock,
+ send_bops.strp);
+
+ lock_sock(tsk->sk);
+}
+
+void stap_send_unlock(struct strparser *strp)
+{
+ struct stap_sock *tsk = container_of(strp, struct stap_sock,
+ send_bops.strp);
+
+ release_sock(tsk->sk);
+}
+
+static struct sk_buff *stap_rx_peek(struct stap_sock *tsk)
+{
+ return tsk->recv_skb;
+}
+
+static struct sk_buff *stap_rx_dequeue(struct stap_sock *tsk)
+{
+ struct sk_buff *skb;
+
+ skb = tsk->recv_skb;
+ tsk->recv_skb = NULL;
+ strp_unpause(&tsk->recv_bops.strp);
+
+ return skb;
+}
+
+static struct sk_buff *stap_wait_data(struct stap_sock *tsk, int flags,
+ long timeo, int *err)
+{
+ DEFINE_WAIT_FUNC(wait, woken_wake_function);
+ struct sock *sk = tsk->sk;
+ struct sk_buff *skb;
+
+ while (!(skb = stap_rx_peek(tsk))) {
+ if (sk->sk_err) {
+ *err = sock_error(sk);
+ return NULL;
+ }
+
+ if (sock_flag(sk, SOCK_DONE))
+ return NULL;
+
+ if ((flags & MSG_DONTWAIT) || !timeo) {
+ *err = -EAGAIN;
+ return NULL;
+ }
+
+ /* Use socket to wait on receive message */
+ add_wait_queue(sk_sleep(sk), &wait);
+ sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
+ sk_wait_event(sk, &timeo, !!stap_rx_peek(tsk), &wait);
+ sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
+ remove_wait_queue(sk_sleep(sk), &wait);
+
+ /* Handle signals */
+ if (signal_pending(current)) {
+ *err = sock_intr_errno(timeo);
+ return NULL;
+ }
+ }
+
+ return skb;
+}
+
+static int stap_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+ int flags)
+{
+ struct stap_sock *tsk = tsk_from_socket(sock);
+ struct sock *sk = sock->sk;
+ long timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
+ struct sk_buff *skb;
+ size_t copied = 0;
+ size_t slen;
+ int err;
+
+ if (unlikely(!tsk))
+ return 0;
+
+ lock_sock(sk);
+
+ while (len && (skb = stap_wait_data(tsk, flags, timeo, &err))) {
+ struct strp_msg *stm = strp_msg(skb);
+
+ slen = len > stm->full_len ? stm->full_len : len;
+ err = skb_copy_datagram_msg(skb, stm->offset, msg, slen);
+ if (err < 0)
+ goto out_error;
+
+ copied += slen;
+ len -= slen;
+
+ if (unlikely(flags & MSG_PEEK)) {
+ /* This limits peek to one messge */
+ goto out;
+ }
+
+ stm->full_len -= slen;
+ stm->offset += slen;
+
+ if (!stm->full_len) {
+ stap_rx_dequeue(tsk);
+ kfree_skb(skb);
+ break;
+ }
+ }
+
+out:
+ release_sock(sk);
+
+ return copied;
+
+out_error:
+ release_sock(sk);
+
+ return copied ? : err;
+}
+
+static ssize_t stap_splice_read(struct socket *sock, loff_t *ppos,
+ struct pipe_inode_info *pipe, size_t len,
+ unsigned int flags)
+{
+ struct stap_sock *tsk = tsk_from_socket(sock);
+ struct sock *sk = sock->sk;
+ long timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
+ struct sk_buff *skb;
+ size_t copied = 0;
+ size_t slen;
+ int err;
+
+ if (unlikely(!tsk))
+ return 0;
+
+ lock_sock(sk);
+
+ while (len && (skb = stap_wait_data(tsk, flags, timeo, &err))) {
+ struct strp_msg *stm = strp_msg(skb);
+
+ slen = len > stm->full_len ? stm->full_len : len;
+
+ slen = skb_splice_bits(skb, sk, stm->offset, pipe,
+ slen, flags);
+ if (slen < 0) {
+ err = slen;
+ goto out_error;
+ }
+
+ stm->full_len -= slen;
+ stm->offset += slen;
+
+ copied += slen;
+ len -= slen;
+ if (!stm->full_len) {
+ stap_rx_dequeue(tsk);
+ kfree_skb(skb);
+ break;
+ }
+ }
+
+ release_sock(sk);
+
+ return copied;
+
+out_error:
+ release_sock(sk);
+
+ return copied ? : err;
+}
+
+static int stap_parse_recv_strparser(struct strparser *strp,
+ struct sk_buff *skb)
+{
+ struct stap_sock *tsk = container_of(strp, struct stap_sock,
+ recv_bops.strp);
+ struct bpf_prog *prog = tsk->recv_bops.parse_prog;
+
+ return (*prog->bpf_func)(skb, prog->insnsi);
+}
+
+/* Called with lower sock held */
+static void stap_input_recv_strparser(struct strparser *strp,
+ struct sk_buff *skb)
+{
+ struct stap_sock *tsk = container_of(strp, struct stap_sock,
+ recv_bops.strp);
+ struct bpf_prog *prog = tsk->recv_bops.verdict_prog;
+ int rc;
+
+ WARN_ON(tsk->recv_skb);
+
+ /* Run the verdict program to get dispostion of the message */
+ rc = (*prog->bpf_func)(skb, prog->insnsi);
+
+ switch (rc) {
+ case BPF_OK:
+ tsk->recv_skb = skb;
+
+ strp_pause(&tsk->recv_bops.strp);
+
+ /* Wake up the socket readers */
+ tsk->save_data_ready(tsk->sk);
+
+ break;
+
+ case BPF_DROP:
+ kfree_skb(skb);
+ return;
+
+ case BPF_REDIRECT:
+ /* Not supported yet. */
+ case BPF_DISCONNECT:
+ /* Kill connection */
+ default:
+ kfree_skb(skb);
+ strp_stop(&tsk->recv_bops.strp);
+ tsk->sk->sk_err = ECONNABORTED;
+ tsk->sk->sk_error_report(tsk->sk);
+ }
+}
+
+static int stap_load_bpf_prog(int fd, struct bpf_prog **prog)
+{
+ *prog = bpf_prog_get_type(fd, BPF_PROG_TYPE_SOCKET_FILTER);
+ if (IS_ERR(*prog))
+ return PTR_ERR(*prog);
+
+ return 0;
+}
+
+/* Sock lock must be held */
+static int stap_ulp_init(struct sock *sk, char __user *optval, int len)
+{
+ struct socket *sock = sk->sk_socket;
+ struct stap_params zparm;
+ struct strp_callbacks cb;
+ struct stap_sock *tsk;
+ int rc = 0;
+
+ /* Need stap parameters */
+ if (len < sizeof(zparm)) {
+ rc = -EINVAL;
+ goto out_error;
+ }
+
+ if (copy_from_user(&zparm, optval, sizeof(zparm))) {
+ rc = -EFAULT;
+ goto out_error;
+ }
+
+ /* Allocate stap socket context */
+ tsk = kzalloc(sizeof(*tsk), GFP_KERNEL);
+ if (!tsk) {
+ rc = -ENOMEM;
+ goto out_error;
+ }
+
+ rc = stap_load_bpf_prog(zparm.bpf_send_parse_fd,
+ &tsk->send_bops.parse_prog);
+ if (rc)
+ goto send_parse_prog_fail;
+
+ rc = stap_load_bpf_prog(zparm.bpf_send_verdict_fd,
+ &tsk->send_bops.verdict_prog);
+ if (rc)
+ goto send_verdict_prog_fail;
+
+ rc = stap_load_bpf_prog(zparm.bpf_recv_parse_fd,
+ &tsk->recv_bops.parse_prog);
+ if (rc)
+ goto recv_parse_prog_fail;
+
+ rc = stap_load_bpf_prog(zparm.bpf_recv_verdict_fd,
+ &tsk->recv_bops.verdict_prog);
+ if (rc)
+ goto recv_verdict_prog_fail;
+
+ tsk->sk = sk;
+
+ tsk->orig_ops = sock->ops;
+ sock->ops = &stap_tcp_stream_ops;
+
+ memset(&cb, 0, sizeof(cb));
+ cb.rcv_msg = stap_input_recv_strparser;
+ cb.parse_msg = stap_parse_recv_strparser;
+
+ rc = strp_init(&tsk->recv_bops.strp, sk, &cb);
+ if (rc)
+ goto strp_recv_fail;
+
+ __skb_queue_head_init(&tsk->build_list);
+ __skb_queue_head_init(&tsk->ready_list);
+
+ sk->sk_ulp_data = tsk;
+
+ memset(&cb, 0, sizeof(cb));
+ cb.rcv_msg = stap_input_send_strparser;
+ cb.parse_msg = stap_parse_send_strparser;
+ cb.lock = stap_send_lock;
+ cb.unlock = stap_send_unlock;
+
+ rc = strp_init(&tsk->send_bops.strp, NULL, &cb);
+ if (rc)
+ goto strp_send_fail;
+
+ write_lock_bh(&sk->sk_callback_lock);
+ tsk->save_data_ready = sk->sk_data_ready;
+ tsk->save_write_space = sk->sk_write_space;
+ tsk->save_state_change = sk->sk_state_change;
+ sk->sk_user_data = tsk;
+ sk->sk_data_ready = stap_data_ready;
+ sk->sk_write_space = stap_write_space;
+ sk->sk_state_change = stap_state_change;
+ write_unlock_bh(&sk->sk_callback_lock);
+
+ strp_check_rcv(&tsk->recv_bops.strp);
+
+ return 0;
+
+strp_send_fail:
+ strp_stop(&tsk->recv_bops.strp);
+ strp_done(&tsk->recv_bops.strp);
+strp_recv_fail:
+ bpf_prog_put(tsk->recv_bops.verdict_prog);
+recv_verdict_prog_fail:
+ bpf_prog_put(tsk->recv_bops.parse_prog);
+recv_parse_prog_fail:
+ bpf_prog_put(tsk->send_bops.verdict_prog);
+send_verdict_prog_fail:
+ bpf_prog_put(tsk->send_bops.parse_prog);
+send_parse_prog_fail:
+ kfree(tsk);
+out_error:
+ return rc;
+}
+
+/* Socket lock must not be held here */
+static void stap_ulp_release(struct sock *sk)
+{
+ struct stap_sock *tsk = (struct stap_sock *)sk->sk_ulp_data;
+
+ write_lock_bh(&sk->sk_callback_lock);
+ sk->sk_user_data = NULL;
+ sk->sk_data_ready = tsk->save_data_ready;
+ sk->sk_write_space = tsk->save_write_space;
+ sk->sk_state_change = tsk->save_state_change;
+ strp_stop(&tsk->recv_bops.strp);
+ strp_stop(&tsk->send_bops.strp);
+ write_unlock_bh(&sk->sk_callback_lock);
+
+ strp_done(&tsk->recv_bops.strp);
+ strp_done(&tsk->send_bops.strp);
+ bpf_prog_put(tsk->send_bops.verdict_prog);
+ bpf_prog_put(tsk->send_bops.parse_prog);
+ bpf_prog_put(tsk->recv_bops.verdict_prog);
+ bpf_prog_put(tsk->recv_bops.parse_prog);
+
+ __skb_queue_purge(&tsk->ready_list);
+ __skb_queue_purge(&tsk->build_list);
+
+ kfree_skb(tsk->recv_skb);
+
+ /* Release BPF progs */
+
+ sk->sk_ulp_data = NULL;
+
+ kfree(tsk);
+}
+
+static struct ulp_ops stap_ulp_ops __read_mostly = {
+ .name = "stap",
+ .owner = THIS_MODULE,
+ .init = stap_ulp_init,
+ .release = stap_ulp_release,
+};
+
+static int __init stap_init(void)
+{
+ int err;
+
+ stap_tcp_stream_ops = inet_stream_ops;
+ stap_tcp_stream_ops.sendmsg = stap_sendmsg;
+ stap_tcp_stream_ops.sendpage = stap_sendpage;
+ stap_tcp_stream_ops.recvmsg = stap_recvmsg;
+ stap_tcp_stream_ops.splice_read = stap_splice_read;
+
+ err = ulp_register(&stap_ulp_ops);
+ if (err)
+ goto register_ulp_fail;
+
+ return 0;
+
+register_ulp_fail:
+ return err;
+}
+
+static void __exit stap_exit(void)
+{
+ ulp_unregister(&stap_ulp_ops);
+}
+
+module_init(stap_init);
+module_exit(stap_exit);
+MODULE_AUTHOR("Tom Herbert");
+MODULE_LICENSE("GPL");
+
--
2.11.0
^ permalink raw reply related
* [PATCH RFC 1/2] bpf: Add a BPF return code to disconnect a connection
From: Tom Herbert @ 2017-08-07 22:12 UTC (permalink / raw)
To: netdev; +Cc: rohit, Tom Herbert
In-Reply-To: <20170807221204.15724-1-tom@quantonium.net>
When using BPF program against a flow a possible verdict is that the
packet should not only be dropped, but that the flow the packet
was received on should be terminated.
Signed-off-by: Tom Herbert <tom@quantonium.net>
---
include/uapi/linux/bpf.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 1d06be1569b1..324e886c3490 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -708,6 +708,7 @@ enum bpf_ret_code {
BPF_DROP = 2,
/* 3-6 reserved */
BPF_REDIRECT = 7,
+ BPF_DISCONNECT = 8,
/* >127 are reserved for prog type specific return codes */
};
--
2.11.0
^ permalink raw reply related
* [PATCH RFC 0/2] stap: Socket tap
From: Tom Herbert @ 2017-08-07 22:12 UTC (permalink / raw)
To: netdev; +Cc: rohit, Tom Herbert
This patch set introduces generic socket tap support. This allows a
means to run BPF programs or implement other functionality in both the
send and receive path of a socket.
The socket tap uses the ULP mechanism recently introduced for kTLS.
The data operations (sendmsg, recvmsg, sendpage, and splice_recv)
are intercepted. In both directions strparser is used to break the
stream into discrete application layer messages. Each message is
then run through a BPF verdict program that indicates the message
is okay, should be dropped, or should be dropped and the connection
terminated.
The data path for socket tap for TCP is illustrated below:
+---------------------+
| Application |
| |
| sendmsg recvmsg |
+---------------------+
| ^
| |
--------|---------|---------------------
| |
| +-------------+ +--------------+ +----------------+
| | Socket tap |<---| Verdict prog |<---| strparser |
| | recvmsg | | | | TCP data ready |
| +-------------+ +--------------+ +----------------+
| ^
| |
| TCP receive queue
V
+-------------+ +-----------+ +--------------+ +---------------+
| Socket tap |-->| strparser |-->| Verdict prog |-->| skb_send_sock |
| sendmsg | | send mode | | | | locked |
+-------------+ +-----------+ +--------------+ +---------------+
|
V
TCP write queue
Interface:
A socket tap is enabled on socket using SO_ULP socket option with
ulp type "stap". The socket option takes ULP specific configuration
in the stap_params structure. The parameters consist of four file
descriptors for BPF programs. These are for the parser (strparser)
in the send path, the verdict program for send path, the parser
and verdict programs in the receive path.
Example configuration to set a socket tap. In this case the same
parse and verdict programs are used on send and receive sides of the
socket.:
struct {
struct ulp_config ulpc;
struct stap_params sp;
} my_config;
load_bpf_file("parse_kern.o");
load_bpf_file("verdict_kern.o");
my_config.ulpc.ulp_name = "stap";
my_config.sp.bpf_send_parse_fd = prog_fd[0];
my_config.sp.bpf_send_verdict_fd = prog_fd[1];
my_config.sp.bpf_recv_parse_fd = prog_fd[0];
my_config.sp.bpf_recv_verdict_fd = prog_fd[1];
setsockopt(fd, SOL_SOCKET, SO_ULP, &my_config, sizeof(myconfig)
Future work:
- Fill in all the expected semantics. A goal of socket tap is
transparency with applications.
- Performance evaluation.
- Add a mechanism to allow an admin process to tap other users'
sockets.
- Add userpsace tap that can diverted applciation messages through
userpsace. I'm thinking to connect tapped sockets to KCM to provide
for interface.
- Integrate with kTLS.
- SUpport for BFP_REDIRECT. This would be useful to redirect messages
to different sockets like in John Fasatabend's socket redirect.
Tom Herbert (2):
bpf: Add a BPF return code to disconnect a connection
stap: Socket tap
include/net/stap.h | 43 +++
include/uapi/linux/bpf.h | 1 +
include/uapi/linux/stap.h | 21 ++
net/Kconfig | 1 +
net/Makefile | 1 +
net/stap/Kconfig | 8 +
net/stap/Makefile | 3 +
net/stap/stap_main.c | 769 ++++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 847 insertions(+)
create mode 100644 include/net/stap.h
create mode 100644 include/uapi/linux/stap.h
create mode 100644 net/stap/Kconfig
create mode 100644 net/stap/Makefile
create mode 100644 net/stap/stap_main.c
--
2.11.0
^ permalink raw reply
* Re: [PATCH] wan: dscc4: add checks for dma mapping errors
From: Francois Romieu @ 2017-08-07 21:59 UTC (permalink / raw)
To: Alexey Khoroshilov; +Cc: David S . Miller, netdev, linux-kernel, ldv-project
In-Reply-To: <1501878204-24270-1-git-send-email-khoroshilov@ispras.ru>
Alexey Khoroshilov <khoroshilov@ispras.ru> :
> The driver does not check if mapping dma memory succeed.
> The patch adds the checks and failure handling.
>
> Found by Linux Driver Verification project (linuxtesting.org).
>
> Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
Please amend your subject line as:
Subject: [PATCH net-next v2 1/1] dscc4: add checks for dma mapping errors.
Rationale: davem is not supposed to guess the branch the patch should be
applied to.
[...]
> diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
> index 799830ffcae2..1a94f0a95b2c 100644
> --- a/drivers/net/wan/dscc4.c
> +++ b/drivers/net/wan/dscc4.c
> @@ -522,19 +522,27 @@ static inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv,
> struct RxFD *rx_fd = dpriv->rx_fd + dirty;
> const int len = RX_MAX(HDLC_MAX_MRU);
> struct sk_buff *skb;
> - int ret = 0;
> + dma_addr_t addr;
>
> skb = dev_alloc_skb(len);
> dpriv->rx_skbuff[dirty] = skb;
> - if (skb) {
> - skb->protocol = hdlc_type_trans(skb, dev);
> - rx_fd->data = cpu_to_le32(pci_map_single(dpriv->pci_priv->pdev,
> - skb->data, len, PCI_DMA_FROMDEVICE));
> - } else {
> - rx_fd->data = 0;
> - ret = -1;
> - }
> - return ret;
> + if (!skb)
> + goto err_out;
> +
> + skb->protocol = hdlc_type_trans(skb, dev);
> + addr = pci_map_single(dpriv->pci_priv->pdev,
> + skb->data, len, PCI_DMA_FROMDEVICE);
> + if (pci_dma_mapping_error(dpriv->pci_priv->pdev, addr))
> + goto err_free_skb;
Nit: please use a local 'struct pci_dev *pdev = dpriv->pci_priv->pdev;'
[...]
> @@ -1147,14 +1155,22 @@ static netdev_tx_t dscc4_start_xmit(struct sk_buff *skb,
> struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
> struct dscc4_pci_priv *ppriv = dpriv->pci_priv;
> struct TxFD *tx_fd;
> + dma_addr_t addr;
> int next;
>
> + addr = pci_map_single(ppriv->pdev, skb->data, skb->len,
> + PCI_DMA_TODEVICE);
> + if (pci_dma_mapping_error(ppriv->pdev, addr)) {
> + dev_kfree_skb_any(skb);
> + dev->stats.tx_errors++;
It should read 'dev->stats.tx_dropped++'.
--
Ueimor
^ permalink raw reply
* Re: [PATCH net-next v3 00/13] Update DSA's FDB API and perform switchdev cleanup
From: David Miller @ 2017-08-07 21:49 UTC (permalink / raw)
To: arkadis
Cc: netdev, jiri, ivecera, f.fainelli, andrew, vivien.didelot,
Woojung.Huh, mlxsw
In-Reply-To: <1502025351-41261-1-git-send-email-arkadis@mellanox.com>
From: Arkadi Sharshevsky <arkadis@mellanox.com>
Date: Sun, 6 Aug 2017 16:15:38 +0300
> The patchset adds support for configuring static FDB entries via the
> switchdev notification chain. The current method for FDB configuration
> uses the switchdev's bridge bypass implementation. In order to support
> this legacy way and to perform the switchdev cleanup, the implementation
> is moved inside DSA.
>
> The DSA drivers cannot sync the software bridge with hardware learned
> entries and use the switchdev's implementation of bypass FDB dumping.
> Because they are the only ones using this functionality, the fdb_dump
> implementation is moved from switchdev code into DSA.
>
> Finally after this changes a major cleanup in switchdev can be done.
> ---
> Please see individual patches for patch specific change logs.
> v1->v2
> - Split MDB/vlan dump removal into core/driver removal.
>
> v2->v3
> - The self implementation for FDB add/del is moved inside DSA.
Series applied, thank you.
^ permalink raw reply
* Re: [PATCH 0/3] ARM: dts: keystone-k2g: Add DCAN instances to 66AK2G
From: Franklin S Cooper Jr @ 2017-08-07 21:31 UTC (permalink / raw)
To: Santosh Shilimkar, wg, mkl, robh+dt, ssantosh, linux, linux-can,
netdev, devicetree, linux-kernel, linux-arm-kernel
In-Reply-To: <69995971-2fe7-87f4-a46a-8ef4f729ffc5@oracle.com>
Hi Santosh,
On 08/04/2017 12:07 PM, Santosh Shilimkar wrote:
> Hi Franklin,
>
> On 8/2/2017 1:18 PM, Franklin S Cooper Jr wrote:
>> Add D CAN nodes to 66AK2G based SoC dtsi.
>>
>> Franklin S Cooper Jr (2):
>> dt-bindings: net: c_can: Update binding for clock and power-domains
>> property
>> ARM: configs: keystone: Enable D_CAN driver
>>
>> Lokesh Vutla (1):
>> ARM: dts: k2g: Add DCAN nodes
>>
> Any DCAN driver dependency with these patchset ? If not, I can
> queue this up so do let me know.
There aren't any dependencies.
>
> Regards,
> Santosh
^ permalink raw reply
* Re: [PATCH] hamradio: baycom: make hdlcdrv_ops const
From: David Miller @ 2017-08-07 21:26 UTC (permalink / raw)
To: bhumirks; +Cc: julia.lawall, t.sailer, linux-hams, netdev, linux-kernel
In-Reply-To: <1502009505-12973-1-git-send-email-bhumirks@gmail.com>
From: Bhumika Goyal <bhumirks@gmail.com>
Date: Sun, 6 Aug 2017 14:21:45 +0530
> Make hdlcdrv_ops structures const as they are only passed to
> hdlcdrv_register function. The corresponding argument is of type const,
> so make the structures const.
>
> Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next] selftests: bpf: add a test for XDP redirect
From: Daniel Borkmann @ 2017-08-07 21:26 UTC (permalink / raw)
To: William Tu, netdev; +Cc: John Fastabend
In-Reply-To: <1502136882-40204-1-git-send-email-u9012063@gmail.com>
On 08/07/2017 10:14 PM, William Tu wrote:
> Add test for xdp_redirect by creating two namespaces with two
> veth peers, then forward packets in-between.
>
> Signed-off-by: William Tu <u9012063@gmail.com>
> Cc: Daniel Borkmann <daniel@iogearbox.net>
> Cc: John Fastabend <john.fastabend@gmail.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
^ permalink raw reply
* Re: [PATCH ipsec-next] xfrm: check that cached bundle is still valid
From: David Miller @ 2017-08-07 21:26 UTC (permalink / raw)
To: fw; +Cc: netdev
In-Reply-To: <20170806081907.5267-1-fw@strlen.de>
From: Florian Westphal <fw@strlen.de>
Date: Sun, 6 Aug 2017 10:19:07 +0200
> Quoting Ilan Tayari:
> 1. Set up a host-to-host IPSec tunnel (or transport, doesn't matter)
> 2. Ping over IPSec, or do something to populate the pcpu cache
> 3. Join a MC group, then leave MC group
> 4. Try to ping again using same CPU as before -> traffic
> doesn't egress the machine at all
>
> Ilan debugged the problem down to the fact that one of the path dsts
> devices point to lo due to earlier dst_dev_put().
> In this case, dst is marked as DEAD and we cannot reuse the bundle.
>
> The cache only asserted that the requested policy and that of the cached
> bundle match, but its not enough - also verify the path is still valid.
>
> Fixes: ec30d78c14a813 ("xfrm: add xdst pcpu cache")
> Reported-by: Ayham Masood <ayhamm@mellanox.com>
> Tested-by: Ilan Tayari <ilant@mellanox.com>
> Signed-off-by: Florian Westphal <fw@strlen.de>
Since this regression is from the flow cache removal that went directly
into my tree, I'll apply this directly to net-next as well.
Thanks Florian.
^ permalink raw reply
* Re: [PATCH net-next v2 0/3] net: dsa: remove useless arguments
From: David Miller @ 2017-08-07 21:24 UTC (permalink / raw)
To: vivien.didelot; +Cc: netdev, linux-kernel, kernel, f.fainelli, andrew
In-Reply-To: <20170805202019.1679-1-vivien.didelot@savoirfairelinux.com>
From: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Date: Sat, 5 Aug 2017 16:20:16 -0400
> Several DSA core setup functions take many arguments, mostly because of
> the legacy code. This patch series removes the useless args of these
> functions, where either the dsa_switch or dsa_port argument is enough.
>
> Changes in v2:
> - ds->dev is already assigned by dsa_switch_alloc
Series applied, thanks.
^ permalink raw reply
* Re: [RFC] iproute: Add support for extended ack to rtnl_talk
From: Stephen Hemminger @ 2017-08-07 21:21 UTC (permalink / raw)
To: David Miller; +Cc: dsahern, simon.horman, daniel, phil, netdev
In-Reply-To: <20170807.132603.2058256055534574552.davem@davemloft.net>
On Mon, 07 Aug 2017 13:26:03 -0700 (PDT)
David Miller <davem@davemloft.net> wrote:
> From: Stephen Hemminger <stephen@networkplumber.org>
> Date: Mon, 7 Aug 2017 12:12:35 -0700
>
> > Dave, I asked for test cases, and received none.
>
> You don't need a test case to type make and make sure the build succeeds.
It did succeed for libmnl but was not doing anything.
^ permalink raw reply
* Re: [PATCH][net-next] net: hns3: fix spelling mistake: "capabilty" -> "capability"
From: David Miller @ 2017-08-07 21:21 UTC (permalink / raw)
To: colin.king
Cc: yisen.zhuang, salil.mehta, lipeng321, xavier.huwei, huangdaode,
netdev, linux-kernel
In-Reply-To: <20170805134635.1256-1-colin.king@canonical.com>
From: Colin King <colin.king@canonical.com>
Date: Sat, 5 Aug 2017 14:46:35 +0100
> From: Colin Ian King <colin.king@canonical.com>
>
> Trivial fix to spelling mistake in dev_err error message and also
> split overly long line to avoid a checkpatch warning.
>
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
Applied, thank you.
^ permalink raw reply
* Re: [PATCH v4 net-next 0/5] Refactor lan9303_xxx_packet_processing
From: David Miller @ 2017-08-07 21:18 UTC (permalink / raw)
To: privat; +Cc: andrew, vivien.didelot, f.fainelli, netdev, linux-kernel, kernel
In-Reply-To: <20170805110550.26337-1-privat@egil-hjelmeland.no>
From: Egil Hjelmeland <privat@egil-hjelmeland.no>
Date: Sat, 5 Aug 2017 13:05:45 +0200
> This series is purely non functional.
>
> It changes the lan9303_enable_packet_processing,
> lan9303_disable_packet_processing() to pass port number (0,1,2) as
> parameter instead of port offset. This aligns them with
> other functions in the module, and makes it possible to simplify the code.
>
> The lan9303_enable_packet_processing, lan9303_disable_packet_processing
> functions operate on port. Therefore rename the functions to reflect that
> as well.
>
> Reviewer pointed out lan9303_get_ethtool_stats would be better off with
> the use of a lan9303_read_switch_port(). So that was added to the series.
...
Series applied, thank you.
^ permalink raw reply
* Re: [PATCH net-next v2 0/5] ipv6: sr: add support for advanced local segment processing
From: David Miller @ 2017-08-07 21:16 UTC (permalink / raw)
To: david.lebrun; +Cc: netdev
In-Reply-To: <20170805103828.21458-1-david.lebrun@uclouvain.be>
From: David Lebrun <david.lebrun@uclouvain.be>
Date: Sat, 5 Aug 2017 12:38:23 +0200
> v2: use EXPORT_SYMBOL_GPL
>
> The current implementation of IPv6 SR supports SRH insertion/encapsulation
> and basic segment endpoint behavior (i.e., processing of an SRH contained in
> a packet whose active segment (IPv6 DA) is routed to the local node). This
> behavior simply consists of updating the DA to the next segment and forwarding
> the packet accordingly. This processing is realised for all such packets,
> regardless of the active segment.
>
> The most recent specifications of IPv6 SR [1] [2] extend the SRH processing
> features as follows. Each segment endpoint defines a MyLocalSID table.
> This table maps segments to operations to perform. For each ingress IPv6
> packet whose DA is part of a given prefix, the segment endpoint looks
> up the active segment (i.e., the IPv6 DA) in the MyLocalSID table and
> applies the corresponding operation. Such specifications enable to specify
> arbitrary operations besides the basic SRH processing and allow for a more
> fine-grained classification.
>
> This patch series implements those extended specifications by leveraging
> a new type of lightweight tunnel, seg6local.
...
Series applied, thanks David.
^ permalink raw reply
* Re: unregister_netdevice: waiting for eth0 to become free. Usage count = 1
From: John Stultz @ 2017-08-07 21:15 UTC (permalink / raw)
To: lkml, Network Development, Linux USB List, David S. Miller,
Felipe Balbi
In-Reply-To: <CALAqxLWVYgnTnwAwm7uNQ6P_Z8xFd96NQ+G_j1qT+h5F6habag@mail.gmail.com>
On Mon, Aug 7, 2017 at 2:05 PM, John Stultz <john.stultz@linaro.org> wrote:
> So, with recent testing with my HiKey board, I've been noticing some
> quirky behavior with my USB eth adapter.
>
> Basically, pluging the usb eth adapter in and then removing it, when
> plugging it back in I often find that its not detected, and the system
> slowly spits out the following message over and over:
> unregister_netdevice: waiting for eth0 to become free. Usage count = 1
The other bit is that after this starts printing, the board will no
longer reboot (it hangs continuing to occasionally print the above
message), and I have to manually reset the device.
thanks
-john
^ permalink raw reply
* Re: [PATCH net] net: sched: fix NULL pointer dereference when action calls some targets
From: Cong Wang @ 2017-08-07 21:15 UTC (permalink / raw)
To: Xin Long; +Cc: network dev, David Miller, netfilter-devel, Jamal Hadi Salim
In-Reply-To: <0fa9a53725dd661571461cf283ec88cf15f4b139.1501932907.git.lucien.xin@gmail.com>
(Cc'ing netfilter and Jamal)
On Sat, Aug 5, 2017 at 4:35 AM, Xin Long <lucien.xin@gmail.com> wrote:
> As we know in some target's checkentry it may dereference par.entryinfo
> to check entry stuff inside. But when sched action calls xt_check_target,
> par.entryinfo is set with NULL. It would cause kernel panic when calling
> some targets.
>
> It can be reproduce with:
> # tc qd add dev eth1 ingress handle ffff:
> # tc filter add dev eth1 parent ffff: u32 match u32 0 0 action xt \
> -j ECN --ecn-tcp-remove
>
> It could also crash kernel when using target CLUSTERIP or TPROXY.
>
> By now there's no proper value for par.entryinfo in ipt_init_target,
> but it can not be set with NULL. This patch is to void all these
> panics by setting it with an ipt_entry obj with all members 0.
>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> ---
> net/sched/act_ipt.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
> index 7c4816b..0f09f70 100644
> --- a/net/sched/act_ipt.c
> +++ b/net/sched/act_ipt.c
> @@ -41,6 +41,7 @@ static int ipt_init_target(struct net *net, struct xt_entry_target *t,
> {
> struct xt_tgchk_param par;
> struct xt_target *target;
> + struct ipt_entry e;
> int ret = 0;
>
> target = xt_request_find_target(AF_INET, t->u.user.name,
> @@ -48,10 +49,11 @@ static int ipt_init_target(struct net *net, struct xt_entry_target *t,
> if (IS_ERR(target))
> return PTR_ERR(target);
>
> + memset(&e, 0, sizeof(e));
> t->u.kernel.target = target;
> par.net = net;
> par.table = table;
> - par.entryinfo = NULL;
> + par.entryinfo = &e;
This looks like a completely API burden?
^ permalink raw reply
* Re: [PATCH v9 0/4] Add new PCI_DEV_FLAGS_NO_RELAXED_ORDERING flag
From: David Miller @ 2017-08-07 21:14 UTC (permalink / raw)
To: dingtianhong
Cc: bhelgaas, helgaas, leedom, ashok.raj, werner, ganeshgr,
asit.k.mallick, patrick.j.cramer, Suravee.Suthikulpanit, Bob.Shaw,
l.stach, amira, gabriele.paoloni, David.Laight, jeffrey.t.kirsher,
catalin.marinas, will.deacon, mark.rutland, robin.murphy,
alexander.duyck, linux-arm-kernel, netdev, linux-pci,
linux-kernel, linuxarm
In-Reply-To: <588b378c-249a-36b0-8890-769258fbb708@huawei.com>
From: Ding Tianhong <dingtianhong@huawei.com>
Date: Mon, 7 Aug 2017 12:13:17 +0800
> Hi David:
>
> I think networking tree merge it is a better choice, as it mainly used to tell the NIC
> drivers how to use the Relaxed Ordering Attribute, and later we need send patch to enable
> RO for ixgbe driver base on this patch. But I am not sure whether Bjorn has some of his own
> view. :)
>
> Hi Bjorn:
>
> Could you help review this patch or give some feedback ?
I'm still waiting on this...
Bjorn?
^ permalink raw reply
* Re: [net-next PATCH v2] bpf: devmap fix mutex in rcu critical section
From: David Miller @ 2017-08-07 21:13 UTC (permalink / raw)
To: john.fastabend; +Cc: daniel, alexander.levin, netdev
In-Reply-To: <20170805050219.12333.47493.stgit@john-Precision-Tower-5810>
From: John Fastabend <john.fastabend@gmail.com>
Date: Fri, 04 Aug 2017 22:02:19 -0700
> Originally we used a mutex to protect concurrent devmap update
> and delete operations from racing with netdev unregister notifier
> callbacks.
>
> The notifier hook is needed because we increment the netdev ref
> count when a dev is added to the devmap. This ensures the netdev
> reference is valid in the datapath. However, we don't want to block
> unregister events, hence the initial mutex and notifier handler.
>
> The concern was in the notifier hook we search the map for dev
> entries that hold a refcnt on the net device being torn down. But,
> in order to do this we require two steps,
...
> Fortunately, by writing slightly better code we can avoid the
> mutex altogether. If CPU 1 in the above example uses a cmpxchg
> and _only_ replaces the dev reference in the map when it is in
> fact the expected dev the race is removed completely. The two
> cases being illustrated here, first the race condition,
...
> And viola the original race we tried to solve with a mutex is
> corrected and the trace noted by Sasha below is resolved due
> to removal of the mutex.
>
> Note: When walking the devmap and removing dev references as needed
> we depend on the core to fail any calls to dev_get_by_index() using
> the ifindex of the device being removed. This way we do not race with
> the user while searching the devmap.
>
> Additionally, the mutex was also protecting list add/del/read on
> the list of maps in-use. This patch converts this to an RCU list
> and spinlock implementation. This protects the list from concurrent
> alloc/free operations. The notifier hook walks this list so it uses
> RCU read semantics.
>
> BUG: sleeping function called from invalid context at kernel/locking/mutex.c:747
> in_atomic(): 1, irqs_disabled(): 0, pid: 16315, name: syz-executor1
> 1 lock held by syz-executor1/16315:
> #0: (rcu_read_lock){......}, at: [<ffffffff8c363bc2>] map_delete_elem kernel/bpf/syscall.c:577 [inline]
> #0: (rcu_read_lock){......}, at: [<ffffffff8c363bc2>] SYSC_bpf kernel/bpf/syscall.c:1427 [inline]
> #0: (rcu_read_lock){......}, at: [<ffffffff8c363bc2>] SyS_bpf+0x1d32/0x4ba0 kernel/bpf/syscall.c:1388
>
> Fixes: 2ddf71e23cc2 ("net: add notifier hooks for devmap bpf map")
> Reported-by: Sasha Levin <alexander.levin@verizon.com>
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> Signed-off-by: John Fastabend <john.fastabend@gmail.com>
Applied, thanks John.
^ permalink raw reply
* Re: [Patch net-next 0/2] net_sched: clean up filter handle
From: David Miller @ 2017-08-07 21:12 UTC (permalink / raw)
To: xiyou.wangcong; +Cc: netdev, jhs, jiri
In-Reply-To: <20170805043143.13680-1-xiyou.wangcong@gmail.com>
From: Cong Wang <xiyou.wangcong@gmail.com>
Date: Fri, 4 Aug 2017 21:31:41 -0700
> This patchset sits in my local branch for a long time, it is time to
> send it out. It cleans up the ambiguous use of 'unsigned long fh',
> please see each of them for details.
Series applied, thanks Cong.
^ permalink raw reply
* Re: [PATCH net-next v2] lwtunnel: replace EXPORT_SYMBOL with EXPORT_SYMBOL_GPL
From: David Miller @ 2017-08-07 21:10 UTC (permalink / raw)
To: roopa; +Cc: netdev
In-Reply-To: <1501895958-64278-1-git-send-email-roopa@cumulusnetworks.com>
From: Roopa Prabhu <roopa@cumulusnetworks.com>
Date: Fri, 4 Aug 2017 18:19:18 -0700
> From: Roopa Prabhu <roopa@cumulusnetworks.com>
>
> Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
> ---
> v2 - fixed a incorrect replace
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next v4 0/2] bpf: add support for sys_{enter|exit}_* tracepoints
From: David Miller @ 2017-08-07 21:10 UTC (permalink / raw)
To: yhs; +Cc: peterz, rostedt, ast, daniel, netdev, kernel-team
In-Reply-To: <20170804230010.2792119-1-yhs@fb.com>
From: Yonghong Song <yhs@fb.com>
Date: Fri, 4 Aug 2017 16:00:08 -0700
> Currently, bpf programs cannot be attached to sys_enter_* and sys_exit_*
> style tracepoints. The main reason is that syscalls/sys_enter_* and syscalls/sys_exit_*
> tracepoints are treated differently from other tracepoints and there
> is no bpf hook to it.
>
> This patch set adds bpf support for these syscalls tracepoints and also
> adds a test case for it.
>
> Changelogs:
> v3 -> v4:
> - Check the legality of ctx offset access for syscall tracepoint as well.
> trace_event_get_offsets will return correct max offset for each
> specific syscall tracepoint.
> - Use variable length array to avoid hardcode 6 as the maximum
> arguments beyond syscall_nr.
> v2 -> v3:
> - Fix a build issue
> v1 -> v2:
> - Do not use TRACE_EVENT_FL_CAP_ANY to identify syscall tracepoint.
> Instead use trace_event_call->class.
Series applied, thank you.
^ permalink raw reply
* Re: [PATCH] of_mdio: use of_property_read_u32_array()
From: David Miller @ 2017-08-07 21:07 UTC (permalink / raw)
To: sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8
Cc: andrew-g2DYL2Zd6BY, f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170804214354.351406407-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
From: Sergei Shtylyov <sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
Date: Sat, 05 Aug 2017 00:43:43 +0300
> 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-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
Applied to net-next.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ 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